示例#1
0
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;
}
示例#2
0
void    gen_index( void )
{
    ixdump( index_dict );
}