Exemplo n.º 1
0
void    scr_th( void )
{
    ifcb    *   cb = input_cbs->if_cb;
    char        linestr[MAX_L_AS_STR];

    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 );
        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_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 + 1;
    return;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
void    scr_pu( void )
{
    int             workn;
    condcode        cc;
    char        *   p;

    garginit();                         // find end of CW

    cc = getarg();                      // workfile number

    if( cc == omit ) {
        numb_err();                     // we need workfile number
        return;
    }

    p = tok_start;

    if( (arg_flen > 1) || (*p < '1') || (*p > '9') ) {
        numb_err();
        return;
    }
    workn = *p - '0';
    scan_restart = scan_stop;

    cc = getarg();                      // text follows

    if( cc == omit ) {                  // no then close workfile
        close_pu_file( workn );
        return;
    }

    open_pu_file( workn );              // open if not already done
    fputs( tok_start, workfile[workn - 1] );
    fputc( '\n', workfile[workn - 1] );

    return;
}
Exemplo n.º 4
0
void    scr_go( void )
{
    condcode        cc;
    getnum_block    gn;
    labelcb     *   golb;
    int             k;
    char            linestr[MAX_L_AS_STR];

    input_cbs->if_cb->if_level = 0;     // .go terminates
    ProcFlags.keep_ifstate = false;     // ... all .if controls

    garginit();

    cc = getarg();
    if( cc != pos ) {
        scan_err = true;
        err_count++;
        g_err( err_missing_name, "" );
        if( input_cbs->fmflags & II_tag_mac ) {
            utoa( input_cbs->s.m->lineno, linestr, 10 );
            g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name );
        } else {
            utoa( input_cbs->s.f->lineno, linestr, 10 );
            g_info( inf_file_line, linestr, input_cbs->s.f->filename );
        }
        show_include_stack();
        return;
    }

    gn.argstart      = tok_start;
    gn.argstop       = scan_stop;
    gn.ignore_blanks = 0;

    cc = getnum( &gn );             // try numeric expression evaluation
    if( cc == pos  || cc  == neg) {     // numeric linenumber
        gotarget[0] = '\0';             // no target label name
        if( gn.num_sign == ' '  ) {     // absolute number
            gotargetno = gn.result;
        } else {
            if( input_cbs->fmflags & II_tag_mac ) {
                gotargetno = input_cbs->s.m->lineno;
            } else {
                gotargetno = input_cbs->s.f->lineno;
            }
            gotargetno += gn.result;    // relative target line number
        }

        if( gotargetno < 1 ) {
            scan_err = true;
            err_count++;
            g_err( err_label_zero );
            if( input_cbs->fmflags & II_tag_mac ) {
                utoa( input_cbs->s.m->lineno, linestr, 10 );
                g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name );
            } else {
                utoa( input_cbs->s.f->lineno, linestr, 10 );
                g_info( inf_file_line, linestr, input_cbs->s.f->filename );
            }
            show_include_stack();
            return;
        }
        if( input_cbs->fmflags & II_tag_mac ) {
            if( gotargetno <= input_cbs->s.m->lineno ) {
                input_cbs->s.m->lineno = 0; // restart from beginning
                input_cbs->s.m->macline = input_cbs->s.m->mac->macline;
            }
        }
    } else {                            // no numeric target label

        gotargetno = 0;                 // no target lineno known
        if( arg_flen >  MAC_NAME_LENGTH ) {
            err_count++;
            g_err( err_sym_long, tok_start );
            if( input_cbs->fmflags & II_tag_mac ) {
                utoa( input_cbs->s.m->lineno, linestr, 10 );
                g_info( inf_mac_line, linestr, input_cbs->s.m->mac->name );
            } else {
                utoa( input_cbs->s.f->lineno, linestr, 10 );
                g_info( inf_file_line, linestr, input_cbs->s.f->filename );
            }
            show_include_stack();
            arg_flen = MAC_NAME_LENGTH;
        }

        for( k = 0; k < MAC_NAME_LENGTH; k++ ) {// copy to work
            gotarget[k] = *tok_start++;
        }
        gotarget[k] = '\0';

        golb = find_label( gotarget );
        if( golb != NULL ) {            // label already known
            gotargetno = golb->lineno;

            if( input_cbs->fmflags & II_tag_mac ) {
                if( golb->lineno <= input_cbs->s.m->lineno ) {
                    input_cbs->s.m->lineno = 0; // restart from beginning
                    input_cbs->s.m->macline = input_cbs->s.m->mac->macline;
                }
            } else {
                if( golb->lineno <= input_cbs->s.f->lineno ) {
                    fsetpos( input_cbs->s.f->fp, &golb->pos );
                    input_cbs->s.f->lineno = golb->lineno - 1;// position file
                }
            }
        }
    }
    free_lines( input_cbs->hidden_head );   // delete split line
    input_cbs->hidden_head = NULL;
    input_cbs->hidden_tail = NULL;
    ProcFlags.goto_active = true;       // special goto processing
    scan_restart = scan_stop + 1;

}
Exemplo n.º 5
0
void    scr_gt( void )
{
    char        *   p;
    char        *   pn;
    char            savetag;
    int             k;
    int             len;
    char            macname[MAC_NAME_LENGTH + 1];
    condcode        cc;
    gtentry     *   wk;
    gtflags         tag_flags;
    enum {
        f_add       = 1,
        f_change,
        f_delete,
        f_off,
        f_on,
        f_print
    } function;

    garginit();                         // find end of CW

    /***********************************************************************/
    /*  isolate tagname   or use previous if tagname *                     */
    /***********************************************************************/

    cc = getarg();                      // Tagname

    if( cc == omit ) {
        // no operands
        tag_name_missing_err();
        return;
    }

    p = tok_start;

    if( *p == '*' ) {                   // single * as tagname
        if( arg_flen > 1 ) {
            xx_err( err_tag_name_inv );
            return;
        }
        savetag = '*';         // remember for possible global delete / print
        if( GlobalFlags.firstpass && input_cbs->fmflags & II_research ) {
            if( tag_entry != NULL ) {
                out_msg("  using tagname %s %s\n", tagname, tag_entry->name );
            }
        }
    } else {
        savetag = ' ';               // no global function for delete / print

        init_tag_att();            // forget previous values for quick access
        attname[0] = '*';

        pn      = tagname;
        len     = 0;

        while( *p && is_macro_char( *p ) ) {
            if( len < TAG_NAME_LENGTH ) {
                *pn++ = tolower( *p++ );// copy lowercase tagname
                *pn   = '\0';
            } else {
                break;
            }
            len++;
        }
        for( k = len; k < TAG_NAME_LENGTH; k++ ) {
            tagname[k] = '\0';
        }
        tagname[TAG_NAME_LENGTH] = '\0';

        if( len < arg_flen ) {
            xx_err( err_tag_name_inv );
            return;
        }
    }


    /***********************************************************************/
    /* get function operand  add, change, ...                              */
    /***********************************************************************/

    cc = getarg();

    if( cc == omit ) {
        xx_err( err_tag_func_inv );
        return;
    }

    p = tok_start;
    function = 0;
    switch( tolower( *p ) ) {
    case   'a':
        if( !strnicmp( "ADD ", p, 4 ) ) {

            function = f_add;
        }
        break;
    case 'c' :
        if( (arg_flen > 2) && (arg_flen < 7)
            && !strnicmp( "CHANGE", p, arg_flen ) ) {

            function = f_change;
        }
        break;
    case 'o' :
        if( !strnicmp( "OFF", p, 3 ) ) {

            function = f_off;
        } else {
            if( !strnicmp( "ON", p, 2 ) ) {

                function = f_on;
            }
        }
        break;
    case 'd' :
        if( (arg_flen > 2) && (arg_flen < 7)
            && !strnicmp( "DELETE", p, arg_flen ) ) {

            function = f_delete;
        }
        break;
    case 'p' :
        if( (arg_flen > 1) && (arg_flen < 6)
            && !strnicmp( "PRINT", p, arg_flen ) ) {

            function = f_print;
        }
        break;
    default:
        // nothing
        break;
    }
    if( function == 0 ) {               // no valid function specified
        xx_err( err_tag_func_inv );
        return;
    }

    cc = getarg();                      // get possible next parm

    /***********************************************************************/
    /*  for add and change    get macroname                                */
    /***********************************************************************/

    if( function == f_add || function == f_change ) {   // need macroname
        if( cc == omit ) {
            xx_err( err_tag_mac_name );
            return;
        }
        p = tok_start;

        pn      = macname;
        len     = 0;

        while( *p && is_macro_char( *p ) ) {
            if( len < MAC_NAME_LENGTH ) {
                *pn++ = tolower( *p++ );    // copy lowercase macroname
                *pn   = '\0';
            } else {
                break;
            }
            len++;
        }
        for( k = len; k < MAC_NAME_LENGTH; k++ ) {
            macname[k] = '\0';
        }
        macname[MAC_NAME_LENGTH] = '\0';

        tag_flags = 0;

        if( function == f_add ) {       // collect tag options
            cc = scan_tag_options( &tag_flags );
            if( cc != omit ) {          // not all processed error
               xx_err( err_tag_opt_inv );
            }
            tag_entry = add_tag( &tag_dict, tagname, macname, tag_flags );  // add to dictionary
            // if tag_entry is now NULL, error (+ msg) was output in add_tag
        } else {                        // is function change
            tag_entry = change_tag( &tag_dict, tagname, macname );
        }
    } else {

    /***********************************************************************/
    /*  after delete, off, on, print nothing allowed                       */
    /***********************************************************************/

        if( cc != omit ) {
            xx_err( err_tag_toomany );  // nothing more allowed
        }

        switch( function ) {
        case f_print :
            if( savetag == '*' ) {
                print_tag_dict( tag_dict );
            } else {
                print_tag_entry( find_tag( &tag_dict, tagname ) );
            }
            break;
        case f_delete :
            if( savetag == '*' ) {
                free_tag_dict( &tag_dict );
            } else {
                free_tag( &tag_dict, find_tag( &tag_dict, tagname ) );
            }
            break;
        case f_off :
            if( savetag == '*' && tag_entry != NULL ) {// off for last defined
                tag_entry->tagflags |= tag_off;
            } else {
                wk = find_tag( &tag_dict, tagname );
                if( wk != NULL ) {
                    wk->tagflags |= tag_off;
                }
            }
            break;
        case f_on :
            if( savetag == '*' && tag_entry != NULL ) {// on for last defined
                tag_entry->tagflags |= tag_off;
            } else {
                wk = find_tag( &tag_dict, tagname );
                if( wk != NULL ) {
                    wk->tagflags &= ~tag_off;
                }
            }
            break;
        default:
            break;
        }
    }
    scan_restart = scan_stop +1;
    return;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
void    scr_ga( void )
{
    char        *   p;
    char        *   pn;
    char            savetag;
    char            saveatt;
    int             k;
    int             len;
    condcode        cc;
    gaflags         att_flags;
    gavalflags      val_flags;
    gavalentry  *   gaval;
    gaentry     *   gawk;


    savetag = ' ';
    saveatt = ' ';
    att_flags = 0;
    val_flags = 0;
    garginit();                         // find end of CW

    cc = getarg();                      // Tagname or *

    if( cc == omit || (*tok_start == '*' && tag_entry == NULL) ) {
        // no operands or tagname * and no previous definition
        tag_name_missing_err();
    }
    if( tag_entry == NULL ) {           // error during previous .gt

        scan_restart = scan_stop + 1;   // ignore .ga
        return;
    }


    /***********************************************************************/
    /*  isolate tagname  use previous if tagname *                         */
    /***********************************************************************/

    p = tok_start;

    if( *p == '*' ) {                   // single * as tagname
        if( arg_flen > 1 ) {
            xx_err( err_tag_name_inv );
            return;
        }
        savetag = '*';                  // remember for possible quick access
        if( GlobalFlags.firstpass && input_cbs->fmflags & II_research ) {
            out_msg("  using tagname %s\n", tagname );
        }
    } else {
        savetag = ' ';                  // no quick access

        init_tag_att();            // forget previous values for quick access

        pn      = tagname;
        len     = 0;

        while( *p && is_macro_char( *p ) ) {
            if( len < TAG_NAME_LENGTH ) {
                *pn++ = tolower( *p++ );// copy lowercase tagname
                *pn   = '\0';
            } else {
                break;
            }
            len++;
        }
        for( k = len; k < TAG_NAME_LENGTH; k++ ) {
            tagname[k] = '\0';
        }
        tagname[TAG_NAME_LENGTH] = '\0';

        if( len < arg_flen ) {
            xx_err( err_tag_name_inv );// name contains invalid or too many chars
            return;
        }
        tag_entry = find_tag( &tag_dict, tagname );
        if( tag_entry == NULL ) {
            nottag_err();               // tagname not defined
            return;
        }
    }

    /***********************************************************************/
    /* isolate attname  use previous if attname *                          */
    /***********************************************************************/

    cc = getarg();                      // Attribute  name or *

    if( cc == omit || (*tok_start == '*' && att_entry == NULL) ) {
        // no operands or attname * and no previous definition
        xx_err( err_att_name_inv );
        return;
    }

    p = tok_start;

    if( *p == '*' ) {                   // single * as attname
        if( arg_flen > 1 ) {
            xx_err( err_att_name_inv );
            return;
        }
        saveatt = '*';                  // remember for possible quick access
        if( GlobalFlags.firstpass && input_cbs->fmflags & II_research ) {
            out_msg("  using attname %s\n", attname );
        }
        att_flags = att_entry->attflags;
    } else {
        saveatt = ' ';                  // no quick access
        att_entry = NULL;
        pn      = attname;
        len     = 0;

        while( *p && is_macro_char( *p ) ) {
            if( len < ATT_NAME_LENGTH ) {
                *pn++ = tolower( *p++ );// copy lowercase tagname
                *pn   = '\0';
            } else {
                break;
            }
            len++;
        }
        for( k = len; k < ATT_NAME_LENGTH; k++ ) {
            attname[k] = '\0';
        }
        attname[ATT_NAME_LENGTH] = '\0';

        if( len < arg_flen ) {
            xx_err( err_att_name_inv );// attname with invalid or too many chars
            cc = neg;
            return;
        }
    }


    /***********************************************************************/
    /*   process options A and options B                                   */
    /***********************************************************************/

    if( cc != omit ) {
        if( saveatt != '*' ) {          // no quickaccess for attribute
            gawk = NULL;
            for( gawk = tag_entry->attribs; gawk != NULL;
                 gawk = gawk->next ) {

                if( !stricmp( attname, gawk->name ) ) {
                    att_flags = gawk->attflags; // get possible uppercase option
                    break;
                }
            }
        } else {
            att_flags = att_entry->attflags;
        }
        cc = scan_att_optionsA( &att_flags );   // process options A

        if( cc != omit ) {

            cc = scan_att_optionsB( &val_flags, cc, &att_flags );// process option B
            if( cc != omit ) {
                xx_err( err_tag_toomany );  // excess parameters
                return;
            }
        }
    }

    /***********************************************************************/
    /*  scanning complete     add/modify attribute in dictionary           */
    /***********************************************************************/
    if( saveatt != '*' ) {              // no quickaccess for attribute
        for( att_entry = tag_entry->attribs; att_entry != NULL;
             att_entry = att_entry->next ) {

            if( !stricmp( attname, att_entry->name ) ) {
                break;
            }
        }
    }
    if( att_entry == NULL ) {           // new attribute
        att_entry = mem_alloc( sizeof( gaentry ) );

        att_entry->next = tag_entry->attribs;
        tag_entry->attribs = att_entry;

        att_entry->vals = NULL;
        att_entry->attflags = att_flags;
        strcpy( att_entry->name, attname );
    } else {
        att_entry->attflags = att_flags;// update flags
    }

    gaval = mem_alloc( sizeof (gavalentry ) );

    if( att_entry->vals == NULL ) {
        att_entry->vals = gaval;
    } else {
        gavalentry  *   valwk;

        for( valwk = att_entry->vals;  valwk != NULL;
                                       valwk = valwk->next ) {
            if( valwk->next == NULL ) {
                break;                      // last entry found
            }
        }
        valwk->next = gaval;
    }
    gaval->next = NULL;

    gaval->valflags = val_flags;
    if( val_flags & val_length ) {
        gaval->a.length = ranges[0];
    } else if( val_flags & val_range ) {
        for( k = 0; k < 4; k++ ) {
            gaval->a.range[k] = ranges[k];
        }
    } else if( val_flags & val_value ) {
        strcpy_s( gaval->a.value, sizeof( gaval->a.value ), stringval );
    } else if( val_flags & val_valptr ) {
        gaval->a.valptr = valptr;
    }
    scan_restart = scan_stop + 1;
    return;
}