main.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 647 行 · 第 1/2 页
C
647 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: wmake input analysis
*
****************************************************************************/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#if defined(__OS2__) || defined(__DOS__)
#include <stdio.h>
#endif
#ifdef __WATCOMC__
#include <process.h>
#endif
#include "massert.h"
#include "mtypes.h"
#include "mtarget.h"
#include "msysdep.h"
#include "macros.h"
#include "make.h"
#include "mcache.h"
#include "mmemory.h"
#include "mexec.h"
#include "mmisc.h"
#include "mparse.h"
#include "mrcmsg.h"
#include "msg.h"
#include "msuffix.h"
#include "mupdate.h"
#include "mvecstr.h"
#include "mautodep.h"
STATIC TLIST *mustTargs; /* targets we must update */
STATIC TLIST *firstTargFound; /* first targets we ever found */
STATIC NODE *filesToDo; /* pointers into argv to -f files */
#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
STATIC void doBuiltIns( const char *makeopts )
/*********************************************
* perform the builtin commands
*/
{
TLIST *list;
char buf[2048];
char *cpy;
if( !Glob.overide ) {
DoingBuiltIn = TRUE;
FmtStr( buf, "%F", BuiltIns );
cpy = MallocSafe( 2048 + strlen( makeopts ) );
FmtStr( cpy, buf, makeopts );
InsString( cpy, FALSE );
list = Parse();
FreeTList( list );
strcpy(cpy, "MAKE=" );
if( _cmdname( cpy + sizeof "MAKE=" - 1 ) == NULL ) {
strcat( cpy, "wmake" );
}
InsString( cpy, FALSE );
list = Parse();
FreeTList( list );
if( Glob.microsoft | Glob.unix ) {
// suffixes must be parsed before builtins
const char *suffices = MSSuffixList;
const char *builtins = MSBuiltIn;
FmtStr( cpy, "%%MAKEFLAGS=$(%%MAKEFLAGS) %F", makeopts );
InsString( cpy, FALSE );
list = Parse();
FreeTList( list );
if( Glob.posix ) {
suffices = POSIXSuffixList;
builtins = POSIXBuiltIn;
} else if( Glob.unix ) {
suffices = UNIXSuffixList;
builtins = UNIXBuiltIn;
}
FmtStr( cpy, "%F", suffices );
InsString( cpy, FALSE );
list = Parse();
FreeTList( list );
FmtStr( buf, "%F", builtins );
} else {
FmtStr( buf, "%F", SuffixList );
}
FmtStr( cpy, buf, makeopts );
InsString( cpy, FALSE );
list = Parse();
FreeTList( list );
FreeSafe( cpy );
DoingBuiltIn = FALSE;
}
}
#ifdef __WATCOMC__
#pragma off(check_stack);
#endif
static void setFirstTarget( TLIST *potential_first )
/**************************************************/
{
if( firstTargFound != NULL || potential_first == NULL ) {
if( potential_first ) {
FreeTList( potential_first );
}
return;
}
/* Note all first targets must not have attribute explicit */
firstTargFound = potential_first;
}
void Header( void )
/*****************/
{
if( Glob.noheader ) {
return;
}
if( !Glob.headerout ) {
Glob.headerout = TRUE; /* so we don't print more than once */
PrtMsg( INF | BANNER );
}
}
STATIC void handleMacroDefn( const char *buf )
/*********************************************
* Can't use Parse() at this point because we need readonly macros, so we
* simply use LexToken().
* This statement is not true for microsoft option. In microsoft, all the
* macros even the one on the command line can be overwritten
*/
{
char *p;
char *q;
assert( buf != NULL );
q = StrDupSafe( buf ); /* we need our own copy */
p = strpbrk( q, "#=" );
assert( p != NULL );
*p = '='; /* lex doesn't recognize '#' */
InsString( q, FALSE ); /* put arg into stream */
while( LexToken( LEX_PARSER ) != STRM_END ) {
/* NOP - eat all the characters */
}
if( Glob.microsoft ) {
/* Insert twice because in nmake declaring a macro in the command line */
/* is equivalent to declaring one as is and one that is all upper case */
/* Approximately so. we cater for foo meaning FOO but not FoO W.Briscoe 20031114 */
/* This is no problem! In make, foo=bar only sets foo and FOO W.Briscoe 20041014 */
while( --p >= q ) {
*p = toupper( *p );
}
InsString( q, FALSE ); /* put arg into stream */
while( LexToken( LEX_PARSER ) != STRM_END ) {
/* NOP - eat the characters. Needs own eater. W.Briscoe 20041014 */
}
}
FreeSafe( q );
}
STATIC void handleTarg( const char *buf )
/***************************************/
{
assert( buf != NULL );
/* if it is not a valid target name, Update() won't be able to make it */
WildTList( &mustTargs, buf, FALSE, TRUE );
}
STATIC void checkCtrl( const char *p )
/************************************/
{
// p != NULL is checked by caller
while( *p ) { // scan for control characters
if( !isprint( *p ) ) {
PrtMsg( FTL | CTRL_CHAR_IN_CMD, *p );
}
++p;
}
}
STATIC char *procFlags( char const * const *argv, const char **log_name )
/************************************************************************
* process the flags, macro=defn, and targets from the command line
* writes targets to mustTargs, files to fileToDo, and defines macros
* it is important to have the ms switch first to have correct functionality
* of some features in microsoft compatability
*/
{
char select = '\0'; /* - or swchar (*argv)[0] */
char option = '\0'; /* the option (*argv)[1] */
const char *p; /* working pointer to *argv */
NODE *new; /* for adding a new file */
int options[256 + 1] = { 0 };
if( (p = argv[1]) != NULL ) {
if( strcmp( p, "?" ) == 0
|| ((p[0] == '-' || p[0] == Glob.swchar) && strcmp( p + 1, "?" ) == 0) ) {
Usage();
}
}
Glob.macreadonly = TRUE;
while( *++argv != NULL ) {
checkCtrl( p = *argv );
select = p[0], option = (char) tolower( p[1] );
if( select == '-' || select == Glob.swchar ) {
if( option != NULLCHAR && p[2] == NULLCHAR ) {
switch( option ) {
case '?': Usage(); break;
case 'a': Glob.all = TRUE; break;
case 'b': Glob.block = TRUE; break;
case 'c': Glob.nocheck = TRUE; break;
case 'd': Glob.debug = TRUE; break;
case 'e': Glob.erase = TRUE; break;
case 'h': Glob.noheader = TRUE; break;
case 'i': Glob.ignore = TRUE; break;
case 'j': Glob.rcs_make = TRUE; break;
case 'k': Glob.cont = TRUE; break;
case 'm': Glob.nomakeinit= TRUE; break;
case 'n': Glob.noexec = TRUE; break;
case 'o': Glob.optimize = TRUE; break;
case 'p': Glob.print = TRUE; break;
case 'q': Glob.query = TRUE; break;
case 'r': Glob.overide = TRUE; break;
case 's': Glob.silent = TRUE; break;
case 't': Glob.touch = TRUE; break;
case 'u': Glob.unix = TRUE; break;
case 'v': Glob.verbose = TRUE; break;
case 'w': Glob.auto_depends = TRUE;break;
#ifdef CACHE_STATS
case 'x': Glob.cachestat = TRUE; break;
#endif
case 'y': Glob.show_offenders = TRUE; break;
case 'z': Glob.hold = TRUE; break;
/* these options require a filename */
case 'f':
case 'l':
if( ( p = *++argv ) == NULL ) {
PrtMsg( ERR | INVALID_FILE_OPTION, select, option );
Usage();
}
checkCtrl( p );
if( option == 'f' ) {
if( (p[0] == '-') && (p[1] == NULLCHAR) ) {
// stdin
} else if( (p[0] == '-') || (p[0] == Glob.swchar) ) {
PrtMsg( ERR | INVALID_FILE_OPTION, select, option );
Usage();
}
new = MallocSafe( sizeof( *new ) );
new->name = (char *)p;
new->next = filesToDo;
filesToDo = new;
} else
*log_name = p;
break;
default:
PrtMsg( ERR | INVALID_OPTION, select, option );
Usage();
break;
}
options[(option | 0x20) + 1] = TRUE;
continue;
}
if( p[3] == NULLCHAR ) {
if( option == 'm' && tolower( p[2] ) == 's' ) {
Glob.microsoft = TRUE;
Glob.nocheck = TRUE;
options[(option | 0x20) + 1] = TRUE;
continue;
}
if( option == 's' && tolower( p[2] ) == 'n' ) {
Glob.silentno = TRUE;
options[(option | 0x20) + 1] = TRUE;
continue;
}
if( option == 'u' && tolower( p[2] ) == 'x' ) {
Glob.unix = TRUE;
Glob.posix = TRUE;
Glob.nomakeinit = TRUE;
Glob.nocheck = TRUE;
options[(option | 0x20) + 1] = TRUE;
continue;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?