mparse.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,157 行 · 第 1/3 页

C
1,157
字号
    while( walk != NULL ) {
        if( !walk->target->special ) {
            PrtMsg( DBG | WRN | LOC | ASSUMING_SYMBOLIC, walk->target->node.name );
            break;
        }
        walk = walk->next;
    }
}


STATIC void parseTargDep( TOKEN_T t, TLIST **btlist )
/****************************************************
 * parse a line of form {target}+ (scolon||dcolon) {depend}*
 *                  or  {target}+
 * where:   target ::= TOK_FILENAME || TOK_SUFSUF || TOK_DOTNAME(with cmds)
 *          depend ::= TOK_FILENAME || DOT_PREC/SYMB/...
 *
 * stack targets into btlist
 */
{
    TATTR       attr;       /* hold attributes here */
    DEPEND      *dep;       /* a DEPEND that describes dependents from file */
    BOOLEAN     nodep;      /* true if no dependents from file              */

        /* get the target list, and the last token processed */
    t = buildTargs( btlist, t );
    if( *btlist == NULL ) {         /* only in error conditions */
        return;
    }

    nodep = t == EOL || t == STRM_END;  /* check if there wasn't a colon */

        /* set the scolon attribute for each of these targets */
    setSColon( *btlist, (int)(t == TOK_SCOLON || nodep) );

    if( !nodep ) {
        dep = buildDepend( &attr );
    } else {
            /* we've reached EOL already, so we'll just assume this */
        if( Glob.debug ) {
            parseTargWarning( *btlist );
        }

        dep = NewDepend();
        TargInitAttr( &attr );
        attr.symb = TRUE;
    }

        /* now we attach this depend to each target */
    linkDepend( *btlist, dep, attr );
    setFirstTarget( *btlist );
}


STATIC void parseExtensions( void )
/**********************************
 * parse lines of form .EXTENSIONS:
 *                  or .EXTENSIONS: {ext}+
 */
{
    TOKEN_T     t;
    BOOLEAN     any;

    for( ;; ) {
        t = LexToken( LEX_PARSER );
        if( t == EOL || t == STRM_END || t == TOK_SCOLON ) {
            break;
        }
        PrtMsg( ERR | LOC | EXPECTING_M, M_SCOLON );
        LexMaybeFree( t );
    }
    if( t == EOL || t == STRM_END ) {
        ClearSuffixes();
        return;
    }
    any = FALSE;
    for( ;; ) {
        t = LexToken( LEX_PARSER );
        if( t == EOL || t == STRM_END ) {
            break;
        }
        if( t == TOK_SUF ) {
            if( !SufExists( CurAttr.ptr ) ) {
                AddSuffix( CurAttr.ptr );   /* we lose CurAttr.ptr */
            /*
             * if microsoft option is set we put it in anyway don't
             * care whether or not it exists
             */
            } else if( Glob.microsoft | Glob.unix ) {
                FreeSafe( CurAttr.ptr );
            } else {
                PrtMsg( ERR | LOC | REDEF_OF_SUFFIX, CurAttr.ptr );
                FreeSafe( CurAttr.ptr );
            }
            any = TRUE;
        } else {
            ignoring( t, TRUE );
        }
    }
    if( !any ) {
        ClearSuffixes();
    }
}


