mlexprs.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 686 行 · 第 1/2 页
C
686 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdlib.h>
#include "massert.h"
#include "mtypes.h"
#include "mlex.h"
#include "macros.h"
#include "make.h"
#include "mmemory.h"
#include "mmisc.h"
#include "mpreproc.h"
#include "mrcmsg.h"
#include "msg.h"
#include "mvecstr.h"
char *targ_path;
char *dep_path;
STATIC TOKEN_T lexLongFilePathName( STRM_T t, 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( t == DOUBLEQUOTE );
pos = 0;
t = PreGetCH();
/* \" 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 && t != DOUBLEQUOTE && t != EOL && t != STRM_END ) {
file[pos++] = t;
t = PreGetCH();
if( t == BACKSLASH ) {
if( pos >= _MAX_PATH ) {
break;
}
t = PreGetCH();
if( t == DOUBLEQUOTE ) {
file[pos++] = t;
t = PreGetCH();
} else {
file[pos++] = BACKSLASH;
}
}
}
if( pos >= _MAX_PATH ) {
PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
}
file[pos] = NULLCHAR;
if( t != DOUBLEQUOTE ) {
UnGetCH( t );
}
CurAttr.ptr = StrDupSafe( file );
return( tok );
}
#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
extern TOKEN_T LexPath( STRM_T t )
/*********************************
* returns: ({filec}*";")+ TOK_PATH
* EOL EOL
* STRM_END STRM_END
*/
{
char path[_MAX_PATH];
char string_open;
unsigned pos;
VECSTR vec; /* we'll store file/path here */
for( ;; ) { /* get first valid character */
if( t == EOL || t == STRM_END ) {
/* now we pass this to LexParser() so that it can reset */
return( LexParser( t ) );
}
if( t == STRM_MAGIC ) {
InsString( DeMacro( EOL ), TRUE );
} else if( !isfilec( t ) && t != PATH_SPLIT && t != ';' && t != '\"' &&
!isws( t ) ) {
PrtMsg( ERR | LOC | EXPECTING_M, M_PATH );
} else if( !isws( t ) ) {
break;
}
t = PreGetCH(); /* keep fetching characters */
}
/* just so you know what we've got now */
assert( isfilec( t ) || t == PATH_SPLIT || t == ';' || t == '\"' );
vec = StartVec();
pos = 0;
for( ;; ) {
/*
* Extract path from stream. If double quote is found, start string mode
* and ignore all filename character specifiers and just copy all
* characters. String mode ends with another double quote. Backslash can
* be used to escape only double quotes, otherwise they are recognized
* as path seperators. If we are not in string mode character validity
* is checked against isfilec().
*/
string_open = 0;
while( pos < _MAX_PATH && t != EOL && t != STRM_END ) {
if( t == BACKSLASH ) {
t = PreGetCH();
if( t == DOUBLEQUOTE ) {
path[pos++] = DOUBLEQUOTE;
} else {
path[pos++] = BACKSLASH;
// make sure we don't cross boundaries
if( pos < _MAX_PATH ) {
path[pos++] = t;
}
}
} else {
if( t == DOUBLEQUOTE ) {
string_open = !string_open;
} else {
if( string_open ) {
path[pos++] = t;
} else if( isfilec( t ) ) {
path[pos++] = t;
} else {
break; // not valid path character, break out.
}
}
}
t = PreGetCH();
}
if( string_open ) {
FreeSafe( FinishVec( vec ) );
PrtMsg( FTL | LOC | ERROR_STRING_OPEN );
}
if( pos == _MAX_PATH ) {
FreeSafe( FinishVec( vec ) );
PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
}
path[pos] = NULLCHAR;
WriteVec( vec, path );
if( t != PATH_SPLIT && t != ';' ) {
break;
}
pos = 0;
path[pos++] = PATH_SPLIT;
t = PreGetCH(); /* use Pre here to allow path;&(nl)path */
}
UnGetCH( t );
CurAttr.ptr = FinishVec( vec );
return( TOK_PATH );
}
#ifdef __WATCOMC__
#pragma off(check_stack);
#endif
#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
STATIC TOKEN_T lexFileName( STRM_T t )
/*************************************
* 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( isfilec( t ) || t == DOUBLEQUOTE ||
(Glob.microsoft || Glob.posix) && t == SPECIAL_TMP_DOL_C );
if( t == DOUBLEQUOTE ) {
return( lexLongFilePathName( t, TOK_FILENAME ) );
}
pos = 0;
while( pos < _MAX_PATH && (isfilec( t ) ||
t == SPECIAL_TMP_DOL_C && (Glob.microsoft || Glob.posix) ) ) {
file[pos++] = t;
t = PreGetCH();
}
if( pos == _MAX_PATH ) {
PrtMsg( FTL | LOC | MAXIMUM_TOKEN_IS, _MAX_PATH - 1 ); // NOTREACHED
}
file[pos] = NULLCHAR;
UnGetCH( t );
/* 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] == COLON ) {
file[pos - 1] = NULLCHAR; /* trim a trailing colon */
UnGetCH( COLON ); /* 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] == COLON ) {
file[pos - 1] = NULLCHAR; /* trim a trailing colon */
UnGetCH( COLON ); /* push back the colon */
}
CurAttr.ptr = StrDupSafe( file );
return( TOK_FILENAME );
}
#ifdef __WATCOMC__
#pragma off(check_stack);
#endif
STATIC BOOLEAN checkDotName( const char *str )
/*********************************************
* check if str is a special dotname. If it is, set CurAttr.num to the
* appropriate value, and return TRUE. If not a special dotname
* return FALSE.
*/
{
char **key;
char const *ptr;
assert( str[0] == DOT );
ptr = str + 1;
key = bsearch( &ptr, DotNames, DOT_MAX,
sizeof( char * ), (int (*)( const void*, const void* ))KWCompare );
if( key == NULL ) { /* not a special dot-name */
return( FALSE );
}
CurAttr.num = (const char **)key - DotNames;
assert( DOT_MIN < CurAttr.num && CurAttr.num < DOT_MAX );
return( TRUE );
}
STATIC char *getCurlPath( void )
/*******************************
* get the path between { and }
*/
{
TOKEN_T t;
char path[_MAX_PATH + 1];
int pos;
pos = 0;
t = PreGetCH();
if( t == L_CURL_PAREN ) {
t = PreGetCH();
while( t != R_CURL_PAREN && t != EOL && pos < _MAX_PATH ) {
path[pos++] = t;
t = PreGetCH();
}
path[pos] = NULLCHAR;
if( t == 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( t );
return( NULL );
}
}
#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
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
* "."{dot-name} TOK_DOTNAME
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?