static void get_macro_line( void ) { macrocb * cb; if( input_cbs->fmflags & II_file ) {// current input is file not macro g_err( err_logic_mac ); show_include_stack(); err_count++; g_suicide(); } cb = input_cbs->s.m; if( cb->macline == NULL ) { // no more macrolines input_cbs->fmflags |= II_eof; input_cbs->fmflags &= ~(II_sol | II_eol); cb->flags |= FF_eof; *buff2 = '\0'; } else { cb->lineno++; cb->flags &= ~FF_eof; input_cbs->fmflags &= ~II_eof; input_cbs->fmflags |= (II_sol | II_eol); strcpy_s( buff2, buf_size, cb->macline->value ); cb->macline = cb->macline->next; } }
condcode scr_d2c( parm parms[MAX_FUN_PARMS], size_t parmcount, char **result, int32_t ressize ) { char * pval; char * pend; condcode cc; int n; getnum_block gn; /* unused parameters */ (void)ressize; if( parmcount != 1 ) { cc = neg; return( cc ); } pval = parms[0].start; pend = parms[0].stop; unquote_if_quoted( &pval, &pend ); if( pend == pval ) { // null string nothing to do **result = '\0'; return( pos ); } n = 0; gn.ignore_blanks = false; if( parms[1].stop > parms[1].start ) { gn.argstart = pval; gn.argstop = pend; cc = getnum( &gn ); if( (cc != pos) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "1 (number)" ); g_info_inp_pos(); err_count++; show_include_stack(); } return( cc ); } n = gn.result; } **result = gn.result; *result += 1; **result = '\0'; return( pos ); }
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; }
condcode scr_min( parm parms[MAX_FUN_PARMS], size_t parmcount, char * * result, int32_t ressize ) { char * pval; char * pend; condcode cc; int k; getnum_block gn; long minimum; ressize = ressize; if( (parmcount < 2) || (parmcount > 6) ) { cc = neg; return( cc ); } minimum = LONG_MAX; gn.ignore_blanks = false; for( k = 0; k < parmcount; k++ ) { pval = parms[k].start; pend = parms[k].stop; unquote_if_quoted( &pval, &pend ); if( pend == pval ) { // null string nothing to do continue; // skip empty value } gn.argstart = pval; gn.argstop = pend; cc = getnum( &gn ); if( !(cc == pos || cc == neg) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "" ); g_info_inp_pos(); err_count++; show_include_stack(); } return( cc ); } if( gn.result < minimum ) { minimum = gn.result; // new minimum } } *result += sprintf( *result, "%ld", minimum ); return( pos ); }
void numb_err( void ) { char linestr[MAX_L_AS_STR]; err_count++; if( input_cbs->fmflags & II_macro ) { ultoa( input_cbs->s.m->lineno, linestr, 10 ); g_err( ERR_PU_NUM, linestr, "macro", input_cbs->s.m->mac->name ); } else { ultoa( input_cbs->s.f->lineno, linestr, 10 ); g_err( ERR_PU_NUM, linestr, "file", input_cbs->s.f->filename ); } show_include_stack(); return; }
void file_mac_info( void ) { char linestr[MAX_L_AS_STR]; char linemac[MAX_L_AS_STR]; if( input_cbs != NULL ) { if( input_cbs->fmflags & II_macro ) { ultoa( input_cbs->s.m->lineno, linestr, 10 ); ultoa( input_cbs->s.m->mac->lineno, linemac, 10 ); g_info( err_inf_mac_def, linestr, input_cbs->s.m->mac->name, linemac, input_cbs->s.m->mac->mac_file_name); } else { ultoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } } show_include_stack(); 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; }
gtentry * add_tag( gtentry * * dict, const char * name, const char * mac, const int flags ) { gtentry * ge; gtentry * wk; char linestr[MAX_L_AS_STR]; wk = find_tag( dict, name ); if( wk != NULL ) { err_count++; g_err( err_tag_exist, name ); if( input_cbs->fmflags & II_macro ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } show_include_stack(); return( NULL ); } ge = mem_alloc( sizeof( gtentry ) ); ge->next = *dict; *dict = ge; memcpy( ge->name, name, sizeof( ge->name ) ); ge->namelen = strlen( ge->name ); strcpy_s( ge->macname, sizeof( ge->macname ), mac ); ge->tagflags = flags; ge->attribs = NULL; ge->usecount = 0; return( ge ); }
void scr_label( void ) { condcode cc; getnum_block gn; labelcb * lb; char linestr[MAX_L_AS_STR]; scan_start += 2; // over dots while( *scan_start == ' ' ) { // may be ...LABEL or ... LABEL scan_start++; // over blanks } if( *scan_start == '\0' ) { // no label? scan_err = true; err_count++; g_err( err_missing_name, "" ); if( input_cbs->fmflags & II_tag_mac ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } show_include_stack(); return; } else { gn.argstart = scan_start; gn.argstop = scan_stop; gn.ignore_blanks = 0; cc = getnum( &gn ); // try numeric expression evaluation if( cc == pos ) { // numeric linenumber scan_start = gn.argstart; // start for next token // check if lineno from label matches actual lineno if( input_cbs->fmflags & II_tag_mac ) { if( gn.result != input_cbs->s.m->lineno ) { scan_err = true; err_count++; g_err( err_label_line, gn.resultstr ); utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); show_include_stack(); return; } } else { if( gn.result != input_cbs->s.f->lineno ) { scan_err = true; err_count++; g_err( err_label_line, gn.resultstr ); utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); show_include_stack(); return; } } if( input_cbs->fmflags & II_tag_mac ) { // numeric macro label no need to store } else { wng_count++; g_warn( wng_label_num ); utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); show_include_stack(); } } else { // no numeric label cc = getarg(); if( cc == pos ) { // label name specefied char * p; char * pt; int len; p = tok_start; pt = token_buf; len = 0; while( len < arg_flen ) { // copy to buffer *pt++ = *p++; len++; } *pt = '\0'; if( len > MAC_NAME_LENGTH ) { err_count++; g_err( err_sym_long, token_buf ); utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); show_include_stack(); token_buf[MAC_NAME_LENGTH] = '\0'; } if( input_cbs->fmflags & II_tag_mac ) { cc = test_duplicate( token_buf, input_cbs->s.m->lineno ); if( cc == pos ) { // ok name and lineno match // nothing to do } else { if( cc == neg ) { // name with different lineno scan_err = true; err_count++; g_err( err_label_dup, token_buf ); utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); show_include_stack(); return; } else { // new label lb = mem_alloc( sizeof( labelcb ) ); lb->prev = input_cbs->s.m->mac->label_cb; input_cbs->s.m->mac->label_cb = lb; lb->pos = 0; lb->lineno = input_cbs->s.m->lineno; strcpy_s( lb->label_name, sizeof( lb->label_name ), token_buf ); } } } else { cc = test_duplicate( token_buf, input_cbs->s.f->lineno ); if( cc == pos ) { // ok name and lineno match // nothing to do } else { if( cc == neg ) { // name with different lineno scan_err = true; err_count++; g_err( err_label_dup, token_buf ); utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); show_include_stack(); return; } else { // new label lb = mem_alloc( sizeof( labelcb ) ); lb->prev = input_cbs->s.f->label_cb; input_cbs->s.f->label_cb = lb; lb->pos = input_cbs->s.f->pos; lb->lineno = input_cbs->s.f->lineno; strcpy_s( lb->label_name, sizeof( lb->label_name ), token_buf ); } } } } else { scan_err = true; err_count++; g_err( err_missing_name, "" ); if( input_cbs->fmflags & II_tag_mac ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } show_include_stack(); return; } } if( *scan_start == ' ' ) { scan_start++; // skip one blank if( *scan_start ) { // rest of line is not empty split_input( buff2, scan_start, false );// split and process next } } scan_restart = scan_stop + 1; return; } }
bool process_tag( gtentry * ge, mac_entry * me ) { bool processed; gaentry * ga; gavalentry * gaval; char * p; char * p2; int rc; char quote; char longwork[20]; bool tag_end_found = false; processed = true; init_dict( &loc_dict ); add_defaults_to_dict( ge, &loc_dict ); /***********************************************************************/ /* scan input for attributes and / or tagtext */ /***********************************************************************/ p = tok_start + ge->namelen + 1; // over tagname if( ge->attribs != NULL ) { // only process attributes if they exist while( *p == ' ' ) { // not yet end of tag, process attributes while( *p == ' ' ) { // over WS to attribute p++; } if( *p == '.' ) { tag_end_found = true; break; } p2 = token_buf; while( is_id_char( *p ) ) { *p2++ = *p++; } *p2 = '\0'; if( p2 != token_buf ) { // ignore nullstring for( ga = ge->attribs; ga != NULL; ga = ga->next ) {// all attrs if( !stricmp( ga->name, token_buf ) ) { ga->attflags |= att_proc_seen; // attribute specified if( ga->attflags & att_auto ) { auto_att_err(); break; } if( *p == '=' ) { // value follows ga->attflags |= att_proc_val; p++; // over = p2 = token_buf; if( is_quote_char( *p ) ) { quote = *p++; while( *p && *p != quote ) {// quoted value *p2++ = *p++; } if( *p == quote ) { p++;// over ending quote } } else { quote = '\0'; while( *p && (*p != ' ') && (*p != '.') ) { *p2++ = *p++; } } *p2 = '\0'; if( ga->attflags & att_off ) {// attribute inactive continue; } if( ga->attflags & att_upper ) {// uppercase option strupr( token_buf ); } scan_err = check_att_value( ga ); } else {// special for range set default2 if no value if( ga->attflags & att_range ) { for( gaval = ga->vals; gaval != NULL; gaval = gaval->next ) { if( gaval->valflags & val_range ) { break; } } if( gaval != NULL ) { sprintf( token_buf, "%d", gaval->a.range[3] ); rc = add_symvar( &loc_dict, ga->name, token_buf, no_subscript, local_var ); } } } break; } } if( ga == NULL ) { // attribute Not found char linestr[MAX_L_AS_STR]; processed = false; wng_count++; //***WARNING*** SC--040: 'abd' is not a valid attribute name g_warn( wng_att_name, token_buf ); 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_include_stack(); } } /***************************************************************/ /* check for tag end . */ /***************************************************************/ if( *p == ' ' ) { continue; // not yet at buffer / tag end } #if 0 /***************************************************************/ /* continue scanning for attriutes on next line if not tag end*/ /* This does not work for constructs such as */ /* */ /* :hdref refid=diffs */ /* .bd to determine if you need to recompile your application.*/ /* from docs\doc\gs\intro.gml line 37 f */ /***************************************************************/ if( *p != '.' ) { // if( get_line( true ) ) { p = buff2; } else { *p = '\0'; } } else { tag_end_found = true; } #else if( (*p == '.') || (*p == '\0') ) { tag_end_found = true; } #endif } /*******************************************************************/ /* check for missing reqrd attributes */ /*******************************************************************/ *token_buf = '\0'; for( ga = ge->attribs; ga != NULL; ga = ga->next ) {// for all attrs if( ga->attflags & att_req ) { if( !(ga->attflags & att_proc_seen) ) { if( *token_buf != '\0' ) { strcat( token_buf, " '" ); } else { strcpy( token_buf, "'" ); } strcat( token_buf, ga->name ); strcat( token_buf, "' " ); } } } if( *token_buf != '\0' ) { // some req attr missing char linestr[MAX_L_AS_STR]; // the errmsg in wgml 4.0 is wrong, it shows the macroname, not tag. // ****ERROR**** SC--047: For the tag '@willi', the required attribute(s) // 'muss2' // 'muss' // have not been specified processed = false; err_count++; g_err( err_att_req, ge->name, token_buf ); 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_include_stack(); } if( *p == '.' ) { // does text follow tag end if( strlen( p + 1 ) > 0 ) { if( ge->tagflags & tag_texterr ) { // no text allowed tag_text_err( ge->name ); processed = false; } } else { if( ge->tagflags & tag_textreq ) { // reqrd text missing tag_text_req_err( ge->name ); processed = false; } } strcpy( token_buf, p + 1 ); rc = add_symvar( &loc_dict, "_", token_buf, no_subscript, local_var ); p += strlen( token_buf ); } scan_start = p + 1; // all processed /*******************************************************************/ /* add standard symbols to dict */ /*******************************************************************/ rc = add_symvar( &loc_dict, "_tag", ge->name, no_subscript, local_var ); ge->usecount++; sprintf( longwork, "%d", ge->usecount ); rc = add_symvar( &loc_dict, "_n", longwork, no_subscript, local_var ); add_macro_cb_entry( me, ge ); // prepare GML macro as input input_cbs->local_dict = loc_dict; inc_inc_level(); // start new include level if( ge->tagflags & tag_cont ) { // +++++++++++++++++++ TBD trial post_space = 0; ProcFlags.ct = true; } if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { print_sym_dict( input_cbs->local_dict ); } } else { // user-defined tag has no attributes if( ge->tagflags & tag_texterr ) { // no text allowed // '.' or CW_sep_char immediately after the tag does not count as text if( (*p == '.') || (*p == CW_sep_char ) ) { p++; } while( *p == ' ' ) { // spaces don't count as text p++; } if( *p ) { // text found tag_text_err( ge->name ); processed = false; return( processed ); } } if( ge->tagflags & tag_textreq ) { // text is required // per wgml 4.0 behavior if( *p == CW_sep_char ) { processed = false; return( processed ); } // '.' immediately after the tag does not count as text if( *p == '.' ) { p++; } while( *p == ' ' ) { // spaces don't count as text p++; } if( !*p ) { // no text found tag_text_req_err( ge->name ); processed = false; return( processed ); } } // per wgml 4.0 behavior if( *p == CW_sep_char ) { processed = false; return( processed ); } // '.' immediately after the tag is not passed to the macro if( *p == '.' ) { p++; } strcpy( token_buf, p ); rc = add_symvar( &loc_dict, "_", token_buf, no_subscript, local_var ); p += strlen( token_buf ); scan_start = p + 1; // all processed /*******************************************************************/ /* add standard symbols to dict */ /*******************************************************************/ rc = add_symvar( &loc_dict, "_tag", ge->name, no_subscript, local_var ); ge->usecount++; sprintf( longwork, "%d", ge->usecount ); rc = add_symvar( &loc_dict, "_n", longwork, no_subscript, local_var ); add_macro_cb_entry( me, ge ); // prepare GML macro as input input_cbs->local_dict = loc_dict; inc_inc_level(); // start new include level if( ge->tagflags & tag_cont ) { // +++++++++++++++++++ TBD trial post_space = 0; ProcFlags.ct = true; } if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { print_sym_dict( input_cbs->local_dict ); } } return( processed ); }
void scr_in( void ) { char * pa; char * p; int len; char cwcurr[4]; bool scanerr; su indentwork; int32_t newindent; int32_t newindentr; cwcurr[0] = SCR_char; cwcurr[1] = 'i'; cwcurr[2] = 'n'; cwcurr[3] = '\0'; p = scan_start; while( *p && *p == ' ' ) { // next word start p++; } pa = p; while( *p && *p != ' ' ) { // end of word p++; } len = p - pa; if( len == 0 ) { // omitted means reset to default newindent = 0; newindentr = 0; } else { newindent = g_indent; // prepare keeping old values newindentr = g_indentr; if( *pa == '*' ) { // keep old indent value p = pa + 1; } else { p = pa; scanerr = cw_val_to_su( &p, &indentwork ); if( scanerr ) { g_err( err_miss_inv_opt_value, cwcurr, pa ); err_count++; show_include_stack(); } else { newindent = round_indent( &indentwork ); if( indentwork.su_relative ) { newindent += g_indent; } if( newindent < 0 ) { newindent = 0; // minimum value } } } while( *p == ' ' ) { p++; } if( *p == '*' ) { // keep old indentr value p++; } else { pa = p; scanerr = cw_val_to_su( &p, &indentwork ); if( scanerr ) { g_err( err_miss_inv_opt_value, cwcurr, pa ); err_count++; show_include_stack(); } else { /***************************************************************/ /* indent right is always relative or 0 for reset to default */ /***************************************************************/ if( indentwork.su_whole + indentwork.su_dec != 0) { newindentr = g_indentr + round_indent( &indentwork ); } else { newindentr = 0; } } } } g_indent = newindent; g_indentr = newindentr; g_page_right = g_page_right_org + g_indentr; ProcFlags.keep_left_margin = false; set_h_start(); // apply new values scan_restart = p; return; }
static condcode scr_lowup( parm parms[MAX_FUN_PARMS], size_t parmcount, char * * result, int32_t ressize, bool upper ) { char * pval; char * pend; condcode cc; int k; int n; int len; getnum_block gn; char linestr[MAX_L_AS_STR]; if( (parmcount < 1) || (parmcount > 3) ) { cc = neg; return( cc ); } pval = parms[0].a; pend = parms[0].e; unquote_if_quoted( &pval, &pend ); len = pend - pval + 1; // default length if( len <= 0 ) { // null string nothing to do **result = '\0'; return( pos ); } n = 0; // default start pos gn.ignore_blanks = false; if( parmcount > 1 ) { // evalute start pos if( parms[1].e >= parms[1].a ) {// start pos specified gn.argstart = parms[1].a; gn.argstop = parms[1].e; cc = getnum( &gn ); if( (cc != pos) || (gn.result > len) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "2 (startpos)" ); if( input_cbs->fmflags & II_macro ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } err_count++; show_include_stack(); } return( cc ); } n = gn.result - 1; } } if( parmcount > 2 ) { // evalute length for upper if( parms[2].e >= parms[2].a ) {// length specified gn.argstart = parms[2].a; gn.argstop = parms[2].e; cc = getnum( &gn ); if( (cc != pos) || (gn.result == 0) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "3 (length)" ); if( input_cbs->fmflags & II_macro ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } err_count++; show_include_stack(); } return( cc ); } len = gn.result; } } for( k = 0; k < n; k++ ) { // copy unchanged before startpos if( (pval > pend) || (ressize <= 0) ) { break; } **result = *pval++; *result += 1; ressize--; } for( k = 0; k < len; k++ ) { // translate if( (pval > pend) || (ressize <= 0) ) { break; } if( upper ) { **result = toupper( *pval++ ); } else { **result = tolower( *pval++ ); } *result += 1; ressize--; } for( ; pval <= pend; pval++ ) { // copy unchanged if( ressize <= 0 ) { break; } **result = *pval; *result += 1; ressize--; } **result = '\0'; return( pos ); }
bool get_line( bool display_line ) { filecb * cb; char * p; inp_line * pline; if( ProcFlags.reprocess_line ) { // there was an unget ProcFlags.reprocess_line = false; // only used for :LAYOUT return( !(input_cbs->fmflags & II_eof) ); } if( input_cbs->hidden_head != NULL ) { // line was previously split, strcpy( buff2, input_cbs->hidden_head->value ); // take next part pline = input_cbs->hidden_head; input_cbs->hidden_head = input_cbs->hidden_head->next; if( pline->sol ) { input_cbs->fmflags |= II_sol; // start of logical record } else { input_cbs->fmflags &= ~II_sol; // not at start of input line } mem_free( pline ); if( input_cbs->hidden_head == NULL ) { // last part of split line input_cbs->hidden_tail = NULL; input_cbs->fmflags |= II_eol; } } else { if( input_cbs->pe_cb.count > 0 ) { // .pe perform active strcpy( buff2, input_cbs->pe_cb.line ); input_cbs->pe_cb.count--; if( input_cbs->pe_cb.count <= 0 ) { reset_pe_cb(); } } else { if( input_cbs->fmflags & II_macro ) { get_macro_line(); // input from macro line } else { cb = input_cbs->s.f; // input from file if( !(cb->flags & FF_open) ) { g_info( err_inf_reopen ); show_include_stack(); reopen_inc_fp( cb ); } do { fgetpos( cb->fp, &cb->pos );// remember position for label p = fgets( buff2, buf_size, cb->fp ); if( p != NULL ) { if( cb->lineno >= cb->linemax ) { input_cbs->fmflags |= II_eof; input_cbs->fmflags &= ~(II_sol | II_eol); cb->flags |= FF_eof; *buff2 = '\0'; break; } cb->lineno++; input_cbs->fmflags |= (II_sol | II_eol); if( cb->flags & FF_crlf ) {// try to delete CRLF at end p += strlen( p ) - 1; while( (*p == '\r') || (*p == '\n') ) { *p-- = '\0'; } } #if 0 if( !ProcFlags.concat && (*buff2 == '\0') ) { *buff2 = ' '; // empty line gets 1 blank *(buff2 + 1) = '\0';// requires more testing } #endif } else { if( feof( cb->fp ) ) { input_cbs->fmflags |= II_eof; input_cbs->fmflags &= ~(II_sol | II_eol); cb->flags |= FF_eof; *buff2 = '\0'; break; } else { strerror_s( buff2, buf_size, errno ); g_err( err_file_io, buff2, cb->filename ); err_count++; g_suicide(); } } } while( cb->lineno < cb->linemin ); } } } buff2_lg = strnlen_s( buff2, buf_size ); #if 0 if( !(input_cbs->fmflags & II_eof) ) { // for empty physical line if( (input_cbs->fmflags & II_sol) && (input_cbs->fmflags & II_eol) ) { if( buff2_lg == 0 ) { *buff2 = SCR_char; // simulate .br input *(buff2 + 1) = 'b'; *(buff2 + 2) = 'r'; buff2_lg = 3; } } } #endif #if 1 if( !ProcFlags.concat ) { if( !(input_cbs->fmflags & II_eof) ) { if( (input_cbs->fmflags & II_sol) && (input_cbs->fmflags & II_eol) ) { #if 0 if( buff2_lg == 0 ) { // empty line blank_lines += 1; ProcFlags.sk_cond = true; // prepare simulated .sk 1 C } #endif } } } #endif *(buff2 + buff2_lg) = '\0'; *(buff2 + buff2_lg + 1) = '\0'; if( input_cbs->fmflags & II_file ) { input_cbs->s.f->usedlen = buff2_lg; if( GlobalFlags.research ) { // research mode if( ProcFlags.researchfile ) { // for single file if( input_cbs->fmflags & II_research ) {// research active if( research_to < input_cbs->s.f->lineno ) { input_cbs->fmflags &= ~II_research;// end of research range } } else { // not (yet) active if( research_from == input_cbs->s.f->lineno ) { if( NULL != strstr( input_cbs->s.f->filename, research_file_name) ) { input_cbs->fmflags |= II_research;// start of research range } } } } else { input_cbs->fmflags |= II_research; } } } if( !(input_cbs->fmflags & II_eof) ) { if( display_line && GlobalFlags.firstpass && input_cbs->fmflags & II_research ) { printf( "%s\n", buff2 ); } } return( !(input_cbs->fmflags & II_eof) ); }
static condcode scr_lowup( parm parms[MAX_FUN_PARMS], size_t parmcount, char * * result, int32_t ressize, bool upper ) { char * pval; char * pend; condcode cc; int k; int n; int len; getnum_block gn; if( (parmcount < 1) || (parmcount > 3) ) { cc = neg; return( cc ); } pval = parms[0].start; pend = parms[0].stop; unquote_if_quoted( &pval, &pend ); if( pend == pval ) { // null string nothing to do **result = '\0'; return( pos ); } gn.ignore_blanks = false; n = 0; // default start pos if( parmcount > 1 ) { // evalute start pos if( parms[1].stop > parms[1].start ) {// start pos specified gn.argstart = parms[1].start; gn.argstop = parms[1].stop; cc = getnum( &gn ); if( (cc != pos) || (gn.result > len) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "2 (startpos)" ); g_info_inp_pos(); err_count++; show_include_stack(); } return( cc ); } n = gn.result - 1; } } len = pend - pval; // default length if( parmcount > 2 ) { // evalute length for upper if( parms[2].stop > parms[2].start ) {// length specified gn.argstart = parms[2].start; gn.argstop = parms[2].stop; cc = getnum( &gn ); if( (cc != pos) || (gn.result == 0) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "3 (length)" ); g_info_inp_pos(); err_count++; show_include_stack(); } return( cc ); } len = gn.result; } } for( k = 0; k < n; k++ ) { // copy unchanged before startpos if( (pval >= pend) || (ressize <= 0) ) { break; } **result = *pval++; *result += 1; ressize--; } for( k = 0; k < len; k++ ) { // translate if( (pval >= pend) || (ressize <= 0) ) { break; } if( upper ) { **result = toupper( *pval++ ); } else { **result = tolower( *pval++ ); } *result += 1; ressize--; } for( ; pval < pend; pval++ ) { // copy unchanged if( ressize <= 0 ) { break; } **result = *pval; *result += 1; ressize--; } **result = '\0'; return( pos ); }
/* ifcompare compare if condition as numeric integer or string * depending whether both terms are integers * */ static bool ifcompare( termcb * t1, relop r, termcb * t2 ) { bool result; long term1; long term2; term1 = t1->term_number; // assume integers term2 = t2->term_number; if( !t1->numeric || !t2->numeric ) { // string compare char * p1 = t1->term_string; char * p2 = t2->term_string; size_t length; length = t1->term_length; if( length > t2->term_length ) length = t2->term_length; while( length > 0 ) { // try to find a difference if( *p1 != *p2 ) { break; // found } else { p1++; p2++; } --length; } term1 = *p1; // unequal chars or term2 = *p2; // corresponding chars of shorter string if( length == 0 ) { // compared parts are equal if( t1->term_length == t2->term_length ) { term1 = term2; // make compare equal true } else { if( t1->term_length < t2->term_length ) { term1 = LONG_MIN; // shorter is smaller } else { term2 = LONG_MIN; } } } } switch( r ) { // now set compare result case EQ : result = (term1 == term2); break; case NE : result = (term1 != term2); break; case LT : result = (term1 < term2); break; case GT : result = (term1 > term2); break; case LE : result = (term1 <= term2); break; case GE : result = (term1 >= term2); break; default: result = false; if( input_cbs->fmflags & II_tag_mac ) { out_msg( "ERR_ifcompare internal logic error\n" "\t\t\tLine %d of macro '%s'\n", input_cbs->s.m->lineno, input_cbs->s.m->mac->name ); } else { out_msg( "ERR_ifcompare internal logic error\n" "\t\t\tLine %d of file '%s'\n", input_cbs->s.f->lineno, input_cbs->s.f->filename ); } show_include_stack(); err_count++; break; } return( result ); }
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; }
condcode scr_index( parm parms[MAX_FUN_PARMS], size_t parmcount, char * * result, int32_t ressize ) { char * pneedle; char * pneedlend; char * phay; char * phayend; condcode cc; int index; int n; int hay_len; int needle_len; getnum_block gn; char * ph; char * pn; char linestr[MAX_L_AS_STR]; if( (parmcount < 2) || (parmcount > 3) ) { cc = neg; return( cc ); } phay = parms[0].a; phayend = parms[0].e; unquote_if_quoted( &phay, &phayend ); hay_len = phayend - phay + 1; // haystack length pneedle = parms[1].a; pneedlend = parms[1].e; unquote_if_quoted( &pneedle, &pneedlend ); needle_len = pneedlend - pneedle + 1; // needle length n = 0; // default start pos gn.ignore_blanks = false; if( parmcount > 2 ) { // evalute start pos if( parms[2].e >= parms[2].a ) {// start pos specified gn.argstart = parms[2].a; gn.argstop = parms[2].e; cc = getnum( &gn ); if( (cc != pos) || (gn.result == 0) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "3 (startpos)" ); if( input_cbs->fmflags & II_tag_mac ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } err_count++; show_include_stack(); } return( cc ); } n = gn.result - 1; } } if( (hay_len <= 0) || // null string nothing to do (needle_len <= 0) || // needle null nothing to do (needle_len > hay_len) || // needle longer haystack (n + needle_len > hay_len) ) { // startpos + needlelen > haystack // ... match impossible **result = '0'; // return index zero *result += 1; **result = '\0'; return( pos ); } ph = phay + n; // startpos in haystack pn = pneedle; index = 0; for( ph = phay + n; ph <= phayend - needle_len + 1; ph++ ) { pn = pneedle; while( (*ph == *pn) && (pn <= pneedlend)) { ph++; pn++; } if( pn > pneedlend ) { index = ph - phay - needle_len + 1; // found, set index break; } } *result += sprintf( *result, "%d", index ); return( pos ); }
condcode scr_left( parm parms[MAX_FUN_PARMS], size_t parmcount, char * * result, int32_t ressize ) { char * pval; char * pend; condcode cc; int k; int len; getnum_block gn; if( parmcount != 2 ) { cc = neg; return( cc ); } pval = parms[0].start; pend = parms[0].stop; unquote_if_quoted( &pval, &pend ); if( pend == pval ) { // null string nothing to do **result = '\0'; return( pos ); } len = pend - pval; // default length if( parms[1].stop > parms[1].start ) {// length specified gn.argstart = parms[1].start; gn.argstop = parms[1].stop; cc = getnum( &gn ); if( cc != pos ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "2 (length)" ); g_info_inp_pos(); err_count++; show_include_stack(); } return( cc ); } len = gn.result; } for( k = 0; k < len; k++ ) { // copy from start if( (pval >= pend) || (ressize <= 0) ) { break; } **result = *pval++; *result += 1; ressize--; } for( ; k < len; k++ ) { // pad to length if( ressize <= 0 ) { break; } **result = ' '; *result += 1; ressize--; } **result = '\0'; return( pos ); }
static void scan_gml( void ) { inputcb * cb; char * p; int toklen; int k; char csave; bool processed; gtentry * ge; // GML user tag entry mac_entry * me; // script macro for processing GML tag char linestr[MAX_L_AS_STR]; char tok_upper[TAG_NAME_LENGTH]; cb = input_cbs; p = scan_start + 1; tok_start = scan_start; while( is_id_char( *p ) && p <= scan_stop ) { // search end of TAG p++; } scan_start = p; // store argument start address toklen = p - tok_start - 1; csave = *p; *p = '\0'; if( toklen >= TAG_NAME_LENGTH ) { err_count++; // SC--009 The tagname is too long if( cb->fmflags & II_macro ) { ultoa( cb->s.m->lineno, linestr, 10 ); g_err( err_tag_name, tok_start + 1, linestr, "macro", cb->s.m->mac->name ); } else { ultoa( cb->s.f->lineno, linestr, 10 ); g_err( err_tag_name, tok_start + 1, linestr, "file", cb->s.f->filename ); } if( inc_level > 0 ) { show_include_stack(); } *p = csave; scan_start = tok_start; // process as text return; } if( GlobalFlags.firstpass && cb->fmflags & II_research ) { if( stricmp( tok_start + 1, "cmt" ) ) { // quiet for :cmt. if( cb->fmflags & II_macro ) { printf_research( "L%d %c%s tag found in macro %s(%d)\n\n", inc_level, GML_char, tok_start + 1, cb->s.m->mac->name, cb->s.m->lineno ); } else { printf_research( "L%d %c%s tag found in file %s(%d)\n\n", inc_level, GML_char, tok_start + 1, cb->s.f->filename, cb->s.f->lineno ); } } add_GML_tag_research( tok_start + 1 ); } if( ProcFlags.layout ) { ge = NULL; // no user tags within :LAYOUT } else { ge = find_tag( &tag_dict, tok_start + 1 ); } processed = false; me = NULL; if( ge != NULL ) { // GML user defined Tag found *p = csave; if( ge->tagflags & tag_off ) { // inactive, treat as text scan_start = tok_start; return; } me = find_macro( macro_dict, ge->macname ); if( me == NULL ) { err_count++; // SC--037: The macro 'xxxxxx' for the gml tag 'yyyyy' // is not defined if( cb->fmflags & II_macro ) { ultoa( cb->s.m->lineno, linestr, 10 ); g_err( err_tag_macro, ge->macname, ge->name, linestr, "macro", cb->s.m->mac->name ); } else { ultoa( cb->s.f->lineno, linestr, 10 ); g_err( err_tag_macro, ge->macname, ge->name, linestr, "file", cb->s.f->filename ); } if( inc_level > 0 ) { show_include_stack(); } *p = csave; scan_start = tok_start; // process as text return; } else { /*******************************************************************/ /* The following is to prevent an endless loop */ /* Example from ow documentation: */ /* .gt ZH1 add zh1 */ /* .gt H1 add zh1 */ /* .dm zh1 begin */ /* ... */ /* :H1 <---- overridden gml tag */ /* ... */ /* .dm zh1 end */ /* */ /* we call the predefined :H1 instead */ /*******************************************************************/ if( (cb->fmflags & II_tag) && (cb->s.m->mac == me) ) { me = NULL; } } } if( me != NULL ) { // usertag and coresponding macro ok processed = process_tag( ge, me ); } else { *p ='\0'; for( k = 0; k <= toklen; k++ ) { tok_upper[k] = toupper( *(tok_start + 1 + k) ); } tok_upper[k] = '\0'; if( ProcFlags.layout ) { // different tags within :LAYOUT for( k = 0; k < LAY_TAGMAX; ++k ) { if( toklen == lay_tags[k].taglen ) { if( !strcmp( lay_tags[k].tagname, tok_upper ) ) { *p = csave; lay_ind = -1; // process tag not attribute lay_tags[k].gmlproc( &lay_tags[k] ); processed = true; lay_ind = k; // now process attributes if any if( *scan_start == '.' ) { scan_start++; } break; } } } if( !processed ) { // check for gml only tag in :LAYOUT for( k = 0; k < GML_TAGMAX; ++k ) { if( toklen == gml_tags[k].taglen ) { if( !strcmp( gml_tags[k].tagname, tok_upper ) ) { g_err( err_gml_in_lay, gml_tags[k].tagname ); err_count++; file_mac_info(); processed = true; scan_start = scan_stop + 1; break; } } } } } else { // not within :LAYOUT for( k = 0; k < GML_TAGMAX; ++k ) { if( toklen == gml_tags[k].taglen ) { if( !strcmp( gml_tags[k].tagname, tok_upper ) ) { if( GlobalFlags.firstpass && !strcmp(tok_upper, "LAYOUT" ) && ProcFlags.fb_document_done ) { g_err( err_lay_too_late ); err_count++; file_mac_info(); processed = true; scan_start = scan_stop + 1; break; } *p = csave; if( (rs_loc == 0) && !ProcFlags.need_li_lp ) { // no restrictions: do them all gml_tags[k].gmlproc( &gml_tags[k] ); } else if( ProcFlags.need_li_lp && ((gml_tags[k].taglocs & li_lp_tag) != 0) ) { // tag is LP or LI gml_tags[k].gmlproc( &gml_tags[k] ); } else if( (gml_tags[k].taglocs & rs_loc) != 0 ) { // tag allowed in this restricted location gml_tags[k].gmlproc( &gml_tags[k] ); } else if( (gml_tags[k].tagflags & tag_is_general) != 0 ) { // tag allowed everywhere gml_tags[k].gmlproc( &gml_tags[k] ); } else { start_doc_sect(); // if not already done if( ProcFlags.need_li_lp ) { xx_nest_err( err_no_li_lp ); } else { // rs_loc > 0 g_err_tag_rsloc( rs_loc, tok_start ); } } processed = true; if( *scan_start == '.' ) { scan_start++; } break; } } } if( !processed ) { // check for layout tag in normal text for( k = 0; k < LAY_TAGMAX; ++k ) { if( toklen == lay_tags[k].taglen ) { if( !strcmp( lay_tags[k].tagname, tok_upper ) ) { g_err( err_lay_in_gml, lay_tags[k].tagname ); err_count++; file_mac_info(); processed = true; scan_start = scan_stop + 1; break; } } } } } } if( *p == '\0' ) { *p = csave; } if( !processed ) { // treat as text scan_start = tok_start; } }
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_go( void ) { condcode cc; getnum_block gn; labelcb * golb; int k; char linestr[MAX_L_AS_STR]; input_cbs->if_cb->if_level = 0; // .go terminates ProcFlags.keep_ifstate = false; // ... all .if controls garginit(); cc = getarg(); if( cc != pos ) { scan_err = true; err_count++; g_err( err_missing_name, "" ); if( input_cbs->fmflags & II_tag_mac ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } show_include_stack(); return; } gn.argstart = tok_start; gn.argstop = scan_stop; gn.ignore_blanks = 0; cc = getnum( &gn ); // try numeric expression evaluation if( cc == pos || cc == neg) { // numeric linenumber gotarget[0] = '\0'; // no target label name if( gn.num_sign == ' ' ) { // absolute number gotargetno = gn.result; } else { if( input_cbs->fmflags & II_tag_mac ) { gotargetno = input_cbs->s.m->lineno; } else { gotargetno = input_cbs->s.f->lineno; } gotargetno += gn.result; // relative target line number } if( gotargetno < 1 ) { scan_err = true; err_count++; g_err( err_label_zero ); if( input_cbs->fmflags & II_tag_mac ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } show_include_stack(); return; } if( input_cbs->fmflags & II_tag_mac ) { if( gotargetno <= input_cbs->s.m->lineno ) { input_cbs->s.m->lineno = 0; // restart from beginning input_cbs->s.m->macline = input_cbs->s.m->mac->macline; } } } else { // no numeric target label gotargetno = 0; // no target lineno known if( arg_flen > MAC_NAME_LENGTH ) { err_count++; g_err( err_sym_long, tok_start ); if( input_cbs->fmflags & II_tag_mac ) { utoa( input_cbs->s.m->lineno, linestr, 10 ); g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name ); } else { utoa( input_cbs->s.f->lineno, linestr, 10 ); g_info( inf_file_line, linestr, input_cbs->s.f->filename ); } show_include_stack(); arg_flen = MAC_NAME_LENGTH; } for( k = 0; k < MAC_NAME_LENGTH; k++ ) {// copy to work gotarget[k] = *tok_start++; } gotarget[k] = '\0'; golb = find_label( gotarget ); if( golb != NULL ) { // label already known gotargetno = golb->lineno; if( input_cbs->fmflags & II_tag_mac ) { if( golb->lineno <= input_cbs->s.m->lineno ) { input_cbs->s.m->lineno = 0; // restart from beginning input_cbs->s.m->macline = input_cbs->s.m->mac->macline; } } else { if( golb->lineno <= input_cbs->s.f->lineno ) { fsetpos( input_cbs->s.f->fp, &golb->pos ); input_cbs->s.f->lineno = golb->lineno - 1;// position file } } } } free_lines( input_cbs->hidden_head ); // delete split line input_cbs->hidden_head = NULL; input_cbs->hidden_tail = NULL; ProcFlags.goto_active = true; // special goto processing scan_restart = scan_stop + 1; }
condcode scr_substr( parm parms[MAX_FUN_PARMS], size_t parmcount, char * * result, int32_t ressize ) { char * pval; char * pend; condcode cc; int k; int n; int stringlen; int len; getnum_block gn; char padchar; char linestr[MAX_L_AS_STR]; if( (parmcount < 2) || (parmcount > 4) ) { return( neg ); } pval = parms[0].a; pend = parms[0].e; unquote_if_quoted( &pval, &pend ); stringlen = pend - pval + 1; // length of string padchar = ' '; // default padchar len = 0; n = 0; // default start pos gn.ignore_blanks = false; if( parmcount > 1 ) { // evalute start pos if( parms[1].e >= parms[1].a ) {// start pos specified gn.argstart = parms[1].a; gn.argstop = parms[1].e; cc = getnum( &gn ); if( (cc != pos) || (gn.result == 0) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "2 (startpos)" ); 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 ); } err_count++; show_include_stack(); } return( cc ); } n = gn.result - 1; } } if( parmcount > 2 ) { // evalute length if( parms[2].e >= parms[2].a ) {// length specified gn.argstart = parms[2].a; gn.argstop = parms[2].e; cc = getnum( &gn ); if( (cc != pos) || (gn.result == 0) ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "3 (length)" ); 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 ); } err_count++; show_include_stack(); } return( cc ); } len = gn.result; } } if( parmcount > 3 ) { // isolate padchar if( parms[3].e >= parms[3].a ) { char * pa = parms[3].a; char * pe = parms[3].e; unquote_if_quoted( &pa, &pe ); padchar = *pa; } } pval += n; // position to startpos if( len == 0 ) { // no length specified len = pend - pval + 1; // take rest of string if( len < 0 ) { // if there is one len = 0; } } for( k = 0; k < len; k++ ) { if( (pval > pend) || (ressize <= 0) ) { break; } **result = *pval++; *result += 1; ressize--; } for( ; k < len; k++ ) { if( ressize <= 0 ) { break; } **result = padchar; *result += 1; ressize--; } **result = '\0'; return( pos ); }
void gml_date( gml_tag gtag ) { char * p; doc_element * cur_el; text_line * p_line; spacing_line spacing_ln; font_number font_save; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, gml_tagname( gtag ), ":TITLEP section" ); err_count++; show_include_stack(); } if( ProcFlags.date_tag_seen ) { // only one DATE tag allowed xx_line_err( err_2nd_date, buff2 ); } ProcFlags.date_tag_seen = true; p = scan_start; if( *p && *p == '.' ) p++; // over . to docnum while( *p == ' ' ) { // over WS to attribute p++; } if( *p ) { // date specified add_symvar( &global_dict, "date", p, no_subscript, 0 ); } start_doc_sect(); // if not already done p_line = alloc_text_line(); p_line->line_height = wgml_fonts[layout_work.docnum.font].line_height; prep_date_line( p_line, p ); spacing_ln = layout_work.titlep.spacing; font_save = g_curr_font; g_curr_font = layout_work.date.font; /************************************************************/ /* pre_skip is treated as pre_top_skip because it is */ /* always used at the top of the page, despite the docs */ /************************************************************/ set_skip_vars( NULL, &layout_work.date.pre_skip, NULL, spacing_ln, g_curr_font ); cur_el = alloc_doc_el( el_text ); cur_el->depth = p_line->line_height + g_spacing; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; cur_el->element.text.overprint = ProcFlags.overprint; ProcFlags.overprint = false; cur_el->element.text.spacing = g_spacing; cur_el->element.text.first = p_line; ProcFlags.skips_valid = false; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop; }
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; }
condcode scr_width( parm parms[MAX_FUN_PARMS], size_t parmcount, char * * result, int32_t ressize ) { char * pval; char * pend; char * pa; char * pe; size_t len; char type; uint32_t width; ressize = ressize; if( (parmcount < 1) || (parmcount > 2) ) { return( neg ); } pval = parms[0].start; pend = parms[0].stop; unquote_if_quoted( &pval, &pend ); if( pend == pval ) { // null string width 0 **result = '0'; *result += 1; **result = '\0'; return( pos ); } len = pend - pval; if( parmcount > 1 ) { // evalute type if( parms[1].stop > parms[1].start ) {// type pa = parms[1].start; pe = parms[1].stop; unquote_if_quoted( &pa, &pe ); type = tolower( *pa ); switch( type ) { case 'c': // CPI width = cop_text_width( pval, len, g_curr_font ); width = (width * CPI + g_resh / 2) / g_resh; break; case 'u': // Device Units width = cop_text_width( pval, len, g_curr_font ); break; case 'n': // character count width = len; break; default: g_err( err_func_parm, "2 (type)" ); g_info_inp_pos(); err_count++; show_include_stack(); return( neg ); break; } } } else { // default type c processing width = cop_text_width( pval, len, g_curr_font ); width = (width * CPI + g_resh / 2) / g_resh; } sprintf( *result, "%d", width ); *result += strlen( *result ); **result = '\0'; return( pos ); }
void gml_docnum( const gmltag * entry ) { char * p; doc_element * cur_el; text_line * p_line; int8_t d_spacing; font_number font_save; int32_t rc; symsub * docnumval; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, entry->tagname, ":TITLEP section" ); err_count++; show_include_stack(); } if( ProcFlags.docnum_tag_seen ) { // only one DOCNUM tag allowed xx_line_err( err_2nd_docnum, buff2 ); } ProcFlags.docnum_tag_seen = true; p = scan_start; if( *p && *p == '.' ) p++; // over . to docnum while( *p == ' ' ) { // over WS to attribute p++; } rc = find_symvar( &sys_dict, "$docnum", no_subscript, &docnumval ); if( *p ) { // docnum specified strcpy_s( docnumval->value, 60, p ); } else { *(docnumval->value) = 0; } start_doc_sect(); // if not already done p_line = alloc_text_line(); p_line->line_height = wgml_fonts[layout_work.docnum.font].line_height; prep_docnum_line( p_line, docnumval->value ); d_spacing = layout_work.titlep.spacing; font_save = g_curr_font; g_curr_font = layout_work.docnum.font; /************************************************************/ /* pre_skip is treated as pre_top_skip because it is */ /* always used at the top of the page, despite the docs */ /************************************************************/ set_skip_vars( NULL, &layout_work.docnum.pre_skip, NULL, d_spacing, g_curr_font ); cur_el = alloc_doc_el( el_text ); cur_el->blank_lines = g_blank_lines; g_blank_lines = 0; cur_el->depth = p_line->line_height + g_spacing; cur_el->subs_skip = g_subs_skip; cur_el->top_skip = g_top_skip; cur_el->element.text.overprint = ProcFlags.overprint; ProcFlags.overprint = false; cur_el->element.text.spacing = g_spacing; cur_el->element.text.first = p_line; ProcFlags.skips_valid = false; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop + 1; }
void gml_title( const gmltag * entry ) { char * p; doc_element * cur_el; text_line * p_line = NULL; int8_t t_spacing; font_number font_save; if( !((ProcFlags.doc_sect == doc_sect_titlep) || (ProcFlags.doc_sect_nxt == doc_sect_titlep)) ) { g_err( err_tag_wrong_sect, entry->tagname, ":TITLEP section" ); err_count++; show_include_stack(); } p = scan_start; if( *p && *p != '.' ) p++; while( *p == ' ' ) { // over WS to attribute p++; } if( *p && ! (strnicmp( "stitle ", p, 7 ) && // look for stitle strnicmp( "stitle=", p, 7 )) ) { char quote; char * valstart; p += 6; while( *p == ' ' ) { p++; } if( *p == '=' ) { p++; while( *p == ' ' ) { p++; } } if( *p == '"' || *p == '\'' ) { quote = *p; ++p; } else { quote = ' '; } valstart = p; while( *p && *p != quote ) { ++p; } *p = '\0'; if( !ProcFlags.stitle_seen ) { // first stitle goes into dictionary add_symvar( &global_dict, "$stitle", valstart, no_subscript, 0 ); ProcFlags.stitle_seen = true; } p++; } if( *p == '.' ) p++; // over '.' if( !ProcFlags.title_text_seen ) { if( *p ) { // first title goes into dictionary add_symvar( &global_dict, "$title", p, no_subscript, 0 ); } } start_doc_sect(); // if not already done font_save = g_curr_font; g_curr_font = layout_work.title.font; t_spacing = layout_work.titlep.spacing; if( !ProcFlags.title_tag_top ) { set_skip_vars( NULL, &layout_work.title.pre_top_skip, NULL, t_spacing, g_curr_font ); ProcFlags.title_tag_top = true; } else { set_skip_vars( &layout_work.title.skip, NULL, NULL, t_spacing, g_curr_font ); } p_line = alloc_text_line(); p_line->line_height = wgml_fonts[g_curr_font].line_height; if( *p ) { prep_title_line( p_line, p ); } cur_el = init_doc_el( el_text, p_line->line_height ); cur_el->element.text.first = p_line; p_line = NULL; insert_col_main( cur_el ); g_curr_font = font_save; scan_start = scan_stop + 1; }
condcode scr_left( parm parms[MAX_FUN_PARMS], size_t parmcount, char * * result, int32_t ressize ) { char * pval; char * pend; condcode cc; int k; int len; getnum_block gn; char linestr[MAX_L_AS_STR]; if( parmcount != 2 ) { cc = neg; return( cc ); } pval = parms[0].a; pend = parms[0].e; unquote_if_quoted( &pval, &pend ); len = pend - pval + 1; // default length if( len <= 0 ) { // null string nothing to do **result = '\0'; return( pos ); } if( parms[1].e >= parms[1].a ) {// length specified gn.argstart = parms[1].a; gn.argstop = parms[1].e; cc = getnum( &gn ); if( cc != pos ) { if( !ProcFlags.suppress_msg ) { g_err( err_func_parm, "2 (length)" ); 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 ); } err_count++; show_include_stack(); } return( cc ); } len = gn.result; } for( k = 0; k < len; k++ ) { // copy from start if( (pval > pend) || (ressize <= 0) ) { break; } **result = *pval++; *result += 1; ressize--; } for( ; k < len; k++ ) { // pad to length if( ressize <= 0 ) { break; } **result = ' '; *result += 1; ressize--; } **result = '\0'; return( pos ); }