mtarget.c

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

C
860
字号
{
    FLIST   *cur;

    while( flist != NULL ) {
        cur        = flist;
        flist      = flist->next;
        cur->next  = freeFLists;
        FreeSafe( cur->body );
        FreeSafe( cur->fileName );
        freeFLists = cur;
    }
}


void FreeCList( CLIST *clist )
/****************************/
{
    CLIST   *cur;

    while( clist != NULL ) {
        cur = clist;
        clist = clist->next;
        FreeSafe( cur->text );
        FreeFList( cur->inlineHead );
        cur->next = freeCLists;
        freeCLists = cur;
    }
}


void FreeDepend( DEPEND *dep )
/*****************************
 * frees tlist, and clist
 */
{
    DEPEND  *cur;

    while( dep != NULL ) {
        cur = dep;
        dep = dep->next;
        FreeTList( cur->targs );
        FreeCList( cur->clist );
        FreeSList( cur->slist );
        cur->next = freeDepends;
        freeDepends = cur;
    }
}


STATIC void freeTarget( TARGET *targ )
/************************************/
{
    assert( targ != NULL );

    FreeDepend( targ->depend );
    FreeSafe( targ->node.name );
    FreeSafe( targ );
}


void KillTarget( const char *name )
/**********************************
 * name is not FreeTarget because one must be careful when using this
 * function that the target is not a member of some TLIST
 */
{
    void    *mykill;

    mykill = RemHashNode( targTab, name, CASESENSITIVE );
    if( mykill != NULL ) {
        freeTarget( mykill );
    }
}


STATIC TARGET *findOrNewTarget( const char *tname, BOOLEAN mentioned )
/*********************************************************************
 * Return a pointer to a target with name name.  Create target if necessary.
 */
{
    char    name[_MAX_PATH];
    TARGET  *targ;

    targ = FindTarget( FixName( strcpy( name, tname ) ) );
    if( targ == NULL ) {
        targ = NewTarget( name );
        if( name[0] == DOT && isextc( name[1] ) ) {
            targ->special = TRUE;
            if( strcmpi( name + 1, BEFORE_S ) == 0 ||
                strcmpi( name + 1, AFTER_S )  == 0 ) {
                targ->before_after = TRUE;
            }
            if( strcmpi( name + 1, DEFAULT_S ) == 0 ) {
                targ->dot_default = TRUE;
            }
        }
    }

    /* mentioned in a makefile */
    targ->mentioned = targ->mentioned || mentioned;

    return( targ );
}


RET_T WildTList( TLIST **list, const char *base, BOOLEAN mentioned,
                 BOOLEAN expandWildCardPath)
/******************************************************************
 * Build a TLIST using base as a wildcarded path.  Uses DoWildCard().
 * Pushes targets onto list.
 */
{
    TARGET      *targ;
    TLIST       *new;
    TLIST       *temp;
    TLIST       *temp2;
    TLIST       *current;
    TLIST       *endOfList;
    const char  *file;

    if( expandWildCardPath ) {
        /* we want to expand the wildCard path */
        file = DoWildCard( base );
        assert( file != NULL );
        if( strpbrk( file, WILD_METAS ) != NULL ) {
            PrtMsg( ERR | LOC | NO_EXISTING_FILE_MATCH, file );
            return( RET_ERROR );
        }
    } else {
        file = base;
    }

    temp = NULL;
    while( file != NULL ) {
        targ = findOrNewTarget( file, mentioned );
        new  = NewTList();
        new->target = targ;
        new->next   = temp;
        temp = new;
        file = DoWildCard( NULL );
    }

    /* reverse the target list  */
    assert( temp );
    current = temp;
    temp    = temp->next;
    current->next = NULL;

    while( temp != NULL ) {
        temp2      = temp->next;
        temp->next = current;
        current    = temp;
        temp       = temp2;
    }
    if( *list == NULL ) {
        *list = current;
    } else {
        endOfList = *list;
        while( endOfList->next != NULL ) {
            endOfList = endOfList->next;
        }
        endOfList->next = current;
    }
    return( RET_SUCCESS );
}


