#247 get_string(), tokenize.c

open
nobody
None
5
2013-02-26
2013-02-26
qWord
No

Hello,
I've found that the get_string() function [tokenize.c] does not probably handle strings in the default case (undelimited_string) : for parentheses and angle bracket the nesting is not count, as MASM seems to do it. This can cause problem with function like macros, where the closing parenthesis is "eaten" by the macro argument: e.g. for:

;-------------------
foo macro x

endm

@foo macro x
echo x
EXITM <0>
endm

foo ~SomeText(xyz:foo) ;<- no problem for procedures

y = @foo(FOO::~FOO()) ;<- fails
;-------------------

Also, I've recognized that this maybe a problem for the switch-cases '{' and '<'.

A quick hack I've found for the default case:

// ###### #############################
undelimited_string:
buf->string_delim = NULLC;
/* this is an undelimited string,
* so just copy it until we hit something that looks like the end.
* this format is used by the INCLUDE directive, but may also
* occur inside the string macros!
*/
/* v2.05: also stop if a ')' is found - see literal2.asm regression test */
level = 0;
level2 = 0;
//for( count = 0 ; count < MAX_STRING_LEN && *src != NULLC && !isspace( *src ) && *src != ',' && *src != ';'; ) {
for( ; count < MAX_STRING_LEN &&
/* v2.08: stop also at < and % */
//*src != NULLC && !isspace( *src ) && *src != ',' && *src != ';' && *src != ')'; ) {
//*src && !isspace( *src ) && *src != ',' && *src != ')' && *src != '<' && *src != '%'; ) {
*src && !isspace( *src ) && *src != ',' && !(*src == ')' && level==0) && !(*src == '>' && level2==0) && *src != '%'; ) {
if ( p->flags == TOK_DEFAULT ) { /* fixme: '\' in <>-literals are handled ALWAYS */
if ( *src == '\\' ) {
if ( ConcatLine( src, count, dst, p ) != EMPTY ) {
DebugMsg1(("Tokenize.get_string: backslash concatenation: >%s<\n", src ));
p->flags3 |= TF3_ISCONCAT;
if ( count )
continue;
return( EMPTY );
}
} else if ( *src == ';' )
break;
}
/* v2.08: handle '!' operator */
if ( *src == '!' && *(src+1) && count < MAX_STRING_LEN - 1 )
*dst++ = *src++;

if ( *src == '(')
level++;
else if ( *src == ')')
level--;
else if ( *src == '<')
level2++;
else if ( *src == '>')
level2--;

*dst++ = *src++;
count++;
}
break;
// ###### #############################

regards, qWord

BTW: I've used the source code JWasm209s.zip

Discussion

  • japheth
    japheth
    2013-02-27

    Thanks, I will try your proposal!

    However, as for v2.10, I don't want to make changes at such core modules - with lots of possible side effects - anymore. A fix will have to wait for a possible v2.11.