STATIC void parseDotName( TOKEN_T t, TLIST **btlist )
/****************************************************
 * parse any of the dotnames
 */
{
    if( IsDotWithCmds( CurAttr.num ) ) {
            parseTargDep( TOK_DOTNAME, btlist );
            return;
    }
    if( CurAttr.num == DOT_EXTENSIONS || CurAttr.num == DOT_SUFFIXES ) {
        parseExtensions();
        return;
    }
    for( ;; ) {
        switch( CurAttr.num ) {
        case DOT_BLOCK:         Glob.block = TRUE;              break;
        case DOT_CONTINUE:      Glob.cont = TRUE;               break;
        case DOT_ERASE:         Glob.erase = TRUE;              break;
        case DOT_FUZZY:         Glob.fuzzy = TRUE;              break;
        case DOT_IGNORE:        Glob.ignore = TRUE;             break;
        case DOT_HOLD:          Glob.hold = TRUE;               break;
        case DOT_NOCHECK:       Glob.nocheck = TRUE;            break;
        case DOT_OPTIMIZE:      Glob.optimize = TRUE;           break;
        case DOT_SILENT:        Glob.silent = TRUE;             break;
        case DOT_RCS_MAKE:      Glob.rcs_make = TRUE;           break;
        default:
            ignoring( TOK_DOTNAME, TRUE );
            break;
        }
        for( ;; ) {
            t = LexToken( LEX_PARSER );
            if( t == EOL || t == STRM_END ) {
                return;
            }
            if( t != TOK_DOTNAME ) {
                ignoring( t, TRUE );
            }
        }
    }
}


/* links the clist to the sufsuf target */
STATIC void linkClistSufsuf( const TARGET *curtarg, const CLIST *clist,
    const char *cur_target_path, const char *cur_depend_path )
/*********************************************************************/
{
    DEPEND  *walk;
    SLIST   *slist;

    assert( curtarg != NULL && curtarg->depend != NULL );

    walk = curtarg->depend;
    while( walk->next != NULL ) {
        walk = walk->next;
    }


    /*
     * if both the dep_path and the target path is null
     * then we are doing the trivial case of just replacing the
     * current clist if not we have to create an SLIST that contains
     * both the new targ_path and  new dep_path
     */
    if( cur_depend_path == NULL && cur_target_path == NULL ) {
        if( walk->clist != NULL ) {
            FreeSafe( walk->clist );
        }

        walk->clist = DupCList( clist );

    } else {
        if( walk->slist == NULL ) {
            walk->slist = NewSList ();
            walk->slist->targ_path = StrDupSafe( cur_target_path );
            walk->slist->dep_path  = StrDupSafe( cur_depend_path );
            walk->slist->clist     = DupCList ( clist );
            walk->slist->next      = NULL;
        } else {
            slist = NewSList ();
            slist->targ_path = StrDupSafe( cur_target_path );
            slist->dep_path  = StrDupSafe( cur_depend_path );
            slist->clist     = DupCList ( clist );
            slist->next      = walk->slist;
            walk->slist      = slist;
        }
    }
}

STATIC void linkCList( TLIST *btlist, CLIST *bclist, const char *cur_target_path,
    const char *cur_depend_path)
/********************************************************************************
 * attach bclist to each target in btlist
 */
{
    CLIST               *clisthead;
    CLIST               *clistcur;
    TLIST const         *tlist;
    DEPEND * const      *walk;
    CLIST               **walkClist;
    TARGET const        *curtarg;

    assert( btlist != NULL );

    /*
     * Remember that cmds were stacked in reverse order.  Now we simply
     * do a pull, and pop onto another stack to reverse them.
     */
    clisthead = NULL;

    while( bclist != NULL ) {
        clistcur = bclist;
        bclist = bclist->next;

        clistcur->next = clisthead;
        clisthead = clistcur;
    }

    /*
     * Attach cmds to the targets.  Assumes that for each of the targets,
     * the last depend in the list target->depend is the owner of this clist.
     */
    tlist = btlist;
    while( tlist != NULL ) {
        curtarg = tlist->target;
        tlist = tlist->next;            /* advance to next in tlist */

        assert( curtarg->depend != NULL );  /* linkDepend() assures this */
        walk = &curtarg->depend;

        if( curtarg->scolon ) {
            /* check if it's an scolon, and attempt more than one clist */
            if( clisthead != NULL && (*walk)->clist != NULL ) {
                if( Glob.microsoft | Glob.unix ) {
                    PrtMsg( WRN | LOC | MORE_THAN_ONE_CLIST, curtarg->node.name );
                } else {
                    PrtMsg( ERR | LOC | MORE_THAN_ONE_CLIST, curtarg->node.name );
                }
            } else if( clisthead != NULL ) {
                /* this is the first clist for this scolon */
                (*walk)->clist = clisthead;
                clisthead = DupCList( clisthead );
            }
        } else if( curtarg->sufsuf ) {
            /* special processing is needed for sufsuf */
            linkClistSufsuf( curtarg, clisthead, cur_target_path,
                cur_depend_path );
        } else {
            /* we walk the dependents to find the last one */
            while( (*walk)->next != NULL ) {
                walk = &(*walk)->next;
            }

            if( curtarg->before_after ) {
                walkClist = &(*walk)->clist;
                /* if the clist being appended is null then clear the list */
                /* just like .SUFFIXES                                     */
                if( clisthead != NULL ) {
                    // for .AFTER and .BEFORE we need to add to the end of the
                    // clist the new clists
                    while( (*walkClist) != NULL ) {
                        walkClist = &(*walkClist)->next;
                    }
                    *walkClist = clisthead;
                } else {
                    FreeCList( *walkClist );
                    *walkClist = NULL;
                }
            } else {
                (*walk)->clist = clisthead;
            }
            clisthead = DupCList( clisthead );
        }
    }

    FreeCList( clisthead ); /* we always make an extra copy */
    FreeTList( btlist );    /* free the tlist we were passed */
}


