📄 scan.c
字号:
return( Y_OR );
state(S_STRING):
/* handle double-byte characters */
if( CharSet[ LookAhead ] == DB_CHAR ) {
VarStringAddChar( newstring, LookAhead );
GetNextChar();
VarStringAddChar( newstring, LookAhead );
do_transition( S_STRING );
}
// if newline in string was detected, remove all whitespace from
// begining of the next line
if( newLineInString ) {
if ( isspace( LookAhead ) ) {
do_transition( S_STRING );
} else {
// non whitespace was detected, reset newline flag, so whitespaces are treated normally
newLineInString = 0;
}
}
switch (LookAhead) {
case '"': do_transition( S_STRINGEND );
case '\\': do_transition( S_ESCAPE_CHAR );
case '\n':
if( RcIoIsCOrHFile() ) {
value->string.string = VarStringEnd( newstring, &(value->string.length) );
DEBUGPUTS( "STRING" )
return( Y_STRING );
} else {
// MSVC's RC uses this obscure way of handling newline in strings and we follow.
// First store <space> and then <newline character>. Then on next line, all white
// spaces from begining of line is removed
VarStringAddChar( newstring, ' ' );
VarStringAddChar( newstring, LookAhead );
newLineInString = 1;
do_transition( S_STRING );
}
default:
VarStringAddChar( newstring, LookAhead );
do_transition( S_STRING );
}
state(S_ESCAPE_CHAR):
if( isdigit( LookAhead ) && LookAhead != '8' && LookAhead != '9' ) {
newint = LookAhead - '0';
do_transition( S_OCTAL_ESCAPE_1 );
} else switch( LookAhead ) {
case 'x':
newint = 0;
do_transition( S_HEX_ESCAPE_1 );
break;
case 'a':
/* this is what Microsoft's RC adds for a \a */
VarStringAddChar( newstring, '\x8' );
do_transition( S_STRING );
break;
case 'b':
VarStringAddChar( newstring, '\b' );
do_transition( S_STRING );
break;
case 'f':
VarStringAddChar( newstring, '\f' );
do_transition( S_STRING );
break;
case 'n':
VarStringAddChar( newstring, '\n' );
do_transition( S_STRING );
break;
case 'r':
VarStringAddChar( newstring, '\r' );
do_transition( S_STRING );
break;
case 't':
VarStringAddChar( newstring, '\t' );
do_transition( S_STRING );
break;
case 'v':
VarStringAddChar( newstring, '\v' );
do_transition( S_STRING );
break;
default:
VarStringAddChar( newstring, LookAhead );
do_transition( S_STRING );
break;
}
state(S_HEX_ESCAPE_1):
if( isxdigit( LookAhead ) ) {
AddDigitToInt( &newint, 16, LookAhead );
do_transition( S_HEX_ESCAPE_2 );
} else {
change_state( S_STRING );
}
state(S_HEX_ESCAPE_2):
if( isxdigit( LookAhead ) ) {
AddDigitToInt( &newint, 16, LookAhead );
VarStringAddChar( newstring, newint );
do_transition( S_STRING );
} else {
VarStringAddChar( newstring, newint );
change_state( S_STRING );
}
state(S_OCTAL_ESCAPE_1):
if( isdigit( LookAhead ) && LookAhead != '8' && LookAhead != '9' ) {
AddDigitToInt( &newint, 8, LookAhead );
do_transition( S_OCTAL_ESCAPE_2 );
} else {
VarStringAddChar( newstring, newint );
change_state( S_STRING );
}
state(S_OCTAL_ESCAPE_2):
if( isdigit( LookAhead ) && LookAhead != '8' && LookAhead != '9' ) {
AddDigitToInt( &newint, 8, LookAhead );
do_transition( S_OCTAL_ESCAPE_3 );
} else {
VarStringAddChar( newstring, newint );
change_state( S_STRING );
}
state(S_OCTAL_ESCAPE_3):
VarStringAddChar( newstring, newint );
change_state( S_STRING );
state(S_STRINGEND):
if( LookAhead == '"' ) { /* a "" in a string means include one " */
VarStringAddChar( newstring, LookAhead );
do_transition( S_STRING );
} else {
stringFromFile = VarStringEnd( newstring,
&( value->string.length ) );
value->string.string = stringFromFile;
#if(0)
//DRW - this code truncates trailing null chars in resources
// like user data. It is commented until I fix it.
if( CmdLineParms.FindAndReplace == TRUE ) {
char *temp;
temp = FindAndReplace( stringFromFile,
CmdLineParms.FindReplaceStrings );
// PrependToString prepends a string if that option
// is specified. As a string from the rc file is only scanned
// once and the string might have been changed by find and
// replace, this is needed here
prependToString( value, temp );
} else if( CmdLineParms.Prepend == TRUE ) {
prependToString( value, stringFromFile );
}
#endif
value->string.lstring = longString;
if( longString && CmdLineParms.TargetOS == RC_TARGET_OS_WIN16 ) {
RcWarning( ERR_LSTRING_IGNORED_FOR_WINDOWS );
value->string.lstring = FALSE;
}
DEBUGPUTS( value->string.string )
return( Y_STRING );
}
state(S_DECIMAL):
VarStringAddChar( newstring, LookAhead );
if( isdigit(LookAhead) ) {
AddDigitToInt( &newint, 10, LookAhead );
do_transition( S_DECIMAL );
} else if( toupper(LookAhead) == 'L' ) {
do_transition( S_LONGSUFFIX );
} else if( toupper(LookAhead) == 'U' ) {
do_transition( S_UNSIGNEDSUFFIX );
} else if( isalpha( LookAhead ) || LookAhead == '.'
|| LookAhead == '\\' || LookAhead == '_' ) {
do_transition( S_DOS_FILENAME );
} else {
value->intinfo.val = newint;
value->intinfo.str = VarStringEnd( newstring, NULL );
DEBUGPUTS( ltoa( newint, debugstring, 10 ) )
return( Y_INTEGER );
}
state(S_LONGSUFFIX):
VarStringAddChar( newstring, LookAhead );
value->intinfo.type |= SCAN_INT_TYPE_LONG;
if( toupper(LookAhead) == 'U' ) {
value->intinfo.type |= SCAN_INT_TYPE_UNSIGNED;
do_transition( S_ENDINT );
} else if( isalpha( LookAhead ) || LookAhead == '.'
|| LookAhead == '\\' || LookAhead == '_' ) {
do_transition( S_DOS_FILENAME );
} else {
value->intinfo.val = newint;
value->intinfo.str = VarStringEnd( newstring, NULL );
DEBUGPUTS( ltoa( newint, debugstring, 10 ) )
return( Y_INTEGER );
}
state(S_UNSIGNEDSUFFIX):
VarStringAddChar( newstring, LookAhead );
value->intinfo.type |= SCAN_INT_TYPE_UNSIGNED;
if( toupper(LookAhead) == 'L' ) {
value->intinfo.type |= SCAN_INT_TYPE_LONG;
do_transition( S_ENDINT );
} else if( isalpha( LookAhead ) || LookAhead == '.'
|| LookAhead == '\\' || LookAhead == '_' ) {
do_transition( S_DOS_FILENAME );
} else {
value->intinfo.val = newint;
value->intinfo.str = VarStringEnd( newstring, NULL );
DEBUGPUTS( ltoa( newint, debugstring, 10 ) )
return( Y_INTEGER );
}
state(S_ENDINT):
if( isalpha( LookAhead ) || LookAhead == '.'
|| LookAhead == '\\' || LookAhead == '_' ) {
VarStringAddChar( newstring, LookAhead );
do_transition( S_DOS_FILENAME );
} else {
value->intinfo.val = newint;
value->intinfo.str = VarStringEnd( newstring, NULL );
DEBUGPUTS( ltoa( newint, debugstring, 10 ) )
return( Y_INTEGER );
}
state(S_HEXSTART):
VarStringAddChar( newstring, LookAhead );
if( isdigit(LookAhead) ) {
if( LookAhead == '8' || LookAhead == '9' ) {
do_transition( S_DOS_FILENAME );
} else {
AddDigitToInt( &newint, 8, LookAhead );
do_transition( S_OCT );
}
} else if( toupper(LookAhead) == 'X' ) {
do_transition( S_HEX );
} else if( toupper(LookAhead) == 'L' ) {
do_transition( S_LONGSUFFIX );
} else if( toupper(LookAhead) == 'U' ) {
do_transition( S_UNSIGNEDSUFFIX );
} else if( isalpha( LookAhead ) || LookAhead == '.'
|| LookAhead == '\\' || LookAhead == '_' ) {
do_transition( S_DOS_FILENAME );
} else {
value->intinfo.val = newint;
DEBUGPUTS( ltoa( newint, debugstring, 10 ) )
value->intinfo.str = VarStringEnd( newstring, NULL );
return( Y_INTEGER );
}
state(S_OCT):
VarStringAddChar( newstring, LookAhead );
if( isdigit(LookAhead) ) {
if( LookAhead == '8' || LookAhead == '9' ) {
do_transition( S_DOS_FILENAME );
} else {
AddDigitToInt( &newint, 8, LookAhead );
do_transition( S_OCT );
}
} else if( toupper(LookAhead) == 'L' ) {
do_transition( S_LONGSUFFIX );
} else if( toupper(LookAhead) == 'U' ) {
do_transition( S_UNSIGNEDSUFFIX );
} else if( isalpha( LookAhead ) || LookAhead == '.'
|| LookAhead == '\\' || LookAhead == '_' ) {
do_transition( S_DOS_FILENAME );
} else {
value->intinfo.val = newint;
value->intinfo.str = VarStringEnd( newstring, NULL );
DEBUGPUTS( ltoa( newint, debugstring, 10 ) )
return( Y_INTEGER );
}
state(S_HEX):
VarStringAddChar( newstring, LookAhead );
if( isxdigit(LookAhead) ) {
AddDigitToInt( &newint, 16, LookAhead );
do_transition( S_HEX );
} else if( toupper(LookAhead) == 'L' ) {
do_transition( S_LONGSUFFIX );
} else if( toupper(LookAhead) == 'U' ) {
do_transition( S_UNSIGNEDSUFFIX );
} else if( isalpha( LookAhead ) || LookAhead == '.'
|| LookAhead == '\\' || LookAhead == '_' ) {
do_transition( S_DOS_FILENAME );
} else {
value->intinfo.val = newint;
value->intinfo.str = VarStringEnd( newstring, NULL );
DEBUGPUTS( ltoa( newint, debugstring, 10 ) )
return( Y_INTEGER );
}
state(S_NAME):
if( isalnum(LookAhead) || LookAhead == '_' ) {
VarStringAddChar( newstring, LookAhead );
do_transition( S_NAME );
} else if( LookAhead == ':' || LookAhead == '\\' || LookAhead == '.' ) {
VarStringAddChar( newstring, LookAhead );
do_transition( S_DOS_FILENAME );
} else {
value->string.string = VarStringEnd( newstring,
&(value->string.length) );
DEBUGPUTS( value->string.string )
token = LookupKeyword( value->string );
if( token != Y_NAME ) {
/* release the string if it is a keyword */
RcMemFree( value->string.string );
}
if( token == Y_RCINCLUDE ) {
/* when inline preprocessing is in place take steps here */
/* to make rcinclude's look line #include's */
RcFatalError( ERR_NO_RCINCLUDES );
}
return( token );
}
state(S_DOS_FILENAME):
if( isalnum(LookAhead) || LookAhead == ':' || LookAhead == '\\'
|| LookAhead == '.' || LookAhead == '_' ) {
VarStringAddChar( newstring, LookAhead );
do_transition( S_DOS_FILENAME );
} else {
value->string.string = VarStringEnd( newstring,
&(value->string.length) );
DEBUGPUTS( value->string.string )
return( Y_DOS_FILENAME );
}
} /* ScanDFA */
extern int Scan( ScanValue *value )
/*********************************/
{
int token;
token = ScanDFA( value );
while( token == Y_POUND_SIGN ) {
token = ScanCPPDirective( value );
}
return( token );
} /* Scan */
extern void ScanInitStatics( void )
/*********************************/
{
_next = 0;
LookAhead = 0;
longString = 0;
}
extern char *FindAndReplace( char *stringFromFile, FRStrings *frStrings )
/***********************************************************************/
{
char *replacedString = NULL;
char *foundString;
int lenOfStringFromFile;
int lenOfFindString;
int lenOfReplaceString;
int diffInLen;
int newMemSize;
int i, j, k;
int noOfInstances; //this is the number of instances
//of the find string in the string
//from the file
while( frStrings != NULL ) {
i = 0;
j = 0;
k = 0;
noOfInstances = 0;
newMemSize = 0;
foundString = NULL;
replacedString = NULL;
lenOfFindString = strlen( frStrings->findString );
lenOfReplaceString = strlen( frStrings->replaceString );
lenOfStringFromFile = strlen( stringFromFile );
diffInLen = lenOfReplaceString - lenOfFindString; //used for reallocation
if( strstr( stringFromFile, frStrings->findString ) != NULL ) {
//checking if a replacement is to be done, then allocating memory
replacedString = RcMemMalloc( lenOfStringFromFile+1 );
for( k=0; k < lenOfStringFromFile; k++) {
replacedString[k] = '\0';
}
while( i <= lenOfStringFromFile ) {
foundString = strstr( stringFromFile+i, frStrings->findString );
if( foundString != NULL ) {
while( foundString != &stringFromFile[i] ) {
//while the ptr is not where the replacment string is, copy.
replacedString[j] = stringFromFile[i];
i++;
j++;
}//end of while
if( diffInLen > 0 ) {
//allocating more memory if the string to replace is
//bigger than the string to find
newMemSize = lenOfStringFromFile + 1
+ diffInLen * ( noOfInstances + 1 );
replacedString = RcMemRealloc( replacedString, newMemSize );
}
strcpy( &replacedString[j], frStrings->replaceString );
j = j + lenOfReplaceString;
i = i + lenOfFindString-1;
noOfInstances++;
} else {
strcpy( &replacedString[j], &stringFromFile[i] );
break;
}//end of if-else
i++;
}//end of while
}
if( replacedString != NULL && frStrings->next != NULL ) {
stringFromFile = RcMemRealloc( stringFromFile,
strlen( replacedString ) + 1 );
strcpy( stringFromFile, replacedString );
RcMemFree( replacedString );
replacedString = NULL;
}
frStrings = frStrings->next;
}
if( replacedString != NULL ) {
RcMemFree( stringFromFile );
return( replacedString );
} else {
RcMemFree( replacedString );
return( stringFromFile );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -