void scr_ix( void ) { condcode cc; // resultcode from getarg() static char cwcurr[4] = {" ix"};// control word string for errmsg int lvl; // max index level in control word data int k; int comp_len;// compare length for searching existing entries int comp_res; // compare result char * ix[3]; // index string(s) to add uint32_t ixlen[3]; // corresponding lengths ix_h_blk * * ixhwork; // anchor point for insert ix_h_blk * ixhwk; // index block ix_h_blk * ixhcurr[3]; // active index heading block per lvl ix_e_blk * ixewk; // index entry block bool do_nothing; // true if index string duplicate uint32_t wkpage; scan_restart = scan_stop + 1; if( !(GlobalFlags.index && GlobalFlags.lastpass) ) { return; // no need to process .ix } // no index wanted or not lastpass cwcurr[0] = SCR_char; lvl = 0; // index level // if( ProcFlags.page_started ) { // wkpage = page; // } else { wkpage = page + 1; // not quite clear TBD // } garginit(); // over control word while( lvl < 3 ) { // try to get 3 lvls of index cc = getarg(); if( cc == omit || cc == quotes0 ) { // no (more) arguments if( lvl == 0 ) { parm_miss_err( cwcurr ); return; } else { break; } } else { if( *tok_start == '.' && arg_flen == 1 ) { if( lvl > 0 ) { xx_opt_err( cwcurr, tok_start ); break; // .ix s1 s2 . ref format not supprted } cc = getarg(); if( cc == pos || cc == quotes ) { // .ix . dump ??? if( arg_flen == 4 ) { if( !strnicmp( tok_start, "DUMP", 4 ) ) { ixdump( index_dict ); break; } } xx_opt_err( cwcurr, tok_start );// unknown option } else { parm_miss_err( cwcurr ); return; } break; // no index entry text } ix[lvl] = tok_start; *(tok_start + arg_flen) = 0; ixlen[lvl] = arg_flen; lvl++; } } cc = getarg(); /***************************************************************************/ /* The docu says .ix "I1" "I2" "I3" "extra" is invalid, but WGML4 accepts */ /* it without error and processes it like the :I3 pg="extra" attribute */ /***************************************************************************/ // if( cc != omit ) { // parm_extra_err( cwcurr, tok_start - (cc == quotes) ); // return; // } if( lvl > 0 ) { // we have at least one index string ixhwork = &index_dict; for( k = 0; k < lvl; ++k ) { do_nothing = false; while( *ixhwork != NULL ) { // find alfabetic point to insert comp_len = ixlen[k]; if( comp_len > (*ixhwork)->ix_term_len ) comp_len = (*ixhwork)->ix_term_len; ++comp_len; comp_res = strnicmp( ix[k], (*ixhwork)->ix_term, comp_len ); if( comp_res > 0 ) { // new is later in alfabet ixhwork = &((*ixhwork)->next); continue; } if( comp_res == 0 ) { // equal if( ixlen[k] == (*ixhwork)->ix_term_len ) { do_nothing = true; break; // entry already there } if( ixlen[k] > (*ixhwork)->ix_term_len ) { ixhwork = &((*ixhwork)->next); continue; // new is longer } } break; // insert point reached } if( !do_nothing ) { // insert point reached ixhwk = mem_alloc( sizeof( ix_h_blk ) ); ixhwk->next = *ixhwork; ixhwk->ix_lvl= k + 1; ixhwk->lower = NULL; ixhwk->entry = NULL; ixhwk->prt_term = NULL; ixhwk->prt_term_len = 0; ixhwk->ix_term_len = ixlen[k]; ixhwk->ix_term = mem_alloc( ixlen[k] + 1 ); strcpy_s( ixhwk->ix_term, ixlen[k] + 1, ix[k] ); *ixhwork = ixhwk; } else { // string already in dictionary at this level ixhwk = *ixhwork; } ixhcurr[lvl] = ixhwk; if( k < lvl ) { ixhwork = &(ixhwk->lower); // next lower level } } // now add the pageno to index entry if( ixhwk->entry == NULL ) { // first pageno for entry /***************************************************************************/ /* The docu says .ix "I1" "I2" "I3" "extra" is invalid, but WGML4 accepts */ /* it without error and processes it like the :I3 pg="extra" attribute */ /* try to process the extra parm */ /***************************************************************************/ if( cc != omit ) { *(tok_start + arg_flen) = 0; fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgstring, tok_start, arg_flen ); } else { fill_ix_e_blk( &(ixhwk->entry), ixhwk, pgpageno, NULL, 0 ); } } else { ixewk = ixhwk->entry; while( ixewk->next != NULL ) { // find last entry ixewk = ixewk->next; } if( (ixewk->entry_typ >= pgstring) || (ixewk->page_no != wkpage) ) { // if last entry doesn't point to current page create entry if( cc != omit ) { *(tok_start + arg_flen) = 0; fill_ix_e_blk( &(ixewk->next), ixhwk, pgstring, tok_start, arg_flen ); } else { fill_ix_e_blk( &(ixewk->next), ixhwk, pgpageno, NULL, 0 ); } } } } return; }
void gen_index( void ) { ixdump( index_dict ); }