void PrintCList( const CLIST *clist )
/***********************************/
{
    for( ; clist != NULL; clist = clist->next ) {
        PrtMsg( INF | NEOL | JUST_A_TAB );
        PrtMsg( INF | PRNTSTR, clist->text );
    }
}


void PrintTargFlags( const TARGET *targ )
/***************************************/
{
    if( targ->attr.prec ) {
        PrtMsg( INF | NEOL | PTARG_DOTNAME, DotNames[DOT_PRECIOUS] );
    }
    if( targ->attr.symb ) {
        PrtMsg( INF | NEOL | PTARG_DOTNAME, DotNames[DOT_SYMBOLIC] );
    }
    if( targ->attr.multi ) {
        PrtMsg( INF | NEOL | PTARG_DOTNAME, DotNames[DOT_MULTIPLE] );
    }
    if( targ->attr.explicit ) {
        PrtMsg( INF | NEOL | PTARG_DOTNAME, DotNames[DOT_EXPLICIT] );
    }
    if( targ->attr.always ) {
        PrtMsg( INF | NEOL | PTARG_DOTNAME, DotNames[DOT_ALWAYS] );
    }
    if( targ->attr.auto_dep ) {
        PrtMsg( INF | NEOL | PTARG_DOTNAME, DotNames[DOT_AUTO_DEPEND] );
    }
}


STATIC BOOLEAN printTarg( void *node, void *ptr )
/***********************************************/
{
    TARGET const * const    targ = node;
    DEPEND const            *curdep;
    TLIST const             *curtlist;

    (void)ptr; // Unused
    if( targ->special ) {
        return( FALSE );             /* don't print special targets */
    } else {
        if( !targ->scolon && targ->depend == NULL ) {
            PrtMsg( INF | NEOL | PTARG_NAME, targ->node.name );
        } else {
            PrtMsg( INF | NEOL | PTARG_IS_TYPE_M, targ->node.name,
                targ->scolon ? M_SCOLON : M_DCOLON );
        }
        PrintTargFlags( targ );
        PrtMsg( INF | NEWLINE );
    }
    if( targ->depend ) {
        curdep = targ->depend;
        while( curdep != NULL ) {
            if( curdep->targs != NULL ) {
                PrtMsg( INF | PTARG_DEPENDS_ON );
                for( curtlist = curdep->targs; curtlist != NULL;
                    curtlist = curtlist->next ) {
                    PrtMsg( INF | PTARG_TAB_TAB_ENV,
                        curtlist->target->node.name );
                }
            }
            if( curdep->clist ) {
                PrtMsg( INF | PTARG_WOULD_EXECUTE_CMDS );
                PrintCList( curdep->clist );
            }
            curdep = curdep->next;
            if( curdep != NULL ) {
                PrtMsg( INF | NEWLINE );
            }
        }
    } else {
        PrtMsg( INF | PTARG_NO_DEPENDENTS );
    }
    PrtMsg( INF | NEWLINE );

    return( FALSE );
}


STATIC void printDot( enum DotNames dot )
/***************************************/
{
    char                buf[MAX_DOT_NAME];
    CLIST const         *cmds;

    cmds = DotCList( dot );
    if( cmds == NULL ) {
        return;
    }
    FmtStr( buf, ".%s", DotNames[dot] );
    PrtMsg( INF | PDOT_CMDS, buf );
    PrintCList( cmds );
    PrtMsg( INF | NEWLINE );
}


void PrintTargets( void )
/***********************/
{
    enum DotNames   i;

    for( i = DOT_MIN; i < DOT_MAX; ++i ) {
        if( IsDotWithCmds( i ) ) {
            printDot( i );
        }
    }

    WalkHashTab( targTab, printTarg, NULL );
}


