cmdline.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 859 行 · 第 1/2 页
C
859 行
char buffer[ _MAX_PATH2 ];
char *drive;
char *dir;
char *fname;
char *ext;
char path[ _MAX_PATH ];
int fh;
_splitpath2( file_name, buffer, &drive, &dir, &fname, &ext );
_makepath( path, drive, dir, fname, ( ext[0] == 0 ) ? WMP_EXTENSION : ext );
fh = open( path, O_RDONLY | O_TEXT );
if( fh == -1 ) {
Fatal( MSG_UNABLE_TO_OPEN_FILE, path );
}
return( fh );
}
STATIC char *readIncludeFile( int fh ) {
#define READ_SIZE 512
size_t file_len;
size_t len_read;
char buf[ READ_SIZE + 1 ]; /* extra byte for a sentinal */
char *file;
char *fptr;
size_t i;
/**/myassert( fh != -1 );
/*
We will count the non-space characters in the file. White space will be
collapsed into a single space (or two spaces if it crosses a READ_SIZE
byte boundary) to save memory.
Be careful! The two loops which read the file must behave identically!
Otherwise the second loop which writes to memory might overwrite the
buffer allocation.
*/
file_len = 0;
/**/myassert( !isspace( 0 ) ); /* will be using 0 as a sentinal */
for(;;) {
len_read = read( fh, buf, READ_SIZE );
if( len_read == 0 ) break;
buf[ len_read ] = 0; /* a sentinal so we can speed this up a bit */
i = 0;
do {
++file_len;
if( file_len == 0 ) {
close( fh );
Fatal( MSG_INCLUDE_TOO_LARGE );
}
if( isspace( buf[ i ] ) ) {
do {
++i;
} while( isspace( buf[ i ] ) ); /* use sentinal to stop */
} else {
++i;
}
} while( i < len_read );
}
if( file_len > 0 ) {
/* now read the file into an array of the appropriate size */
if( lseek( fh, (long)0, SEEK_SET ) == -1 ) {
Fatal( MSG_DISK_ERROR, "lseek" );
}
file = MemAlloc( file_len + 1 );
fptr = file;
for(;;) {
len_read = read( fh, buf, READ_SIZE );
if( len_read == 0 ) break;
buf[ len_read ] = 0; /* set sentinal */
i = 0;
do {
*fptr++ = buf[ i ];
if( isspace( buf[ i ] ) ) {
do {
++i;
} while( isspace( buf[ i ] ) ); /* use sentinal */
} else {
++i;
}
} while( i < len_read );
}
*fptr = 0;
} else {
file = NULL;
}
close( fh );
return( file );
#undef READ_SIZE
}
FORWARD STATIC void parseString( const char *str );
STATIC const char *doInclude( const char *str ) {
int fh;
char *file;
char *file_name;
const char *env_var;
/**/myassert( str != NULL );
if( isBreakChar( *str ) ) unrecognized( '@' );
file_name = getFile( &str );
env_var = getenv( file_name );
if( env_var != NULL ) {
MemFree( file_name );
parseString( env_var );
} else {
/* both these functions use a lot of stack, so we separate them */
fh = openIncludeFile( file_name );
MemFree( file_name );
file = readIncludeFile( fh );
if( file != NULL ) {
parseString( file );
MemFree( file );
}
}
return( str );
}
#pragma off( check_stack );
STATIC void parseString( const char *str ) {
/**/myassert( str != NULL );
for(;;) {
while( isspace( *str ) ) ++str;
switch( *str ) {
case 0:
return;
case SWCHAR:
case '-':
str += 2;
switch( str[-1] ) {
case 'o': str = doOutput( str ); break;
case 'd': str = doDebug( str ); break;
case 'p': str = doParse( str ); break;
case 'f': str = doFile( str ); break;
case 'q': /* FALL THROUGH */
#if 0
case 'l':
#endif
case 'b': str = doToggle( str ); break;
default: usage();
}
if( !isBreakChar( *str ) ) usage();
break;
case INCCHAR:
str = doInclude( str + 1 );
break;
case CMTCHAR:
str = doComment( str + 1 );
break;
default:
str = addFile( str );
break;
}
}
}
cmdline_t *CmdLineParse( void ) {
/*****************************/
const char *env_var;
char *cmd_line;
size_t cmd_len;
act_grp_t *cur;
act_grp_t *next;
tempFileNum = 0;
env_var = getenv( ENVVAR );
if( env_var != NULL ) {
parseString( env_var );
}
cmd_line = MemAlloc( 10240 ); /* FIXME - arbitrarily large constant! */
getcmd( cmd_line );
cmd_len = strlen( cmd_line );
if( cmd_len > 0 ) {
cmd_line = MemRealloc( cmd_line, cmd_len + 1 );
parseString( cmd_line );
}
MemFree( cmd_line );
/* reverse the stack of actions */
cmdLine.action = NULL; /* no actions by default */
cur = curAct;
while( cur != NULL ) {
next = cur->next;
if( cur->num_files == 0 ) { /* trim out the needless actions */
MemFree( cur );
} else {
cur->next = cmdLine.action; /* stack it up */
cmdLine.action = cur;
}
cur = next;
}
if( cmdLine.action == NULL ) {
usage();
}
cmdLine.quiet = cmdLine.action->quiet;
header();
return( &cmdLine );
}
void ActionInit( cmdline_t *cmd ) {
/*******************************/
act_grp_t *cur;
int os2_specific;
/**/myassert( cmd != NULL && cmd->action != NULL );
cur = cmd->action;
cmdLine.quiet = cmdLine.action->quiet;
os2_specific = 0;
switch( cur->omf_generator ) {
case OGEN_NULL:
cmd->need_output = 0;
break;
case OGEN_MICROSOFT_OS2:
os2_specific = 1;
/* fall through */
case OGEN_MICROSOFT:
GenMSOmfInit();
cmd->need_output = 1;
break;
case OGEN_PHARLAP:
GenPharInit();
cmd->need_output = 1;
break;
default:
/**/ never_reach();
}
switch( cur->dbg_generator ) {
case DGEN_NULL:
break;
case DGEN_TXT:
Can2TxtInit();
break;
case DGEN_MICROSOFT:
Can2MsInit( 0, os2_specific );
break;
case DGEN_METAWARE:
Can2MsInit( 1, os2_specific );
break;
case DGEN_TURBO:
Can2TDInit();
break;
default:
/**/ never_reach();
}
if( cur->deflib ) {
DefLibInit();
}
switch( cur->dbg_parser ) {
case PARSE_NULL: break;
case PARSE_WATCOM: Wat2CanInit( 0 ); break;
case PARSE_WATCOM_70: Wat2CanInit( 1 ); break;
default:
/**/ never_reach();
}
}
void ActionFini( cmdline_t *cmd ) {
/*******************************/
act_grp_t *cur;
act_grp_t *next;
size_t file_num;
size_t num_files;
/**/myassert( cmd != NULL && cmd->action != NULL );
cur = cmd->action;
switch( cur->dbg_parser ) {
case PARSE_NULL: break;
case PARSE_WATCOM: Wat2CanFini(); break;
case PARSE_WATCOM_70: Wat2CanFini(); break;
default:
/**/ never_reach();
}
if( cur->deflib ) {
DefLibFini();
}
switch( cur->dbg_generator ) {
case DGEN_NULL: break;
case DGEN_TXT: Can2TxtFini(); break;
case DGEN_MICROSOFT: Can2MsFini(); break;
case DGEN_METAWARE: Can2MsFini(); break;
case DGEN_TURBO: Can2TDFini(); break;
default:
/**/ never_reach();
}
switch( cur->omf_generator ) {
case OGEN_NULL: break;
case OGEN_MICROSOFT_OS2:GenMSOmfFini(); break;
case OGEN_MICROSOFT: GenMSOmfFini(); break;
case OGEN_PHARLAP: GenPharFini(); break;
default:
/**/ never_reach();
}
if( cur->output != NULL ) {
MemFree( cur->output );
}
num_files = cur->num_files;
for( file_num = 0; file_num < num_files; ++file_num ) {
MemFree( cur->files[ file_num ] );
}
next = cur->next;
MemFree( cur );
cmd->action = next;
}
void ActionInfile( cmdline_t *cmd, char *buf, uint file_num ) {
/***********************************************************/
char buffer[ _MAX_PATH2 ];
char *drive;
char *dir;
char *fname;
char *ext;
/**/myassert( cmd != NULL );
/**/myassert( cmd->action != NULL );
/**/myassert( file_num < cmd->action->num_files );
_splitpath2( cmd->action->files[ file_num ], buffer,
&drive, &dir, &fname, &ext );
_makepath( buf, drive, dir, fname, ( ext[0]==0 ) ? OBJ_EXTENSION : ext );
}
void ActionOutfile( cmdline_t *cmd, char *buf, uint file_num ) {
/************************************************************/
char sp_buf[ _MAX_PATH2 ];
char *drive;
char *dir;
char fname[ _MAX_FNAME ];
const char *output;
/**/myassert( cmd != NULL );
/**/myassert( cmd->need_output );
/**/myassert( cmd->action != NULL );
/**/myassert( file_num < cmd->action->num_files );
output = cmd->action->output;
_splitpath2( ( output == NULL || output[0] == 0 ) ?
cmd->action->files[ file_num ] : output,
sp_buf, &drive, &dir, NULL, NULL );
fname[0] = '_';
fname[1] = 'W';
for(;;) {
StrDec( &fname[2], tempFileNum++ );
_makepath( buf, drive, dir, fname, "TMP" );
if( access( buf, 0 ) == -1 ) {
break;
}
}
}
/*
FIXME: this is an ugly function!
*/
void ActionRename( cmdline_t *cmd, const char *in, const char *out,
uint file_num, int make_lib, size_t page_size ) {
/***************************************************/
char sp_buf[ _MAX_PATH2 ];
char sp_buf2[ _MAX_PATH2 ];
char *drive;
char *dir;
char *fname;
char *ext;
char buf[ _MAX_PATH ];
const char *output;
act_grp_t *cur;
int rc;
/**/myassert( cmd != NULL );
/**/myassert( cmd->need_output );
/**/myassert( cmd->action != NULL );
/**/myassert( file_num < cmd->action->num_files );
cur = cmd->action;
output = cur->output;
if( output == NULL || output[0] == 0 ) {
/* get the drive and directory of input file */
_splitpath2( in, sp_buf, &drive, &dir, NULL, NULL );
fname = "";
ext = "";
} else {
/* split up the output spec */
_splitpath2( output, sp_buf, &drive, &dir, &fname, &ext );
}
/* If the output spec was like '/o=.mbj' or '/o=f:\tmp\.mbj' then
we have to use the filename and/or the extension from the input. */
_splitpath2( cur->files[ file_num ], sp_buf2, NULL, NULL,
( fname[0] == 0 ) ? &fname : NULL, /* get filename from input */
( ext[0] == 0 ) ? &ext : NULL ); /* get extension from input */
if( ext[0] == 0 ) { /* use default extension if necessary */
ext = OBJ_EXTENSION;
}
_makepath( buf, drive, dir, fname, ext );
if( make_lib ) {
if( cur->batch ) {
PrtFmt( "wlib %s /b/n/p=%u +%s\n", buf, page_size, out );
PrtFmt( "del %s\n", out );
} else {
char pbuf[ sizeof( size_t ) * 3 ];
StrDec( pbuf, page_size );
#ifdef M_I86
_fheapshrink();
#endif
_nheapshrink();
rc = spawnlp(P_WAIT,"wlib","wlib",buf,"/b/n/p=",pbuf,"+",out,NULL);
if( rc < 0 ) {
Fatal( MSG_DISK_ERROR, "spawnlp( , \"wlib\", ... )" );
} else if( rc > 0 ) {
Fatal( MSG_WLIB_ERROR );
}
if( unlink( out ) != 0 ) {
Fatal( MSG_DISK_ERROR, "unlink" );
}
}
} else if( cur->batch ) {
PrtFmt( "if exist %s del %s\n", buf, buf );
PrtFmt( "rename %s %s\n", out, buf );
} else {
unlink( buf ); /* delete any file of this name */
if( rename( out, buf ) != 0 ) {
Fatal( MSG_DISK_ERROR, "rename" );
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?