/*** *initctyp.c - contains _init_ctype * * Copyright (c) 1991-1993, 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 *** * *Revision History: * 12-08-91 ETC Created. * 12-20-91 ETC Updated to use new NLSAPI GetLocaleInfo. * 12-18-92 CFW Ported to Cuda tree, changed _CALLTYPE4 to _CRTAPI3. * 01-19-03 CFW Move to _NEWCTYPETABLE, remove switch. * 02-08-93 CFW Bug fixes under _INTL switch. * 05-20-93 GJF Include windows.h, not individual win*.h files * 06-11-93 CFW Now inithelp takes void *. * *******************************************************************************/ #ifdef _INTL #include #include #include #include #include #include #include #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 _CRTAPI3 _init_ctype ( void ) { #if defined _POSIX_ return 0; #else /* _POSIX_ */ /* 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 */ int size; // char buffer sizes int wcsize; // wide char buffer sizes 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 CPInfo; // 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_IDEFAULTCODEPAGE, (void *)&_lc_codepage) == -1) goto error_cleanup; } /* allocate new buffers for tables */ newctype1 = (unsigned short *) malloc (_CTABSIZE * sizeof(unsigned short)); newwctype1 = (unsigned short *) malloc (_CTABSIZE * sizeof(unsigned short)); cbuffer = (unsigned char *) malloc (_CTABSIZE * sizeof(char)); wbuffer = (wchar_t *) malloc (_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, &CPInfo) == FALSE) goto error_cleanup; if (CPInfo.MaxCharSize > MB_LEN_MAX) goto error_cleanup; __mb_cur_max = (unsigned short) CPInfo.MaxCharSize; /* zero out leadbytes so MBtoWC doesn't interpret as multi-byte chars */ if (__mb_cur_max > 1) { for (cp = (unsigned char *)CPInfo.LeadByte; cp[0] && cp[1]; cp += 2) { for (i = cp[0]; i <= cp[1]; i++) cbuffer[i] = 0; } } /* convert to wide character string */ size = (_CTABSIZE-1) * sizeof(char); wcsize = (_CTABSIZE-1) * sizeof(wchar_t); if (MultiByteToWideChar (_lc_codepage, 0, (char *)cbuffer, size, wbuffer, wcsize) == 0) goto error_cleanup; /* convert to newctype1 table */ if (GetStringTypeW (CT_CTYPE1, wbuffer, _CTABSIZE-1, newctype1+1) == 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 newctype1 table */ if (GetStringTypeW (CT_CTYPE1, wbuffer, _CTABSIZE-1, newwctype1+1) == 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 *)CPInfo.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 (ctype1); ctype1 = newctype1; if (wctype1) free (wctype1); wctype1 = newwctype1; /* cleanup and return success */ free (cbuffer); free (wbuffer); return 0; error_cleanup: free (newctype1); free (newwctype1); free (cbuffer); free (wbuffer); return 1; } else { /* set pointers to static C-locale table */ _pctype = _ctype + 1; _pwctype = _ctype + 1; /* free dynamic locale-specific tables */ free (ctype1); free (wctype1); ctype1 = NULL; wctype1 = NULL; return 0; } #endif /* _POSIX_ */ } #endif /* _INTL */