static char *scr_single_func_unsupport( char * in, char * * result ) { char charstr[2]; result = result; charstr[0] = *(in + 1); charstr[1] = '\0'; g_warn( wng_func_unsupport, charstr ); g_info_inp_pos(); // do nothing return( in + 3 ); }
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 ); }
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 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 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 ); }
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 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 ); }
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; }
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, "%ld", gaval->a.range[3] ); rc = add_symvar( &loc_dict, ga->name, token_buf, no_subscript, local_var ); } } } break; } } if( ga == NULL ) { // attribute Not found processed = false; wng_count++; //***WARNING*** SC--040: 'abd' is not a valid attribute name g_warn( wng_att_name, token_buf ); g_info_inp_pos(); 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 // 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 ); g_info_inp_pos(); 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, "%lu", 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; if( !(input_cbs->fmflags & II_sol) ) { ProcFlags.utc = 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, "%lu", 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; if( !(input_cbs->fmflags & II_sol) ) { ProcFlags.utc = true; } } if( input_cbs->fmflags & II_research && GlobalFlags.firstpass ) { print_sym_dict( input_cbs->local_dict ); } } return( processed ); }