File: locale.cpp

package info (click to toggle)
openbabel 2.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 36,644 kB
  • ctags: 33,717
  • sloc: cpp: 242,528; ansic: 87,037; sh: 10,280; perl: 5,518; python: 5,156; pascal: 793; makefile: 747; cs: 392; xml: 97; ruby: 54; java: 23
file content (130 lines) | stat: -rw-r--r-- 3,733 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**********************************************************************
locale.cpp - Handle internal numeric locale issues -- parse data in "C"
 
Copyright (C) 2008 by Geoffrey R. Hutchison
 
This file is part of the Open Babel project.
For more information, see <http://openbabel.sourceforge.net/>
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 2 of the License.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
***********************************************************************/

#include <stdlib.h>
#include <string.h>
#include <openbabel/locale.h>

#if HAVE_XLOCALE_H
#include <xlocale.h>
#endif
#if HAVE_LOCALE_H
#include <locale.h>
#endif

namespace OpenBabel
{
  class OBLocalePrivate {
  public:
    char *old_locale_string;
#if HAVE_USELOCALE
    locale_t new_c_num_locale;
    locale_t old_locale;
#endif
    unsigned int counter; // Reference counter -- ensures balance in SetLocale/RestoreLocale calls

    OBLocalePrivate(): counter(0)
    {
#if HAVE_USELOCALE
      new_c_num_locale = newlocale(LC_NUMERIC_MASK, NULL, NULL);
#endif
    }
    
    ~OBLocalePrivate()
    {    }
  }; // class definition for OBLocalePrivate

  /** \class OBLocale locale.h <openbabel/locale.h>
   *
   * Many users will utilize Open Babel and tools built on top of the library
   * in non-English locales. In particular, the numeric locale (LC_NUMERIC) 
   * is used to determine the parsing of numeric data in files, reference data,
   * etc.
   *
   * The OBLocale class, and its global variable obLocale handle both internal
   * parsing of data through the ANSI-C numeric locale and can be used for
   * external use as well.
   *
   * In particular, where available, OBLocale will use the enhanced uselocale()
   * interface, which sets the locale for a particular thread, rather
   * for the entire process. (This is available on Linux, Mac OS X, 
   * and other platforms.)
   *
   * \code
   * obLocale.SetLocale(); // set the numeric locale before reading data
   * ... // your data processing here
   * obLocale.RestoreLocale(); // restore the numeric locale
   * \endcode
   *
   * To prevent errors, OBLocale will handle reference counting.
   * If nested function calls all set the locale, only the first call
   * to SetLocale() and the last call to RestoreLocale() will do any work.
   **/

  OBLocale::OBLocale()
  {
    d = new OBLocalePrivate;
  }
  
  OBLocale::~OBLocale()
  {
    if (d) {
      delete d;
      d = NULL;
    }
  }

  void OBLocale::SetLocale()
  {
    if (d->counter == 0) {
      // Set the locale for number parsing to avoid locale issues: PR#1785463
#if HAVE_USELOCALE
      // Extended per-thread interface
      d->old_locale = uselocale(d->new_c_num_locale);
#else
      // Original global POSIX interface
      d->old_locale_string = strdup (setlocale (LC_NUMERIC, NULL));
  	  setlocale(LC_NUMERIC, "C");
#endif
    }
    
    ++d->counter;
  }
  
  void OBLocale::RestoreLocale()
  {
    --d->counter;
    if(d->counter == 0) {
      // return the locale to the original one
#ifdef HAVE_USELOCALE
      uselocale(d->old_locale);
#else
      setlocale(LC_NUMERIC, d->old_locale_string);
      free (d->old_locale_string);
#endif
    }
  }

  //global definitions
  // Global OBLocale for setting and restoring locale information
  OBLocale   obLocale;

} // namespace OpenBabel

//! \file locale.cpp
//! \brief Handle internal numeric locale issues -- parse data in "C"