home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / initnum.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  5KB  |  157 lines

  1. /***
  2. *initnum.c - contains __init_numeric
  3. *
  4. *       Copyright (c) 1991-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Contains the locale-category initialization function: __init_numeric().
  8. *
  9. *       Each initialization function sets up locale-specific information
  10. *       for their category, for use by functions which are affected by
  11. *       their locale category.
  12. *
  13. *       *** For internal use by setlocale() only ***
  14. *
  15. *******************************************************************************/
  16.  
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <windows.h>
  20. #include <locale.h>
  21. #include <setlocal.h>
  22. #include <malloc.h>
  23. #include <nlsint.h>
  24. #include <dbgint.h>
  25.  
  26. static void fix_grouping(
  27.         char *grouping
  28.         )
  29. {
  30.         /*
  31.          * ANSI specifies that the fields should contain "\3" [\3\0] to indicate
  32.          * thousands groupings (100,000,000.00 for example).
  33.          * NT uses "3;0"; ASCII 3 instead of value 3 and the ';' is extra.
  34.          * So here we convert the NT version to the ANSI version.
  35.          */
  36.  
  37.         while (*grouping)
  38.         {
  39.             /* convert '3' to '\3' */
  40.             if (*grouping >= '0' && *grouping <= '9')
  41.             {
  42.                 *grouping = *grouping - '0';
  43.                 grouping++;
  44.             }
  45.  
  46.             /* remove ';' */
  47.             else if (*grouping == ';')
  48.             {
  49.                 char *tmp = grouping;
  50.  
  51.                 do
  52.                     *tmp = *(tmp+1);
  53.                 while (*++tmp);
  54.             }
  55.  
  56.             /* unknown (illegal) character, ignore */
  57.             else
  58.                 grouping++;
  59.         }
  60. }
  61.  
  62. /***
  63. *int __init_numeric() - initialization for LC_NUMERIC locale category.
  64. *
  65. *Purpose:
  66. *
  67. *Entry:
  68. *       None.
  69. *
  70. *Exit:
  71. *       0 success
  72. *       1 fail
  73. *
  74. *Exceptions:
  75. *
  76. *******************************************************************************/
  77.  
  78. int __cdecl __init_numeric (
  79.         void
  80.         )
  81. {
  82.         static char *dec_pnt = NULL;
  83.         static char *thous_sep = NULL;
  84.         static char *grping = NULL;
  85.         int ret = 0;
  86.  
  87.         /* Numeric data is country--not language--dependent.  NT work-around. */
  88.         LCID ctryid = MAKELCID(__lc_id[LC_NUMERIC].wCountry, SORT_DEFAULT);
  89.  
  90.         if (__lc_handle[LC_NUMERIC] != _CLOCALEHANDLE)
  91.         {
  92.                 ret |= __getlocaleinfo(LC_STR_TYPE, ctryid, LOCALE_SDECIMAL, (void *)&dec_pnt);
  93.                 ret |= __getlocaleinfo(LC_STR_TYPE, ctryid, LOCALE_STHOUSAND, (void *)&thous_sep);
  94.                 ret |= __getlocaleinfo(LC_STR_TYPE, ctryid, LOCALE_SGROUPING, (void *)&grping);
  95.             fix_grouping(grping);
  96.  
  97.                 if (ret)
  98.                 {
  99.                         _free_crt (dec_pnt);
  100.                         _free_crt (thous_sep);
  101.                         _free_crt (grping);
  102.                         dec_pnt = NULL;
  103.                         thous_sep = NULL;
  104.                         grping = NULL;
  105.                         return -1;
  106.                 }
  107.  
  108.                 if (__lconv->decimal_point != __lconv_static_decimal)
  109.                 {
  110.                         _free_crt(__lconv->decimal_point);
  111.                         _free_crt(__lconv->thousands_sep);
  112.                         _free_crt(__lconv->grouping);
  113.                 }
  114.  
  115.                 __lconv->decimal_point = dec_pnt;
  116.                 __lconv->thousands_sep = thous_sep;
  117.                 __lconv->grouping = grping;
  118.  
  119.  
  120.                 /* set global decimal point character */
  121.                 *__decimal_point = *__lconv->decimal_point;
  122.                 __decimal_point_length = 1;
  123.  
  124.                 return 0;
  125.  
  126.         } else {
  127.                 _free_crt (dec_pnt);
  128.                 _free_crt (thous_sep);
  129.                 _free_crt (grping);
  130.                 dec_pnt = NULL;
  131.                 thous_sep = NULL;
  132.                 grping = NULL;
  133.  
  134.                 /* malloc them so we can free them */
  135.                 if ((__lconv->decimal_point =
  136.                     _malloc_crt(2)) == NULL)
  137.                 return -1;
  138.                 strcpy(__lconv->decimal_point, ".");
  139.  
  140.                 if ((__lconv->thousands_sep =
  141.                     _malloc_crt(2)) == NULL)
  142.                 return -1;
  143.                 __lconv->thousands_sep[0] = '\0';
  144.  
  145.                 if ((__lconv->grouping =
  146.                     _malloc_crt(2)) == NULL)
  147.                 return -1;
  148.                 __lconv->grouping[0] = '\0';
  149.  
  150.                 /* set global decimal point character */
  151.                 *__decimal_point = *__lconv->decimal_point;
  152.                 __decimal_point_length = 1;
  153.  
  154.                 return 0;
  155.         }
  156. }
  157.