mupdate.c

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

C
1,176
字号
    TARGET  *targ;

    ret = RET_SUCCESS;
    while( tlist != NULL ) {
        targ = tlist->target;
        tlist = tlist->next;
        if( targ->mentioned == FALSE ) {
            PrtMsg( WRN | TARGET_NOT_MENTIONED, targ->node.name );
            targ->mentioned = TRUE;
        }   /* warning suggested by John */
        if( Update( targ ) != RET_SUCCESS ) {
            ret = RET_ERROR;
        }
    }
    return( ret );
}


STATIC void implyDebugInfo( TARGET *targ, UINT32 startcount )
/***********************************************************/
{
    enum MsgClass   msg;

    if( Glob.debug ) {
        if( targExists( targ ) ) {
            if( startcount != cListCount ) {
                msg = M_HAD_TO_BE_UPDATED;
            } else {
                msg = M_IS_CLEAR_WITH;
            }
        } else {
            msg = M_COULD_NOT_BE_IMPLIED;
        }
        PrtMsg( DBG | INF | IMP_ENV_M, targ->node.name, msg );
    }
}

STATIC BOOLEAN autoDepCompare( time_t targ_time, time_t auto_time )
/*****************************************************************/
{
    if( dateCmp( targ_time, auto_time ) < 0 ) {
        return( TRUE );
    }
    return( FALSE );
}


STATIC BOOLEAN checkForAutoDeps( TARGET *targ, char *name, time_t *max_time )
/***************************************************************************/
{
    return( AutoDepCheck( name, targ->date, autoDepCompare, max_time ) );
}


STATIC BOOLEAN autoOutOfDate( TARGET *targ, time_t *max_time )
/************************************************************/
{
    char    buffer[_MAX_PATH];

    if( TrySufPath( buffer, targ->node.name, NULL, FALSE ) != RET_SUCCESS ) {
        return( FALSE );
    }
    return( checkForAutoDeps( targ, buffer, max_time ) );
}


STATIC RET_T isOutOfDate( TARGET *targ, TARGET *deptarg, BOOLEAN *outofdate )
/****************************************************************************
 * Checks if the current target is out of date
 */
{
    getDate( targ );
    if( targ->existing && targ->attr.existsonly ) {
        return( RET_SUCCESS );
    }
    getDate( deptarg );
    if( targ->existing && deptarg->existing && deptarg->attr.existsonly ) {
        return( RET_SUCCESS );
    }
    if( dateCmp( targ->date, deptarg->date ) < 0 ) {
        *outofdate = TRUE;
        if( Glob.show_offenders ) {
            PrtMsg( INF | WILL_BE_BUILT_BECAUSE_OF,
                targ->node.name, deptarg->node.name);
        }
    }
    if( deptarg->error ) {
       /* one of the targets had an error while being updated
        * abort now
        */
        return( RET_ERROR );
    }
    if( (!deptarg->attr.recheck && deptarg->cmds_done) || deptarg->backdated ) {
        *outofdate = TRUE;
    }
    return( RET_SUCCESS );
}


STATIC RET_T implyMaybePerform( TARGET *targ, TARGET *imptarg,
    TARGET *cretarg, BOOLEAN must, SLIST *slistCmd )
/*************************************************************
 * perform cmds if targ is older than imptarg || must
 *
 * targ     is the target to be updated
 * imptarg  is the dependent for target (ie: "targ : imptarg" )
 * cretarg  is the implicit rule to use
 * must     must we do it?
 */
{
    RET_T   ret;
    DEPEND  *newdep;
    TLIST   *newtlist;
    time_t  max_time;

    max_time = OLDEST_DATE;
    if( imptarg->error ) {
        /* there was an error making imptarg before, so just abort */
        return( RET_ERROR );
    }
    if( cretarg->attr.always ) {
        must = TRUE;
    }

    if( isOutOfDate( targ, imptarg, &must ) == RET_ERROR ) {
        return( RET_ERROR );
    }

    if( !must && USE_AUTO_DEP( cretarg ) ) {
        if( autoOutOfDate( targ, &max_time ) ) {
            must = TRUE;
        }
    }

    if( must ) {
        assert( cretarg->depend != NULL );

        /* construct a depend for perform */

        newdep           = DupDepend( cretarg->depend );
        newtlist         = NewTList();
        newtlist->target = imptarg;
        newdep->targs    = newtlist;
        newdep->slistCmd = slistCmd;

        /* handle implied attributes (.symb/.prec/.multi) */
        TargOrAttr( targ, cretarg->attr );

        ret = perform( targ, newdep, max_time );
        FreeDepend( newdep );           /* don't need depend any more */

        if( ret != RET_SUCCESS ) {
            return( RET_ERROR );
        }

        if( Glob.noexec || Glob.query ) {               /* 29-oct-90 */
            targ->executed = TRUE;
            targ->touched = TRUE;
        }
    }

    return( RET_SUCCESS );
}


STATIC RET_T imply( TARGET *targ, const char *drive, const char *dir,
    const char *fname, const char *ext, BOOLEAN must )
/********************************************************************
 * targ     is the target to be implied
 * drive    is the drive of the target
 * dir      is the path of the target
 * fname    is the portion of targ's name without the extension
 * ext      is the extension of targ's name
 * must     must we make this target?
 *
 * RET_SUCCESS - performed cmds,
 * RET_WARN unable to imply,
 * RET_ERROR - perform failed
 */
{
    SUFFIX      *srcsuf;
    CREATOR     *cur;
    SUFFIX      *cursuf;
    TARGET      *imptarg;
    RET_T       ret;
    BOOLEAN     newtarg;
    UINT32      startcount;
    char        *buf;
    SLIST       *curslist;
    SLIST       *slistCmd;  // Slist chosen for sufsuf
    SLIST       *slistDef;  // Slist that has dependent path = ""
    SLIST       *slistEmptyTargDepPath;
    BOOLEAN     UseDefaultSList;
    int         slistCount;

    srcsuf = FindSuffix( ext );
    if( srcsuf == NULL || srcsuf->creator == NULL ) {
        PrtMsg( DBG | INF | IMP_ENV_M, targ->node.name, M_HAS_NO_IMPLICIT );
        return( RET_WARN );
    }
    PrtMsg( DBG | INF | IMP_ENV_M, targ->node.name, M_CHECKING_IMPLICIT );
    startcount = cListCount;

    for( cur = srcsuf->creator; cur != NULL; cur = cur->next ) {
        cursuf = cur->suffix;

        /* allocate a buffer */
        buf = MallocSafe( _MAX_PATH );
        slistCmd = NULL;
        slistDef = NULL;
        slistEmptyTargDepPath = NULL;

        assert( cur->cretarg         != NULL );
        assert( cur->cretarg->depend != NULL );
        curslist = cur->cretarg->depend->slist;

        ret = RET_ERROR;

        UseDefaultSList = TRUE;
        slistCount = 0;
        /* find path in SLIST */
        while( curslist != NULL && ret != RET_SUCCESS ) {
            _makepath( buf, drive, dir, NULL, NULL );
            /*
             * note the path of the current target must match the
             * path as specified in the slist
             */
            if( strcmpi( buf, curslist->targ_path ) == 0 ) {
                /* build filename for implied target */
                _makepath( buf, NULL, curslist->dep_path,
                           fname, cursuf->node.name );
                /* try to find this file on path or in targets */
                ret = TrySufPath( buf, buf, &imptarg, FALSE );
                if( ret == RET_SUCCESS ) {
                    slistCmd = curslist;
                /* later on we need to check if implied target does not */
                /* exist we need to create it on the first directory we */
                /* see on the SLIST since                               */
                /* the first on the list is the one that was defined    */
                /* last in the makefile                                 */
                } else if( slistDef == NULL ) {
                    slistDef = curslist;
                }
            }
            if( curslist->targ_path[0] == NULLCHAR &&
                curslist->dep_path[0]  == NULLCHAR ) {
                slistEmptyTargDepPath = curslist;
            }

            if( slistCount > 0 && slistEmptyTargDepPath != NULL ) {
                UseDefaultSList = FALSE;
            }
            curslist = curslist->next ;
            ++slistCount;
        }

        if( UseDefaultSList && slistCmd  == NULL && !Glob.microsoft ) {
            _makepath( buf, NULL, NULL, fname, cursuf->node.name );
            /* try to find this file on path or in targets */
            ret = TrySufPath( buf, buf, &imptarg, FALSE );
            switch( ret ) {
            case RET_WARN:
                break;
            case RET_ERROR:
                if( !Glob.microsoft ) {
                    slistDef = slistEmptyTargDepPath;
                }
                break;
            case RET_SUCCESS:
                slistCmd = slistEmptyTargDepPath;
                break;
            }
        }


        if( (ret == RET_SUCCESS && imptarg == NULL) || ret == RET_ERROR ) {
            /* Either file doesn't exist, or it exists and we don't already
             * have a target for it.  Either way, we create a new target.
             */
            if( ret == RET_ERROR ) {
                /*
                 * No Default Slist found so must continue and find
                 * another slist
                 */
                if( slistDef == NULL ) {
                    FreeSafe( buf );
                    continue;
                } else {
                    slistCmd = slistDef;
                }
                    /* file doesn't exist, assume in directory */
                    /* pointed to by the slistDef              */
                _makepath( buf, NULL, slistCmd->dep_path,
                           fname, cursuf->node.name );

            }
            newtarg = TRUE;
            imptarg = NewTarget( buf );
            FreeSafe( buf );        /* don't need any more */
            getStats( imptarg );
            imptarg->busy = TRUE;   /* protect against recursion */
            if( imply( imptarg, NULL, slistCmd->dep_path,
                        fname, cursuf->node.name, FALSE ) ==
                RET_ERROR ) {
                imptarg->error = TRUE;
            }
            if( startcount != cListCount && (Glob.noexec || Glob.query) ) {
                imptarg->touched = TRUE;
                imptarg->executed = TRUE;       /* 29-oct-90 */
            }
            imptarg->updated = TRUE;
            imptarg->busy = FALSE;
        } else {
            /* We already know about imptarg, so just update it */
            assert( imptarg != NULL );
            FreeSafe( buf );        /* don't need any more */
            newtarg = FALSE;        /* this isn't a new target */
            Update( imptarg );
        }

        /* We've tried our best to make the imptarg, check if it exists
         * after our efforts.
         */
        if( targExists( imptarg ) ) {
            /* it exists - now we perform the implicit cmd list, and return */
            ret = implyMaybePerform( targ, imptarg, cur->cretarg, must,
                slistCmd );
            if( newtarg && !Glob.noexec ) {
                /* destroy the implied target, because the info in the target
                 * structure is nicely stored on disk (unless Glob.noexec)
                 */
                KillTarget( imptarg->node.name );
            }
            implyDebugInfo( targ, startcount );
            return( ret );
        } else if( newtarg ) {
            /* we created an unsuccessful target - so destroy it */
            KillTarget( imptarg->node.name );
        }

        /* We couldn't imply with this suffix... try next one */
    }
    implyDebugInfo( targ, startcount );
    return( RET_WARN );
}


STATIC RET_T tryImply( TARGET *targ, BOOLEAN must )
/*************************************************/
{
    PGROUP  *pg;
    RET_T   ret;

    if( Glob.block ) {
        return( RET_WARN );
    }

    pg = SplitPath( targ->node.name );

    ret = imply( targ, pg->drive,pg->dir,pg->fname, pg->ext, must );

    DropPGroup( pg );

    return( ret );
}


STATIC void ExpandWildCards( TARGET *targ, DEPEND *depend )
/**********************************************************
 * Expand the wild cards now
 * also deMacroSpecial macros
 */
{
   TLIST    *tlist;
   TLIST    *currentEnd;
   TLIST    *outTList;
   TLIST    *temp;
   char     *NodeName;

   assert( depend != NULL );

   tlist = depend->targs;
   currentEnd = outTList = NULL;
   while( tlist != NULL ) {
       temp = NULL;
       // In Microsoft it is possible to have macros in the dependency.
       if( Glob.microsoft ) {
           exPush( targ, NULL, NULL );
           NodeName = DeMacroSpecial( tlist->target->node.name );
           exPop();
           WildTList( &temp, NodeName, TRUE, TRUE );
           FreeSafe( NodeName );

⌨️ 快捷键说明

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