home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
crt
/
src
/
initctyp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-17
|
7KB
|
202 lines
/***
*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;
}
}