📄 builder.c
字号:
}
if( rep == NULL ) {
if( UndefWarn ) {
Log( FALSE, "<%s> is undefined\n", out );
}
rep = "";
}
strcpy( out, rep );
*inp = in + 1;
return( out + strlen( out ) );
case '<':
++in;
p = SubstOne( &in, p );
break;
case '\0':
Fatal( "Missing '>'\n" );
break;
default:
*p++ = *in++;
break;
}
}
}
static void SubstLine( const char *in, char *out )
{
bool first;
first = TRUE;
in = SkipBlanks( in );
for( ;; ) {
switch( *in ) {
case '^': // Escape next byte special meaning
++in;
switch( *in ) {
case '\n':
case '\0':
case '\r': // Allow DOS line in UNIX port
case DOS_EOF_CHAR: // Allow DOS EOF in UNIX port
break;
default:
*out++ = *in++;
break;
}
break;
case '[': // Surround special chars with a space
case ']':
case '(':
case ')':
if( !first )
*out++ = ' ';
*out++ = *in++;
*out++ = ' ';
break;
case '<':
++in;
out = SubstOne( &in, out );
break;
case '\n':
case '\0':
case '\r': // Allow DOS line in UNIX port
case DOS_EOF_CHAR: // Allow DOS EOF in UNIX port
*out = '\0';
return;
default:
*out++ = *in++;
}
first = FALSE;
}
}
static char *FirstWord( char *p )
{
char *start;
p = SkipBlanks( p );
if( *p == '\0' )
return( NULL );
start = p;
for( ;; ) {
switch( *p ) {
case '\0':
p[1] = '\0';
/* fall through */
case ' ':
case '\t':
*p = '\0';
return( start );
}
++p;
}
}
static char *NextWord( char *p )
{
return( FirstWord( p + strlen( p ) + 1 ) );
}
/****************************************************************************
*
* MatchFound. Examines a string of space separated words. If the first word or
* words (between parentheses) matches any of the words following it, returns 1.
* If not, returns 0. String is terminated by 0 or ']'.
* If there isn't at least one word in the string, terminates program.
*
***************************************************************************/
static int MatchFound( char *p )
{
char *Match[20]; // 20 is enough for builder
int MatchWords = 0;
int i;
int EmptyOk = FALSE;
int WordsExamined = 0;
p = NextWord( p );
if( p == NULL )
Fatal( "Missing match word\n" );
if( *p == '(' ) { // Multiple match words, store them
p = NextWord( p );
for( ; MatchWords < 20; ) {
if( p == NULL )
Fatal( "Missing match word\n" );
if( stricmp( p, "\"\"" ) == 0 ) // 'No parameter' indicator
EmptyOk = TRUE;
else
Match[MatchWords++] = p;
p = NextWord( p );
if( strcmp( p, ")" ) == 0 ) {
p = NextWord( p );
break;
}
}
} else {
Match[MatchWords++] = p;
p = NextWord( p );
}
// At this point, p must point to the first word after the (last) match word
for( ;; ) {
if( p == NULL || strcmp( p, "]" ) == 0 ) { // End of string
if( WordsExamined == 0 && EmptyOk )
return 1;
else
return 0;
}
WordsExamined++;
for( i = 0; i < MatchWords; i++ )
if( stricmp( Match[i], p ) == 0 )
return 1;
p = NextWord( p );
}
}
static void ProcessCtlFile( const char *name )
{
char *p;
char *log_name;
unsigned res;
bool logit;
PushInclude( name );
while( GetALine( Line ) ) {
SubstLine( Line, ProcLine );
p = ProcLine;
switch( *p ) {
case '#':
case '\0':
/* just a comment */
break;
case '[':
/* a directive */
p = FirstWord( p + 1 );
if( stricmp( p, "INCLUDE" ) == 0 ) {
if( IncludeStk->skipping == 0 ) {
PushInclude( NextWord( p ) );
}
}
else if( stricmp( p, "LOG" ) == 0 ) {
if( IncludeStk->skipping == 0 ) {
log_name = NextWord( p );
p = NextWord( log_name );
if( p == NULL || strcmp( p, "]" ) == 0 ) {
BackupLog( log_name, LogBackup );
} else {
BackupLog( log_name, strtoul( p, NULL, 0 ) );
}
if( LogFile == NULL ) {
OpenLog( log_name );
}
}
} else if( stricmp( p, "BLOCK" ) == 0 ) {
IncludeStk->skipping = 0; // New block: reset skip flags
IncludeStk->ifdefskipping = 0;
if( !MatchFound( p ) )
IncludeStk->skipping++;
break;
} else if( stricmp( p, "IFDEF" ) == 0 ) {
if( IncludeStk->ifdefskipping != 0 )
IncludeStk->ifdefskipping--;
if( !MatchFound( p ) )
IncludeStk->ifdefskipping++;
break;
} else if( stricmp( p, "ENDIF" ) == 0 ) {
if( IncludeStk->ifdefskipping != 0 )
IncludeStk->ifdefskipping--;
break;
} else {
Fatal( "Unknown directive '%s'\n", p );
}
break;
default:
/* a command */
logit = ( VerbLevel > 0 );
if( *p == '@' ) {
logit = FALSE;
p = SkipBlanks( p + 1 );
}
if( IncludeStk->skipping == 0 && IncludeStk->ifdefskipping == 0 ) {
if( logit ) {
Log( FALSE, "+++<%s>+++\n", p );
}
strcpy( Line, p );
res = RunIt( p );
if( res != 0 ) {
if( !logit ) {
Log( FALSE, "<%s> => ", Line );
}
Log( FALSE, "non-zero return: %d\n", res );
if( StopOnError ) {
Fatal( "Build failed\n" );
}
}
LogFlush();
} else if( logit && ( VerbLevel > 1 ) ) {
Log( FALSE, "---<%s>---\n", p );
}
}
}
}
static bool SearchUpDirs( const char *name, char *result )
{
char buff[_MAX_PATH2];
char *drive;
char *dir;
char *fn;
char *ext;
char *end;
FILE *fp;
_fullpath( result, name, _MAX_PATH );
for( ;; ) {
fp = fopen( result, "r" );
if( fp != NULL ) {
fclose( fp );
return( TRUE );
}
_splitpath2( result, buff, &drive, &dir, &fn, &ext );
end = &dir[strlen( dir ) - 1];
if( end == dir )
return( FALSE );
switch( *end ) {
case '\\':
case '/':
--end;
}
for( ;; ) {
if( end == dir ) {
*end++ = '/';
break;
}
if( *end == '\\' || *end == '/' )
break;
--end;
}
*end = '\0';
_makepath( result, drive, dir, fn, ext );
}
}
int main( int argc, char *argv[] )
{
ctl_file *next;
const char *p;
SysInit( argc, argv );
ProcessOptions( argv + 1 );
if( CtlList == NULL ) {
p = getenv( DEFCTLENV );
if( p == NULL )
p = DEFCTLNAME;
if( !SearchUpDirs( p, Line ) ) {
Fatal( "Can not find '%s'\n", p );
}
AddCtlFile( Line );
}
while( CtlList != NULL ) {
ProcessCtlFile( CtlList->name );
next = CtlList->next;
free( CtlList );
CtlList = next;
}
CloseLog();
return( 0 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -