mupdate.c

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

C
1,176
字号
       } else {
           WildTList( &temp, tlist->target->node.name, TRUE, TRUE );
       }
       tlist = tlist->next;
       if( outTList != NULL ) {
           currentEnd->next = temp;
       } else {
           outTList = temp;
       }

       if( temp != NULL ) {
           currentEnd = temp;
           /* find the current end */
           while( currentEnd->next != NULL ) {
               currentEnd = currentEnd -> next;
           }
       }
   }
   FreeTList( depend->targs );
   depend->targs = outTList;
}


STATIC RET_T resolve( TARGET *targ, DEPEND *depend )
/***************************************************
 * If there are no dependents, then perform the associated commands, if req'd.
 * If there are dependents: update them all; compare the date of each dep
 * to the targ; if any of the deps had an error previously, abort; if targ
 * is out of date then perform the clist (or attempt to imply).
 */
{
    TLIST       *tlist;
    TARGET      *curtarg;
    RET_T       tmp;
    BOOLEAN     outofdate;
    BOOLEAN     exec_cmds;
    time_t      max_time;

    max_time = OLDEST_DATE;

    ExpandWildCards( targ, depend );

    if( depend->targs == NULL ) {
        /* 10-oct-90 AFS make the target if it doesn't exist or it's symbolic */
        /* 30-oct-90 AFS a "::" target with no dependents must be made */
        exec_cmds = FALSE;
        if( !targ->scolon || !targ->existing ) {
            exec_cmds = TRUE;
        }
        if( targ->attr.symb || targ->attr.always ) {
            exec_cmds = TRUE;
        }
        /* 11-sep-92 AFS if all targets must be made, so should this one */
        if( Glob.all ) {
            exec_cmds = TRUE;
        }
        if( !exec_cmds && USE_AUTO_DEP( targ ) ) {
            if( autoOutOfDate( targ, &max_time ) ) {
                exec_cmds = TRUE;
            }
        }
        if( exec_cmds ) {
            return( perform( targ, depend, max_time ) );
        }
        return( RET_SUCCESS );
    }

    MakeList( depend->targs );

    getDate( targ );

    outofdate = FALSE;
    tlist = depend->targs;
    while( tlist != NULL ) {    /* check if out of date with deps */
        curtarg = tlist->target;
        tlist = tlist->next;    /* advance the tlist */

        if( isOutOfDate( targ, curtarg, &outofdate ) == RET_ERROR ) {
            return( RET_ERROR );
        }
    }
    if( targ->attr.always ) {
        outofdate = TRUE;
    }
    if( !outofdate && USE_AUTO_DEP( targ ) ) {
        if( autoOutOfDate( targ, &max_time ) ) {
            outofdate = TRUE;
        }
    }
    if( outofdate ) {
        /* if we get this far, then none of the deps had a previous error,
         * and at least one of the deps is newer than targ, so we perform
         */
        if( depend->clist != NULL ) {
            return( perform( targ, depend, max_time ) );
        } else {
            tmp = tryImply( targ, TRUE );
            if( tmp == RET_WARN ) {
                /* couldn't imply - will do DEFAULT cmds */
                return( perform( targ, depend, max_time ) );
            }
            return( tmp );
        }
    }

    return( RET_SUCCESS );
}


