void scr_th( void ) { ifcb * cb = input_cbs->if_cb; char linestr[MAX_L_AS_STR]; scan_err = false; cb->if_flags[cb->if_level].ifcwte = false; if( !cb->if_flags[cb->if_level].iflast || !(cb->if_flags[cb->if_level].iftrue || cb->if_flags[cb->if_level].iffalse) || cb->if_flags[cb->if_level].ifthen || cb->if_flags[cb->if_level].ifelse || cb->if_flags[cb->if_level].ifdo ) { scan_err = true; g_err( err_if_then ); if( input_cbs->fmflags & II_macro ) { ultoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { ultoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } show_ifcb( "then", cb ); show_include_stack(); err_count++; return; } cb->if_flags[cb->if_level].iflast = false; cb->if_flags[cb->if_level].ifthen = true; ProcFlags.keep_ifstate = true; if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { show_ifcb( "then", cb ); } garginit(); // find end of control word while( *scan_start == ' ' ) { scan_start++; } if( *scan_start ) { // rest of line is not empty split split_input( buff2, scan_start, false );// and process next } scan_restart = scan_stop + 1; return; }
void scr_th( void ) { ifcb * cb = input_cbs->if_cb; scan_err = false; cb->if_flags[cb->if_level].ifcwte = false; if( !cb->if_flags[cb->if_level].iflast || !(cb->if_flags[cb->if_level].iftrue || cb->if_flags[cb->if_level].iffalse) || cb->if_flags[cb->if_level].ifthen || cb->if_flags[cb->if_level].ifelse || cb->if_flags[cb->if_level].ifdo ) { scan_err = true; g_err( err_if_then ); g_info_inp_pos(); show_ifcb( "then", cb ); show_include_stack(); err_count++; return; } cb->if_flags[cb->if_level].iflast = false; cb->if_flags[cb->if_level].ifthen = true; ProcFlags.keep_ifstate = true; if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { show_ifcb( "then", cb ); } garginit(); // find end of control word while( *scan_start == ' ' ) { scan_start++; } if( *scan_start ) { // rest of line is not empty split split_input( buff2, scan_start, false );// and process next } scan_restart = scan_stop; return; }
condcode test_process( ifcb * cb ) { condcode cc; char linestr[MAX_L_AS_STR]; #ifdef DEBTESTPROC int start_level = cb->if_level; if( input_cbs->fmflags & II_research && GlobalFlags.firstpass && cb->if_level ) { show_ifcb( "Anf teif", cb ); } #endif cc = no; //mainif if( cb->if_flags[cb->if_level].iflast // 1. rec after .if && !cb->if_flags[cb->if_level].ifcwte) {// not .th or .el cb->if_flags[cb->if_level].iflast = false; // reset first switch cb->if_flags[cb->if_level].ifthen = true; // treat as then } //mnif01 if( cb->if_flags[cb->if_level].ifcwif ) { // .if //mnif03 if( cb->if_flags[cb->if_level].ifthen || cb->if_flags[cb->if_level].ifelse ) {// object of .th or .el cc = pos; } else { //mnif03a while( cb->if_level > 0 ) { // pop one level cb->if_level--; if( cb->if_flags[cb->if_level].ifdo ) { break; } } cc = pos; // .do or all popped } #ifdef DEBTESTPROC if( input_cbs->fmflags & II_research && GlobalFlags.firstpass && (start_level || cb->if_level) ) { char * txt = (cc == pos ? "EX1 pos" : "EX1 no" ); show_ifcb( txt, cb ); } #endif return( cc ); } else { // not .if //mnif01 cont. if( cb->if_flags[cb->if_level].ifcwdo ) { // if .do cc = pos; #ifdef DEBTESTPROC if( input_cbs->fmflags & II_research && GlobalFlags.firstpass && (start_level || cb->if_level) ) { char * txt = (cc == pos ? "Edo pos" : "Edo no" ); show_ifcb( txt, cb ); } #endif return( cc ); } if( cb->if_flags[cb->if_level].ifthen || cb->if_flags[cb->if_level].ifelse ) {// object of .th or .el //mnif05 if( cb->if_flags[cb->if_level].ifelse ) { // object of .el //mnif06 if( cb->if_flags[cb->if_level].iftrue ) {// omit if true for .el //mnif08 cc = neg; } else { cc = pos; } } else { if( cb->if_flags[cb->if_level].iffalse ) {// omit false for .th cc = neg; } else { cc = pos; } } } else { if( cb->if_flags[cb->if_level].ifcwte ) { cc = pos; } else { //mnif02 while( cb->if_level > 0 ) { cb->if_level--; if( cb->if_flags[cb->if_level].ifdo ) { //mnif05 if( cb->if_flags[cb->if_level].ifelse ) {// object of .el //mnif06 if( cb->if_flags[cb->if_level].iftrue ) { //mnif08 cc = neg; // omit if true for .el } else { cc = pos; } } else { if( cb->if_flags[cb->if_level].iffalse ) { cc = neg; // omit false for .th } else { cc = pos; } } break; } } if( cc == no ) { // not set then process record cc = pos; } } } } if( cc == no ) { // cc not set program logic error if( input_cbs->fmflags & II_macro ) { ultoa( input_cbs->s.m->lineno, linestr, 10 ); g_err( err_if_intern, linestr, "macro", input_cbs->s.m->mac->name ); } else { ultoa( input_cbs->s.f->lineno, linestr, 10 ); g_err( err_if_intern, linestr, "file", input_cbs->s.f->filename ); } if( inc_level > 1 ) { show_include_stack(); } err_count++; } #ifdef DEBTESTPROC if( input_cbs->fmflags & II_research && GlobalFlags.firstpass && (start_level || cb->if_level) ) { char * txt = (cc == pos ? "EX3 pos" : "EX3 no" ); show_ifcb( txt, cb ); } #endif return( cc ); }
void scr_do( void ) { ifcb * cb = input_cbs->if_cb; condcode cc; scan_err = false; garginit(); // find end of control word cc = getarg(); cb->if_flags[cb->if_level].ifcwdo = false; if( cc == omit || !strnicmp( tok_start, "begin", 5 )) { if( !(cb->if_flags[cb->if_level].ifthen || cb->if_flags[cb->if_level].ifelse) || cb->if_flags[cb->if_level].ifdo ) { scan_err = true; g_err( err_if_do ); g_info_inp_pos(); show_ifcb( "dobegin", cb ); show_include_stack(); err_count++; return; } cb->if_flags[cb->if_level].ifdo = true; if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { show_ifcb( "dobegin", cb ); } scan_restart = scan_stop; return; } else { if( !strnicmp( tok_start, "end", 3 )) { if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { show_ifcb( "doend", cb ); } do { // loop for last active .do begin if( cb->if_flags[cb->if_level].ifdo ) { cb->if_flags[cb->if_level].ifdo = false; if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { show_ifcb( "doend", cb ); } scan_restart = scan_stop; return; } if( cb->if_flags[cb->if_level].ifthen || cb->if_flags[cb->if_level].ifelse || !(cb->if_flags[cb->if_level].iftrue || cb->if_flags[cb->if_level].iffalse) ) { scan_err = true; g_err( err_if_do_end ); g_info_inp_pos(); show_ifcb( "doend", cb ); show_include_stack(); err_count++; return; } } while( cb->if_level-- > 0 ); #if 0 if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { out_msg( "\t.do end Level %d\n" "\t.ifcb iftrue %d, iffalse %d\n", cb->if_level, cb->if_flags[cb->if_level].iftrue, cb->if_flags[cb->if_level].iffalse ); } #endif } else { scan_err = true; g_err( err_if_do_fun ); g_info_inp_pos(); show_include_stack(); err_count++; return; } } if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { show_ifcb( "do xx", cb ); } scan_restart = scan_stop; return; }
void scr_if( void ) { ifcb * cb; // if stack ptr condcode cct1; condcode cct2; condcode ccrelop; termcb t1; // first argument termcb t2; // second argument relop relation; // the relation between t1 and t2 logop logical; // if more than 1 condition bool ifcond; // current condition bool totalcondition; // resultant condition bool firstcondition; // first comparison .if scan_err = false; firstcondition = true; // first 2 terms to compare garginit(); // find end of control word cb = input_cbs->if_cb; // get .if control block cb->if_flags[cb->if_level].ifcwif = false; // reset cwif switch for( ;; ) { // evaluate if conditions cct1 = gargterm( &t1 ); // get term 1 ccrelop = gargrelop( &relation ); // get relation operator cct2 = gargterm( &t2 ); // get term 2 if( (cct1 == no) || (cct2 == no) ) { scan_err = true; err_count++; g_err( err_if_term ); g_info_inp_pos(); show_include_stack(); return; } if( ccrelop != pos ) { scan_err = true; err_count++; g_err( err_if_relop ); g_info_inp_pos(); show_include_stack(); return; } // terms and operator ok now compare ifcond = ifcompare( &t1, relation, &t2 ); mem_free( t1.term_string ); // don't need the strings anymore mem_free( t2.term_string ); if( firstcondition ) { firstcondition = false; if( cb->if_level < MAX_IF_LEVEL ) { cb->if_level++; memset( &cb->if_flags[cb->if_level], '\0', sizeof( cb->if_flags[cb->if_level] ) ); cb->if_flags[cb->if_level].iflast = true; cb->if_flags[cb->if_level].ifcwte = false; // no .th .el yet cb->if_flags[cb->if_level].iftrue = false; // cond not yet true cb->if_flags[cb->if_level].iffalse = false; // cond not yet false } else { scan_err = true; g_err( err_if_nesting ); g_info_inp_pos(); show_include_stack(); err_count++; return; } totalcondition = ifcond; } else { // resultant condition if( logical == AND ) { totalcondition &= ifcond; } else { totalcondition |= ifcond; } } if( totalcondition ) { // set if true / false flags cb->if_flags[cb->if_level].iftrue = true; cb->if_flags[cb->if_level].iffalse = false; } else { cb->if_flags[cb->if_level].iffalse = true; cb->if_flags[cb->if_level].iftrue = false; } while( *scan_start == ' ' ) { scan_start++; } /* * test logical condition if not line end * .if a = b or c GT d * ^^ */ if( *scan_start ) { if( *scan_start == SCR_char ) { break; // .xx can't be logical operator } if( *(scan_start + 1) == ' ' ) {// single char + blank if( *scan_start == '&' ) { logical = AND; scan_start += 2; continue; // do next conditions } else if( *scan_start == '|' ) { logical = OR; scan_start += 2; continue; // do next conditions } } else { if( !strnicmp( scan_start, "and ", 4 ) ) { logical = AND; scan_start += 4; continue; // do next conditions } else if( !strnicmp( scan_start, "or ", 3 ) ) { logical = OR; scan_start += 3; continue; // do next conditions } } } break; // no more operators / conditions } if( cb->if_level > 1 ) { // nested if if( cb->if_flags[cb->if_level - 1].ifthen ) { // object of .th if( cb->if_flags[cb->if_level - 1].iffalse ) {// last .if false cb->if_flags[cb->if_level].iftrue = true;// process nothing cb->if_flags[cb->if_level].iffalse = true; } } else { if( cb->if_flags[cb->if_level - 1].ifelse // object of .el && cb->if_flags[cb->if_level - 1].iftrue ) {// last .if true cb->if_flags[cb->if_level].iftrue = true;// process nothing cb->if_flags[cb->if_level].iffalse = true; } } } if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { show_ifcb( "if", cb ); #if 0 out_msg( "\t.if is %s Level %d\n" "\t.ifcb iftrue %d, iffalse %d\n", totalcondition ? "true " : "false", cb->if_level, cb->if_flags[cb->if_level].iftrue, cb->if_flags[cb->if_level].iffalse ); #endif } if( *scan_start ) { // rest of line is not empty split_input( buff2, scan_start, false ); // split and process next } scan_restart = scan_stop; return; }