diff options
author | neonloop | 2021-10-20 14:54:27 +0000 |
---|---|---|
committer | neonloop | 2021-10-20 14:54:27 +0000 |
commit | ea1947ffcc606d757357398b24e74a3f4ecefa07 (patch) | |
tree | 2031b8d4fc4c61063c710a7148378f57e662efbd /core/common | |
download | bennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.tar.gz bennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.tar.bz2 bennugd-ea1947ffcc606d757357398b24e74a3f4ecefa07.zip |
Initial commit from steward-fu releasemain
Diffstat (limited to 'core/common')
-rw-r--r-- | core/common/b_crypt.c | 136 | ||||
-rw-r--r-- | core/common/debug.c | 311 | ||||
-rw-r--r-- | core/common/files.c | 901 | ||||
-rw-r--r-- | core/common/xctype.c | 185 |
4 files changed, 1533 insertions, 0 deletions
diff --git a/core/common/b_crypt.c b/core/common/b_crypt.c new file mode 100644 index 0000000..649a0b7 --- /dev/null +++ b/core/common/b_crypt.c @@ -0,0 +1,136 @@ +/* + * Copyright © 2006-2013 SplinterGU (Fenix/Bennugd) + * + * This file is part of Bennu - Game Development + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +/* ------------------------------------------------------------------------- */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "b_crypt.h" + +/* ------------------------------------------------------------------------- */ + +crypt_handle * crypt_create( int method, char * key ) +{ + crypt_handle * ch = calloc( sizeof( crypt_handle ), 1 ); + if ( !ch ) return NULL; + + ch->method = method; + + switch ( method ) + { + case CRYPT_DES : +#ifdef USE_LIBDES + if ( !DES_key_sched( ( DES_cblock * ) key, ch->ks[KEY0] ) ) return ch; +#else + if ( !DES_key_sched( ( DES_cblock * ) key, &ch->ks[KEY0] ) ) return ch; +#endif + break; + + case CRYPT_3DES : +#ifdef USE_LIBDES + if ( DES_key_sched( ( DES_cblock * ) key, ch->ks[KEY0] ) ) { free( ch ); return NULL; } + if ( DES_key_sched( ( DES_cblock * ) ( 8 + key ), ch->ks[KEY1] ) ) { free( ch ); return NULL; } + if ( !DES_key_sched( ( DES_cblock * ) ( 16 + key ), ch->ks[KEY2] ) ) return ch; +#else + if ( DES_key_sched( ( DES_cblock * ) key, &ch->ks[KEY0] ) ) { free( ch ); return NULL; } + if ( DES_key_sched( ( DES_cblock * ) ( 8 + key ), &ch->ks[KEY1] ) ) { free( ch ); return NULL; } + if ( !DES_key_sched( ( DES_cblock * ) ( 16 + key ), &ch->ks[KEY2] ) ) return ch; +#endif + break; + } + + free( ch ); + return NULL; +} + +/* ------------------------------------------------------------------------- */ + +void crypt_destroy( crypt_handle * ch ) +{ + if ( ch ) free( ch ); +} + +/* ------------------------------------------------------------------------- */ + +int crypt_data( crypt_handle * ch, char * in, char * out, int size, int enc ) +{ + DES_cblock aux; + + if ( !ch || ( size < 1 || size > 8 ) ) return -1; + + if ( enc && size < 8 ) memset( &in[size], '\0', 8 - size ); + + switch( ch->method ) + { + case CRYPT_DES : + if ( enc ) +#ifdef USE_LIBDES + DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, ch->ks[KEY0], DES_ENCRYPT ); +#else + DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, &ch->ks[KEY0], DES_ENCRYPT ); +#endif + else +#ifdef USE_LIBDES + DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, ch->ks[KEY0], DES_DECRYPT ); +#else + DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, &ch->ks[KEY0], DES_DECRYPT ); +#endif + break; + + case CRYPT_3DES : + if ( enc ) + { +#ifdef USE_LIBDES + DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, ch->ks[KEY0], DES_ENCRYPT ); + DES_ecb_encrypt( ( DES_cblock * ) out, ( DES_cblock * ) &aux, ch->ks[KEY1], DES_DECRYPT ); + DES_ecb_encrypt( ( DES_cblock * ) &aux, ( DES_cblock * ) out, ch->ks[KEY2], DES_ENCRYPT ); +#else + DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, &ch->ks[KEY0], DES_ENCRYPT ); + DES_ecb_encrypt( ( DES_cblock * ) out, ( DES_cblock * ) &aux, &ch->ks[KEY1], DES_DECRYPT ); + DES_ecb_encrypt( ( DES_cblock * ) &aux, ( DES_cblock * ) out, &ch->ks[KEY2], DES_ENCRYPT ); +#endif + } + else + { +#ifdef USE_LIBDES + DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, ch->ks[KEY2], DES_DECRYPT ); + DES_ecb_encrypt( ( DES_cblock * ) out, ( DES_cblock * ) &aux, ch->ks[KEY1], DES_ENCRYPT ); + DES_ecb_encrypt( ( DES_cblock * ) &aux, ( DES_cblock * ) out, ch->ks[KEY0], DES_DECRYPT ); +#else + DES_ecb_encrypt( ( DES_cblock * ) in, ( DES_cblock * ) out, &ch->ks[KEY2], DES_DECRYPT ); + DES_ecb_encrypt( ( DES_cblock * ) out, ( DES_cblock * ) &aux, &ch->ks[KEY1], DES_ENCRYPT ); + DES_ecb_encrypt( ( DES_cblock * ) &aux, ( DES_cblock * ) out, &ch->ks[KEY0], DES_DECRYPT ); +#endif + } + break; + } + + return ( enc ? 8 : size ); +} + +/* ------------------------------------------------------------------------- */ diff --git a/core/common/debug.c b/core/common/debug.c new file mode 100644 index 0000000..edbd767 --- /dev/null +++ b/core/common/debug.c @@ -0,0 +1,311 @@ +/* + * Copyright © 2006-2013 SplinterGU (Fenix/Bennugd) + * Copyright © 2002-2006 Fenix Team (Fenix) + * Copyright © 1999-2002 José Luis Cebrián Pagüe (Fenix) + * + * This file is part of Bennu - Game Development + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#include <stdio.h> + +#include "pslang.h" +#include "dcb.h" +#include "xstrings.h" + +#ifndef __BGDRTM__ +#include "bgdc.h" +#include "identifiers.h" +#else +#include "sysprocs_p.h" +#include "i_procdef.h" +#endif + +/* ---------------------------------------------------------------------- */ +/* Este módulo contiene funciones que muestran el equivalente */ +/* en texto de una instrucción o mnemónico */ +/* ---------------------------------------------------------------------- */ + +struct +{ + char * name; + int code; + int params ; +} +mnemonics[] = +{ + { "ARRAY" , MN_ARRAY , 1 }, + { "GET_PRIVATE" , MN_GET_PRIV , 1 }, + { "GET_REMOTE" , MN_GET_REMOTE , 1 }, + { "GET_LOCAL" , MN_GET_LOCAL , 1 }, + { "GET_GLOBAL" , MN_GET_GLOBAL , 1 }, + { "PRIVATE" , MN_PRIVATE , 1 }, + { "REMOTE" , MN_REMOTE , 1 }, + { "LOCAL" , MN_LOCAL , 1 }, + { "GLOBAL" , MN_GLOBAL , 1 }, + { "DUP" , MN_DUP , 0 }, + { "PUSH" , MN_PUSH , 1 }, + { "POP" , MN_POP , 0 }, + { "INDEX" , MN_INDEX , 1 }, + { "NEG" , MN_NEG , 0 }, + { "NOT" , MN_NOT , 0 }, + { "CALL" , MN_CALL , 1 }, + { "PROCESS" , MN_PROC , 1 }, + { "SYSCALL" , MN_SYSCALL , 1 }, + { "SYSPROC" , MN_SYSPROC , 1 }, + { "CLONE" , MN_CLONE , 1 }, + { "END" , MN_END , 0 }, + { "RETURN" , MN_RETURN , 0 }, + { "FRAME" , MN_FRAME , 0 }, + { "TYPE" , MN_TYPE , 1 }, + + { "MUL" , MN_MUL , 0 }, + { "DIV" , MN_DIV , 0 }, + { "ADD" , MN_ADD , 0 }, + { "SUB" , MN_SUB , 0 }, + { "MOD" , MN_MOD , 0 }, + { "ROR" , MN_ROR , 0 }, + { "ROL" , MN_ROL , 0 }, + { "AND" , MN_AND , 0 }, + { "OR" , MN_OR , 0 }, + { "XOR" , MN_XOR , 0 }, + + { "BNOT" , MN_BNOT , 0 }, + { "BAND" , MN_BAND , 0 }, + { "BOR" , MN_BOR , 0 }, + { "BXOR" , MN_BXOR , 0 }, + + { "EQ" , MN_EQ , 0 }, + { "NE" , MN_NE , 0 }, + { "GT" , MN_GT , 0 }, + { "LT" , MN_LT , 0 }, + { "GTE" , MN_GTE , 0 }, + { "LTE" , MN_LTE , 0 }, + + { "FLOAT2INT" , MN_FLOAT2INT , 1 }, + { "INT2FLOAT" , MN_INT2FLOAT , 1 }, + { "INT2WORD" , MN_INT2WORD , 1 }, + { "INT2BYTE" , MN_INT2BYTE , 1 }, + + { "POSTINC" , MN_POSTINC , 1 }, + { "POSTDEC" , MN_POSTDEC , 1 }, + { "INC" , MN_INC , 1 }, + { "DEC" , MN_DEC , 1 }, + { "VARADD" , MN_VARADD , 0 }, + { "VARSUB" , MN_VARSUB , 0 }, + { "VARMUL" , MN_VARMUL , 0 }, + { "VARDIV" , MN_VARDIV , 0 }, + { "VARMOD" , MN_VARMOD , 0 }, + { "VARXOR" , MN_VARXOR , 0 }, + { "VARAND" , MN_VARAND , 0 }, + { "VAROR" , MN_VAROR , 0 }, + { "VARROR" , MN_VARROR , 0 }, + { "VARROL" , MN_VARROL , 0 }, + { "LET" , MN_LET , 0 }, + { "LETNP" , MN_LETNP , 0 }, + + { "REPEAT" , MN_REPEAT , 1 }, + { "BREAK" , MN_BREAK , 1 }, + { "BRFALSE" , MN_BRFALSE , 1 }, + { "RETRUE" , MN_RETRUE , 1 }, + { "REFALSE" , MN_REFALSE , 1 }, + { "JUMP" , MN_JUMP , 1 }, + { "JFALSE" , MN_JFALSE , 1 }, + { "JTRUE" , MN_JTRUE , 1 }, + { "JTFALSE" , MN_JTFALSE , 1 }, + { "JTTRUE" , MN_JTTRUE , 1 }, + { "PTR" , MN_PTR , 0 }, + + { "SWITCH" , MN_SWITCH , 0 }, + { "CASE" , MN_CASE , 0 }, + { "CASE_R" , MN_CASE_R , 0 }, + { "JNOCASE" , MN_JNOCASE , 1 }, + + { "STRI2CHR" , MN_STRI2CHR , 0 }, + { "SUBSTR" , MN_SUBSTR , 1 }, + + { "STR2INT" , MN_STR2INT , 1 }, + { "STR2CHR" , MN_STR2CHR , 1 }, + { "INT2STR" , MN_INT2STR , 1 }, + { "CHR2STR" , MN_CHR2STR , 1 }, + { "STR2FLOAT" , MN_STR2FLOAT , 1 }, + { "FLOAT2STR" , MN_FLOAT2STR , 1 }, + { "POINTER2STR" , MN_POINTER2STR , 1 }, + + { "A2STR" , MN_A2STR , 0 }, + { "STR2A" , MN_STR2A , 0 }, + { "STRACAT" , MN_STRACAT , 0 }, + + { "MN_NCALL" , MN_NCALL , 1 }, + + { "MN_EXITHNDLR" , MN_EXITHNDLR , 1 }, + { "MN_ERRHNDLR" , MN_ERRHNDLR , 1 }, + { "MN_RESUME" , MN_RESUME , 1 }, + { "MN_RESUMEGOTO" , MN_RESUMEGOTO , 1 }, + + { "DEBUG" , MN_DEBUG , 1 }, + { "" , MN_SENTENCE , 1 }, + + { "PUBLIC" , MN_PUBLIC , 1 }, + { "GET_PUBLIC" , MN_GET_PUBLIC , 1 }, + + { "REMOTE_PUBLIC" , MN_REMOTE_PUBLIC , 1 }, + { "GET_REMOTE_PUBLIC" , MN_GET_REMOTE_PUBLIC , 1 }, + + { 0 , -1 , 0 } +} ; + +/* ---------------------------------------------------------------------- */ + +#ifdef __BGDRTM__ +extern int debug; +#endif + +static int mnemonics_inited = 0; + +struct +{ + char name[21]; + int params ; +} +mnemonics_sorted[256]; + +/* ---------------------------------------------------------------------- */ + +void mnemonic_dump( int i, int param ) +{ + int n = 0 ; + + if ( !mnemonics_inited ) + { + while ( mnemonics[n].name ) + { + sprintf( mnemonics_sorted[mnemonics[n].code & MN_MASK].name, "%-20s", mnemonics[n].name ); + mnemonics_sorted[mnemonics[n].code & MN_MASK].params = mnemonics[n].params; + n++ ; + } + mnemonics_inited = 1; + } + + n = i & MN_MASK ; + +#ifdef __BGDRTM__ + if ( debug > 1 ) + { +#endif + if ( MN_PARAMS( i ) ) printf( "%08X %08X " , i, param ); + else printf( "%08X ", i ); +#ifdef __BGDRTM__ + } +#endif + + if ( mnemonics_sorted[ n ].name ) + { +#ifdef __BGDRTM__ + if ( debug > 1 ) + { +#endif + switch ( MN_TYPEOF( i ) ) + { + case MN_UNSIGNED: + printf( "UNSIGNED " ) ; + break ; + + case MN_WORD: + printf( "SHORT " ) ; + break ; + + case MN_WORD | MN_UNSIGNED: + printf( "WORD " ) ; + break ; + + case MN_BYTE: + printf( "CHAR " ) ; + break ; + + case MN_BYTE | MN_UNSIGNED: + printf( "BYTE " ) ; + break ; + + case MN_FLOAT: + printf( "FLOAT " ) ; + break ; + + case MN_STRING: + printf( "STRING " ) ; + break ; + + default: + printf( " " ) ; + break ; + } + + printf( "%s", mnemonics_sorted[n].name ) ; + + if ( i == MN_SYSCALL || i == MN_SYSPROC ) + { + printf( "%s (%d)\n", sysproc_name( param ), param ) ; + } + else if ( i == MN_CALL || i == MN_PROC || i == MN_TYPE ) + { +#ifndef __BGDRTM__ + if ( libmode ) printf( "%s (%d)\n", identifier_name( (procdef_search(param))->identifier ), param ) ; + else printf( "%s (%d)\n", identifier_name( (procdef_get(param))->identifier ), param ) ; +#else + printf( "%s (%d)\n", procdef_get(param)->name, param ) ; +#endif + } + else if ( i != MN_SENTENCE ) + { + switch ( MN_PARAMS( i ) ) + { + case 1: + printf( "%d", param ) ; + break; + + } + printf( "\n" ) ; + } + +#ifdef __BGDRTM__ + } +#endif + + if ( i == MN_SENTENCE ) + { +#ifdef __BGDRTM__ + if ( dcb.sourcecount[param >> 24] ) + { + if ( dcb.data.Version == 0x0700 ) printf( "%s:%-10d %s\n", dcb.sourcefiles[param >> 24], param & 0xFFFFFF, dcb.sourcelines[param >> 24] [( param & 0xFFFFFF )-1] ) ; + else printf( "%s:%-10d %s\n", dcb.sourcefiles[param >> 20], param & 0xFFFFF , dcb.sourcelines[param >> 20] [( param & 0xFFFFF )-1] ) ; + } +#else + printf( "%s:%-10d\n", files[param>>20], param&(( 1 << 20 ) - 1 ) ) ; +#endif + } + } +#ifdef __BGDRTM__ + else if ( debug > 1 ) +#endif + printf( "\n" ); + +} diff --git a/core/common/files.c b/core/common/files.c new file mode 100644 index 0000000..8c3be7d --- /dev/null +++ b/core/common/files.c @@ -0,0 +1,901 @@ +/* + * Copyright � 2006-2013 SplinterGU (Fenix/Bennugd) + * Copyright � 2002-2006 Fenix Team (Fenix) + * Copyright � 1999-2002 Jos� Luis Cebri�n Pag�e (Fenix) + * + * This file is part of Bennu - Game Development + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#ifdef _WIN32 +#include <windows.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#ifdef TARGET_BEOS +#include <posix/assert.h> +#else +#include <assert.h> +#endif + +#include <stdint.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "files.h" + +#define MAX_POSSIBLE_PATHS 128 + +char * possible_paths[MAX_POSSIBLE_PATHS] = { NULL } ; + +int opened_files = 0; + +typedef struct +{ + char * stubname ; + char * name ; + int offset ; + int size ; + FILE * fp ; +} +XFILE ; + +XFILE * x_file = NULL ; +int max_x_files = 0; + +int x_files_count = 0 ; + +/* Add new file to PATH */ + +void xfile_init( int maxfiles ) +{ + x_file = ( XFILE * ) calloc( sizeof( XFILE ), maxfiles ); + max_x_files = maxfiles; +} + +void file_add_xfile( file * fp, char * stubname, long offset, char * name, int size ) +{ + char * ptr ; + + assert( x_files_count < max_x_files ) ; + assert( fp->type == F_FILE ) ; + + x_file[x_files_count].stubname = strdup( stubname ); + x_file[x_files_count].fp = fp->fp ; + x_file[x_files_count].offset = offset ; + x_file[x_files_count].size = size ; + x_file[x_files_count].name = strdup( name ) ; + + ptr = x_file[x_files_count].name; + while ( *ptr ) + { + if ( *ptr == '\\' ) *ptr = '/'; /* Unix style */ + ptr++; + } + + x_files_count++ ; +} + +/* Read a datablock from file */ + +int file_read( file * fp, void * buffer, int len ) +{ + assert( len != 0 ); + + if ( fp->type == F_XFILE ) + { + XFILE * xf ; + int result ; + + xf = &x_file[fp->n] ; + + if (( len + fp->pos ) > ( xf->offset + xf->size ) ) + { + fp->eof = 1 ; + len = xf->size + xf->offset - fp->pos ; + } + + fseek( fp->fp, fp->pos, SEEK_SET ) ; + result = fread( buffer, 1, len, fp->fp ) ; + + fp->pos = ftell( fp->fp ) ; + return result ; + } + +#ifndef NO_ZLIB + if ( fp->type == F_GZFILE ) + { + int result = gzread( fp->gz, buffer, len ) ; + fp->error = ( result < len ); + if ( result < 0 ) result = 0; + return result ; + } +#endif + + return fread( buffer, 1, len, fp->fp ) ; +} + +/* Save a unquoted string to a file */ + +int file_qputs( file * fp, char * buffer ) +{ + char dest[1024], * optr ; + const char * ptr ; + + ptr = buffer ; + optr = dest ; + while ( *ptr ) + { + if ( optr > dest + 1000 ) + { + *optr++ = '\\' ; + *optr++ = '\n' ; + *optr = 0 ; + file_write( fp, dest, optr - dest ) ; + optr = dest ; + } + if ( *ptr == '\n' ) + { + *optr++ = '\\' ; + *optr++ = 'n' ; + ptr++ ; + continue ; + } + if ( *ptr == '\\' ) + { + *optr++ = '\\' ; + *optr++ = *ptr++ ; + continue ; + } + *optr++ = *ptr++ ; + } + *optr++ = '\n' ; + return file_write( fp, dest, optr - dest ) ; +} + +/* Load a string from a file and unquoted it */ + +int file_qgets( file * fp, char * buffer, int len ) +{ + char * ptr, * result = NULL ; + + if ( fp->type == F_XFILE ) + { + XFILE * xf ; + int l = 0; + char * ptr = result = buffer ; + + xf = &x_file[fp->n] ; + + fseek( fp->fp, fp->pos, SEEK_SET ) ; + while ( l < len ) + { + if ( fp->pos >= xf->offset + xf->size ) + { + fp->eof = 1 ; + break ; + } + fread( ptr, 1, 1, fp->fp ) ; + l++ ; + fp->pos++ ; + if ( *ptr++ == '\n' ) break ; + } + *ptr = 0 ; + fp->pos = ftell( fp->fp ) ; + + if ( l == 0 ) return 0 ; + } +#ifndef NO_ZLIB + else if ( fp->type == F_GZFILE ) + { + result = gzgets( fp->gz, buffer, len ) ; + } +#endif + else + { + result = fgets( buffer, len, fp->fp ); + } + + if ( result == NULL ) + { + buffer[0] = 0 ; return 0 ; + } + + ptr = buffer ; + while ( *ptr ) + { + if ( *ptr == '\\' ) + { + if ( ptr[1] == 'n' ) ptr[1] = '\n' ; + strcpy( ptr, ptr + 1 ) ; + ptr++ ; + continue ; + } + if ( *ptr == '\n' ) + { + *ptr = 0 ; + break ; + } + ptr++ ; + } + return strlen( buffer ) ; +} + +/* Save a string to file */ + +int file_puts( file * fp, char * buffer ) +{ + return file_write( fp, buffer, strlen( buffer ) ) ; +} + +/* Load a string from a file and unquoted it */ + +int file_gets( file * fp, char * buffer, int len ) +{ + char * result = NULL ; + + if ( fp->type == F_XFILE ) + { + XFILE * xf ; + int l = 0; + char * ptr = result = buffer ; + + xf = &x_file[fp->n] ; + + fseek( fp->fp, fp->pos, SEEK_SET ) ; + while ( l < len ) + { + if ( fp->pos >= xf->offset + xf->size ) + { + fp->eof = 1 ; + break ; + } + fread( ptr, 1, 1, fp->fp ) ; + l++ ; + fp->pos++ ; + if ( *ptr++ == '\n' ) break ; + } + *ptr = 0 ; + fp->pos = ftell( fp->fp ) ; + + if ( l == 0 ) return 0 ; + } +#ifndef NO_ZLIB + else if ( fp->type == F_GZFILE ) + { + result = gzgets( fp->gz, buffer, len ) ; + } +#endif + else + { + result = fgets( buffer, len, fp->fp ); + } + + if ( result == NULL ) + { + buffer[0] = 0 ; + return 0 ; + } + + return strlen( buffer ) ; +} + +/* Save an int data to a binary file */ + +int file_writeSint8( file * fp, int8_t * buffer ) +{ + return file_write( fp, buffer, sizeof( uint8_t ) ); +} + +int file_writeUint8( file * fp, uint8_t * buffer ) +{ + return file_write( fp, buffer, sizeof( uint8_t ) ); +} + +int file_writeSint16( file * fp, int16_t * buffer ) +{ +#if __BYTEORDER == __LIL_ENDIAN + return file_write( fp, buffer, sizeof( int16_t ) ); +#else + file_write( fp, ( uint8_t * )buffer + 1, 1 ); + return file_write( fp, ( uint8_t * )buffer, 1 ); +#endif +} + +int file_writeUint16( file * fp, uint16_t * buffer ) +{ + return file_writeSint16( fp, ( int16_t * ) buffer ); +} + +int file_writeSint32( file * fp, int32_t * buffer ) +{ +#if __BYTEORDER == __LIL_ENDIAN + return file_write( fp, buffer, sizeof( int32_t ) ); +#else + file_write( fp, ( uint8_t * )buffer + 3, 1 ); + file_write( fp, ( uint8_t * )buffer + 2, 1 ); + file_write( fp, ( uint8_t * )buffer + 1, 1 ); + return file_write( fp, ( uint8_t * )buffer, 1 ); +#endif +} + +int file_writeUint32( file * fp, uint32_t * buffer ) +{ + return file_writeSint32( fp, ( int32_t * )buffer ); +} + +/* Save an array to a binary file */ + +int file_writeSint8A( file * fp, int8_t * buffer, int n ) +{ + return file_write( fp, buffer, n ); +} + +int file_writeUint8A( file * fp, uint8_t * buffer, int n ) +{ + return file_write( fp, buffer, n ); +} + +int file_writeSint16A( file * fp, int16_t * buffer, int n ) +{ +#if __BYTEORDER == __LIL_ENDIAN + return file_write( fp, buffer, n << 1 ) >> 1 ; +#else + int i; + for ( i = 0; i < n; i++ ) + if ( !file_writeSint16( fp, ( int16_t * )buffer++ ) ) break; + return i; +#endif +} + +int file_writeUint16A( file * fp, uint16_t * buffer, int n ) +{ + return file_writeSint16A( fp, ( int16_t * )buffer, n ); +} + +int file_writeSint32A( file * fp, int32_t * buffer, int n ) +{ +#if __BYTEORDER == __LIL_ENDIAN + return file_write( fp, buffer, n << 2 ) >> 2; +#else + int i; + for ( i = 0; i < n; i++ ) + if ( !file_writeSint32( fp, ( int32_t * )buffer++ ) ) break; + return i; +#endif +} + +int file_writeUint32A( file * fp, uint32_t * buffer, int n ) +{ + return file_writeSint32A( fp, ( int32_t * )buffer, n ); +} + +/* Read an int data from a binary file */ + +int file_readSint8( file * fp, int8_t * buffer ) +{ + return file_read( fp, buffer, sizeof( int8_t ) ); +} + +int file_readUint8( file * fp, uint8_t * buffer ) +{ + return file_read( fp, buffer, sizeof( int8_t ) ); +} + +int file_readSint16( file * fp, int16_t * buffer ) +{ +#if __BYTEORDER == __LIL_ENDIAN + return file_read( fp, buffer, sizeof( int16_t ) ); +#else + file_read( fp, ( uint8_t * )buffer + 1, 1 ); + return file_read( fp, ( uint8_t * )buffer, 1 ); +#endif +} + +int file_readUint16( file * fp, uint16_t * buffer ) +{ + return file_readSint16( fp, (int16_t *)buffer ); +} + +int file_readSint32( file * fp, int32_t * buffer ) +{ +#if __BYTEORDER == __LIL_ENDIAN + return file_read( fp, buffer, sizeof( int32_t ) ); +#else + file_read( fp, ( uint8_t * )buffer + 3, 1 ); + file_read( fp, ( uint8_t * )buffer + 2, 1 ); + file_read( fp, ( uint8_t * )buffer + 1, 1 ); + return file_read( fp, ( uint8_t * )buffer, 1 ); +#endif +} + +int file_readUint32( file * fp, uint32_t * buffer ) +{ + return file_readSint32( fp, ( int32_t * )buffer ); +} + +/* Read an array from a binary file */ + +int file_readSint8A( file * fp, int8_t * buffer, int n ) +{ + return file_read( fp, buffer, n ); +} + +int file_readUint8A( file * fp, uint8_t * buffer, int n ) +{ + return file_read( fp, buffer, n ); +} + +int file_readSint16A( file * fp, int16_t * buffer, int n ) +{ +#if __BYTEORDER == __LIL_ENDIAN + return file_read( fp, buffer, n << 1 ) >> 1; +#else + int i; + for ( i = 0; i < n; i++ ) + if ( !file_readSint16( fp, ( int16_t * )buffer++ ) ) break; + return i; +#endif +} + +int file_readUint16A( file * fp, uint16_t * buffer, int n ) +{ + return file_readSint16A( fp, ( int16_t * )buffer, n ); +} + +int file_readSint32A( file * fp, int32_t * buffer, int n ) +{ +#if __BYTEORDER == __LIL_ENDIAN + return file_read( fp, buffer, n << 2 ) >> 2; +#else + int i; + for ( i = 0; i < n; i++ ) + if ( !file_readSint32( fp, ( int32_t * )buffer++ ) ) break; + return i; +#endif +} + +int file_readUint32A( file * fp, uint32_t * buffer, int n ) +{ + return file_readSint32A( fp, ( int32_t * )buffer, n ); +} + + +/* Write a datablock to a file */ + +int file_write( file * fp, void * buffer, int len ) +{ + if ( fp->type == F_XFILE ) + { + XFILE * xf ; + int result ; + + xf = &x_file[fp->n] ; + + if (( len + fp->pos ) > ( xf->offset + xf->size ) ) + { + fp->eof = 1 ; + len = xf->size + xf->offset - fp->pos ; + } + fseek( fp->fp, fp->pos, SEEK_SET ) ; + result = fwrite( buffer, 1, len, fp->fp ) ; + fp->pos = ftell( fp->fp ) ; + return result ; + } + +#ifndef NO_ZLIB + if ( fp->type == F_GZFILE ) + { + int result = gzwrite( fp->gz, buffer, len ) ; + if (( fp->error = ( result < 0 ) ) != 0 ) result = 0 ; + return ( result < len ) ? 0 : len ; + } +#endif + + return fwrite( buffer, 1, len, fp->fp ) ; +} + +/* Return file size */ + +int file_size( file * fp ) +{ + long pos, size ; + + if ( fp->type == F_XFILE ) return x_file[fp->n].size ; + + pos = file_pos( fp ); +#ifndef NO_ZLIB + if ( fp->type == F_GZFILE ) + { + char buffer[8192]; + size = pos; + while ( !file_eof( fp ) ) size += file_read( fp, buffer, sizeof(buffer) ); + } + else +#endif + { + file_seek(fp, 0, SEEK_END ) ; + size = file_pos( fp ) ; + } + file_seek(fp, pos, SEEK_SET ) ; + + return size ; +} + +/* Get current file pointer position */ + +int file_pos( file * fp ) +{ + if ( fp->type == F_XFILE ) return fp->pos - x_file[fp->n].offset ; + +#ifndef NO_ZLIB + if ( fp->type == F_GZFILE ) return gztell( fp->gz ) ; +#endif + + return ftell( fp->fp ) ; +} + +int file_flush( file * fp ) +{ + if ( fp->type == F_XFILE ) return 0 ; + +#ifndef NO_ZLIB + if ( fp->type == F_GZFILE ) return 0 ; +#endif + + return fflush( fp->fp ) ; +} + +/* Set current file pointer position */ + +int file_seek( file * fp, int pos, int where ) +{ + assert( fp ); + if ( fp->type == F_XFILE ) + { + if ( where == SEEK_END ) + pos = x_file[fp->n].size - pos + 1 ; + else if ( where == SEEK_CUR ) + pos += ( fp->pos - x_file[fp->n].offset ); + + if ( x_file[fp->n].size < pos ) pos = x_file[fp->n].size ; + + if ( pos < 0 ) pos = 0 ; + + fp->pos = pos + x_file[fp->n].offset ; + return pos ; + } + +#ifndef NO_ZLIB + if ( fp->type == F_GZFILE ) + { + assert( fp->gz ); + return gzseek( fp->gz, pos, where ) ; + } +#endif + + assert( fp->fp ); + return fseek( fp->fp, pos, where ) ; +} + +void file_rewind( file * fp ) +{ + fp->error = 0; + + switch ( fp->type ) + { + case F_XFILE: + fp->pos = x_file[fp->n].offset ; + break; + +#ifndef NO_ZLIB + case F_GZFILE: + gzrewind( fp->gz ) ; + break; +#endif + + default: + rewind( fp->fp ) ; + } +} + +/* Open file */ + +static int open_raw( file * f, const char * filename, const char * mode ) +{ + char _mode[5]; + char *p; + +#ifndef NO_ZLIB + if ( !strchr( mode, '0' ) ) + { + f->type = F_GZFILE ; + f->gz = gzopen( filename, mode ) ; + f->eof = 0 ; + if ( f->gz ) return 1 ; + } +#endif + + p = _mode; + while ( *mode ) + { + if ( *mode != '0' ) + { + *p = *mode; + p++; + } + mode++; + } + *p = '\0'; + + f->eof = 0 ; + f->type = F_FILE ; + f->fp = fopen( filename, _mode ) ; + if ( f->fp ) return 1 ; + return 0 ; +} + +file * file_open( const char * filename, char * mode ) +{ + char work [__MAX_PATH]; + char here [__MAX_PATH]; + + char * name = NULL ; + char * p, c ; + int i; + + file * f ; + + f = ( file * ) calloc( 1, sizeof( file ) ) ; + assert( f ) ; + + p = f->name; + while ( *filename ) + { + *p++ = *filename++; + if ( p[-1] == '\\' ) p[-1] = '/'; /* Unix style */ + } + p[0] = '\0'; + + filename = f->name; + + if ( open_raw( f, filename, mode ) ) + { + opened_files++; + return f ; + } + + + /* if real file don't exists in disk */ + if ( strchr( mode, 'r' ) && strchr( mode, 'b' ) && /* Only read-only files */ + !strchr( mode, '+' ) && !strchr( mode, 'w' ) ) + { + for ( i = 0 ; i < x_files_count ; i++ ) + { + if ( strcmp( filename, x_file[i].name ) == 0 ) + { + f->eof = 0; + f->pos = x_file[i].offset; + f->type = F_XFILE; + f->n = i; + f->fp = fopen( x_file[i].stubname, "rb" ); + + opened_files++; + return f ; + } + } + } + + p = name = work; + while (( c = *filename ) ) + { + if ( c == '\\' || c == '/' ) + { + c = 0; + name = p + 1; + } + *p++ = c; + filename++; + } + *p = '\0'; + + /* Use file extension for search in a directory named as it (for example: FPG dir for .FPG files) */ + if ( strchr( name, '.' ) ) + { + strcpy( here, strrchr( name, '.' ) + 1 ) ; + strcat( here, PATH_SEP ) ; + strcat( here, name ) ; + if ( open_raw( f, here, mode ) ) + { + opened_files++; + return f ; + } + } + + for ( i = 0 ; possible_paths[i] ; i++ ) + { + strcpy( here, possible_paths[i] ) ; + strcat( here, name ) ; + if ( open_raw( f, here, mode ) ) + { + opened_files++; + return f ; + } + } + + free( f ) ; + return 0 ; +} + +/* Close file */ + +void file_close( file * fp ) +{ + if ( fp == NULL ) return; + if ( fp->type == F_FILE ) fclose( fp->fp ) ; + if ( fp->type == F_XFILE ) fclose( fp->fp ) ; +#ifndef NO_ZLIB + if ( fp->type == F_GZFILE ) gzclose( fp->gz ) ; +#endif + opened_files--; + free( fp ) ; +} + +/* Add a new dir to PATH */ + +void file_addp( const char * path ) +{ + char truepath[__MAX_PATH]; + int n ; + + if ( !path || !*path ) return; + + strcpy( truepath, path ) ; + + for ( n = 0 ; truepath[n] ; n++ ) if ( truepath[n] == '\\' ) truepath[n] = '/' ; + if ( truepath[strlen( truepath )-1] != '/' ) strcat( truepath, "/" ) ; + + for ( n = 0 ; n < MAX_POSSIBLE_PATHS - 1 && possible_paths[n] ; n++ ) ; + + possible_paths[n] = strdup( truepath ) ; + possible_paths[n+1] = NULL ; +} + +/* --- */ + +int file_remove( const char * filename ) +{ + return ( remove( filename ) ); +} + +/* --- */ + +int file_move( const char * source_file, const char * target_file ) +{ + return ( rename( source_file, target_file ) ); +} + +/* Check for file exists */ + +int file_exists( const char * filename ) +{ + file * fp ; + + fp = file_open( filename, "rb" ) ; + if ( fp ) + { + file_close( fp ) ; + return 1 ; + } + return 0 ; +} + +/* Check for file end is reached */ + +int file_eof( file * fp ) +{ + if ( fp->type == F_XFILE ) + { + return fp->eof ? 1 : 0; + } + +#ifndef NO_ZLIB + if ( fp->type == F_GZFILE ) + { + if ( fp->error ) return 1 ; + return gzeof( fp->gz ) ? 1 : 0; + } +#endif + + return feof( fp->fp ) ? 1 : 0; +} + +/* Get the FILE * of the file */ + +FILE * file_fp( file * f ) +{ + if ( f->type == F_XFILE ) + { +// XFILE * xf = &x_file[f->n] ; + fseek( f->fp, f->pos, SEEK_SET ) ; + return f->fp ; + } + + return f->fp ; +} + +/* ------------------------------------------------------------------------------------ */ + +char * getfullpath( char *rel_path ) +{ + char fullpath[ __MAX_PATH ] = ""; +#ifdef _WIN32 + GetFullPathName( rel_path, sizeof( fullpath ), fullpath, NULL ); +#else + realpath( rel_path, fullpath ); +#endif + if ( *fullpath ) return strdup( fullpath ); + return NULL; +} + +/* ------------------------------------------------------------------------------------ */ + +#ifdef _WIN32 + #define ENV_PATH_SEP ';' +#else + #define ENV_PATH_SEP ':' +#endif + +char * whereis( char *file ) +{ + char * path = getenv( "PATH" ), *pact = path, *p; + char fullname[ __MAX_PATH ]; + + while ( pact && *pact ) + { + struct stat st; + + if ( ( p = strchr( pact, ENV_PATH_SEP ) ) ) *p = '\0'; + sprintf( fullname, "%s%s%s", pact, ( pact[ strlen( pact ) - 1 ] == ENV_PATH_SEP ) ? "" : PATH_SEP, file ); + + if ( !stat( fullname, &st ) && S_ISREG( st.st_mode ) ) + { + pact = strdup( pact ); + if ( p ) *p = ENV_PATH_SEP; + return ( pact ); + } + + if ( !p ) break; + + *p = ENV_PATH_SEP; + pact = p + 1; + } + + return NULL; +} + +/* ------------------------------------------------------------------------------------ */ diff --git a/core/common/xctype.c b/core/common/xctype.c new file mode 100644 index 0000000..1c5bf8f --- /dev/null +++ b/core/common/xctype.c @@ -0,0 +1,185 @@ +/* + * Copyright © 2006-2013 SplinterGU (Fenix/Bennugd) + * Copyright © 2002-2006 Fenix Team (Fenix) + * Copyright © 1999-2002 José Luis Cebrián Pagüe (Fenix) + * + * This file is part of Bennu - Game Development + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xctype.h" + +/* Tabla de conversión de caracteres MS-DOS a Windows */ + +int dos_chars = 0 ; + +unsigned char dos_to_win[256] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, +112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, +199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238, 236, 196, 197, +201, 230, 198, 244, 246, 242, 251, 249, 255, 214, 220, 248, 163, 216, 215, 131, +225, 237, 243, 250, 241, 209, 170, 186, 191, 174, 172, 189, 188, 161, 171, 187, +166, 166, 166, 166, 166, 193, 194, 192, 169, 166, 166, 43, 43, 162, 165, 43, + 43, 45, 45, 43, 45, 43, 227, 195, 43, 43, 45, 45, 166, 45, 43, 164, +240, 208, 202, 203, 200, 105, 205, 206, 207, 43, 43, 166, 95, 166, 204, 175, +211, 223, 212, 210, 245, 213, 181, 254, 222, 218, 219, 217, 253, 221, 175, 180, +173, 177, 61, 190, 182, 167, 247, 184, 176, 168, 183, 185, 179, 178, 166, 160 +} ; + +/* Tabla de conversión de caracteres Windows a MS-DOS */ + +unsigned char win_to_dos[256] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 130, 159, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 255, 173, 189, 156, 207, 190, 254, 245, 249, 184, 166, 174, 170, 240, 169, 238, + 248, 241, 253, 252, 239, 230, 244, 250, 247, 251, 167, 175, 172, 171, 243, 168, + 183, 181, 182, 199, 142, 143, 146, 128, 212, 144, 210, 211, 222, 214, 215, 216, + 209, 165, 227, 224, 226, 229, 153, 158, 157, 235, 233, 234, 154, 237, 232, 225, + 133, 160, 131, 198, 132, 134, 145, 135, 138, 130, 136, 137, 141, 161, 140, 139, + 208, 164, 149, 162, 147, 228, 148, 246, 155, 151, 163, 150, 129, 236, 231, 152 +} ; + +/* Tipos de caracter */ + +char c_type[256] ; +unsigned char c_upper[256] ; +unsigned char c_lower[256] ; + +int c_type_initialized = 0 ; + +unsigned char convert (unsigned char c) +{ + return dos_chars ? c : win_to_dos[c] ; +} + +static void set_c_range (int first, int last, int type) +{ + while (first <= last) c_type[first++] |= type ; +} + +static void set_c_from (const unsigned char * chars, int type) +{ + if (dos_chars) + while (*chars) c_type[win_to_dos[*chars++]] |= type ; + else + while (*chars) c_type[*chars++] |= type ; +} + +static void set_c_as (int prev_type, int type) +{ + int n ; + + for (n = 0 ; n < 256 ; n++) + { + if (c_type[n] & prev_type) + c_type[n] |= type ; + } +} + +static void set_c_upper (const unsigned char * from, const unsigned char * to) +{ + if (dos_chars) + while (*from) c_upper[win_to_dos[*from++]] = win_to_dos[*to++] ; + else + while (*from) c_upper[*from++] = *to++ ; +} + +static void set_c_lower (const unsigned char * from, const unsigned char * to) +{ + if (dos_chars) + while (*from) c_lower[win_to_dos[*from++]] = win_to_dos[*to++] ; + else + while (*from) c_lower[*from++] = *to++ ; +} + +void init_c_type () +{ + int c ; + + memset (c_type, 0, sizeof(c_type)) ; + + if (dos_chars) + for (c = 0 ; c < 256 ; c++) + c_lower[c] = c_upper[c] = win_to_dos[c] ; + else + for (c = 0 ; c < 256 ; c++) + c_lower[c] = c_upper[c] = c ; + + set_c_upper ((const unsigned char *)"abcdefghijklmnopqrstuvwxyz", + (const unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ") ; + set_c_lower ((const unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZ", + (const unsigned char *)"abcdefghijklmnopqrstuvwxyz") ; +#ifdef RESPETAR_ACENTOS + set_c_upper ((const unsigned char *)"áéíóúñçàèìòùäëïöüýâêîôûæãåõ", + (const unsigned char *)"ÁÉÍÓÚÑÇÀÈÌÒÙÄËÏÖÜÝÂÊÎÔÛÆÃÅÕ") ; + set_c_lower ((const unsigned char *)"ÁÉÍÓÚÑÇÀÈÌÒÙÄËÏÖÜÝÂÊÎÔÛÆÃÅÕ", + (const unsigned char *)"áéíóúñçàèìòùäëïöüýâêîôûæãåõ") ; +#else + set_c_upper ((const unsigned char *)"áéíóúñÑçÇàèìòùäëïöüýâêîôûæãåõÁÉÍÓÚ", + (const unsigned char *)"AEIOUNNCCAEIOUAEIOUYAEIOUÆAAOAEIOU") ; + set_c_lower ((const unsigned char *)"áéíóúñÑçÇàèìòùäëïöüýâêîôûæãåõÁÉÍÓÚ", + (const unsigned char *)"aeiounnccaeiouaeiouyaeiouÆaaoaeiou") ; +#endif + + set_c_from ((const unsigned char *)" \t\n\r", CTYPE_SPACE) ; + + set_c_range ('0', '9', CTYPE_NUM) ; + + set_c_range ('0', '9', CTYPE_ALNUM) ; + set_c_range ('A', 'F', CTYPE_ALNUM) ; + set_c_range ('a', 'f', CTYPE_ALNUM) ; + + set_c_range ('A', 'Z', CTYPE_ALPHA) ; + set_c_range ('a', 'z', CTYPE_ALPHA) ; + set_c_from ((const unsigned char *)"áéíóúÁÉÍÓÚñÑçÇàèìòùÀÈÌÒÙäëïöüÄËÏÖÜÿýâêîôûÂÊÎÔÛ" + "æÆãåðõªºÃÅÐÕØ", CTYPE_ALPHA) ; + + set_c_as (CTYPE_ALPHA, CTYPE_WORDCHAR) ; + set_c_from ((const unsigned char *)"_", CTYPE_WORDCHAR) ; + set_c_as (CTYPE_WORDCHAR, CTYPE_WORDFIRST) ; + + set_c_range ('0', '9', CTYPE_WORDCHAR) ; + + c_type_initialized = 1 ; +} + + |