📄 bwb_cnd.c
字号:
struct bwb_line *bwb_endif( l ) struct bwb_line *l;#endif {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_endif(): entered function" ); bwb_debug( bwb_ebuf );#endif if (( CURTASK excs[ CURTASK exsc ].code != EXEC_IFTRUE ) && ( CURTASK excs[ CURTASK exsc ].code != EXEC_IFFALSE )) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_endif(): END IF without IF" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif } bwb_decexec();#if MULTISEG_LINES adv_eos( l->buffer, &( l->position ));#endif return bwb_zline( l ); }/*************************************************************** FUNCTION: find_endif() DESCRIPTION: This C function attempts to find an END IF statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_endif( struct bwb_line *l, struct bwb_line **else_line )#elsestatic struct bwb_line *find_endif( l, else_line ) struct bwb_line *l; struct bwb_line **else_line;#endif { struct bwb_line *current; register int i_level; int position; *else_line = NULL; i_level = 1; for ( current = l->next; current != &CURTASK bwb_end; current = current->next ) { position = 0; if ( current->marked != TRUE ) { line_start( current->buffer, &position, &( current->lnpos ), &( current->lnum ), &( current->cmdpos ), &( current->cmdnum ), &( current->startpos ) ); } current->position = current->startpos; if ( current->cmdnum > -1 ) { if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_if ) { ++i_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_endif(): found IF at line %d, level %d", current->number, i_level ); bwb_debug( bwb_ebuf );#endif } else if ( is_endif( current ) == TRUE ) { --i_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_endif(): found END IF at line %d, level %d", current->number, i_level ); bwb_debug( bwb_ebuf );#endif if ( i_level == 0 ) { return current; } } else if ( ( bwb_cmdtable[ current->cmdnum ].vector == bwb_else ) || ( bwb_cmdtable[ current->cmdnum ].vector == bwb_elseif )) { /* we must only report the first ELSE or ELSE IF we encounter at level 1 */ if ( ( i_level == 1 ) && ( *else_line == NULL )) { *else_line = current; } } } }#if PROG_ERRORS sprintf( bwb_ebuf, "Multiline IF without END IF" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif return NULL; }/*************************************************************** FUNCTION: is_endif() DESCRIPTION: This C function attempts to determine if a given line contains an END IF statement.***************************************************************/#if ANSI_Cstatic intis_endif( struct bwb_line *l )#elsestatic intis_endif( l ) struct bwb_line *l;#endif { int position; char tbuf[ MAXVARNAMESIZE + 1]; if ( bwb_cmdtable[ l->cmdnum ].vector != bwb_xend ) { return FALSE; } position = l->startpos; adv_ws( l->buffer, &position ); adv_element( l->buffer, &position, tbuf ); bwb_strtoupper( tbuf ); if ( strcmp( tbuf, "IF" ) == 0 ) { return TRUE; } return FALSE; }/*************************************************************** FUNCTION: bwb_select() DESCRIPTION: This C function handles the BASIC SELECT statement. SYNTAX: SELECT CASE expression***************************************************************/#if ANSI_Cstruct bwb_line *bwb_select( struct bwb_line *l )#elsestruct bwb_line *bwb_select( l ) struct bwb_line *l;#endif { char tbuf[ MAXSTRINGSIZE + 1 ]; struct exp_ese *e;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_select(): entered function" ); bwb_debug( bwb_ebuf );#endif /* first element should be "CASE" */ adv_element( l->buffer, &( l->position ), tbuf ); bwb_strtoupper( tbuf ); if ( strcmp( tbuf, "CASE" ) != 0 ) {#if PROG_ERRORS sprintf( bwb_ebuf, "SELECT without CASE" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax ); return bwb_zline( l );#endif } /* increment the level and set to EXEC_SELFALSE */ bwb_incexec(); CURTASK excs[ CURTASK exsc ].code = EXEC_SELFALSE; /* evaluate the expression at this level */ e = bwb_exp( l->buffer, FALSE, &( l->position ) );#if OLDWAY memcpy( &( CURTASK excs[ CURTASK exsc ].expression ), e, sizeof( struct exp_ese ) );#endif if ( e->type == STRING ) { CURTASK excs[ CURTASK exsc ].expression.type = STRING; str_btob( &( CURTASK excs[ CURTASK exsc ].expression.sval ), &( e->sval ) ); } else { CURTASK excs[ CURTASK exsc ].expression.type = NUMBER; CURTASK excs[ CURTASK exsc ].expression.nval = exp_getnval( e ); } /* return */#if MULTISEG_LINES adv_eos( l->buffer, &( l->position ));#endif return bwb_zline( l ); }/*************************************************************** FUNCTION: bwb_case() DESCRIPTION: This C function handles the BASIC CASE statement. SYNTAX: CASE constant | IF partial-expression | ELSE***************************************************************/#if ANSI_Cstruct bwb_line *bwb_case( struct bwb_line *l )#elsestruct bwb_line *bwb_case( l ) struct bwb_line *l;#endif { char tbuf[ MAXSTRINGSIZE + 1 ]; int oldpos; struct exp_ese minvalue; struct exp_ese *maxval, *minval; struct bwb_line *retline; char cbuf1[ MAXSTRINGSIZE + 1 ]; char cbuf2[ MAXSTRINGSIZE + 1 ];#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_case(): entered function" ); bwb_debug( bwb_ebuf );#endif /* if code is EXEC_SELTRUE, then we should jump to the end */ if ( CURTASK excs[ CURTASK exsc ].code == EXEC_SELTRUE ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_case(): exit EXEC_SELTRUE" ); bwb_debug( bwb_ebuf );#endif retline = find_endselect( l ); retline->position = 0; return retline; } /* read first element */ oldpos = l->position; adv_element( l->buffer, &( l->position ), tbuf ); bwb_strtoupper( tbuf ); /* check for CASE IF */ if ( strcmp( tbuf, CMD_IF ) == 0 ) { return bwb_caseif( l ); } /* check for CASE ELSE: if true, simply proceed to the next line, because other options should have been detected by now */ else if ( strcmp( tbuf, CMD_ELSE ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_case(): execute CASE ELSE" ); bwb_debug( bwb_ebuf );#endif return bwb_zline( l ); } /* neither CASE ELSE nor CASE IF; presume constant here for min value */ l->position = oldpos; minval = bwb_exp( l->buffer, FALSE, &( l->position )); memcpy( &minvalue, minval, sizeof( struct exp_ese ) ); maxval = minval = &minvalue; /* check for string value */ if ( minvalue.type == STRING ) { str_btoc( cbuf1, &( CURTASK excs[ CURTASK exsc ].expression.sval ) ); str_btoc( cbuf2, &( minvalue.sval ) );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_case(): compare strings <%s> and <%s>", cbuf1, cbuf2 ); bwb_debug( bwb_ebuf );#endif if ( strncmp( cbuf1, cbuf2, MAXSTRINGSIZE ) == 0 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_case(): string comparison returns TRUE" ); bwb_debug( bwb_ebuf );#endif CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;#if MULTISEG_LINES adv_eos( l->buffer, &( l->position ));#endif return bwb_zline( l ); } else {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_case(): string comparison returns FALSE" ); bwb_debug( bwb_ebuf );#endif retline = find_case( l ); retline->position = 0; return retline; } } /* not a string; advance */ adv_ws( l->buffer, &( l->position )); /* check for TO */ if ( is_eol( l->buffer, &( l->position )) != TRUE ) { /* find the TO statement */ adv_element( l->buffer, &( l->position ), tbuf ); bwb_strtoupper( tbuf ); if ( strcmp( tbuf, CMD_TO ) != 0 ) {#if PROG_ERRORS sprintf( bwb_ebuf, "CASE has inexplicable code following expression" ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#if MULTISEG_LINES adv_eos( l->buffer, &( l->position ));#endif return bwb_zline( l );#endif } /* now evaluate the MAX expression */ maxval = bwb_exp( l->buffer, FALSE, &( l->position )); } /* evaluate the expression */ if ( case_eval( &( CURTASK excs[ CURTASK exsc ].expression ), minval, maxval ) == TRUE ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_case(): evaluation returns TRUE" ); bwb_debug( bwb_ebuf );#endif CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;#if MULTISEG_LINES adv_eos( l->buffer, &( l->position ));#endif return bwb_zline( l ); } /* evaluation returns a FALSE value; find next CASE or END SELECT statement */ else {#if INTENSIVE_DEBUGb sprintf( bwb_ebuf, "in bwb_case(): evaluation returns FALSE" ); bwb_debug( bwb_ebuf );#endif retline = find_case( l ); retline->position = 0; return retline; } }/*************************************************************** FUNCTION: bwb_caseif() DESCRIPTION: This C function handles the BASIC CASE IF statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *bwb_caseif( struct bwb_line *l )#elsestatic struct bwb_line *bwb_caseif( l ) struct bwb_line *l;#endif { char tbuf[ MAXSTRINGSIZE + 1 ]; int position; struct exp_ese *r; struct bwb_line *retline; if ( CURTASK excs[ CURTASK exsc ].expression.type == NUMBER ) { sprintf( tbuf, "%f %s", (float) CURTASK excs[ CURTASK exsc ].expression.nval, &( l->buffer[ l->position ] ) ); } else { bwb_error( err_mismatch );#if MULTISEG_LINES adv_eos( l->buffer, &( l->position ));#endif return bwb_zline( l ); } position = 0; r = bwb_exp( tbuf, FALSE, &position ); if ( r->nval == (bnumber) TRUE ) { CURTASK excs[ CURTASK exsc ].code = EXEC_SELTRUE;#if MULTISEG_LINES adv_eos( l->buffer, &( l->position ));#endif return bwb_zline( l ); } else { retline = find_case( l ); retline->position = 0; return retline; } }/*************************************************************** FUNCTION: case_eval() DESCRIPTION: This function evaluates a case statement by comparing minimum and maximum values with a set expression. It returns either TRUE or FALSE***************************************************************/#if ANSI_Cstatic intcase_eval( struct exp_ese *expression, struct exp_ese *minval, struct exp_ese *maxval )#elsestatic intcase_eval( expression, minval, maxval ) struct exp_ese *expression; struct exp_ese *minval; struct exp_ese *maxval;#endif { /* string value */ if ( expression->type == STRING ) { bwb_error( err_mismatch ); return FALSE; } /* numerical value */#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in case_eval(): n <%f> min <%f> max <%f>", (float) expression->nval, (float) minval->nval, (float) maxval->nval ); bwb_debug( bwb_ebuf );#endif if ( ( expression->nval >= minval->nval ) && ( expression->nval <= maxval->nval )) { return TRUE; } return FALSE; }/*************************************************************** FUNCTION: find_case() DESCRIPTION: This function searches for a line containing a CASE statement corresponding to a previous SELECT CASE statement.***************************************************************/#if ANSI_Cstatic struct bwb_line *find_case( struct bwb_line *l )#elsestatic struct bwb_line *find_case( l ) struct bwb_line *l;#endif { struct bwb_line *current; register int c_level; int position; c_level = 1; for ( current = l->next; current != &CURTASK bwb_end; current = current->next ) { position = 0; if ( current->marked != TRUE ) { line_start( current->buffer, &position, &( current->lnpos ), &( current->lnum ), &( current->cmdpos ), &( current->cmdnum ), &( current->startpos ) ); } current->position = current->startpos; if ( current->cmdnum > -1 ) { if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_select ) { ++c_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_case(): found SELECT at line %d, level %d", current->number, c_level ); bwb_debug( bwb_ebuf );#endif } else if ( is_endselect( current ) == TRUE ) { --c_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_endif(): found END SELECT at line %d, level %d", current->number, c_level ); bwb_debug( bwb_ebuf );#endif if ( c_level == 0 ) { return current; } } else if ( bwb_cmdtable[ current->cmdnum ].vector == bwb_case ) { --c_level;#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in find_case(): found CASE at line %d, level %d", current->number, c_level );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -