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 ); } } } }
void OSLoadDLL( char *cmd_name, char *dll_name, char *ent_name ) /**************************************************************/ { DLL_CMD *n; // we want newer !loaddlls to take precedence n = MallocSafe( sizeof( *n ) ); n->cmd_name = StrDupSafe( cmd_name ); n->next = dllCommandList; dllCommandList = n; IdeDrvInit( &n->inf, StrDupSafe( dll_name ), (ent_name == NULL) ? NULL : StrDupSafe( ent_name ) ); }
STATIC char *getCurlPath( void ) /******************************* * get the path between { and } */ { STRM_T s; char path[_MAX_PATH + 1]; int pos; pos = 0; s = PreGetCH(); if( s == L_CURL_PAREN ) { for( s = PreGetCH(); s != R_CURL_PAREN && s != EOL && pos < _MAX_PATH; s = PreGetCH() ) { path[pos++] = s; } path[pos] = NULLCHAR; if( s == EOL ) { UnGetCH( EOL ); PrtMsg( ERR | LOC | NON_MATCHING_CURL_PAREN); } else if( pos == _MAX_PATH ) { PrtMsg( WRN | LOC | PATH_TOO_LONG ); } return( StrDupSafe( path ) ); } else { UnGetCH( s ); return( "" ); } }
TOKEN_T LexMacDef( STRM_T s ) /************************************ * returns: MAC_TEXT, or MAC_WS up to EOL or $+ */ { char *cur; BOOLEAN onlyws; /* are we collecting ws? */ char text[MAX_TOK_SIZE]; /* store stuff here temp. */ if( s == STRM_END ) { return( TOK_END ); } if( s == STRM_MAGIC ) { return( TOK_MAGIC ); } if( s == EOL ) { return( TOK_EOL ); } assert( isascii( s ) ); cur = text; if( s == DOLLAR ) { *cur++ = DOLLAR; s = PreGetCH(); if( s == '+' ) { return( MAC_EXPAND_ON ); } } onlyws = isws( s ); while( cur - text < MAX_TOK_SIZE - 1 ) { *cur++ = s; s = PreGetCH(); if( s == STRM_END || s == STRM_MAGIC || s == EOL || s == DOLLAR || (onlyws && !isws( s )) || (!onlyws && isws( s )) ) { break; } } UnGetCH( s ); *cur = NULLCHAR; CurAttr.u.ptr = StrDupSafe( text ); if( onlyws ) { return( MAC_WS ); } return( MAC_TEXT ); }
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 ); }
STATIC bool checkMacro( STRM_T s ) /********************************* * returns: true if the line WAS a macro defn * false if it wasn't * recognizes: {macc}+{ws}*"="{ws}*{defn}*"\n" * {macc}+{ws}*"+="{ws}*{defn}*"\n" * second gets translated from "macro += defn" to "macro=$+$(macro)$- defn" */ { char mac[MAX_MAC_NAME]; unsigned pos; bool ws; pos = 0; while( pos < MAX_MAC_NAME && sismacc( s ) ) { mac[pos++] = s; s = PreGetCHR(); } if( pos == MAX_MAC_NAME ) { PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_MAC_NAME - 1 ); ExitFatal(); // never return } mac[pos] = NULLCHAR; ws = sisws( s ); while( sisws( s ) ) { s = PreGetCHR(); } if( s == '=' ) { DefMacro( mac ); return( true ); /* go around again */ } else if( s == '+' ) { s = PreGetCHR(); if( s == '=' ) { InsString( ")$-", false ); InsString( mac, false ); InsString( "$+$(", false ); DefMacro( mac ); return( true ); /* go around again */ } UnGetCHR( s ); s = '+'; } UnGetCHR( s ); /* not a macro line, put everything back*/ if( ws ) { UnGetCHR( ' ' ); } InsString( StrDupSafe( mac + 1 ), true ); return( false ); }
STATIC BOOLEAN checkMacro( STRM_T s ) /************************************* * returns: TRUE if the line WAS a macro defn * FALSE if it wasn't * recognizes: {macc}+{ws}*"="{ws}*{defn}*"\n" * {macc}+{ws}*"+="{ws}*{defn}*"\n" * second gets translated from "macro += defn" to "macro=$+$(macro)$- defn" */ { char mac[MAX_MAC_NAME]; unsigned pos; BOOLEAN ws; pos = 0; while( pos < MAX_MAC_NAME && ismacc( s ) ) { mac[pos++] = s; s = PreGetCH(); } if( pos == MAX_MAC_NAME ) { PrtMsgExit(( FTL | LOC | MAXIMUM_TOKEN_IS, MAX_MAC_NAME - 1 )); } mac[pos] = NULLCHAR; ws = isws( s ); while( isws( s ) ) { s = PreGetCH(); } if( s == '=' ) { DefMacro( mac ); return( TRUE ); /* go around again */ } else if( s == '+' ) { s = PreGetCH(); if( s == '=' ) { InsString( ")$-", FALSE ); InsString( mac, FALSE ); InsString( "$+$(", FALSE ); DefMacro( mac ); return( TRUE ); /* go around again */ } UnGetCH( s ); s = '+'; } UnGetCH( s ); /* not a macro line, put everything back*/ if( ws ) { UnGetCH( SPACE ); } InsString( StrDupSafe( mac + 1 ), TRUE ); return( FALSE ); }
STATIC TOKEN_T lexFileName( STRM_T s ) /************************************* * Now we need two ways of taking file names if the filename needs special * characters then use "filename" this will ignore all the different * characters except for the quote which can be specified as \t */ { char file[_MAX_PATH]; unsigned pos; assert( sisfilec( s ) || s == '\"' || ( (Glob.compat_nmake || Glob.compat_posix) && s == SPECIAL_TMP_DOLLAR ) ); if( s == '\"' ) { return( lexLongFilePathName( s, TOK_FILENAME ) ); } pos = 0; while( pos < _MAX_PATH && (sisfilec( s ) || ( s == SPECIAL_TMP_DOLLAR && (Glob.compat_nmake || Glob.compat_posix) ) ) ) { file[pos++] = s; s = PreGetCHR(); } if( pos == _MAX_PATH ) { PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED ExitFatal(); // never return } file[pos] = NULLCHAR; UnGetCHR( s ); /* if it is a file, we have to check last position for a ':', and * trim it off if it's there */ if( pos > 1 && file[pos - 1] == ':' ) { file[pos - 1] = NULLCHAR; /* trim a trailing colon */ UnGetCHR( ':' ); /* push back the colon */ --pos; } /* * try to do the trim twice because if file ends with a double colon * it means its a double colon explicit rule */ if( pos > 1 && file[pos - 1] == ':' ) { file[pos - 1] = NULLCHAR; /* trim a trailing colon */ UnGetCHR( ':' ); /* push back the colon */ } CurAttr.u.ptr = StrDupSafe( file ); return( TOK_FILENAME ); }
STATIC TOKEN_T lexLongFilePathName( STRM_T s, TOKEN_T tok ) /********************************************************** * This will enable taking in of special filenames * it takes long file names or long path names */ { char file[_MAX_PATH]; int pos; assert( s == '\"' ); pos = 0; s = PreGetCHR(); /* \" is considered a double quote character */ /* and if a double quote is found again then we break out as the end */ /* of the filename */ while( pos < _MAX_PATH && s != '\"' && s != '\n' && s != STRM_END ) { file[pos++] = s; s = PreGetCHR(); if( s == '\\' ) { if( pos >= _MAX_PATH ) { break; } s = PreGetCHR(); if( s == '\"' ) { file[pos++] = s; s = PreGetCHR(); } else { file[pos++] = '\\'; } } } if( pos >= _MAX_PATH ) { PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED ExitFatal(); // never return } file[pos] = NULLCHAR; if( s != '\"' ) { UnGetCHR( s ); } CurAttr.u.ptr = StrDupSafe( file ); return( tok ); }
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 ); }
char *GetCurDeps( bool younger, bool isMacInf ) /*********************************************/ { TLIST *tlist; VECSTR vec; bool written; TARGET *targ; struct exStack cur; const char *formattedString; char *ret; cur = exGetCurVars(); // This is for Glob.compat_nmake and Glob.compat_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; for( tlist = cur.dep->targs; tlist != NULL; tlist = tlist->next ) { targ = tlist->target; if( !younger || dateCmp( cur.targ->date, targ->date ) < 0 ) { if( written ) { WriteVec( vec, " " ); } formattedString = procPath( targ->node.name ); WriteVec( vec, formattedString ); written = true; } } ret = FinishVec( vec ); return( ret ); }
RET_T InsFile( const char *name, BOOLEAN envsearch ) /********************************************************** * Open file named name, and push it into stream. If can't find name, it * tries an implicit suffix search (possibly using the env variable PATH) */ { SENT *tmp; int fh; char path[_MAX_PATH]; assert( name != NULL ); if( TrySufPath( path, name, NULL, envsearch ) == RET_SUCCESS ) { PrtMsg( DBG | INF | LOC | ENTERING_FILE, path ); fh = sopen3( path, O_RDONLY | O_BINARY, SH_DENYWR ); if( fh == -1 ) { return( RET_ERROR ); } tmp = getSENT( SENT_FILE ); tmp->free = TRUE; tmp->data.file.name = StrDupSafe( path ); pushFH( tmp, fh ); if( !Glob.overide ) { UnGetCH( EOL ); InsString( path, FALSE ); InsString( "$+$(__MAKEFILES__)$- ", FALSE ); DefMacro( "__MAKEFILES__" ); } return( RET_SUCCESS ); } return( RET_ERROR ); }
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 ); } }
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 ) ); }
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 ); }