void TargInitAttr( TATTR *attr )
/******************************/
{
    attr->prec       = FALSE;
    attr->symb       = FALSE;
    attr->multi      = FALSE;
    attr->explicit   = FALSE;
    attr->always     = FALSE;
    attr->auto_dep   = FALSE;
    attr->existsonly = FALSE;
    attr->recheck    = FALSE;
}


void TargOrAttr( TARGET *targ, TATTR attr )
/*****************************************/
{
    targ->attr.prec       |= attr.prec;
    targ->attr.symb       |= attr.symb;
    targ->attr.multi      |= attr.multi;
    targ->attr.explicit   |= attr.explicit;
    targ->attr.always     |= attr.always;
    targ->attr.auto_dep   |= attr.auto_dep;
    targ->attr.existsonly |= attr.existsonly;
    targ->attr.recheck    |= attr.recheck;
}


STATIC BOOLEAN resetEx( void *targ, void *ptr )
/*********************************************/
{
    (void)ptr; // Unused
    ((TARGET *)targ)->executed = TRUE;
    return( FALSE );
}


void ResetExecuted( void )
/************************/
{
    WalkHashTab( targTab, resetEx, NULL );
}


#if defined( USE_SCARCE ) || !defined( NDEBUG )
STATIC RET_T cleanupLeftovers( void )
/***********************************/
{
    DEPEND      *dep;
    CLIST       *c;
    SLIST       *s;
    TLIST       *t;
    FLIST       *f;
    NKLIST      *nk;

    if( freeDepends != NULL ) {
        do {
            dep = freeDepends;
            freeDepends = dep->next;
            FreeSafe( dep );
        } while( freeDepends != NULL );
        return( RET_SUCCESS );
    }
    if( freeTLists != NULL ) {
        do {
            t = freeTLists;
            freeTLists = t->next;
            FreeSafe( t );
        } while( freeTLists != NULL );
        return( RET_SUCCESS );
    }
    if( freeNKLists != NULL ) {
        do {
            nk = freeNKLists;
            freeNKLists = nk->next;
            FreeSafe( nk );
        } while( freeNKLists != NULL );
        return( RET_SUCCESS );
    }
    if( freeSLists != NULL ) {
        do {
            s = freeSLists;
            freeSLists = s->next;
            FreeSafe( s );
        } while( freeSLists != NULL );
        return( RET_SUCCESS );
    }
    if( freeFLists != NULL ) {
        do {
            f = freeFLists;
            freeFLists = f->next;
            FreeSafe( f );
        } while( freeFLists != NULL );
        return( RET_SUCCESS );
    }
    if( freeCLists != NULL ) {
        do {
            c = freeCLists;
            freeCLists = c->next;
            FreeSafe( c );
        } while( freeCLists != NULL );
        return( RET_SUCCESS );
    }
    return( RET_ERROR );
}
#endif


void TargetInit( void )
/*********************/
{
    targTab     = NULL;
    freeDepends = NULL;
    freeTLists  = NULL;
    freeCLists  = NULL;
    freeFLists  = NULL;
    freeNKLists = NULL;
    freeSLists  = NULL;
    targTab = NewHashTab( HASH_PRIME );
#ifdef USE_SCARCE
    IfMemScarce( cleanupLeftovers );
#endif
}


#ifndef NDEBUG
STATIC BOOLEAN walkFree( void *targ, void *ptr )
/**********************************************/
{
    (void)ptr; // Unused
    freeTarget( (TARGET*)targ );
    return( FALSE );
}
#endif


void TargetFini( void )
/*********************/
{
#ifndef NDEBUG
    WalkHashTab( targTab, walkFree, NULL );
    FreeHashTab( targTab );
    targTab = NULL;
    while( cleanupLeftovers() != RET_ERROR )
        ;
#endif
}

⌨️ 快捷键说明

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