STATIC void parseSuf( void )
/***************************
 * parse {TOK_SUF}+ : TOK_PATH
 *   or  {TOK_SUF}+ :
 *   or  {TOK_SUF}+
 */
{
    TOKEN_T t;
    char    *path;
    NODE    *head;
    NODE    *cur;

    head = NULL;

    t = TOK_SUF;

    for( ;; ) {
        if( t == EOL || t == STRM_END || t == TOK_SCOLON ) {
            break;
        }
        if( t == TOK_SUF ) {
            if( !SufExists( CurAttr.ptr ) ) {
                PrtMsg( ERR | LOC | SUFFIX_DOESNT_EXIST, CurAttr.ptr );
                FreeSafe( CurAttr.ptr );
            } else {
                cur = MallocSafe( sizeof( *cur ) );
                cur->name = CurAttr.ptr;
                cur->next = head;
                head = cur;
            }
        } else {
            ignoring( t, TRUE );
        }
        t = LexToken( LEX_PARSER );
    }

                /* note that we use mode LEX_PATH here NOT LEX_PARSER! */
    if( t == STRM_END || t == EOL ) {
        path = NULL;
    } else {
        t = LexToken( LEX_PATH );
        assert( t == TOK_PATH || t == STRM_END || t == EOL );
        if( t == STRM_END || t == EOL ) {
            path = NULL;
        } else {
            path = CurAttr.ptr;
            t = LexToken( LEX_PATH ); /* prefetch next token */
        }
    }

    for( ;; ) {
        if( t == STRM_END || t == EOL ) {
            break;
        }
        ignoring( t, TRUE );
        t = LexToken( LEX_PATH );
    }

    while( head != NULL ) {
        cur = head;
        head = head->next;
        SetSufPath( cur->name, path );
        FreeSafe( cur->name );
        FreeSafe( cur );
    }
    if( path != NULL ) {
        FreeSafe( path );               /* from CurAttr.ptr */
    }
}


STATIC char *getFileName( const char *intext, size_t *offset )
/*************************************************************
 * get the filename from the given text
 * if there is no file name then get the text body
 * offset - how long after the << is the file name
 * this only gets the explicit fileName
 * for the fileNames that need to be generated
 * we do it later but still we create an FLIST for
 * the temp file anyway
 */
{
    VECSTR      tempStr;
    char        *ret;
    BOOLEAN     doubleQuote;    //are there double quotes

    assert( intext != NULL && offset != NULL );

    *offset     = 0;
    doubleQuote = FALSE;

    if( intext[*offset] == DOUBLEQUOTE ) {
        doubleQuote = TRUE;
        *offset     = 1;
    }
    for( ;; ) {
        if( intext[*offset] == NULLCHAR ) {
            break;
        } else if( (isws( intext[*offset] )        ||
                    intext[*offset]== LESSTHAN     ||
                    intext[*offset]== GREATERTHAN) &&

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?