WizardsToolkit  1.0.7
locale.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                  L       OOO    CCCC   AAA   L      EEEEE                   %
00007 %                  L      O   O  C      A   A  L      E                       %
00008 %                  L      O   O  C      AAAAA  L      EEE                     %
00009 %                  L      O   O  C      A   A  L      E                       %
00010 %                  LLLLL   OOO    CCCC  A   A  LLLLL  EEEEE                   %
00011 %                                                                             %
00012 %                                                                             %
00013 %                      WizardCore Image Locale Methods                        %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                                 July 2003                                   %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2012 ImageWizard Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagewizard.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "wizard/studio.h"
00043 #include "wizard/blob.h"
00044 #include "wizard/client.h"
00045 #include "wizard/configure.h"
00046 #include "wizard/exception.h"
00047 #include "wizard/exception-private.h"
00048 #include "wizard/hashmap.h"
00049 #include "wizard/locale_.h"
00050 #include "wizard/log.h"
00051 #include "wizard/memory_.h"
00052 #include "wizard/semaphore.h"
00053 #include "wizard/splay-tree.h"
00054 #include "wizard/string_.h"
00055 #include "wizard/token.h"
00056 #include "wizard/utility.h"
00057 #include "wizard/xml-tree.h"
00058 
00059 /*
00060   Define declarations.
00061 */
00062 #define LocaleFilename  "locale.xml"
00063 #define MaxRecursionDepth  200
00064 
00065 static SemaphoreInfo
00066   *locale_semaphore = (SemaphoreInfo *) NULL;
00067 
00068 static volatile locale_t
00069   c_locale = (locale_t) NULL;
00070 
00071 static volatile WizardBooleanType
00072   instantiate_locale = WizardFalse;
00073 
00074 /*
00075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00076 %                                                                             %
00077 %                                                                             %
00078 %                                                                             %
00079 +   A c q u i r e C L o c a l e                                               %
00080 %                                                                             %
00081 %                                                                             %
00082 %                                                                             %
00083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00084 %
00085 %  AcquireCLocale() allocates the C locale object, or (locale_t) 0 with
00086 %  errno set if it cannot be acquired.
00087 %
00088 %  The format of the AcquireCLocale method is:
00089 %
00090 %      locale_t AcquireCLocale(void)
00091 %
00092 */
00093 static locale_t AcquireCLocale(void)
00094 {
00095 #if defined(WIZARDSTOOLKIT_HAVE_NEWLOCALE)
00096   if (c_locale == (locale_t) NULL)
00097     c_locale=newlocale(LC_ALL_MASK,"C",(locale_t) 0);
00098 #elif defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00099   if (c_locale == (locale_t) NULL)
00100     c_locale=_create_locale(LC_ALL,"C");
00101 #endif
00102   return(c_locale);
00103 }
00104 
00105 /*
00106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00107 %                                                                             %
00108 %                                                                             %
00109 %                                                                             %
00110 +   D e s t r o y C L o c a l e                                               %
00111 %                                                                             %
00112 %                                                                             %
00113 %                                                                             %
00114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00115 %
00116 %  DestroyCLocale() releases the resources allocated for a locale object
00117 %  returned by a call to the AcquireCLocale() method.
00118 %
00119 %  The format of the DestroyCLocale method is:
00120 %
00121 %      void DestroyCLocale(void)
00122 %
00123 */
00124 static void DestroyCLocale(void)
00125 {
00126 #if defined(WIZARDSTOOLKIT_HAVE_NEWLOCALE)
00127   if (c_locale != (locale_t) NULL)
00128     freelocale(c_locale);
00129 #elif defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00130   if (c_locale != (locale_t) NULL)
00131     _free_locale(c_locale);
00132 #endif
00133   c_locale=(locale_t) NULL;
00134 }
00135 
00136 /*
00137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00138 %                                                                             %
00139 %                                                                             %
00140 %                                                                             %
00141 +  F o r m a t L o c a l e F i l e                                            %
00142 %                                                                             %
00143 %                                                                             %
00144 %                                                                             %
00145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00146 %
00147 %  FormatLocaleFile() prints formatted output of a variable argument list to a
00148 %  file in the "C" locale.
00149 %
00150 %  The format of the FormatLocaleFile method is:
00151 %
00152 %      ssize_t FormatLocaleFile(FILE *file,const char *format,...)
00153 %
00154 %  A description of each parameter follows.
00155 %
00156 %   o file:  the file.
00157 %
00158 %   o format:  A file describing the format to use to write the remaining
00159 %     arguments.
00160 %
00161 */
00162 
00163 WizardExport ssize_t FormatLocaleFileList(FILE *file,
00164   const char *restrict format,va_list operands)
00165 {
00166   ssize_t
00167     n;
00168 
00169 #if defined(WIZARDSTOOLKIT_HAVE_VFPRINTF_L)
00170  {
00171     locale_t
00172       locale;
00173 
00174     locale=AcquireCLocale();
00175     if (locale == (locale_t) NULL)
00176       n=(ssize_t) vfprintf(file,format,operands);
00177     else
00178 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00179       n=(ssize_t) vfprintf_l(file,format,locale,operands);
00180 #else
00181       n=(ssize_t) vfprintf_l(file,locale,format,operands);
00182 #endif
00183   }
00184 #else
00185 #if defined(WIZARDSTOOLKIT_HAVE_USELOCALE)
00186   {
00187     locale_t
00188       locale,
00189       previous_locale;
00190 
00191     locale=AcquireCLocale();
00192     if (locale == (locale_t) NULL)
00193       n=(ssize_t) vfprintf(file,format,operands);
00194     else
00195       {
00196         previous_locale=uselocale(locale);
00197         n=(ssize_t) vfprintf(file,format,operands);
00198         uselocale(previous_locale);
00199       }
00200   }
00201 #else
00202   n=(ssize_t) vfprintf(file,format,operands);
00203 #endif
00204 #endif
00205   return(n);
00206 }
00207 
00208 WizardExport ssize_t FormatLocaleFile(FILE *file,const char *restrict format,
00209   ...)
00210 {
00211   ssize_t
00212     n;
00213 
00214   va_list
00215     operands;
00216 
00217   va_start(operands,format);
00218   n=FormatLocaleFileList(file,format,operands);
00219   va_end(operands);
00220   return(n);
00221 }
00222 
00223 /*
00224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00225 %                                                                             %
00226 %                                                                             %
00227 %                                                                             %
00228 +  F o r m a t L o c a l e S t r i n g                                        %
00229 %                                                                             %
00230 %                                                                             %
00231 %                                                                             %
00232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00233 %
00234 %  FormatLocaleString() prints formatted output of a variable argument list to
00235 %  a string buffer in the "C" locale.
00236 %
00237 %  The format of the FormatLocaleString method is:
00238 %
00239 %      ssize_t FormatLocaleString(char *string,const size_t length,
00240 %        const char *format,...)
00241 %
00242 %  A description of each parameter follows.
00243 %
00244 %   o string:  FormatLocaleString() returns the formatted string in this
00245 %     character buffer.
00246 %
00247 %   o length: the maximum length of the string.
00248 %
00249 %   o format:  A string describing the format to use to write the remaining
00250 %     arguments.
00251 %
00252 */
00253 
00254 WizardExport ssize_t FormatLocaleStringList(char *restrict string,
00255   const size_t length,const char *restrict format,va_list operands)
00256 {
00257   ssize_t
00258     n;
00259 
00260 #if defined(WIZARDSTOOLKIT_HAVE_VSNPRINTF_L)
00261   {
00262     locale_t
00263       locale;
00264 
00265     locale=AcquireCLocale();
00266     if (locale == (locale_t) NULL)
00267       n=(ssize_t) vsnprintf(string,length,format,operands);
00268     else
00269 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00270       n=(ssize_t) vsnprintf_l(string,length,format,locale,operands);
00271 #else
00272       n=(ssize_t) vsnprintf_l(string,length,locale,format,operands);
00273 #endif
00274   }
00275 #elif defined(WIZARDSTOOLKIT_HAVE_VSNPRINTF)
00276 #if defined(WIZARDSTOOLKIT_HAVE_USELOCALE)
00277   {
00278     locale_t
00279       locale,
00280       previous_locale;
00281 
00282     locale=AcquireCLocale();
00283     if (locale == (locale_t) NULL)
00284       n=(ssize_t) vsnprintf(string,length,format,operands);
00285     else
00286       {
00287         previous_locale=uselocale(locale);
00288         n=(ssize_t) vsnprintf(string,length,format,operands);
00289         uselocale(previous_locale);
00290       }
00291   }
00292 #else
00293   n=(ssize_t) vsnprintf(string,length,format,operands);
00294 #endif
00295 #else
00296   n=(ssize_t) vsprintf(string,format,operands);
00297 #endif
00298   if (n < 0)
00299     string[length-1]='\0';
00300   return(n);
00301 }
00302 
00303 WizardExport ssize_t FormatLocaleString(char *restrict string,
00304   const size_t length,const char *restrict format,...)
00305 {
00306   ssize_t
00307     n;
00308 
00309   va_list
00310     operands;
00311 
00312   va_start(operands,format);
00313   n=FormatLocaleStringList(string,length,format,operands);
00314   va_end(operands);
00315   return(n);
00316 }
00317 
00318 /*
00319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00320 %                                                                             %
00321 %                                                                             %
00322 %                                                                             %
00323 +   I n t e r p r e t L o c a l e V a l u e                                   %
00324 %                                                                             %
00325 %                                                                             %
00326 %                                                                             %
00327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00328 %
00329 %  InterpretLocaleValue() interprets the string as a floating point number in
00330 %  the "C" locale and returns its value as a double. If sentinal is not a null
00331 %  pointer, the method also sets the value pointed by sentinal to point to the
00332 %  first character after the number.
00333 %
00334 %  The format of the InterpretLocaleValue method is:
00335 %
00336 %      double InterpretLocaleValue(const char *value,char **sentinal)
00337 %
00338 %  A description of each parameter follows:
00339 %
00340 %    o value: the string value.
00341 %
00342 %    o sentinal:  if sentinal is not NULL, a pointer to the character after the
00343 %      last character used in the conversion is stored in the location
00344 %      referenced by sentinal.
00345 %
00346 */
00347 WizardExport double InterpretLocaleValue(const char *restrict string,
00348   char **restrict sentinal)
00349 {
00350   char
00351     *q;
00352 
00353   double
00354     value;
00355 
00356   if ((*string == '0') && ((string[1] | 0x20)=='x'))
00357     value=(double) strtoul(string,&q,16);
00358   else
00359     {
00360 #if defined(WIZARDSTOOLKIT_HAVE_STRTOD_L)
00361       locale_t
00362         locale;
00363 
00364       locale=AcquireCLocale();
00365       if (locale == (locale_t) NULL)
00366         value=strtod(string,&q);
00367       else
00368         value=strtod_l(string,&q,locale);
00369 #else
00370       value=strtod(string,&q);
00371 #endif
00372     }
00373   if (sentinal != (char **) NULL)
00374     *sentinal=q;
00375   return(value);
00376 }
00377 
00378 /*
00379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00380 %                                                                             %
00381 %                                                                             %
00382 %                                                                             %
00383 +   L o c a l e C o m p o n e n t G e n e s i s                               %
00384 %                                                                             %
00385 %                                                                             %
00386 %                                                                             %
00387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00388 %
00389 %  LocaleComponentGenesis() instantiates the locale component.
00390 %
00391 %  The format of the LocaleComponentGenesis method is:
00392 %
00393 %      WizardBooleanType LocaleComponentGenesis(void)
00394 %
00395 */
00396 WizardExport WizardBooleanType LocaleComponentGenesis(void)
00397 {
00398   AcquireSemaphoreInfo(&locale_semaphore);
00399   return(WizardTrue);
00400 }
00401 
00402 /*
00403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00404 %                                                                             %
00405 %                                                                             %
00406 %                                                                             %
00407 +   L o c a l e C o m p o n e n t T e r m i n u s                             %
00408 %                                                                             %
00409 %                                                                             %
00410 %                                                                             %
00411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00412 %
00413 %  LocaleComponentTerminus() destroys the locale component.
00414 %
00415 %  The format of the LocaleComponentTerminus method is:
00416 %
00417 %      LocaleComponentTerminus(void)
00418 %
00419 */
00420 WizardExport void LocaleComponentTerminus(void)
00421 {
00422   if (locale_semaphore == (SemaphoreInfo *) NULL)
00423     AcquireSemaphoreInfo(&locale_semaphore);
00424   LockSemaphoreInfo(locale_semaphore);
00425   DestroyCLocale();
00426   instantiate_locale=WizardFalse;
00427   UnlockSemaphoreInfo(locale_semaphore);
00428   DestroySemaphoreInfo(&locale_semaphore);
00429 }