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/bgdc/src/strings.c | |
download | bennugd-main.tar.gz bennugd-main.tar.bz2 bennugd-main.zip |
Initial commit from steward-fu releasemain
Diffstat (limited to 'core/bgdc/src/strings.c')
-rw-r--r-- | core/bgdc/src/strings.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/core/bgdc/src/strings.c b/core/bgdc/src/strings.c new file mode 100644 index 0000000..1939862 --- /dev/null +++ b/core/bgdc/src/strings.c @@ -0,0 +1,241 @@ +/* + * Copyright © 2006-2016 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 <stdlib.h> +#include <string.h> +#ifdef TARGET_BEOS +#include <posix/assert.h> +#else +#include <assert.h> +#endif + +#include "bgdc.h" + +/* ---------------------------------------------------------------------- */ +/* Gestor de cadenas */ +/* ---------------------------------------------------------------------- */ + +char * string_mem = 0 ; +int string_allocated = 0 ; +int string_used = 0 ; + +int * string_offset = 0 ; +int string_max = 0 ; +int string_count = 0 ; + +int autoinclude = 0 ; + +void string_init() +{ + string_mem = ( char * ) calloc( 4096, sizeof( char ) ) ; + string_allocated = 4096 ; + string_used = 1 ; + string_count = 1 ; + string_offset = ( int * ) calloc( 1024, sizeof( int ) ) ; + string_max = 1024 ; + string_mem[ 0 ] = 0 ; + string_offset[ 0 ] = 0 ; +} + +void string_alloc( int bytes ) +{ + string_mem = ( char * ) realloc( string_mem, string_allocated += bytes ) ; + if ( !string_mem ) + { + fprintf( stdout, "string_alloc: out of memory\n" ) ; + exit( 1 ) ; + } +} + +void string_dump( void ( *wlog )( const char *fmt, ... ) ) +{ + int i ; + printf( "\n---- %d strings ----\n\n", string_count ) ; + for ( i = 0 ; i < string_count ; i++ ) + printf( "%4d: %s\n", i, string_mem + string_offset[ i ] ) ; +} + +int string_new( const char * text ) +{ + int len = strlen( text ) + 1 ; + int i; + + /* Reuse strings */ + for ( i = 0; i < string_count; i++ ) if ( !strcmp( text, string_mem + string_offset[ i ] ) ) return i; + + if ( string_count == string_max ) + { + string_max += 1024 ; + string_offset = ( int * ) realloc( string_offset, string_max * sizeof( int ) ) ; + if ( string_offset == 0 ) + { + fprintf( stdout, "Too many strings\n" ) ; + exit( 1 ) ; + } + } + + while ( string_used + len >= string_allocated ) string_alloc( 1024 ) ; + + string_offset[ string_count ] = string_used ; + strcpy( string_mem + string_used, text ) ; + string_used += len ; + return string_count++ ; +} + + +char * validchars = "\\/."; +char * invalidchars = \ + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" \ + "*?\"<>|"; + +int check_for_valid_pathname( char * pathname ) +{ + int n, l; + + if ( !pathname || ( l = strlen( pathname ) ) > __MAX_PATH ) return 0; + +#if WIN32 + /* Only ':' with this sintax: "L:..." */ + if ( pathname[ 0 ] == ':' || ( l > 2 && strchr( pathname + 2, ':' ) ) ) return 0; +#endif + + /* Some invalid character? */ + for ( n = 0; n < strlen( invalidchars ); n++ ) + if ( strchr( pathname, invalidchars[ n ] ) ) return 0; + + return 1; +} + +int no_include_this_file = 0; + +int string_compile( const char ** source ) +{ + char c = *( *source ) ++, conv ; + const char * ptr ; + int string_used_back = string_used; + + if ( string_count == string_max ) + { + string_max += 1024 ; + string_offset = ( int * ) realloc( string_offset, string_max * sizeof( int ) ) ; + if ( string_offset == 0 ) + { + fprintf( stdout, "Too many strings\n" ) ; + exit( 1 ) ; + } + } + + string_offset[ string_count ] = string_used ; + + while ( *( *source ) ) + { + if ( *( *source ) == c ) /* Termina la string? */ + { + ( *source ) ++ ; + if ( *( *source ) == c ) /* Comienza una nueva? (esto es para strings divididas) */ + { + ( *source ) ++ ; + } + else + { + /* Elimino todos los espacios para buscar si hay otra string, esto es para strings divididas */ + ptr = ( *source ) ; + while ( ISSPACE( *ptr ) ) + { + if ( *ptr == '\n' ) line_count++ ; + ptr++ ; + } + /* Si despues de saltar todos los espacios, no tengo un delimitador de string, salgo */ + if ( *ptr != c ) + { + ( *source ) = ptr; /* Fix: Splinter, por problema con numeracion de lineas */ + break ; + } + + /* Obtengo delimitador de string, me posiciono en el caracter siguiente, dentro de la string */ + ( *source ) = ptr + 1 ; + continue ; + } + } + else if ( *( *source ) == '\n' ) + { + line_count++ ; + string_mem[ string_used++ ] = '\n' ; + + ( *source ) ++ ; + } + else + { +#ifdef __USE_C_STRING_ESCAPE + if ( *( *source ) == '\\' && *( *source + 1 ) == c ) ( *source ) ++ ; +#endif + conv = convert( *( *source ) ) ; + string_mem[ string_used++ ] = conv ; + + ( *source ) ++ ; + } + + if ( string_used >= string_allocated ) + string_alloc( 1024 ) ; + } + + string_mem[ string_used++ ] = 0 ; + + int i; + + /* Reuse strings */ + + for ( i = 0; i < string_count; i++ ) + { + if ( !strcmp( string_mem + string_used_back, string_mem + string_offset[ i ] ) ) + { + string_used = string_used_back; + return i; + } + } + + if ( string_used >= string_allocated ) string_alloc( 1024 ) ; + + /* Hack: añade el posible fichero al DCB */ + + if ( !no_include_this_file && autoinclude && check_for_valid_pathname( string_mem + string_offset[ string_count ] ) ) + dcb_add_file( string_mem + string_offset[ string_count ] ) ; + + no_include_this_file = 0; + + return string_count++ ; +} + +const char * string_get( int code ) +{ + assert( code < string_count && code >= 0 ) ; + return string_mem + string_offset[ code ] ; +} + |