bool str_is_slot_name(const char* s, fint len) { assert(len >= 0, "shouldn't be negative length"); if (len == 0) { return false; } char c = *s; if (!is_lower(c)) { if (!is_punct(c)) return false; switch (c) { case '^': case '|': case '\\': case '.': if (len == 1) return false; } for (int i = 0; i < len; ) { c = s[i++]; if (! is_punct(c)) return false; switch (c) { case '(': case ')': case '\'': case '\"': case ':': case '[': case ']': return false; } } return true; } for (int i = 1; i < len; ) { c = s[i++]; if (is_id_char(c)) continue; if (c != ':') return false; if (i == len) return true; // this was final ":" if (!is_upper(s[i])) return false; // after ":" must be uppercase if (s[len-1] != ':') return false; // one ":" -> last is ":" } return true; }
bool CMaExpander::IsValidToken(const CC_STRING& s) { const char *p = s.c_str(); if(p == NULL) return false; if( ! isalpha(*p) && *p != '_' ) return false; for(p++; *p != '\0'; p++ ) { if( isblank(*p) ) break; if( ! is_id_char(*p) ) return false; } return true; }
char * get_refid_value( char * p ) { char * pa; char * pe; int len; char c; p = get_att_value( p ); if( val_start == NULL || val_len == 0 ) { // no valid id return( p ); } pa = val_start; while( is_id_char( *pa ) ) { pa++; } len = pa - val_start; pe = val_start + len; if( len > 7 ) { // wgml 4 warning level c = *pe; *pe = '\0'; g_warn( wng_id_xxx, val_start ); *pe = c; g_info( inf_id_len ); file_mac_info(); wng_count++; } /***************************************************************/ /* restrict the length to ID_LEN (15) in the hope that no */ /* truncation occurs */ /* wgml4 warns about ids of more than 7 chars, but processes */ /* much longer ids TBD */ /***************************************************************/ val_len = min( ID_LEN, len ); // restrict length *(val_start + val_len) = '\0'; return( p ); }
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 ); }
/* _agstrcanon: * Canonicalize ordinary strings. * Assumes buf is large enough to hold output. */ static char *_agstrcanon(char *arg, char *buf) { char *s, *p; unsigned char uc; int cnt = 0, dotcnt = 0; int needs_quotes = FALSE; int maybe_num; int backslash_pending = FALSE; static const char *tokenlist[] /* must agree with scan.l */ = { "node", "edge", "strict", "graph", "digraph", "subgraph", NIL(char *) }; const char **tok; if (EMPTY(arg)) return "\"\""; s = arg; p = buf; *p++ = '\"'; uc = *(unsigned char *) s++; maybe_num = isdigit(uc) || (uc == '.') || (uc == '-'); while (uc) { if (uc == '\"') { *p++ = '\\'; needs_quotes = TRUE; } else if (maybe_num) { if (uc == '-') { if (cnt) { maybe_num = FALSE; needs_quotes = TRUE; } } else if (uc == '.') { if (dotcnt++) { maybe_num = FALSE; needs_quotes = TRUE; } } else if (!isdigit(uc)) { maybe_num = FALSE; needs_quotes = TRUE; } } else if (!ISALNUM(uc)) needs_quotes = TRUE; *p++ = (char) uc; uc = *(unsigned char *) s++; cnt++; /* If breaking long strings into multiple lines, only allow breaks after a non-id char, not a backslash, where the next char is an * id char. */ if (Max_outputline) { if (uc && backslash_pending && !(is_id_char(p[-1]) || (p[-1] == '\\')) && is_id_char(uc)) { *p++ = '\\'; *p++ = '\n'; needs_quotes = TRUE; backslash_pending = FALSE; cnt = 0; } else if (uc && (cnt >= Max_outputline)) { if (!(is_id_char(p[-1]) || (p[-1] == '\\')) && is_id_char(uc)) { *p++ = '\\'; *p++ = '\n'; needs_quotes = TRUE; cnt = 0; } else { backslash_pending = TRUE; } } } } *p++ = '\"'; *p = '\0'; if (needs_quotes || ((cnt == 1) && ((*arg == '.') || (*arg == '-')))) return buf; /* Use quotes to protect tokens (example, a node named "node") */ /* It would be great if it were easier to use flex here. */ for (tok = tokenlist; *tok; tok++) if (!strcasecmp(*tok, arg)) return buf; return arg; }
Token* Scanner::read_name(fint c) { Token::TokenType t; fint l = line; fint col = column - 1; const char* ss = sourceAddr() - 1; fint len; if (c == ':') { t = Token::ARG; len = 0; } else { t = c == '_' ? Token::PRIMNAME : Token::NAME; len = 1; buffer[0] = char(c); } while (c = get_char(), is_id_char(c)) { buffer[len++] = char(c); } if (c == ':' && (t == Token::NAME || t == Token::PRIMNAME)) { buffer[len++] = char(c); if (is_upper((fint)*buffer)) t = Token::CAPKEYWORD; else t = c == '_' ? Token::PRIMKEYWORD : Token::KEYWORD; } else { push_char(c); } buffer[len] = '\0'; if (t == Token::ARG && len == 0) { t = as_TokenType(':'); } else if (t == Token::NAME || t == Token::PRIMNAME) { c = get_char(); if (c == '.') { c = get_char(); push_char(c); if (is_id_alpha(c) || is_punct(c)) { t = Token::DELEGATE; } else { push_char('.'); } } else { push_char(c); } } if (strcmp(buffer, "self") == 0) { if (t == Token::NAME) { t = Token::SELF_TOKEN; } else { return TokenizingError( "using \"self\" as a parent name for a directed resend"); } } else if (strcmp(buffer, "resend") == 0) { if (t == Token::DELEGATE) { t = Token::RESEND_TOKEN; } else { return TokenizingError("not using \"resend\" in a resend"); } } String* s; if (t == Token::NAME || t == Token::PRIMNAME || t == Token::ARG || t == Token::DELEGATE || t == Token::KEYWORD || t == Token::PRIMKEYWORD || t == Token::CAPKEYWORD) { s = new String(copy_string(buffer)); } else { s = NULL; } return new Token(t, s, l, col, ss); }
static void split_at_GML_tag( void ) { char * p; char * p2; char * pchar; char c; bool layoutsw; size_t toklen; if( *buff2 == GML_char ) { if( !strnicmp( (buff2 + 1), "CMT", 3 ) && ((*(buff2 + 4) == '.') || (*(buff2 + 4) == ' ')) ) { return; // no split for :cmt. line } } /***********************************************************************/ /* Look for GML tag start char(s) until a known tag is found */ /* then split the line */ /***********************************************************************/ pchar = strchr( buff2 + 1, GML_char ); while( pchar != NULL ) { while( *(pchar + 1) == GML_char ) { pchar++; // handle repeated GML_chars } for( p2 = pchar + 1; is_id_char( *p2 ) && (p2 < (buff2 + buf_size)); p2++ ) /* empty loop */ ; if( (p2 > pchar + 1) && ((*p2 == '.') || is_space_tab_char( *p2 ) || (*p2 == '\0') || (*p2 == GML_char) ) ) { // 'good' tag end c = *p2; if( ProcFlags.layout && (c == '\t') ) { c = ' '; // replace tab with space in layout } *p2 = '\0'; // null terminate string toklen = p2 - pchar - 1; /***************************************************************/ /* Verify valid user or system tag */ /***************************************************************/ if( (find_tag( &tag_dict, pchar + 1 ) != NULL) || (find_sys_tag( pchar + 1, toklen ) != NULL) || (find_lay_tag( pchar + 1, toklen ) != NULL) ) { *p2 = c; if( input_cbs->fmflags & II_sol ) { // remove spaces before tags at sol in restricted sections // in or just before LAYOUT tag layoutsw = ProcFlags.layout; if( !layoutsw && (strncmp( "LAYOUT", pchar + 1, 6 ) == 0 ) ) { layoutsw = true; } if( (rs_loc > 0) || layoutsw ) { p = buff2; while( is_space_tab_char( *p ) ) { p++; } if( p == pchar ) { // only leading blanks memmove( buff2, pchar, buf_size - (p - buff2) ); buff2_lg = strlen( buff2 );// new length pchar = strchr( buff2 + 1, GML_char ); // try next GMLchar continue; // dummy split done try again } } } split_input( buff2, pchar, false );// split line if( ProcFlags.literal ) { // if literal active if( li_cnt < LONG_MAX ) {// we decrement, adjust for split line li_cnt++; } } break; // we did a split stop now } else { *p2 = c; } } pchar = strchr( pchar + 1, GML_char ); // try next GMLchar } }
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; } }
void gml_hdref( const gmltag * entry ) { char * p; char * pa; char * pe; char * idp; char quote; char c; bool idseen; bool pageseen; bool withpage; size_t len; char buf64[64]; ref_entry * re; static char undefid[] = "\"Undefined Heading\" on page XXX"; idseen = false; pageseen = false; withpage = false; p = scan_start; re = NULL; /***********************************************************************/ /* Scan attributes for :HDREF */ /* id= */ /* page= */ /***********************************************************************/ for( ;; ) { while( *p == ' ' ) { p++; } if( *p == '\0' || *p == '.' ) { break; // tag end found } if( !strnicmp( "page=", p, 5 ) ) { p += 5; while( *p == ' ' ) { p++; } pa = p; if( !strnicmp( "yes", p, 3 ) ) { pageseen = true; withpage = true; p += 3; } else { if( !strnicmp( "no", p, 2 ) ) { pageseen = true; withpage = false; p += 2; } else { g_err( err_inv_att_val ); file_mac_info(); err_count++; while( *p && (*p != '.') && (*p != ' ') ) p++; } } scan_start = p; continue; } if( !strnicmp( "refid=", p, 6 ) ) { p += 6; while( *p == ' ' ) { p++; } if( is_quote_char( *p ) ) { quote = *p; p++; } else { quote = '\0'; } pa = p; while( *p && is_id_char( *p ) ) { p++; } len = __min( ID_LEN, p - pa );// restrict length as in ghx.c if( len > 0 ) { idseen = true; // valid id attribute found pe = pa + len; c = *pe; *pe = '\0'; re = find_refid( ref_dict, strlwr( pa ) ); if( re != NULL ) { // id found in ref dict idp = mem_alloc( 4 + strlen( re->text_cap ) ); *idp = '"'; // decorate with quotes strcpy( idp + 1, re->text_cap ); strcat( idp, "\"" ); } else { if( GlobalFlags.lastpass ) { g_warn( wng_id_xxx, pa ); g_info( inf_id_unknown ); file_mac_info(); wng_count++; } } *pe = c; } if( *p && (quote == *p) ) { p++; } scan_start = p; continue; } /*******************************************************************/ /* no more valid attributes */ /*******************************************************************/ break; } if( *p == '.' ) { // tag end ? p++; } if( idseen ) { // id attribute was specified bool concatsave = ProcFlags.concat; ProcFlags.concat = true; // make process_text add to line if( re == NULL ) { // undefined refid process_text( undefid, g_curr_font_num ); } else { process_text( idp, g_curr_font_num ); if( withpage || (!pageseen && (page != re->pageno)) ) { sprintf_s( buf64, sizeof( buf64 ), "on page %d", re->pageno ); process_text( buf64, g_curr_font_num ); } mem_free( idp ); } ProcFlags.concat = concatsave; } else { g_err( err_att_missing ); // id attribute missing file_mac_info(); err_count++; } scan_start = p; return; }