📄 bwb_var.c
字号:
v->name, v->type, v->dimensions ); bwb_debug( bwb_ebuf ); getchar();#endif return v; }/*************************************************************** FUNCTION: var_new() DESCRIPTION: This function assigns memory for a new variable.***************************************************************/#if ANSI_Cstruct bwb_variable *var_new( char *name )#elsestruct bwb_variable *var_new( name ) char *name;#endif { struct bwb_variable *v; /* get memory for new variable */ /* Revised to CALLOC pass-thru call by JBV */ if ( ( v = (struct bwb_variable *) CALLOC( 1, sizeof( struct bwb_variable ), "var_new" )) == NULL ) { bwb_error( err_getmem ); return NULL; } /* copy the name into the appropriate structure */ strcpy( v->name, name ); /* set memory in the new variable */ var_make( v, (int) v->name[ strlen( v->name ) - 1 ] ); /* and return */ return v; }/*************************************************************** FUNCTION: bwb_isvar() DESCRIPTION: This function determines if the string in 'buffer' is the name of a previously- existing variable.***************************************************************/#if ANSI_Cintbwb_isvar( char *buffer )#elseintbwb_isvar( buffer ) char *buffer;#endif { struct bwb_variable *v; /* run through the variable list and try to find a match */ for ( v = CURTASK var_start.next; v != &CURTASK var_end; v = v->next ) { if ( strcmp( v->name, buffer ) == 0 ) { return TRUE; } } /* search failed */ return FALSE; }/*************************************************************** FUNCTION: var_getnval() DESCRIPTION: This function returns the current value of the variable argument as a number.***************************************************************/#if ANSI_Cbnumbervar_getnval( struct bwb_variable *nvar )#elsebnumbervar_getnval( nvar ) struct bwb_variable *nvar;#endif { switch( nvar->type ) { case NUMBER: return *( var_findnval( nvar, nvar->array_pos ) ); }#if PROG_ERRORS sprintf( bwb_ebuf, "in var_getnval(): type is <%d>=<%c>.", nvar->type, nvar->type ); bwb_error( bwb_ebuf );#else bwb_error( err_mismatch );#endif return (bnumber) 0.0; }/*************************************************************** FUNCTION: var_getsval() DESCRIPTION: This function returns the current value of the variable argument as a pointer to a BASIC string structure.***************************************************************/#if ANSI_Cbstring *var_getsval( struct bwb_variable *nvar )#elsebstring *var_getsval( nvar ) struct bwb_variable *nvar;#endif { static bstring b; b.rab = FALSE; switch( nvar->type ) { case STRING: return var_findsval( nvar, nvar->array_pos ); case NUMBER: sprintf( bwb_ebuf, "%*f ", prn_precision( nvar ), *( var_findnval( nvar, nvar->array_pos ) ) ); str_ctob( &b, bwb_ebuf ); return &b; default:#if PROG_ERRORS sprintf( bwb_ebuf, "in var_getsval(): type is <%d>=<%c>.", nvar->type, nvar->type ); bwb_error( bwb_ebuf );#else bwb_error( err_mismatch );#endif return NULL; } }/*************************************************************** FUNCTION: bwb_dim() DESCRIPTION: This function implements the BASIC DIM statement, allocating memory for a dimensioned array of variables. SYNTAX: DIM variable(elements...)[variable(elements...)]...***************************************************************/#if ANSI_Cstruct bwb_line *bwb_dim( struct bwb_line *l )#elsestruct bwb_line *bwb_dim( l ) struct bwb_line *l;#endif { register int n; static int n_params; /* number of parameters */ static int *pp; /* pointer to parameter values */ struct bwb_variable *newvar; bnumber *np; int loop; int old_name, old_dimensions; char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_dim(): entered function." ); bwb_debug( bwb_ebuf );#endif loop = TRUE; while ( loop == TRUE ) { old_name = FALSE; /* Get variable name */ adv_ws( l->buffer, &( l->position ) ); bwb_getvarname( l->buffer, tbuf, &( l->position ) ); /* check for previously used variable name */ if ( bwb_isvar( tbuf ) == TRUE ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_dim(): variable name is already used.", l->number ); bwb_debug( bwb_ebuf );#endif old_name = TRUE; } /* get the new variable */ newvar = var_find( tbuf );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_dim(): new variable name is <%s>.", newvar->name ); bwb_debug( bwb_ebuf );#endif /* note that DIM has been called */ dimmed = TRUE; /* read parameters */ old_dimensions = newvar->dimensions; dim_getparams( l->buffer, &( l->position ), &n_params, &pp ); newvar->dimensions = n_params; /* Check parameters for an old variable name */ if ( old_name == TRUE ) { /* check to be sure the number of dimensions is the same */ if ( newvar->dimensions != old_dimensions ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_dim(): variable <%s> cannot be re-dimensioned", newvar->name ); bwb_error( bwb_ebuf );#else bwb_error( err_redim );#endif } /* check to be sure sizes for the old variable are the same */ for ( n = 0; n < newvar->dimensions; ++n ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_dim(): old var <%s> parameter <%d> size <%d>.", newvar->name, n, pp[ n ] ); bwb_debug( bwb_ebuf );#endif if ( ( pp[ n ] + ( 1 - dim_base )) != newvar->array_sizes[ n ] ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_dim(): variable <%s> parameter <%d> cannot be resized", newvar->name, n ); bwb_error( bwb_ebuf );#else bwb_error( err_redim );#endif } } } /* end of conditional for old variable */ /* a new variable */ else { /* assign memory for parameters */ /* Revised to CALLOC pass-thru call by JBV */ if ( ( newvar->array_sizes = (int *) CALLOC( n_params, sizeof( int ), "bwb_dim" )) == NULL ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in line %d: Failed to find memory for array_sizes for <%s>", l->number, newvar->name ); bwb_error( bwb_ebuf );#else bwb_error( err_getmem );#endif return bwb_zline( l ); } for ( n = 0; n < newvar->dimensions; ++n ) { newvar->array_sizes[ n ] = pp[ n ] + ( 1 - dim_base );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_dim(): array_sizes dim <%d> value <%d>", n, newvar->array_sizes[ n ] ); bwb_debug( bwb_ebuf );#endif } /* assign memory for current position */ /* Revised to CALLOC pass-thru call by JBV */ if ( ( newvar->array_pos = (int *) CALLOC( n_params, sizeof( int ), "bwb_dim" )) == NULL ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in line %d: Failed to find memory for array_pos for <%s>", l->number, newvar->name ); bwb_error( bwb_ebuf );#else bwb_error( err_getmem );#endif return bwb_zline( l ); } for ( n = 0; n < newvar->dimensions; ++n ) { newvar->array_pos[ n ] = dim_base; } /* calculate the array size */ newvar->array_units = (size_t) MAXINTSIZE; /* avoid error in dim_unit() */ newvar->array_units = dim_unit( newvar, pp ) + 1;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_dim(): array memory requires <%ld> units", (long) newvar->array_units ); bwb_debug( bwb_ebuf );#endif /* assign array memory */ switch( newvar->type ) { case STRING:#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_dim(): 1 STRING requires <%ld> bytes", (long) sizeof( bstring )); bwb_debug( bwb_ebuf ); sprintf( bwb_ebuf, "in bwb_dim(): STRING array memory requires <%ld> bytes", (long) ( newvar->array_units + 1 ) * sizeof( bstring )); bwb_debug( bwb_ebuf );#endif /*------------------------------------------------------*/ /* memnum, not memstr, was used here -- incorrect (JBV) */ /* Revised to CALLOC pass-thru call by JBV */ /*------------------------------------------------------*/ if ( ( newvar->memstr = (bstring *) CALLOC( newvar->array_units, sizeof( bstring), "bwb_dim" )) == NULL ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in line %d: Failed to find memory for array <%s>", l->number, newvar->name ); bwb_error( bwb_ebuf );#else bwb_error( err_getmem );#endif return bwb_zline( l ); } break; case NUMBER:#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_dim(): 1 DOUBLE requires <%ld> bytes", (long) sizeof( double )); bwb_debug( bwb_ebuf ); sprintf( bwb_ebuf, "in bwb_dim(): DOUBLE array memory requires <%ld> bytes", (long) ( newvar->array_units + 1 ) * sizeof( double )); bwb_debug( bwb_ebuf );#endif /* Revised to CALLOC pass-thru call by JBV */ if ( ( np = (bnumber *) CALLOC( newvar->array_units, sizeof( bnumber ), "bwb_dim" )) == NULL ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in line %d: Failed to find memory for array <%s>", l->number, newvar->name ); bwb_error( bwb_ebuf );#else bwb_error( err_getmem );#endif return bwb_zline( l ); } newvar->memnum = np; break; default:#if PROG_ERRORS sprintf( bwb_ebuf, "in line %d: New variable has unrecognized type.", l->number ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif return bwb_zline( l ); } } /* end of conditional for new variable */ /* now check for end of string */ if ( l->buffer[ l->position ] == ')' ) { ++( l->position ); } adv_ws( l->buffer, &( l->position )); switch( l->buffer[ l->position ] ) { case '\n': /* end of line */ case '\r': case ':': /* end of line segment */ case '\0': /* end of string */ loop = FALSE; break; case ',': ++( l->position ); adv_ws( l->buffer, &( l->position ) ); loop = TRUE; break; default:#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_dim(): unexpected end of string, buf <%s>", &( l->buffer[ l->position ] ) ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif loop = FALSE; break; } } /* end of loop through variables */ /* return */ return bwb_zline( l ); }/*************************************************************** FUNCTION: dim_unit() DESCRIPTION: This function calculates the unit position for an array.***************************************************************/#if ANSI_Cstatic size_tdim_unit( struct bwb_variable *v, int *pp )#elsestatic size_tdim_unit( v, pp ) struct bwb_variable *v; int *pp;#endif { size_t r; size_t b; register int n; /* Calculate and return the address of the dimensioned array */ b = 1; r = 0; for ( n = 0; n < v->dimensions; ++n ) { r += b * ( pp[ n ] - dim_base ); b *= v->array_sizes[ n ]; }#if INTENSIVE_DEBUG for ( n = 0; n < v->dimensions; ++n ) { sprintf( bwb_ebuf, "in dim_unit(): variable <%s> pos <%d> val <%d>.", v->name, n, pp[ n ] ); bwb_debug( bwb_ebuf ); } sprintf( bwb_ebuf, "in dim_unit(): return unit: <%ld>", (long) r ); bwb_debug( bwb_ebuf );#endif if ( r > v->array_units ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in dim_unit(): unit value <%ld> exceeds array units <%ld>", r, v->array_units ); bwb_error( bwb_ebuf );#else bwb_error( err_valoorange );#endif return 0; } return r; }/*************************************************************** FUNCTION: dim_getparams() DESCRIPTION: This function reads a string in <buffer> beginning at position <pos> and finds a list of parameters surrounded by paren- theses, returning in <n_params> the number of parameters found, and returning in <pp> an array of n_params integers giving the sizes for each dimension of the array.***************************************************************/#if ANSI_Cintdim_getparams( char *buffer, int *pos, int *n_params, int **pp )#elseintdim_getparams( buffer, pos, n_params, pp ) char *buffer; int *pos; int *n_params; int **pp;#endif { int loop; static int params[ MAX_DIMS ]; int x_pos, s_pos; struct exp_ese *e; char tbuf[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG register int n;#endif /* set initial values */ *n_params = 0;#if OLDSTUFF paren_found = FALSE;#endif /* advance and check for undimensioned variable */ adv_ws( buffer, pos ); if ( buffer[ *pos ] != '(' ) { *n_params = 1; params[ 0 ] = dim_base; *pp = params; return TRUE; } else { ++(*pos); } /* Variable has DIMensions: Find each parameter */ s_pos = 0; tbuf[ 0 ] = '\0'; loop = TRUE; while( loop == TRUE ) { switch( buffer[ *pos ] ) { case ')': /* end of parameter list */ x_pos = 0; if ( tbuf[ 0 ] == '\0' ) { params[ *n_params ] = DEF_SUBSCRIPT; } else {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in dim_getparams(): call bwb_exp() for last element" ); bwb_debug( bwb_ebuf );#endif e = bwb_exp( tbuf, FALSE, &x_pos );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in dim_getparams(): return from bwb_exp() for last element" ); bwb_debug( bwb_ebuf );#endif params[ *n_params ] = (int) exp_getnval( e ); } ++(*n_params); loop = FALSE; ++( *pos ); break; case ',': /* end of a parameter */ x_pos = 0; if ( tbuf[ 0 ] == '\0' ) { params[ *n_params ] = DEF_SUBSCRIPT; } else {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in dim_getparams(): call bwb_exp() for element (not last)" ); bwb_debug( bwb_ebuf );#endif e = bwb_exp( tbuf, FALSE, &x_pos ); params[ *n_params ] = (int) exp_getnval( e ); } ++(*n_params); tbuf[ 0 ] = '\0'; ++(*pos); s_pos = 0; break; case ' ': /* whitespace -- skip */ case '\t': ++(*pos); break; default: tbuf[ s_pos ] = buffer[ *pos ]; ++(*pos); ++s_pos; tbuf[ s_pos ] = '\0'; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -