📄 bwbasic.c
字号:
#elsebwb_mainloop()#endif { if ( CURTASK exsc > -1 ) { bwb_execline(); /* execute one line of program */ }#if INTERACTIVE else { bwb_interact(); /* get user interaction */ }#endif }/*************************************************************** FUNCTION: bwb_execline() DESCRIPTION: This function executes a single line of a program in memory. This function is called by bwb_mainloop().***************************************************************/void#if ANSI_Cbwb_execline( void )#elsebwb_execline()#endif { struct bwb_line *r, *l; l = CURTASK excs[ CURTASK exsc ].line; /* if the line is &CURTASK bwb_end, then break out of EXEC loops */ if ( l == &CURTASK bwb_end ) { CURTASK exsc = -1; return; } /* Check for wacko line numbers */#if INTENSIVE_DEBUG if ( l->number < -1 ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_execline(): received line number <%d> < -1", l->number ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif return; } if ( l->number > MAXLINENO ) {#if PROG_ERRORS sprintf( bwb_ebuf, "in bwb_execline(): received line number <%d> > MAX <%d>", l->number, MAXLINENO ); bwb_error( bwb_ebuf );#else bwb_error( err_syntax );#endif return; }#endif#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_execline(): buffer <%s>", &( l->buffer[ l->position ] ) ); bwb_debug( bwb_ebuf );#endif /* Print line number if trace is on */ if ( bwb_trace == TRUE ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "[ %d ]", l->number ); prn_xprintf( errfdevice, bwb_ebuf );#else if ( l->number > 0 ) { sprintf( bwb_ebuf, "[ %d ]", l->number ); prn_xprintf( errfdevice, bwb_ebuf ); }#endif } /* Set current line for error/break handling */ CURTASK number = l->number; CURTASK bwb_l = l; /* advance beyond whitespace */ adv_ws( l->buffer, &( l->position ) ); /* advance past segment delimiter and warn */#if MULTISEG_LINES if ( l->buffer[ l->position ] == ':' ) { ++( l->position ); adv_ws( l->buffer, &( l->position ) ); } l->marked = FALSE;#else#if PROG_ERRORS if ( l->buffer[ l->position ] == ':' ) { ++( l->position ); adv_ws( l->buffer, &( l->position ) ); sprintf( bwb_ebuf, "Enable MULTISEG_LINES for multi-segmented lines", VERSION ); bwb_error( bwb_ebuf ); }#endif#endif /* set positions in buffer */#if MULTISEG_LINES if ( ( l->marked != TRUE ) || ( l->position > l->startpos )) { line_start( l->buffer, &( l->position ), &( l->lnpos ), &( l->lnum ), &( l->cmdpos ), &( l->cmdnum ), &( l->startpos ) ); l->marked = TRUE; } else {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_execline(): line <%d> is already marked", l->number ); bwb_debug( bwb_ebuf );#endif } l->position = l->startpos;#else /* not MULTISEG_LINES */ line_start( l->buffer, &( l->position ), &( l->lnpos ), &( l->lnum ), &( l->cmdpos ), &( l->cmdnum ), &( l->startpos ) ); if ( l->position < l->startpos ) { l->position = l->startpos; }#endif /* if there is a BASIC command in the line, execute it here */ if ( l->cmdnum > -1 ) {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_execline(): executing <%s>", l->buffer ); bwb_debug( bwb_ebuf );#endif /* execute the command vector */ r = bwb_cmdtable[ l->cmdnum ].vector ( l ); } /* No BASIC command; try to execute it as a shell command */#if COMMAND_SHELL else {#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "Breaking out to shell, line num <%d> buf <%s> cmd <%d> pos <%d>", l->number, &( l->buffer[ l->position ] ), l->cmdnum, l->position ); bwb_debug( bwb_ebuf ); getchar();#endif bwx_shell( l ); bwb_setexec( l->next, 0, CURTASK excs[ CURTASK exsc ].code ); return; }#else /* COMMAND_SHELL == FALSE */ else { bwb_error( err_uc ); }#endif /* check for end of line: if so, advance to next line and return */ adv_ws( r->buffer, &( r->position ) ); switch( r->buffer[ r->position ] ) { case '\n': case '\r': case '\0':#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_execline(): detected end of line" ); bwb_debug( bwb_ebuf );#endif r->next->position = 0; bwb_setexec( r->next, 0, CURTASK excs[ CURTASK exsc ].code ); return; /* and return */ } /* else reset with the value in r */ bwb_setexec( r, r->position, CURTASK excs[ CURTASK exsc ].code );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in bwb_execline(): exit setting line number <%d>", r->number ); bwb_debug( bwb_ebuf );#endif }/*************************************************************** FUNCTION: ln_asbuf() DESCRIPTION: This function allocates memory and copies a null-terminated string to a line buffer.***************************************************************/int#if ANSI_Cln_asbuf( struct bwb_line *l, char *s )#elseln_asbuf( l, s ) struct bwb_line *l; char *s;#endif {/* Reinstated by JBV *//* #if DONTDOTHIS */ /* but why not? */ if ( l->buffer != NULL ) { /* Revised to FREE pass-thru call by JBV */ FREE( l->buffer, "ln_asbuf" ); l->buffer = NULL; /* JBV */ }/* #endif */ /* Revised to CALLOC pass-thru call by JBV */ if ( ( l->buffer = CALLOC( strlen( s ) + 2, sizeof( char ), "ln_asbuf") ) == NULL ) {#if PROG_ERRORS bwb_error( "in ln_asbuf(): failed to find memory for new line" );#else bwb_error( err_getmem );#endif return FALSE; } /* copy the whole line to the line structure buffer */ strcpy( l->buffer, s );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in ln_asbuf(): allocated buffer <%s>", l->buffer ); bwb_debug( bwb_ebuf );#endif /* strip CR from the buffer */ bwb_stripcr( l->buffer );#if INTENSIVE_DEBUG sprintf( bwb_ebuf, "in ln_asbuf(): stripped CRs" ); bwb_debug( bwb_ebuf );#endif return TRUE; }/*************************************************************** FUNCTION: bwb_gets() DESCRIPTION: This function reads a single line from the specified buffer.***************************************************************/int#if ANSI_Cbwb_gets( char *buffer )#elsebwb_gets( buffer ) char *buffer;#endif { struct bwb_variable *v; char tbuf[ MAXSTRINGSIZE + 1 ];#if PARACT char ubuf[ MAXSTRINGSIZE + 1 ];#endif CURTASK number = 0; v = var_find( DEFVNAME_PROMPT ); str_btoc( tbuf, var_getsval( v ) );#if PARACT sprintf( ubuf, "TASK %d %s", bwb_curtask, tbuf ); strcpy( tbuf, ubuf );#endif bwx_input( tbuf, buffer ); return TRUE; }/*************************************************************** FUNCTION: break_mes() DESCRIPTION: This function is called (a) by a SIGINT signal or (b) by error-handling routines. It prints an error message then calls break_handler() to handle the program interruption.***************************************************************/void#if ANSI_Cbreak_mes( int x )#elsebreak_mes( x ) int x;#endif { static char *tmp_buffer; static int init = FALSE; /* get memory for temporary buffer if necessary */ if ( init == FALSE ) { init = TRUE; /* Revised to CALLOC pass-thru call by JBV */ if ( ( tmp_buffer = CALLOC( MAXSTRINGSIZE + 1, sizeof( char ), "break_mes")) == NULL ) {#if PROG_ERRORS bwb_error( "in break_mes(): failed to find memory for tmp_buffer" );#else bwb_error( err_getmem );#endif } } CURTASK expsc = 0; sprintf( tmp_buffer, "\r%s %d\n", MES_BREAK, CURTASK number ); prn_xprintf( errfdevice, tmp_buffer ); break_handler(); }/*************************************************************** FUNCTION: break_handler() DESCRIPTION: This function is called by break_mes() and handles program interruption by break (or by the STOP command).***************************************************************/void#if ANSI_Cbreak_handler( void )#elsebreak_handler()#endif {#if INTERACTIVE /* INTERACTIVE: reset counters and jump back to mark */ /* reset all stack counters */ CURTASK exsc = -1; CURTASK expsc = 0; CURTASK xtxtsc = 0; err_gosubl[ 0 ] = '\0'; /* reset the break handler */#if HAVE_SIGNAL signal( SIGINT, break_mes );#endif#if HAVE_LONGJUMP longjmp( mark, -1 );#else /* HAVE_LONGJUMP = FALSE; no jump available; terminate */ bwx_terminate();#endif #else /* nonINTERACTIVE: terminate immediately */ bwx_terminate();#endif }/*************************************************************** FUNCTION: is_ln() DESCRIPTION: This function determines whether a program line (in buffer) begins with a line number.***************************************************************/int#if ANSI_Cis_ln( char *buffer )#elseis_ln( buffer ) char *buffer;#endif { static int position; position = 0; adv_ws( buffer, &position ); switch( buffer[ position ] ) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return TRUE; default: return FALSE; } }/*************************************************************** FUNCTION: CALLOC() DESCRIPTION: Pass-thru function to calloc() for debugging purposes. Added by JBV 10/95***************************************************************/void *#if ANSI_CCALLOC( size_t nelem, size_t elsize, char *str )#elseCALLOC( nelem, elsize, str ) size_t nelem; size_t elsize; char *str;#endif{ void *ptr; ptr = calloc(nelem, elsize); /* printf("%x %x\n", ptr, mallocblksize(ptr)); */ return ptr;}/*************************************************************** FUNCTION: FREE() DESCRIPTION: Pass-thru function to free() for debugging purposes. Added by JBV 10/95***************************************************************/void#if ANSI_CFREE( void *ptr, char *str )#elseFREE( ptr, str ) void *ptr; char *str;#endif{ /* printf("%x\n", ptr); */ free(ptr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -