Ejemplo n.º 1
0
STATIC void popSENT( void )
/**************************
 * pop top SENT off stack.  If necessary, close or free the apropriate things.
 */
{
    SENT    *tmp;

    assert( headSent != NULL );

    tmp = headSent;

    switch( tmp->type ) {
    case SENT_FILE:
        if( tmp->free ) {
            close( tmp->data.file.fh );
            PrtMsg( DBG | INF | LOC | FINISHED_FILE, tmp->data.file.name );
        }
        FreeSafe( tmp->data.file.buf );
        FreeSafe( (void *)headSent->data.file.name );
        break;
    case SENT_STR:
        if( tmp->free ) {
            FreeSafe( (void *)headSent->data.str.str );
        }
        break;
    case SENT_CHAR:
        break;
    }

    headSent = tmp->next;       /* advance to next SENT */
    tmp->next = freeSent;       /* push onto free stack */
    freeSent = tmp;
}
Ejemplo n.º 2
0
void LexFini( void )
/*************************/
{
    if( *targ_path != NULLCHAR ) {
        FreeSafe( targ_path );
        targ_path = "";
    }
    if( *dep_path != NULLCHAR ) {
        FreeSafe( dep_path );
        dep_path = "";
    }
    PreProcFini();
}
Ejemplo n.º 3
0
void DoWildCardClose( void )
/*********************************/
{
    if( path != NULL ) {
        FreeSafe( path );
        path = NULL;
    }
    if( pattern != NULL ) {
        FreeSafe( pattern );
        pattern = NULL;
    }
    if( parent != NULL ) {
        closedir( parent );
        parent = NULL;
    }
}
Ejemplo n.º 4
0
STATIC void freePathRing( PATHRING pathring )
/*******************************************/
{
    PATHNODE    *walk;
    PATHNODE    *cur;

    if( pathring == NULL ) {
        return;
    }

    walk = pathring;
    do {
        cur = walk;
        walk = walk->next;
        FreeSafe( cur->name );
        FreeSafe( cur );
    } while( walk != pathring );
}
Ejemplo n.º 5
0
void RenameTarget( TARGET *targ, const char *newname )
/****************************************************/
{
    (void)RemHashNode( targTab, targ->node.name, CASESENSITIVE );
    if( targ->node.name != NULL ) {
        FreeSafe( targ->node.name );
    }
    targ->node.name = FixName( StrDupSafe( newname ) );
    AddHashNode( targTab, (HASHNODE *)targ );
}
Ejemplo n.º 6
0
int PutEnvSafe( ENV_TRACKER *env )
/****************************************
 * This function takes over responsibility for freeing env
 */
{
    char        *p;
    ENV_TRACKER **walk;
    ENV_TRACKER *old;
    int         rc;
    size_t      len;

    p = env->value;
                                // upper case the name
    while( *p != '=' && *p != NULLCHAR ) {
        *p = toupper( *p );
        ++p;
    }
    rc = putenv( env->value );  // put into environment
    if( p[0] == '=' && p[1] == '\0' ) {
        rc = 0;                 // we are deleting the envvar, ignore errors
    }
    len = p - env->value + 1;   // len including '='
    walk = &envList;
    while( *walk != NULL ) {
        if( strncmp( (*walk)->value, env->value, len ) == 0 ) {
            break;
        }
        walk = &(*walk)->next;
    }
    old = *walk;
    if( old != NULL ) {
        *walk = old->next;      // unlink from chain
        FreeSafe( old );
    }
    if( p[1] != 0 ) {           // we're giving it a new value
        env->next = envList;    // save the memory since putenv keeps a
        envList = env;          // pointer to it...
    } else {                    // we're deleting an old value
        FreeSafe( env );
    }
    return( rc );
}
Ejemplo n.º 7
0
void PutEnvFini( void )
/****************************/
{
    ENV_TRACKER *cur;

    while( envList != NULL ) {
        cur = envList;
        envList = cur->next;
        FreeSafe( cur );
    }
}
Ejemplo n.º 8
0
char *GetMacroValue( const char *name )
/*********************************************
 * Now we need to check for string substitution
 * $(MACRONAME:oldstring=newstring)
 */
{
    char        *InName;
    const char  *beforeSub;
    char        *afterSub;
    char        *current;
    const char  *new;
    const char  *old;
    char        *line;

    InName = StrDupSafe( name );
    current = strchr( InName, COLON );

    if( current == NULL ) {
        beforeSub = GetMacroValueProcess( InName );
        if( beforeSub == NULL ) {
            afterSub = NULL;
        } else {
            afterSub  = StrDupSafe( beforeSub );
        }
    } else {
        *current++ = NULLCHAR;
        beforeSub = GetMacroValueProcess( InName );

        if( beforeSub == NULL ) {
            afterSub = NULL;
        } else {
            line = NULL;
            // recursively expand so $(macro:sub) OK if macro contains another
            if( strchr( beforeSub, DOLLAR ) != NULL ) {
                UnGetCH( STRM_MAGIC );
                InsString( beforeSub, FALSE );
                beforeSub = line = DeMacro( TOK_MAGIC );
                GetCHR();   // eat STRM_MAGIC
            }
            if( beforeSub == NULL ) {
                afterSub = NULL;
            } else {
                if( getOldNewString( current, &old, &new ) == RET_SUCCESS ) {
                    afterSub = doStringSubstitute( beforeSub, old, new );
                } else {
                    afterSub = NULL;
                    PrtMsg( ERR | LOC | INVALID_STRING_SUBSTITUTE );
                }
                if( line ) {
                    FreeSafe( line );
                }
            }
        }
    }
Ejemplo n.º 9
0
STATIC void cleanDLLCmd( void )
{
#ifdef DLLS_IMPLEMENTED
    DLL_CMD     *n;
    DLL_CMD     *temp;

    n  = dllCommandList;
    while( n != NULL ) {
        FreeSafe( (char *)n->cmd_name );
        if( n->inf.dll_name != NULL ) {
            FreeSafe( (char*) n->inf.dll_name );
        }
        if( n->inf.ent_name != NULL ) {
            FreeSafe( (char *)n->inf.ent_name );
        }
        temp = n;
        n = n->next;
        FreeSafe( temp );
    }
#endif
}
Ejemplo n.º 10
0
STATIC BOOLEAN freeSuffix( void *node, void *ptr )
/************************************************/
{
    SUFFIX  *suffix = node;
    CREATOR *creator;
    CREATOR *creator_next;

    (void)ptr; // Unused
    FreeSafe( suffix->node.name );
    freePathRing( suffix->pathring );

    for( creator = suffix->creator; creator != NULL; creator = creator_next ) {
        creator_next = creator->next;
        FreeSList( creator->slist );
        FreeSafe( creator );
    }

    FreeSafe( suffix );

    return( FALSE );
}
Ejemplo n.º 11
0
STATIC BOOLEAN freeSuffix( void *node, void *ptr )
/************************************************/
{
    SUFFIX  *suf = node;
    CREATOR *ccur;
    CREATOR *cwalk;

    (void)ptr; // Unused
    FreeSafe( suf->node.name );
    freePathRing( suf->first );

    cwalk = suf->creator;
    while( cwalk != NULL ) {
        ccur = cwalk;
        cwalk = cwalk->next;
        KillTarget( ccur->cretarg->node.name );
        FreeSafe( ccur );
    }

    FreeSafe( suf );

    return( FALSE );
}
Ejemplo n.º 12
0
STATIC char *CatModifier( char *inString, BOOLEAN destroy )
/**********************************************************
 *  Get the modifier
 *  if it is modify the value inInString to the specs of the modifier
 *  it then returns the modified string with the right format
 */
{
    STRM_T  s;
    VECSTR  output;
    char    buffer[2];
    char    *ret;

    assert( inString != NULL );

    s = PreGetCH();

    if( ismsmodifier( s ) ) {
        buffer[0] = s;
        buffer[1] = NULLCHAR;
        output = StartVec();
        WriteVec( output, "" );
        CatStrToVec( output, inString );
        CatStrToVec( output, buffer );
        if( destroy ) {
            FreeSafe( inString );
        }
        return( FinishVec( output ) );
    } else {
        UnGetCH( s );
        ret = StrDupSafe( inString );
        if( destroy ) {
            FreeSafe( inString );
        }
        return( ret );
    }
}
Ejemplo n.º 13
0
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 );
       } 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;
}
Ejemplo n.º 14
0
STATIC RET_T streamScarce( void )
/*******************************/
{
    SENT    *cur;

    if( freeSent == NULL ) {
        return( RET_ERROR );
    }

    while( freeSent != NULL ) {
        cur = freeSent;
        freeSent = freeSent->next;
        FreeSafe( cur );
    }

    return( RET_SUCCESS );
}
Ejemplo n.º 15
0
void LexMaybeFree( TOKEN_T tok )
/**************************************
 * remarks: Some tokens set CurAttr.u.ptr to a memory region.  This routine
 *          FreeSafes the region if tok is one of these token types.
 */
{
    switch( tok ) {
    case TOK_FILENAME:
    case TOK_CMD:
    case TOK_SUF:
    case TOK_SUFSUF:
    case TOK_PATH:
    case MAC_WS:
    case MAC_NAME:
    case MAC_PUNC:
    case MAC_TEXT:
        FreeSafe( CurAttr.u.ptr );
        break;
    }
}
Ejemplo n.º 16
0
TOKEN_T LexParser( STRM_T s )
/************************************
 * returns: next token for parser
 * remarks: possibly defines a macro
 */
{
    static BOOLEAN  atstart = TRUE;
    char            *p;

    for( ;; ) {

        if( atstart ) {
                /* atstart == TRUE if either of these succeed */
            if( isws( s ) ) {           /* cmd line */
                return( lexCmd() );
            }
            if( ismacc( s ) && checkMacro( s ) ) {  /* check if macro = body */
                s = PreGetCH();
                continue;
            }

            atstart = FALSE;
            UnGetCH( s );           /* put back our probe */
            s = STRM_MAGIC;         /* force macro expansion */
        }

        switch( s ) {
        case STRM_END:
            atstart = TRUE;
            return( TOK_END );
        case EOL:
            atstart = TRUE;
            return( TOK_EOL );
        case STRM_TMP_LEX_START:
        case STRM_MAGIC:
            p = DeMacroDoubleQuote( FALSE );  /* expand to next white space */
            if( *p == NULLCHAR ) {  /* already at ws */
                FreeSafe( p );
                s = PreGetCH();     /* eat the ws */
                while( isws( s ) ) {
                    s = PreGetCH();
                }
                if( s == EOL ) {
                    atstart = TRUE;
                    return( TOK_EOL );
                }
                if( s == STRM_END ) {
                    atstart = TRUE;
                    return( TOK_END );
                }
                UnGetCH( s );
                p = DeMacroDoubleQuote( FALSE );
            }
            UnGetCH( STRM_MAGIC );  /* mark spot we have to expand from nxt */
            InsString( p, TRUE );   /* put expansion in stream */
            break;
        case SPACE: /* fall through */
        case TAB:
            break;
        case L_CURL_PAREN:          /* could only be a sufsuf */
        case DOT:
            UnGetCH( s );
            return( lexDotName() ); /* could be a file... */
        case SEMI:                  /* treat semi-colon as {nl}{ws} */
            InsString( "\n ", FALSE );
            break;                  /* try again */
        case COLON:
            s = PreGetCH();
            if( s == COLON ) {
                return( TOK_DCOLON );
            }
            UnGetCH( s );
            return( TOK_SCOLON );
        default:
            if( isfilec( s ) || s == DOUBLEQUOTE ||
                ( (Glob.compat_nmake || Glob.compat_posix) &&  s == SPECIAL_TMP_DOL_C ) ) {
                return( lexFileName( s ) );
            }
            PrtMsg( WRN | LOC | UNKNOWN_TOKEN, s );
            break;
        }
        s = PreGetCH();             /* fetch a character */
    }
}
Ejemplo n.º 17
0
STATIC char *DeMacroDoubleQuote( BOOLEAN IsDoubleQuote )
/*******************************************************
 * This procedure takes care of double quotes in the stream
 * Note: each double quote must be paired with a double quote in the
 * input stream or this will expand until the EOL a backlash double
 * quote will be considered as a non-double quote.
 */
{
    char    buffer[_MAX_PATH];
    char    *current;
    char    *p;
    VECSTR  OutString;
    int     pos;
    STRM_T  s;
    BOOLEAN StartDoubleQuote;


    s = PreGetCH();
    UnGetCH( s );
    if( s == EOL || s == STRM_END || s == STRM_MAGIC ) {
        return( StrDupSafe( "" ) );
    }
    if( s == STRM_TMP_LEX_START ) {
        PreGetCH();  /* Eat STRM_TMP_LEX_START */
        pos = 0;
        for( s = PreGetCH(); s != STRM_MAGIC && pos < _MAX_PATH; s = PreGetCH() ) {
            assert( s != EOL || s != STRM_END );
            buffer[pos++] = s;
        }

        if( pos >= _MAX_PATH ) {
            PrtMsgExit(( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 )); // NOTREACHED
        }

        buffer[pos] = NULLCHAR;
        p = StrDupSafe( buffer );
    } else {
        p = DeMacro( MAC_WS );
    }

    StartDoubleQuote = IsDoubleQuote;

    for( current = p; *current != NULLCHAR; ++current ) {
        if( *current == DOUBLEQUOTE ) {
            if( !IsDoubleQuote ) {
                /* Found the start of a Double Quoted String */
                if( current != p ) {
                    UnGetCH( STRM_MAGIC );
                    InsString( StrDupSafe( current ), TRUE );
                    UnGetCH( STRM_TMP_LEX_START );
                    *current = NULLCHAR;
                    return( p );
                }
                IsDoubleQuote = TRUE;
            } else {
                /* Found the end of the Double Quoted String */
                if( *(current + 1) != NULLCHAR) {
                    UnGetCH( STRM_MAGIC );
                    InsString( StrDupSafe( current + 1 ), TRUE );
                    UnGetCH( STRM_TMP_LEX_START );
                    *(current + 1) = NULLCHAR;
                }
                return( p );
            }
        }
    }

    if( !StartDoubleQuote && !IsDoubleQuote ) {
        /* there are no double quotes in the text */
        /* so return text as is */
        return( p );

    }
    pos = 0;
    s = PreGetCH();
    while( isws( s ) ) {
        buffer[pos++] = s;
        s = PreGetCH();
    }
    buffer[pos] = NULLCHAR;
    UnGetCH( s );
    OutString = StartVec();
    CatStrToVec( OutString, p );
    FreeSafe( p );
    CatStrToVec( OutString, buffer );
    p = DeMacroDoubleQuote( TRUE );
    CatStrToVec( OutString, p );
    FreeSafe( p );
    return( FinishVec( OutString ) );
}
Ejemplo n.º 18
0
STATIC TOKEN_T lexDotName( void )
/********************************
 * Given that the last character was a DOT, input the maximum string
 * possible, and check if it is a TOK_DOTNAME, TOK_SUF, or TOK_SUFSUF
 * Special cases to look for: "."{dirc}; ".."{dirc}; ".."{extc}+;
 * and "."{extc}+"."
 * recognizes:
 *   "."{extc}*                                 TOK_SUF
 *   "."{extc}*"."{extc}*                       TOK_SUFSUF
 *   "{"path"}""."{extc}*"{"path"}""."{extc}    TOK_SUFSUF
 *   "."{dot-name}                              TOK_DOTNAME
 *   "."{dirc}                                  passes to lexFileName()
 *   ".."{dirc}                                 passes to lexFileName()
 */
{
    char        ext[MAX_SUFFIX];
    unsigned    pos;
    STRM_T      s;
    STRM_T      s2;
    TOKEN_T     ret;

    pos  = 0;

    if( *targ_path != NULLCHAR ) {
        FreeSafe( targ_path );
        targ_path = "";
    }
    if( *dep_path != NULLCHAR ) {
        FreeSafe( dep_path );
        dep_path = "";
    }
    dep_path = getCurlPath();
    s = PreGetCH();
    if( s != DOT ) {
        PrtMsg( ERR | LOC | INVALID_SUFSUF );
        return( TOK_NULL );
    } else {
        ext[pos++] = DOT;
        s = PreGetCH();
    }

    if( isdirc( s ) || s == PATH_SPLIT || s == ';' ) {  // check for "."{dirc}
        UnGetCH( s );
        if( *dep_path != NULLCHAR ) {
            PrtMsg( ERR | LOC | INVALID_SUFSUF );
        }
        return( lexFileName( DOT ) );
    }

    if( s == DOT ) {        /* check if ".."{extc} or ".."{dirc} */
        s2 = PreGetCH();    /* probe one character */
        UnGetCH( s2 );
        if( isdirc( s2 ) || s2 == PATH_SPLIT || s2 == ';' ) {   // is ".."{dirc}
            UnGetCH( s );
            if( *dep_path != NULLCHAR ) {
                PrtMsg( ERR | LOC | INVALID_SUFSUF );
            }
            return( lexFileName( DOT ) );
        }
    } else {    /* get string {extc}+ */
        while( pos < MAX_SUFFIX && isextc( s ) && s != L_CURL_PAREN ) {
            ext[pos++] = s;
            s = PreGetCH();
        }
        if( pos == MAX_SUFFIX ) {
            PrtMsgExit(( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_SUFFIX - 1 ));
        }
        ext[pos] = NULLCHAR;
    }

    UnGetCH( s );

    targ_path = getCurlPath();

    s = PreGetCH();         /* next char */

    if( s == DOT ) {        /* maybe of form "."{extc}*"."{extc}* */
        ext[pos++] = s;
        for( s = PreGetCH(); pos < MAX_SUFFIX && isextc( s ); s = PreGetCH() ) {
            ext[pos++] = s;
        }
        if( pos == MAX_SUFFIX ) {
            PrtMsgExit(( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_SUFFIX - 1 )); //NOTREACHED
        }
        ext[pos] = NULLCHAR;

        ret = TOK_SUFSUF;
    } else {
        if( *targ_path != NULLCHAR && *dep_path != NULLCHAR ) {
            PrtMsg( ERR | LOC | INVALID_SUFSUF );
        }
        ret = TOK_SUF;
    }
    UnGetCH( s );           /* put back what we don't need */

    if( *targ_path != NULLCHAR && *dep_path != NULLCHAR && ret == TOK_SUF ) {
        PrtMsg( ERR | LOC | INVALID_SUFSUF );
    } else if( ret == TOK_SUF && checkDotName( ext ) ) {
        return( TOK_DOTNAME );
    }
    CurAttr.u.ptr = StrDupSafe( ext );
    return( ret );
}
Ejemplo n.º 19
0
TOKEN_T LexParser( STRM_T s )
/************************************
 * returns: next token for parser
 * remarks: possibly defines a macro
 */
{
    static bool     atstart = true;
    char            *p;

    for( ;; ) {

        if( atstart ) {
                /* atstart == true if either of these succeed */
            if( sisws( s ) ) {           /* cmd line */
                return( lexCmd() );
            }
            if( sismacc( s ) && checkMacro( s ) ) {  /* check if macro = body */
                s = PreGetCHR();
                continue;
            }

            atstart = false;
            UnGetCHR( s );           /* put back our probe */
            s = STRM_MAGIC;         /* force macro expansion */
        }

        switch( s ) {
        case STRM_END:
            atstart = true;
            return( TOK_END );
        case '\n':
            atstart = true;
            return( TOK_EOL );
        case STRM_TMP_LEX_START:
        case STRM_MAGIC:
            p = DeMacroDoubleQuote( false );  /* expand to next white space */
            if( *p == NULLCHAR ) {  /* already at ws */
                FreeSafe( p );
                s = PreGetCHR();    /* eat the ws */
                while( sisws( s ) ) {
                    s = PreGetCHR();
                }
                if( s == '\n' ) {
                    atstart = true;
                    return( TOK_EOL );
                }
                if( s == STRM_END ) {
                    atstart = true;
                    return( TOK_END );
                }
                UnGetCHR( s );
                p = DeMacroDoubleQuote( false );
            }
            UnGetCHR( STRM_MAGIC ); /* mark spot we have to expand from nxt */
            InsString( p, true );   /* put expansion in stream */
            break;
        case ' ':
        case '\t':
            break;
        case '{':                   /* could only be a sufsuf */
        case '.':
            UnGetCHR( s );
            return( lexDotName() ); /* could be a file... */
        case ';':                   /* treat semi-colon as {nl}{ws} */
            InsString( "\n ", false );
            break;                  /* try again */
        case ':':
            s = PreGetCHR();
            if( s == ':' ) {
                return( TOK_DCOLON );
            }
            UnGetCHR( s );
            return( TOK_SCOLON );
        default:
            if( sisfilec( s ) || s == '\"' || ( (Glob.compat_nmake || Glob.compat_posix) && s == SPECIAL_TMP_DOLLAR ) ) {
                return( lexFileName( s ) );
            }
            PrtMsg( WRN | LOC | UNKNOWN_TOKEN, s );
            break;
        }
        s = PreGetCHR();             /* fetch a character */
    }
}
Ejemplo n.º 20
0
STATIC RET_T imply( TARGET *targ, const char *drive, const char *dir,
    const char *fname, const char *ext, bool 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 = NULL;
    RET_T       ret;
    bool        newtarg;
    UINT32      startcount;
    char        *buf;
    SLIST       *curslist;
    SLIST       *slist;     // Slist chosen for sufsuf
    SLIST       *slistDef;  // Slist that has dependent path = ""
    SLIST       *slistEmptyTargDepPath;
    bool        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 );
        slist = NULL;
        slistDef = NULL;
        slistEmptyTargDepPath = NULL;

        ret = RET_ERROR;

        UseDefaultSList = true;
        /* find path in SLIST */
        slistCount = 0;
        for( curslist = cur->slist; curslist != NULL && ret != RET_SUCCESS; curslist = curslist->next ) {
            _makepath( buf, drive, dir, NULL, NULL );
            FixName( buf );
            /*
             * note the path of the current target must match the
             * path as specified in the slist
             */
            if( stricmp( 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 ) {
                    slist = 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 == NULLCHAR && *curslist->dep_path == NULLCHAR ) {
                slistEmptyTargDepPath = curslist;
            }

            if( slistCount > 0 && slistEmptyTargDepPath != NULL ) {
                UseDefaultSList = false;
            }
            ++slistCount;
        }

        if( UseDefaultSList && slist == NULL && !Glob.compat_nmake ) {
            _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.compat_nmake ) {
                    slistDef = slistEmptyTargDepPath;
                }
                break;
            case RET_SUCCESS:
                slist = slistEmptyTargDepPath;
                break;
            }
        }

        if( ret == RET_ERROR && slistDef == NULL ) {
            /*
             * No Default Slist found so must continue and find
             * another slist
             */
            FreeSafe( buf );
            continue;
        }

        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 ) {
                slist = slistDef;
                /* file doesn't exist, assume in directory */
                /* pointed to by the slistDef              */
                _makepath( buf, NULL, slist->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, slist->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;
            }
            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, slist->cretarg, must );
            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 );
}
Ejemplo n.º 21
0
TOKEN_T LexPath( STRM_T s )
/*********************************
 * returns: ({filec}*";")+          TOK_PATH
 *          EOL                     EOL
 *          STRM_END                STRM_END
 */
{
    char        path[_MAX_PATH];
    char        string_open;
    unsigned    pos;
    VECSTR      vec;                /* we'll store file/path here */

    for( ;; ) {                     /* get first valid character */
        if( s == EOL || s == STRM_END ) {
            /* now we pass this to LexParser() so that it can reset */
            return( LexParser( s ) );
        }

        if( s == STRM_MAGIC ) {
            InsString( DeMacro( TOK_EOL ), TRUE );
        } else if( !isfilec( s ) && s != PATH_SPLIT && s != ';' && s != '\"' && !isws( s ) ) {
            PrtMsg( ERR | LOC | EXPECTING_M, M_PATH );
        } else if( !isws( s ) ) {
            break;
        }

        s = PreGetCH(); /* keep fetching characters */
    }
    /* just so you know what we've got now */
    assert( isfilec( s ) || s == PATH_SPLIT || s == ';' || s == '\"' );

    vec = StartVec();

    pos = 0;
    for( ;; ) {
        /*
         * Extract path from stream. If double quote is found, start string mode
         * and ignore all filename character specifiers and just copy all
         * characters. String mode ends with another double quote. Backslash can
         * be used to escape only double quotes, otherwise they are recognized
         * as path seperators.  If we are not in string mode character validity
         * is checked against isfilec().
         */

        string_open = 0;

        while( pos < _MAX_PATH && s != EOL && s != STRM_END ) {
            if( s == BACKSLASH ) {
                s = PreGetCH();

                if( s == DOUBLEQUOTE ) {
                    path[pos++] = DOUBLEQUOTE;
                } else if( s == EOL || s == STRM_END ) {
                    // Handle special case when backslash is placed at end of
                    // line or file
                    path[pos++] = BACKSLASH;
                } else {
                    path[pos++] = BACKSLASH;

                    // make sure we don't cross boundaries
                    if( pos < _MAX_PATH ) {
                        path[pos++] = s;
                    }
                }
            } else {
                if( s == DOUBLEQUOTE ) {
                    string_open = !string_open;
                } else {
                    if( string_open ) {
                        path[pos++] = s;
                    } else if( isfilec( s ) ) {
                        path[pos++] = s;
                    } else {
                        break; // not valid path character, break out.
                    }
                }
            }

            s = PreGetCH();
        }

        if( string_open ) {
            FreeSafe( FinishVec( vec ) );
            PrtMsgExit(( FTL | LOC | ERROR_STRING_OPEN ));
        }

        if( pos == _MAX_PATH ) {
            FreeSafe( FinishVec( vec ) );
            PrtMsgExit(( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 )); // NOTREACHED
        }

        path[pos] = NULLCHAR;
        WriteVec( vec, path );

        if( s != PATH_SPLIT && s != ';' ) {
            break;
        }

        pos = 0;
        path[pos++] = PATH_SPLIT;
        s = PreGetCH();        /* use Pre here to allow path;&(nl)path */
    }
    UnGetCH( s );

    CurAttr.u.ptr = FinishVec( vec );

    return( TOK_PATH );
}