static bool remove_leading_space( void ) { char * p; char * p2; bool removed = false; if( ProcFlags.literal ) { // .li active return( false ); // don't change input } p = buff2; while( is_space_tab_char( *p ) ) { p++; } if( (p != buff2) && (*p == GML_char) ) { p2 = buff2; do { *p2++ = *p++; } while( *p ); *p2++ = '\0'; *p2 = '\0'; removed = true; } return( removed ); }
static void gml_ixxx_common( const gmltag * entry, int hx_lvl ) { bool idseen; bool refidseen; bool seeseen; bool seeidseen; bool pgseen; bool printseen; char * p; ereftyp pgvalue; char * pgtext; size_t pgtextlen; size_t printtxtlen; size_t seetextlen; char * printtxt; char * seetext; ref_entry * refwork; ref_entry reid; ref_entry * rewk; ref_entry refid; ref_entry * refwk; ref_entry reseeid; ref_entry * rswk; ix_h_blk * ihm1; ix_e_blk * ixewk; ix_e_blk * ixewksav; ix_h_blk * ixhwk; ix_h_blk * * ixhwork; uint32_t wkpage; size_t txtlen; char * txt; char hxstring[TAG_NAME_LENGTH +1]; char lvlc; if( !GlobalFlags.index ) { // index option not active scan_start = scan_stop + 1; // ignore tag return; } lvlc = '0' + (char)hx_lvl; *hxstring = GML_char; // construct tagname for possible error msg strcpy_s( (hxstring + 1), TAG_NAME_LENGTH, entry->tagname ); if( (hxstring[2] == lvlc) && // :Ix tags not allowed before :GDOC !((ProcFlags.doc_sect >= doc_sect_gdoc) || (ProcFlags.doc_sect_nxt >= doc_sect_gdoc)) ) { g_err( err_tag_before_gdoc, hxstring ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } if( hx_lvl > 1 ) { // test for missing previous parent index tag if( ixhtag[hx_lvl - 1] == NULL ) { g_err( err_parent_undef ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } } idseen = false; pgseen = false; refidseen = false; printseen = false; seeseen = false; seeidseen = false; ixewk = NULL; pgvalue = pgnone; pgtext = NULL; pgtextlen = 0; printtxt = NULL; printtxtlen = 0; seetext = NULL; wkpage = page + 1; p = scan_start; ProcFlags.tag_end_found = false; /***********************************************************************/ /* Scan attributes for :Ix :IHx :IREF */ /* */ /* id= */ /* refid= */ /* pg= */ /* print= */ /* see= */ /* seeid= */ /***********************************************************************/ for( ;; ) { if( ProcFlags.tag_end_found ) { break; } while( is_space_tab_char( *p ) ) { p++; } if( *p == '.' ) { ProcFlags.tag_end_found = true; break; } if( *p == '\0' ) { break; } /*******************************************************************/ /* ID='xxxxxxxx' for :Ix :IHx */ /*******************************************************************/ if( !strnicmp( "id", p, 2 ) ) { p += 2; p = get_refid_value( p ); if( (val_start != NULL) && (val_len > 0) ) { if( hx_lvl > 0 ) { // :Ix :IHx idseen = true; // id attribute found init_ref_entry( &reid, val_start, val_len ); rewk = find_refid( iref_dict, reid.id ); if( rewk != NULL ) { if( rewk->lineno != reid.lineno ) { g_err( inf_id_duplicate ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } } } else { // not allowed for :IREF g_err( err_refid_not_allowed, hxstring ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } } scan_start = p; continue; } /*******************************************************************/ /* REFID='xxxxxxxx' for :IREF :I2 :I3 */ /*******************************************************************/ if( !strnicmp( "refid", p, 5 ) ) { p += 5; p = get_refid_value( p ); if( val_start != NULL && val_len > 0 ) { if( (hx_lvl == 0) || ((hx_lvl > 1) && (hxstring[2] == lvlc)) ) { fill_id( &refid, val_start, val_len ); refidseen = true; // refid attribute found refwk = find_refid( iref_dict, refid.id ); if( refwk == NULL ) { // refid not in dict if( GlobalFlags.lastpass ) {// this is an error g_err( inf_id_unknown );// during lastpass err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } } } else { // not allowed for :I1 and :IHx g_err( err_refid_not_allowed, hxstring ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } } scan_start = p; continue; } /*******************************************************************/ /* PG= for :IREF :Ix */ /*******************************************************************/ if( !strnicmp( "pg", p, 2 ) ) { p += 2; p = get_att_value( p ); scan_start = p; if( val_start == NULL || val_len == 0 ) { // no valid pg continue; // ignore } if( quote_char == '\0' ) { // value not quoted if( !strnicmp( "start", val_start, 5 ) ) { pgvalue = pgstart; } else if( !strnicmp( "end", val_start, 3 ) ) { pgvalue = pgend; } else if( !strnicmp( "major", val_start, 5 ) ) { pgvalue = pgmajor; } else { continue; // ignore } } else { pgvalue = pgstring; pgtext = mem_alloc( val_len + 1 ); strncpy( pgtext, val_start, val_len );// use text instead of pageno *(pgtext + val_len) = '\0'; pgtextlen = val_len; } pgseen = true; continue; } /*******************************************************************/ /* PRINT= for :IHx */ /*******************************************************************/ if( !strnicmp( "print", p, 5 ) ) { p += 5; p = get_att_value( p ); scan_start = p; if( val_start == NULL || val_len == 0 ) { continue; // ignore } printtxt = mem_alloc( val_len + 1 ); printtxtlen = val_len; strncpy( printtxt, val_start, val_len ); *(printtxt + val_len) = '\0'; printseen = true; continue; } /*******************************************************************/ /* SEE='xxxxxxxx' for :IREF :IH1 :IH2 */ /*******************************************************************/ if( !strnicmp( "see", p, 3 ) ) { p += 3; p = get_att_value( p ); scan_start = p; if( (val_start != NULL) || val_len > 0 ) { if( hx_lvl == 0 || ((hx_lvl < 3) && (hxstring[3] == lvlc)) ) {// :IREF :IH1 :IH2 seetext = mem_alloc( val_len +1 ); strncpy( seetext, val_start, val_len ); *(seetext + val_len) = '\0'; seetextlen = val_len; seeseen = true; } else { // not allowed for :IH3, :Ix g_err( err_refid_not_allowed, hxstring ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } } continue; } /*******************************************************************/ /* SEEID='xxxxxxxx' for :IREF :IH1 :IH2 */ /*******************************************************************/ if( !strnicmp( "seeid", p, 5 ) ) { p += 5; p = get_refid_value( p ); if( (val_start != NULL) && (val_len > 0) ) { if( (hx_lvl <= 3) && (hxstring[3] == lvlc) ) { seeidseen = true; fill_id( &reseeid, val_start, val_len );// copy lower id rswk = find_refid( iref_dict, reseeid.id ); if( rswk == NULL ) {// not in dict, this is an error if( GlobalFlags.lastpass ) { // during lastpass g_err( inf_id_unknown ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } } } else { // not allowed for :IH3, :Ix :IREF g_err( err_refid_not_allowed, hxstring ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } } scan_start = p; continue; } /*******************************************************************/ /* no more valid attributes */ /*******************************************************************/ break; } if( ProcFlags.tag_end_found ) { // tag end ? p++; if( hx_lvl > 0 ) { // we need a text line for :Ix :IHx if( !*p ) { get_line( true ); p = buff2; } } } /***********************************************************************/ /* process the found attributes and the text line */ /***********************************************************************/ txt = p; txtlen = strlen( p ); if( !pgseen ) { pgvalue = pgpageno; // set default } if( hx_lvl == 0 ) { // :IREF tag /***********************************************************************/ /* processing for :IREF */ /***********************************************************************/ if( !refidseen ) { // refid= missing g_err( err_att_missing ); err_count++; file_mac_info(); scan_start = scan_stop + 1; return; } if( GlobalFlags.lastpass ) { if( refidseen && (refwk != NULL) ) { ixhwk = refwk->u.refb.hblk; } else { ixhwk = ixhtag[hx_lvl]; } /***************************************************************/ /* create index entry with page no / text */ /***************************************************************/ if( ixhwk->entry == NULL ) { // first entry ixewk = fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgvalue, pgtext, pgtextlen ); } else { if( pgvalue == pgmajor ) { // major becomes first in chain ixewksav = ixhwk->entry; ixhwk->entry = NULL; ixewk = fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgvalue, pgtext, pgtextlen ); ixewk->next = ixewksav; } else { ixewk = ixhwk->entry; if( pgvalue < pgstring ) { // pageno variants if( ixewk->entry_typ < pgstring ) { while( ixewk->next != NULL ) {// insert before pgstring if( ixewk->next->entry_typ >= pgstring ) { break; } ixewk = ixewk->next; } } else { ixewksav = ixhwk->entry; ixhwk->entry = NULL; ixewk = fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgvalue, pgtext, pgtextlen ); ixewk->next = ixewksav; } if( ixewk->u.page_no != wkpage ) { ixewksav = ixewk->next; ixewk->next = NULL; ixewk = fill_ix_e_blk( &(ixewk->next), ixhwk, pgvalue, pgtext, pgtextlen ); ixewk->next = ixewksav; } } else { while( ixewk->next != NULL ) { // find last entry ixewk = ixewk->next; } ixewk = fill_ix_e_blk( &(ixewk->next), ixhwk, pgvalue, pgtext, pgtextlen ); } } } } } else // :Ix :IHx tags if( ((hxstring[2] == lvlc) ) ) { // test for :Ix /***********************************************************************/ /* processing for :Ix */ /***********************************************************************/ switch( hx_lvl ) { // processing for :I1 :I2 :I3 case 1 : ixhwork = &index_dict; ixhwk = find_create_ix_h_entry( ixhwork, &printtxt, printtxtlen, txt, txtlen, hx_lvl ); printtxt = NULL; ixhtag[hx_lvl] = ixhwk; break; case 2 : case 3 : ihm1 = ixhtag[hx_lvl - 1]; if( refidseen && (refwk != NULL) ) { if( hx_lvl > refwk->u.refb.hblk->ix_lvl ) { ixhwork = &(refwk->u.refb.hblk->lower); } else { ixhwork = &(refwk->u.refb.hblk); } } else { ixhwork = &(ixhtag[hx_lvl - 1]->lower); } ixhwk = find_create_ix_h_entry( ixhwork, &printtxt, printtxtlen, txt, txtlen, hx_lvl ); printtxt = NULL; if( !refidseen ) { ixhtag[hx_lvl] = ixhwk; } break; default: break; } /*******************************************************************/ /* create index entry with page no / text */ /*******************************************************************/ if( ixhwk->entry == NULL ) { // first entry ixewk = fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgvalue, pgtext, pgtextlen ); } else { if( pgvalue == pgmajor ) { // major becomes first in chain ixewksav = ixhwk->entry; ixhwk->entry = NULL; ixewk = fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgvalue, pgtext, pgtextlen ); ixewk->next = ixewksav; } else { ixewk = ixhwk->entry; if( pgvalue < pgstring ) { // pageno variants if( ixewk->entry_typ < pgstring ) { while( ixewk->next != NULL ) {// insert before pgstring if( ixewk->next->entry_typ >= pgstring ) { break; } ixewk = ixewk->next; } } else { ixewksav = ixhwk->entry; ixhwk->entry = NULL; ixewk = fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgvalue, pgtext, pgtextlen ); ixewk->next = ixewksav; } if( ixewk->u.page_no != wkpage ) { ixewksav = ixewk->next; ixewk->next = NULL; ixewk = fill_ix_e_blk( &(ixewk->next), ixhwk, pgvalue, pgtext, pgtextlen ); ixewk->next = ixewksav; } } else { while( ixewk->next != NULL ) { // find last entry ixewk = ixewk->next; } ixewk = fill_ix_e_blk( &(ixewk->next), ixhwk, pgvalue, pgtext, pgtextlen ); } } } } else // :IHx if( ((hxstring[3] == lvlc) ) ) { // test for :IHx /***********************************************************************/ /* processing for :IHx */ /***********************************************************************/ switch( hx_lvl ) { // processing for :IH1 :IH2 :IH3 case 1 : ixhwork = &index_dict; ixhwk = find_create_ix_h_entry( ixhwork, &printtxt, printtxtlen, txt, txtlen, hx_lvl ); printtxt = NULL; ixhtag[hx_lvl] = ixhwk; break; case 2 : case 3 : ihm1 = ixhtag[hx_lvl - 1]; ixhwork = &(ixhtag[hx_lvl - 1]->lower); ixhwk = find_create_ix_h_entry( ixhwork, &printtxt, printtxtlen, txt, txtlen, hx_lvl ); printtxt = NULL; ixhtag[hx_lvl] = ixhwk; break; default: break; } if( seeseen ) { pgvalue = pgsee; if( ixhwk->entry == NULL ) { ixewk = fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgvalue, seetext, seetextlen ); } else { ixewk = ixhwk->entry; while( ixewk->next != NULL ) { // find last entry ixewk = ixewk->next; } ixewk = fill_ix_e_blk( &(ixewk->next), ixhwk, pgvalue, seetext, seetextlen ); } } else { if( seeidseen ) { ix_e_blk * * anchor; pgvalue = pgsee; if( ixhwk->entry == NULL ) { anchor = &(ixhwk->entry); } else { ixewk = ixhwk->entry; while( ixewk->next != NULL ) { // find last entry ixewk = ixewk->next; } anchor = &(ixewk->next); } if( rswk->u.refb.hblk->prt_term != NULL ) { ixewk = fill_ix_e_blk( anchor, ixhwk, pgvalue, rswk->u.refb.hblk->prt_term, rswk->u.refb.hblk->prt_term_len ); } else { ixewk = fill_ix_e_blk( anchor, ixhwk, pgvalue, rswk->u.refb.hblk->ix_term, rswk->u.refb.hblk->ix_term_len ); } } } } if( idseen ) { // ID specified create reference entry reid.u.refb.hblk = ixhwk; reid.u.refb.eblk = ixewk; reid.flags = rf_ix; refwork = mem_alloc( sizeof( reid ) ); memcpy( refwork, &reid, sizeof( reid ) ); add_ref_entry( &iref_dict, refwork ); } if( pgtext != NULL ) { mem_free( pgtext ); } if( printtxt != NULL ) { mem_free( printtxt ); } if( seetext != NULL ) { mem_free( seetext ); } scan_start = scan_stop + 1; return; }
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 } }
condcode get_lay_sub_and_value( att_args * args ) { char * p; char quote; condcode rc; p = scan_start; rc = no; while( is_space_tab_char( *p ) ) { // over WS to start of name p++; } args->start[0] = p; args->len[0] = -1; // switch for scanning error args->len[1] = -1; // switch for scanning error while( *p && is_lay_att_char( *p ) ) { p++; } if( *p == '\0' ) { if( p == args->start[0] ) { rc = omit; // nothing found } return( rc ); // or parsing error } args->len[0] = p - args->start[0]; if( args->len[0] < 4 ) { // attribute name length err_count++; g_err( err_att_name_inv ); file_mac_info(); return( rc ); } while( is_space_tab_char( *p ) ) { // over WS to = p++; } if(*p && *p == '=' ) { p++; while( is_space_tab_char( *p ) ) { // over WS to attribute value p++; } } else { err_count++; g_err( err_att_val_inv ); file_mac_info(); return( no ); // parsing err '=' missing } args->start[1] = p; // delimiters must be included for error checking if( is_quote_char( *p ) ) { quote = *p; ++p; args->quoted = true; } else { quote = ' '; args->quoted = false; } while( *p && *p != quote ) { ++p; } if( args->quoted && is_quote_char( *p ) ) { p++; // over terminating quote } args->len[1] = p - args->start[1]; if( args->len[1] < 1 ) { // attribute value length err_count++; g_err( err_att_val_inv ); file_mac_info(); } else { rc = pos; } if( *p == '.' ) { ProcFlags.tag_end_found = true; p++; } val_start = args->start[1]; val_len = args->len[1]; if( args->quoted) { // delimiters must be omitted for these externs val_start++; val_len -= 2; } scan_start = p; return( rc ); }