cmdutils.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,253 行 · 第 1/3 页
C
1,253 行
bool isdig;
bool isvalid;
char ch;
int size;
unsigned value;
size = 0;
value = 0;
for(;;) {
ch = tolower( *str );
isdig = isdigit( ch );
if( radix == 8 ) {
isvalid = isdig && !(ch == '8' && ch == '9');
} else {
isvalid = isxdigit( ch );
}
if( !isvalid ) break;
value *= radix;
if( isdig ) {
value += ch - '0';
} else {
value += ch - 'a' + 10;
}
size++;
str++;
}
*Token.next = value;
return( size );
}
static void MapEscapeChar( void )
/*******************************/
/* turn the current character located at Token.next into a possibly unprintable
* character using C escape codes */
{
char * str;
int shift;
shift = 2;
str = Token.next + 1;
switch( *str ) {
case 'a':
*Token.next = '\a';
break;
case 'b':
*Token.next = '\b';
break;
case 'f':
*Token.next = '\f';
break;
case 'n':
*Token.next = '\n';
break;
case 'r':
*Token.next = '\r';
break;
case 't':
*Token.next = '\t';
break;
case 'v':
*Token.next = '\v';
break;
case 'x':
shift += ParseNumber( ++str, 16 );
break;
case '0': case '1': case '2': case '3': case '4': case'5': case '6':
case '7': case '8': case '9':
shift += ParseNumber( str, 8 ) - 1;
break;
default:
*Token.next = *str;
break;
}
str = Token.next + shift;
memmove( Token.next + 1, str, strlen( str ) + 1 );
}
static int MapDoubleByteChar( char c )
/************************************/
/* if the double byte character support is on, check if the current character
* is a double byte character skip it */
{
switch( CmdFlags & CF_LANGUAGE_MASK ) {
case CF_LANGUAGE_JAPANESE:
if( (c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <=0xFC) ) {
Token.next++;
return 1;
}
break;
case CF_LANGUAGE_CHINESE:
if( c > 0xFC ) break;
case CF_LANGUAGE_KOREAN: // note the fall through
if( c > 0xFD ) break;
if( c < 0x81 ) break;
Token.next++;
return 1;
}
return 0;
}
static bool MakeToken( tokcontrol ctrl, sep_type separator )
/**********************************************************/
{
bool quit;
char hmm;
int len;
bool forcematch;
bool hitmatch;
bool keepspecial;
Token.this = Token.next;
len = 0;
quit = FALSE;
forcematch = (separator == SEP_QUOTE) || (separator == SEP_PAREN)
|| (separator == SEP_PERCENT);
keepspecial = (separator == SEP_SPACE) || (separator == SEP_DOT_EXT);
if( separator == SEP_DOT_EXT ) { /* KLUDGE! we want to allow a zero*/
len--; /* length token for parsing wlib files, so */
Token.next--; /* artificially back up one here. */
}
if( *Token.next == '\\' && separator == SEP_QUOTE
&& !(ctrl & TOK_IS_FILENAME) ) {
MapEscapeChar(); /* get escape chars starting in 1st pos. */
}
hmm = *Token.next;
len += MapDoubleByteChar( hmm );
hitmatch = FALSE;
for(;;) {
len++;
hmm = *++Token.next;
switch( hmm ) {
case '\'':
if( separator == SEP_QUOTE ) {
++Token.next; // don't include end quote in next token.
hitmatch = TRUE;
quit = TRUE;
}
break;
case ')':
if( separator == SEP_PAREN ) {
++Token.next; // don't include end paren in next token.
hitmatch = TRUE;
quit = TRUE;
}
break;
case '%':
if( separator == SEP_PERCENT ) {
++Token.next; // don't include end percent in next token.
hitmatch = TRUE;
quit = TRUE;
}
break;
case '.':
if( !(ctrl & TOK_INCLUDE_DOT) && !forcematch ) {
quit = TRUE;
}
break;
case '{':
case '}':
case '(':
case ',':
case '=':
case '#':
case '@':
if( keepspecial ) {
break;
} // NOTE the potential fall through
case '\t':
case ' ':
if( !forcematch ) {
quit = TRUE;
}
break;
case '\\':
if( separator == SEP_QUOTE && !(ctrl & TOK_IS_FILENAME) ) {
MapEscapeChar();
}
break;
case '\0':
case '\r':
case '\n':
case CTRLZ:
quit = TRUE;
break;
default:
len += MapDoubleByteChar( hmm );
}
if( quit ) {
break;
}
}
Token.len = len;
if( forcematch && !hitmatch ) {
return( FALSE ); // end quote/paren not found before token end.
}
return( TRUE );
}
extern char *FileName( char *buff, int len, byte etype, bool force )
/******************************************************************/
{
char * namptr;
char * namstart;
char * ptr;
int cnt;
int namelen;
namptr = buff + len;
cnt = 0;
while( cnt != len ) {
cnt++;
--namptr;
if( IS_PATH_SEP( *namptr ) ) break;
}
if( IS_PATH_SEP( *namptr ) ) {
namptr++;
}
namstart = namptr;
cnt = len - ( (int) namptr - (int) buff );
if( cnt == 0 ) {
ptr = alloca( len + 1 );
memcpy( ptr, buff, len );
ptr[len] = '\0';
LnkMsg( LOC+LINE+FTL+MSG_INV_FILENAME, "s", ptr );
}
namelen = cnt;
namptr = buff + len - 1;
while( --cnt != 0 && *namptr != '.' ) {
namptr--;
}
if( force || *namptr != '.' ) {
if( force && etype == E_MAP ) { // op map goes in current dir.
buff = namstart;
len = namelen;
}
if( cnt != 0 ) {
len = namptr - buff;
}
_ChkAlloc( ptr, len + strlen( DefExt[ etype ] ) + 1 );
memcpy( ptr, buff, len );
strcpy( ptr + len, DefExt[ etype ] );
} else {
_ChkAlloc( ptr, len + 1 );
memcpy( ptr, buff, len );
ptr[ len ] = '\0';
}
return( ptr );
}
extern void RestoreCmdLine( void )
/********************************/
// Restore a saved command line.
{
cmdfilelist * temp;
if( CmdFile->prev == NULL ) { /* can't free last file */
Token.where = ENDOFCMD;
return;
}
switch( Token.how ) {
case SYSTEM:
break;
default:
_LnkFree( Token.buff );
if( CmdFile->file > STDIN_HANDLE ) {
QClose( CmdFile->file, CmdFile->name );
}
break;
}
if( CmdFile->symprefix)
_LnkFree( CmdFile->symprefix );
CmdFile->symprefix = NULL;
_LnkFree( CmdFile->name );
temp = CmdFile->prev;
temp->next = CmdFile->next;
if( temp->next != NULL ) {
temp->next->prev = temp;
}
_LnkFree( CmdFile );
CmdFile = temp;
memcpy( &Token, &CmdFile->token, sizeof( tok ) ); // restore old state.
}
extern bool IsSystemBlock()
/*************************/
// Are we in a system block?
{
cmdfilelist * temp;
if( Token.how == SYSTEM ) return( TRUE );
for( temp = CmdFile; temp != NULL; temp = temp->prev ) {
if( temp->token.how == SYSTEM ) return( TRUE );
}
return( FALSE );
}
extern void BurnUtils( void )
/***************************/
// Burn data structures used in command utils.
{
void * temp;
if( CmdFile->next != NULL ) {
LnkMsg( LOC+LINE+ERR+MSG_NO_INPUT_LEFT, NULL );
}
while( CmdFile != NULL ) {
if( CmdFile->file > STDIN_HANDLE ) {
QClose( CmdFile->file, CmdFile->name );
}
if( CmdFile->symprefix)
_LnkFree( CmdFile->symprefix );
CmdFile->symprefix = NULL;
_LnkFree( CmdFile->name );
switch( CmdFile->token.how ) {
case ENVIRONMENT:
case SYSTEM:
break;
default:
_LnkFree( CmdFile->token.buff );
break;
}
temp = CmdFile;
CmdFile = CmdFile->prev;
_LnkFree( temp );
}
Token.how = BUFFERED; // so error message stuff reports right name
}
extern outfilelist * NewOutFile( char * filename )
/************************************************/
{
outfilelist * fnode;
fnode = OutFiles;
while( fnode != NULL ) {
if( FNAMECMPSTR( filename, fnode->fname ) == 0 ) {
_LnkFree( filename ); // don't need this now.
return( fnode );
}
fnode = fnode->next;
}
// file name not already in list, so add a list entry.
_ChkAlloc( fnode, sizeof( outfilelist ) );
InitBuffFile( fnode, filename, TRUE );
fnode->next = OutFiles;
OutFiles = fnode;
return( fnode );
}
int stricmp_wrapper( const void *s1, const void *s2 )
{
return stricmp( s1, s2 );
}
extern section * NewSection( void )
/*********************************/
{
section *sect;
OvlNum++;
_ChkAlloc( sect, sizeof( section ) );
sect->next_sect = NULL;
sect->classlist = NULL;
sect->orderlist = NULL;
sect->areas = NULL;
sect->files = NULL;
sect->modFilesHashed = CreateHTable( 256, StringiHashFunc, stricmp_wrapper,
ChkLAlloc, LFree );
sect->mods = NULL;
sect->reloclist = NULL;
sect->sect_addr.off = 0;
sect->sect_addr.seg = UNDEFINED;
sect->ovl_num = 0;
sect->parent = NULL;
sect->relocs = 0;
sect->size = 0;
sect->outfile = NULL;
sect->u.dist_mods = NULL;
sect->dbg_info = NULL;
return( sect );
}
extern char * GetFileName( char **membname, bool setname )
/********************************************************/
{
char * ptr;
int namelen;
char * objname;
char * fullmemb;
int memblen;
namelen = Token.len;
objname = alloca( namelen );
memcpy( objname, Token.this, namelen );
if( GetToken( SEP_PAREN, TOK_INCLUDE_DOT ) ) { // got LIBNAME(LIB_MEMBER)
fullmemb = alloca( Token.len + 1 );
memcpy( fullmemb, Token.this, Token.len );
fullmemb[Token.len] = '\0';
fullmemb = RemovePath( fullmemb, &memblen );
_ChkAlloc( *membname, memblen + 1 );
memcpy( *membname, fullmemb, memblen );
(*membname)[memblen] = '\0';
ptr = FileName( objname, namelen, E_LIBRARY, FALSE );
} else {
*membname = NULL;
if( setname && Name == NULL ) {
_ChkAlloc( Name, namelen + 1 );
memcpy( Name, objname, namelen );
Name[ namelen ] = '\0';
}
ptr = FileName( objname, namelen, E_OBJECT, FALSE );
}
return( ptr );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?