summaryrefslogtreecommitdiffstats
path: root/private/crt32/misc/initctyp.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/misc/initctyp.c')
-rw-r--r--private/crt32/misc/initctyp.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/private/crt32/misc/initctyp.c b/private/crt32/misc/initctyp.c
new file mode 100644
index 000000000..02382a1b2
--- /dev/null
+++ b/private/crt32/misc/initctyp.c
@@ -0,0 +1,212 @@
+/***
+*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 <stdlib.h>
+#include <windows.h>
+#include <locale.h>
+#include <setlocal.h>
+#include <ctype.h>
+#include <malloc.h>
+#include <limits.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 _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 */