/*************************************************************** bwb_str.c String-Management Routines for Bywater BASIC Interpreter Copyright (c) 1993, Ted A. Campbell Bywater Software email: tcamp@delphi.com Copyright and Permissions Information: All U.S. and international rights are claimed by the author, Ted A. Campbell. This software is released under the terms of the GNU General Public License (GPL), which is distributed with this software in the file "COPYING". The GPL specifies the terms under which users may copy and use the software in this distribution. A separate license is available for commercial distribution, for information on which you should contact the author. ***************************************************************/ /*---------------------------------------------------------------*/ /* NOTE: Modifications marked "JBV" were made by Jon B. Volkoff, */ /* 11/1995 (eidetics@cerf.net). */ /*---------------------------------------------------------------*/ #include #include "bwbasic.h" #include "bwb_mes.h" #if INTENSIVE_DEBUG || TEST_BSTRING static char tbuf[ MAXSTRINGSIZE + 1 ]; #endif /*************************************************************** FUNCTION: str_btob() DESCRIPTION: This C function assigns a bwBASIC string structure to another bwBASIC string structure. ***************************************************************/ #if ANSI_C int str_btob( bstring *d, bstring *s ) #else int str_btob( d, s ) bstring *d; bstring *s; #endif { char *t; register int i; #if TEST_BSTRING sprintf( tbuf, "in str_btob(): entry, source b string name is <%s>", s->name ); bwb_debug( tbuf ); sprintf( tbuf, "in str_btob(): entry, destination b string name is <%s>", d->name ); bwb_debug( tbuf ); #endif /* get memory for new buffer */ /* Following section removed by JBV (no more mass string reallocation) */ /* if ( ( t = (char *) CALLOC( s->length + 1, 1, "str_btob" )) == NULL ) { #if PROG_ERRORS bwb_error( "in str_btob(): failed to get memory for new buffer" ); #else bwb_error( err_getmem ); #endif return FALSE; } */ /* Only one of these two conditions necessitates reallocation (JBV) */ if ( ( d->sbuffer == NULL ) || ( d->rab == TRUE ) ) { if ( ( t = (char *) CALLOC( MAXSTRINGSIZE + 1, 1, "str_btob" )) == NULL ) { #if PROG_ERRORS bwb_error( "in str_btob(): failed to get memory for new buffer" ); #else bwb_error( err_getmem ); #endif return FALSE; } } else t = d->sbuffer; /* Leave well enough alone (JBV) */ /* write the b string to the temp c string */ t[ 0 ] = '\0'; for ( i = 0; i < (int) s->length; ++i ) { t[ i ] = s->sbuffer[ i ]; t[ i + 1 ] = '\0'; /* JBV */ #if INTENSIVE_DEBUG tbuf[ i ] = s->sbuffer[ i ]; tbuf[ i + 1 ] = '\0'; #endif } /* deallocate old memory */ #if INTENSIVE_DEBUG if ( d->rab == TRUE ) { sprintf( bwb_ebuf, "in str_btob(): reallocating RAB" ); bwb_debug( bwb_ebuf ); } #endif /* Following section removed by JBV (no more mass string reallocation) */ /* if (( d->rab != TRUE ) && ( d->sbuffer != NULL )) { #if INTENSIVE_DEBUG sprintf( tbuf, "in str_btob(): deallocating string memory" ); bwb_debug ( tbuf ); #endif FREE( d->sbuffer, "str_btob" ); d->sbuffer = NULL; } else { d->rab = (char) FALSE; } */ d->rab = (char) FALSE; /* JBV */ /* reassign buffer */ d->sbuffer = t; /* reassign length */ d->length = s->length; #if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in str_btob(): exit length <%d> string <%s>", d->length, tbuf ); bwb_debug( bwb_ebuf ); #endif /* return */ return TRUE; } /*************************************************************** FUNCTION: str_ctob() DESCRIPTION: This C function assigns a null-terminated C string to a bwBASIC string structure. ***************************************************************/ #if ANSI_C int str_ctob( bstring *s, char *buffer ) #else int str_ctob( s, buffer ) bstring *s; char *buffer; #endif { char *t; register int i; #if INTENSIVE_DEBUG sprintf( tbuf, "in str_ctob(): entry, c string is <%s>", buffer ); bwb_debug( tbuf ); #endif #if TEST_BSTRING sprintf( tbuf, "in str_ctob(): entry, b string name is <%s>", s->name ); bwb_debug( tbuf ); #endif /* get memory for new buffer */ /* Following section removed by JBV (no more mass string reallocation) */ /* if ( ( t = (char *) CALLOC( strlen( buffer ) + 1, 1, "str_ctob" )) == NULL ) { #if PROG_ERRORS bwb_error( "in str_ctob(): failed to get memory for new buffer" ); #else bwb_error( err_getmem ); #endif return FALSE; } */ /* Only one of these two conditions necessitates reallocation (JBV) */ if ( ( s->sbuffer == NULL ) || ( s->rab == TRUE ) ) { if ( ( t = (char *) CALLOC( MAXSTRINGSIZE + 1, 1, "str_ctob" )) == NULL ) { #if PROG_ERRORS bwb_error( "in str_ctob(): failed to get memory for new buffer" ); #else bwb_error( err_getmem ); #endif return FALSE; } } else t = s->sbuffer; /* Leave well enough alone (JBV) */ /* write the c string to the temp c string */ t[ 0 ] = '\0'; for ( i = 0; i < (int) strlen( buffer ); ++i ) { t[ i ] = buffer[ i ]; t[ i + 1 ] = '\0'; /* JBV */ #if INTENSIVE_DEBUG tbuf[ i ] = buffer[ i ]; tbuf[ i + 1 ] = '\0'; #endif } /* deallocate old memory */ #if INTENSIVE_DEBUG if ( s->rab == TRUE ) { sprintf( bwb_ebuf, "in str_ctob(): reallocating RAB" ); bwb_debug( bwb_ebuf ); } #endif /* Following section removed by JBV (no more mass string reallocation) */ /* if (( s->rab != TRUE ) && ( s->sbuffer != NULL )) { FREE( s->sbuffer, "str_ctob" ); s->sbuffer = NULL; } else { s->rab = (char) FALSE; } */ s->rab = (char) FALSE; /* JBV */ /* reassign buffer */ s->sbuffer = t; /* reassign length */ s->length = (unsigned char) strlen( buffer ); #if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in str_ctob(): exit length <%d> string <%s>", s->length, tbuf ); bwb_debug( bwb_ebuf ); #endif /* return */ return TRUE; } /*************************************************************** FUNCTION: str_btoc() DESCRIPTION: This C function assigns a null-terminated C string to a bwBASIC string structure. ***************************************************************/ #if ANSI_C int str_btoc( char *buffer, bstring *s ) #else int str_btoc( buffer, s ) char *buffer; bstring *s; #endif { register int i; #if INTENSIVE_DEBUG sprintf( tbuf, "in str_btoc(): entry, b string length is <%d>", s->length ); bwb_debug( tbuf ); #endif #if TEST_BSTRING sprintf( tbuf, "in str_btoc(): entry, b string name is <%s>", s->name ); bwb_debug( tbuf ); #endif /* write the b string to the c string */ buffer[ 0 ] = '\0'; for ( i = 0; i < (int) s->length; ++i ) { buffer[ i ] = s->sbuffer[ i ]; buffer[ i + 1 ] = '\0'; if ( i >= MAXSTRINGSIZE ) { i = s->length + 1; } } #if INTENSIVE_DEBUG sprintf( tbuf, "in str_btoc(): exit, c string is <%s>", buffer ); bwb_debug( tbuf ); #endif /* return */ return TRUE; } /*************************************************************** FUNCTION: str_cat() DESCRIPTION: This C function performs the equivalent of the C strcat() function, using BASIC strings. ***************************************************************/ #if ANSI_C char * str_cat( bstring *a, bstring *b ) #else char * str_cat( a, b ) bstring *a; bstring *b; #endif { char abuf[ MAXSTRINGSIZE + 1 ]; char bbuf[ MAXSTRINGSIZE + 1 ]; char *r; str_btoc( abuf, a ); str_btoc( bbuf, b ); #if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in str_cat(): a <%s> b <%s>", abuf, bbuf ); bwb_debug( bwb_ebuf ); #endif strcat( abuf, bbuf ); str_ctob( a, abuf ); #if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in str_cat(): returns <%s>", abuf ); bwb_debug( bwb_ebuf ); #endif return r; } /*************************************************************** FUNCTION: str_cmp() DESCRIPTION: This C function performs the equivalent of the C strcmp() function, using BASIC strings. ***************************************************************/ #if ANSI_C int str_cmp( bstring *a, bstring *b ) #else int str_cmp( a, b ) bstring *a; bstring *b; #endif { char abuf[ MAXSTRINGSIZE + 1 ]; char bbuf[ MAXSTRINGSIZE + 1 ]; str_btoc( abuf, a ); str_btoc( bbuf, b ); return strcmp( abuf, bbuf ); }