extern RET_T Update( TARGET *targ )
/*********************************/
{
    DEPEND      *curdep;
    UINT32      startcount;
    BOOLEAN     target_exists;

    CheckForBreak();
    if( targ->error ) {
        return( RET_ERROR );
    }
    if( targ->updated ) {
        return( RET_SUCCESS );
    }
    if( targ->special ) {
        PrtMsg( FTL | ATTEMPT_MAKE_SPECIAL, targ->node.name );
    }
    if( targ->busy ) {
        PrtMsg( FTL | RECURSIVE_DEFINITION, targ->node.name );
    }
    PrtMsg( DBG|INF|NEOL| UPDATING_TARGET, targ->node.name );
    targ->busy = TRUE;
    targExists( targ );     /* find file using sufpath */
    startcount = cListCount;

    if( targ->depend == NULL ||
        (targ->depend->clist == NULL && targ->depend->targs == NULL) ) {
                    /* has no depend/explicit rules */
        PrtMsg( DBG | INF | M_EXPLICIT_RULE, M_NO );
        if( tryImply( targ, FALSE ) == RET_ERROR ) {
            targ->busy = FALSE;
            targ->error = TRUE;
            return( RET_ERROR );
        }
    } else if( targ->scolon == FALSE ) {    /* double colon */
        PrtMsg( DBG | INF | M_EXPLICIT_RULE, M_DCOLON );
        curdep = targ->depend;
        while( curdep != NULL ) {
            if( resolve( targ, curdep ) != RET_SUCCESS ) {
                targ->busy = FALSE;
                targ->error = TRUE;
                return( RET_ERROR );
            }
            curdep = curdep->next;
        }
        if( !Glob.microsoft ) {
            if( tryImply( targ, FALSE ) == RET_ERROR ) {
                targ->busy = FALSE;
                targ->error = TRUE;
                return( RET_ERROR );
            }
        }
    } else {
        PrtMsg( DBG | INF | M_EXPLICIT_RULE, M_SCOLON );
        if( resolve( targ, targ->depend ) != RET_SUCCESS ) {
            targ->busy = FALSE;
            targ->error = TRUE;
            return( RET_ERROR );
        }
    }

    if( (targ->attr.symb || Glob.noexec || Glob.query)
        && startcount != cListCount ) {
        targ->existing = TRUE;
        targ->touched = TRUE;
        targ->executed = FALSE;
        targ->date = YOUNGEST_DATE;
    }

    target_exists = targExists( targ );                         /* 18-nov-91 */
    if( target_exists || targ->attr.symb || Glob.ignore ) {
        // Target exists or it is symbolic or we're ignoring errors,
        // therefore everyone's happy and we can charge forward
        PrtMsg( DBG | INF | TARGET_IS_UPDATED, targ->node.name );
    } else {
        // Target doesn't exist, we may be in trouble
        if( targ->cmds_done && Glob.nocheck ) {
            // Target doesn't exist even though we processed some commands,
            // but we're not checking existence of files. Consider it uptodate.
            targ->existing = TRUE;
            PrtMsg( DBG | INF | TARGET_FORCED_UPTODATE, targ->node.name );
        } else if( Glob.cont ) {
            // Target doesn't exist but we're forcibly continuing. Report
            // nonfatal error.
            targ->error = TRUE;
            targ->busy = FALSE;
            PrtMsg( ERR | UNABLE_TO_MAKE, targ->node.name );
            return( RET_ERROR );
        } else {
            // Target doesn't exist and we have no clue how to make it. Bomb out.
            PrtMsg( FTL | UNABLE_TO_MAKE, targ->node.name );
            return( RET_ERROR );
        }
    }

    targ->updated = targ->attr.multi == FALSE;
    targ->busy = FALSE;
    targ->error = FALSE;
    return( RET_SUCCESS );
}


