home *** CD-ROM | disk | FTP | other *** search
- /***
- *initctyp.c - contains __init_ctype
- *
- * Copyright (c) 1991-1998, Microsoft Corporation. All rights reserved.
- *
- *Purpose:
- * Contains the locale-category initialization function: __init_ctype().
- *
- * Each initialization function sets up locale-specific information
- * for their category, for use by functions which are affected by
- * their locale category.
- *
- * *** For internal use by setlocale() only ***
- *
- *******************************************************************************/
-
- #include <stdlib.h>
- #include <windows.h>
- #include <locale.h>
- #include <setlocal.h>
- #include <ctype.h>
- #include <malloc.h>
- #include <limits.h>
- #include <awint.h>
- #include <dbgint.h>
-
- #define _CTABSIZE 257 /* size of ctype tables */
-
- /***
- *int __init_ctype() - initialization for LC_CTYPE locale category.
- *
- *Purpose:
- * In non-C locales, preread ctype tables for chars and wide-chars.
- * Old tables are freed when new tables are fully established, else
- * the old tables remain intact (as if original state unaltered).
- * The leadbyte table is implemented as the high bit in ctype1.
- *
- * In the C locale, ctype tables are freed, and pointers point to
- * the static ctype table.
- *
- * Tables contain 257 entries: -1 to 256.
- * Table pointers point to entry 0 (to allow index -1).
- *
- *Entry:
- * None.
- *
- *Exit:
- * 0 success
- * 1 fail
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- int __cdecl __init_ctype (
- void
- )
- {
- /* non-C locale table for char's */
- static unsigned short *ctype1 = NULL; /* keep around until next time */
- unsigned short *newctype1; /* temp new table */
-
- /* non-C locale table for wchar_t's */
- static unsigned short *wctype1 = NULL; /* keep around until next time */
- unsigned short *newwctype1; /* temp new table */
-
- unsigned char *cbuffer = NULL; /* char working buffer */
- wchar_t *wbuffer = NULL; /* wchar_t working buffer */
-
- int i; /* general purpose counter */
- unsigned char *cp; /* char pointer */
- wchar_t *wcp; /* wide char pointer */
- CPINFO lpCPInfo; /* struct for use with GetCPInfo */
-
- /* allocate and set up buffers before destroying old ones */
- /* codepage will be restored by setlocale if error */
-
-
- if (__lc_handle[LC_CTYPE] != _CLOCALEHANDLE)
- {
- if (__lc_codepage == 0)
- { /* code page was not specified */
- if ( __getlocaleinfo( LC_INT_TYPE,
- MAKELCID(__lc_id[LC_CTYPE].wLanguage, SORT_DEFAULT),
- LOCALE_IDEFAULTANSICODEPAGE,
- (char **)&__lc_codepage ) )
- goto error_cleanup;
- }
-
- /* allocate new buffers for tables */
- newctype1 = (unsigned short *)
- _malloc_crt(_CTABSIZE * sizeof(unsigned short));
- newwctype1 = (unsigned short *)
- _malloc_crt(_CTABSIZE * sizeof(unsigned short));
- cbuffer = (unsigned char *)
- _malloc_crt (_CTABSIZE * sizeof(char));
- wbuffer = (wchar_t *)
- _malloc_crt (_CTABSIZE * sizeof(wchar_t));
-
- if (!newctype1 || !newwctype1 || !cbuffer || !wbuffer)
- goto error_cleanup;
-
- /* construct string composed of first 256 chars in sequence */
- for (cp=cbuffer, i=0; i<_CTABSIZE-1; i++)
- *cp++ = (unsigned char)i;
-
- if (GetCPInfo( __lc_codepage, &lpCPInfo) == FALSE)
- goto error_cleanup;
-
- if (lpCPInfo.MaxCharSize > MB_LEN_MAX)
- goto error_cleanup;
-
- __mb_cur_max = (unsigned short) lpCPInfo.MaxCharSize;
-
- /* zero out leadbytes so GetStringType doesn't interpret as multi-byte chars */
- if (__mb_cur_max > 1)
- {
- for (cp = (unsigned char *)lpCPInfo.LeadByte; cp[0] && cp[1]; cp += 2)
- {
- for (i = cp[0]; i <= cp[1]; i++)
- cbuffer[i] = 0;
- }
- }
-
- /* convert to newctype1 table - ignore invalid char errors */
- if ( __crtGetStringTypeA( CT_CTYPE1,
- cbuffer,
- _CTABSIZE-1,
- newctype1+1,
- 0,
- 0,
- FALSE ) == FALSE )
- goto error_cleanup;
- *newctype1 = 0; /* entry for EOF */
-
- /* construct wide char string composed of first 256 chars in sequence */
- for (wcp=wbuffer, i=0; i<_CTABSIZE-1; i++)
- *wcp++ = (wchar_t)i;
-
- /* convert to newwctype1 table */
- if ( __crtGetStringTypeW( CT_CTYPE1,
- wbuffer,
- _CTABSIZE-1,
- newwctype1+1,
- 0,
- 0 ) == FALSE )
- goto error_cleanup;
- *newwctype1 = 0; /* entry for EOF */
-
- /* ignore DefaultChar */
-
- /* mark lead-byte entries in newctype1 table */
- if (__mb_cur_max > 1)
- {
- for (cp = (unsigned char *)lpCPInfo.LeadByte; cp[0] && cp[1]; cp += 2)
- {
- for (i = cp[0]; i <= cp[1]; i++)
- newctype1[i+1] = _LEADBYTE;
- }
- }
-
- /* set pointers to point to entry 0 of tables */
- _pctype = newctype1 + 1;
- _pwctype = newwctype1 + 1;
-
- /* free old tables */
- if (ctype1)
- _free_crt (ctype1);
- ctype1 = newctype1;
-
- if (wctype1)
- _free_crt (wctype1);
- wctype1 = newwctype1;
-
- /* cleanup and return success */
- _free_crt (cbuffer);
- _free_crt (wbuffer);
- return 0;
-
- error_cleanup:
- _free_crt (newctype1);
- _free_crt (newwctype1);
- _free_crt (cbuffer);
- _free_crt (wbuffer);
- return 1;
-
- } else {
-
- /* set pointers to static C-locale table */
- _pctype = _ctype + 1;
- _pwctype = _ctype + 1;
-
- /* free dynamic locale-specific tables */
- _free_crt (ctype1);
- _free_crt (wctype1);
- ctype1 = NULL;
- wctype1 = NULL;
-
- return 0;
- }
- }
-