static struct exStack exGetCurVars( void )
/*****************************************
 * Go up through the exStack, and return the most local non-null
 * target and dep pointers; or NULL if none exist.
 */
{
    int             walk;
    int             top;
    struct exStack  buf;
    DEPEND          *curdep;
    DEPEND          *curimpDep;
    TARGET          *curtarg;

    buf.dep = NULL;
    buf.targ = NULL;
    buf.impDep = NULL;
    curtarg = NULL;
    curdep = NULL;
    top = exStackP - 1;
    for( walk = top; walk >= 0; --walk ) {
        if( buf.dep == NULL ) {
            curdep = exStack[walk].dep;
            if( curdep != NULL && curdep->targs != NULL ) {
                buf.dep = curdep;
            }
        }
        if( buf.impDep == NULL ) {
            curimpDep = exStack[walk].impDep;
            if( curimpDep != NULL && curimpDep->targs != NULL ) {
                buf.impDep = curimpDep;
            }
        }
        if( buf.targ == NULL ) {
            curtarg = exStack[walk].targ;
            if( curtarg != NULL && ! curtarg->attr.symb ) {
                /* we want non-NULL and non-SYMBOLIC! (30-jan-92 AFS) */
                buf.targ = curtarg;
            }
        }
    }
    if( buf.targ == NULL ) {
        /* no non-symbolic targets? return current symbolic target */
        if( top >= 0 ) {
            buf.targ = exStack[top].targ;
        }
    }

    return( buf );
}


extern char *GetCurDeps( BOOLEAN younger, BOOLEAN isMacInf )
/**********************************************************/
{
    TLIST           *walk;
    VECSTR          vec;
    BOOLEAN         written;
    TARGET          *targ;
    struct exStack  cur;
    const char      *formattedString;
    char            *ret;

    cur = exGetCurVars();

    // This is for Glob.microsoft and Glob.posix
    // $< and $** are different
    if( isMacInf ) {
        cur.dep = cur.impDep;
    } else {
        if( cur.dep == NULL ) {
            cur.dep = cur.impDep;
        }
    }

    if( (younger && cur.targ == NULL) ||
        cur.dep == NULL || cur.dep->targs == NULL ) {
        return( StrDupSafe( "" ) );
    }

    vec = StartVec();
    written = FALSE;

    walk = cur.dep->targs;
    while( walk != NULL ) {
        targ = walk->target;
        if( !younger || dateCmp( cur.targ->date, targ->date ) < 0 ) {
            if( written ) {
                WriteVec( vec, " " );
            }
            formattedString = procPath( targ->node.name );
            WriteVec( vec, formattedString );
            written = TRUE;
        }
        walk = walk->next;
    }
    ret = FinishVec( vec );

    return( ret );
}


extern const char *GetCurTarg( void )
/***********************************/
{
    struct exStack  cur;

    cur = exGetCurVars();
    if( cur.targ == NULL ) {
        return( NULL );
    }
    return( cur.targ->node.name );
}


extern const char *GetFirstDep( void )
/************************************/
{
    struct exStack  cur;

    cur = exGetCurVars();
    if( cur.impDep != NULL ) {
        cur.dep = cur.impDep;
    }
    if( cur.dep != NULL && cur.dep->targs != NULL ) {
        return( cur.dep->targs->target->node.name );
    }
    return( NULL );
}


extern const char *GetLastDep( void )
/***********************************/
{
    struct exStack  cur;
    TLIST           *walk;

    cur = exGetCurVars();
    if( cur.impDep != NULL ) {
        cur.dep = cur.impDep;
    }
    if( cur.dep != NULL && cur.dep->targs != NULL ) {
        walk = cur.dep->targs;
        while( walk->next != NULL ) {
            walk = walk->next;
        }
        return( walk->target->node.name );
    }
    return( NULL );
}


extern void UpdateInit( void )
/****************************/
{
    /* according to ANSI standard... this should be true */

    assert(     doneBefore == FALSE
            &&  cListCount == 0ul
            &&  exStackP == 0
    );
    DoingUpdate = TRUE;
}


extern void UpdateFini( void )
/****************************/
{
    CLIST   *after;

    assert( exStackP == 0 );

    after = DotCList( DOT_AFTER );
    if( doneBefore && after != NULL ) {
        ++cListCount;
        if( ExecCList( DotCList( DOT_AFTER ) ) != RET_SUCCESS ) {
            PrtMsg( ERR | S_COMMAND_RET_BAD, DotNames[DOT_AFTER] );
        }
    }
    DoingUpdate = FALSE;
}

⌨️ 快捷键说明

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