mirror of https://github.com/swig/swig
Fix parsing of <= and >= in templated lambda
Skipping between matching delimiters is now done at the token level rather than the character level. Partly addresses #2630
This commit is contained in:
parent
94ba29410c
commit
40033f8498
|
@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.2.0 (in progress)
|
||||
===========================
|
||||
|
||||
2023-06-07: olly
|
||||
#2630 Fix parsing of <= and >= in templated lambda.
|
||||
|
||||
Skipping between matching delimiters is now done at the token level
|
||||
rather than the character level.
|
||||
|
||||
2023-06-02: mmomtchev
|
||||
[Javascript] #2622 Fix support for %typemap(default) and improve
|
||||
support for default arguments in general.
|
||||
|
|
|
@ -9,4 +9,8 @@
|
|||
%inline %{
|
||||
#include <vector>
|
||||
auto templated_lambda = []<typename T>(std::vector<T> t){};
|
||||
|
||||
// Regression test for parsing bug fixed in SWIG 4.2.0 (#2630)
|
||||
auto y = []<bool X = 1>=2> { return 1; };
|
||||
auto z = []<bool X = 1<=2> { return 1; };
|
||||
%}
|
||||
|
|
|
@ -1554,126 +1554,55 @@ void Scanner_skip_line(Scanner *s) {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) {
|
||||
char c;
|
||||
int num_levels = 1;
|
||||
int state = 0;
|
||||
String *locator = 0;
|
||||
Clear(s->text);
|
||||
Setfile(s->text, Getfile(s->str));
|
||||
Setline(s->text, s->line);
|
||||
int old_line = s->line;
|
||||
long position = Tell(s->str);
|
||||
|
||||
Putc((char)startchar, s->text);
|
||||
while (num_levels > 0) {
|
||||
if ((c = nextchar(s)) == 0) {
|
||||
Delete(locator);
|
||||
return -1;
|
||||
}
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (c == startchar)
|
||||
num_levels++;
|
||||
else if (c == endchar)
|
||||
num_levels--;
|
||||
else if (c == '/')
|
||||
state = 10;
|
||||
else if (c == '\"')
|
||||
state = 20;
|
||||
else if (c == '\'')
|
||||
state = 30;
|
||||
int num_levels = 1;
|
||||
int starttok, endtok;
|
||||
switch (endchar) {
|
||||
case '}':
|
||||
starttok = SWIG_TOKEN_LBRACE;
|
||||
endtok = SWIG_TOKEN_RBRACE;
|
||||
break;
|
||||
case 10:
|
||||
if (c == '/')
|
||||
state = 11;
|
||||
else if (c == '*')
|
||||
state = 12;
|
||||
else if (c == startchar) {
|
||||
state = 0;
|
||||
num_levels++;
|
||||
}
|
||||
else
|
||||
state = 0;
|
||||
case ')':
|
||||
starttok = SWIG_TOKEN_LPAREN;
|
||||
endtok = SWIG_TOKEN_RPAREN;
|
||||
break;
|
||||
case 11:
|
||||
if (c == '\n')
|
||||
state = 0;
|
||||
else
|
||||
state = 11;
|
||||
case ']':
|
||||
starttok = SWIG_TOKEN_LBRACKET;
|
||||
endtok = SWIG_TOKEN_RBRACKET;
|
||||
break;
|
||||
case 12: /* first character inside C comment */
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
else if (c == '@')
|
||||
state = 40;
|
||||
else
|
||||
state = 13;
|
||||
break;
|
||||
case 13:
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
break;
|
||||
case 14: /* possible end of C comment */
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
else if (c == '/')
|
||||
state = 0;
|
||||
else
|
||||
state = 13;
|
||||
break;
|
||||
case 20:
|
||||
if (c == '\"')
|
||||
state = 0;
|
||||
else if (c == '\\')
|
||||
state = 21;
|
||||
break;
|
||||
case 21:
|
||||
state = 20;
|
||||
break;
|
||||
case 30:
|
||||
if (c == '\'')
|
||||
state = 0;
|
||||
else if (c == '\\')
|
||||
state = 31;
|
||||
break;
|
||||
case 31:
|
||||
state = 30;
|
||||
break;
|
||||
/* 40-45 SWIG locator checks - a C comment with contents starting: @SWIG */
|
||||
case 40:
|
||||
state = (c == 'S') ? 41 : (c == '*') ? 14 : 13;
|
||||
break;
|
||||
case 41:
|
||||
state = (c == 'W') ? 42 : (c == '*') ? 14 : 13;
|
||||
break;
|
||||
case 42:
|
||||
state = (c == 'I') ? 43 : (c == '*') ? 14 : 13;
|
||||
break;
|
||||
case 43:
|
||||
state = (c == 'G') ? 44 : (c == '*') ? 14 : 13;
|
||||
if (c == 'G') {
|
||||
Delete(locator);
|
||||
locator = NewString("/*@SWIG");
|
||||
}
|
||||
break;
|
||||
case 44:
|
||||
if (c == '*')
|
||||
state = 45;
|
||||
Putc(c, locator);
|
||||
break;
|
||||
case 45: /* end of SWIG locator in C comment */
|
||||
if (c == '/') {
|
||||
state = 0;
|
||||
Putc(c, locator);
|
||||
Scanner_locator(s, locator);
|
||||
} else {
|
||||
/* malformed locator */
|
||||
state = (c == '*') ? 14 : 13;
|
||||
}
|
||||
case '>':
|
||||
starttok = SWIG_TOKEN_LESSTHAN;
|
||||
endtok = SWIG_TOKEN_GREATERTHAN;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int tok = Scanner_token(s);
|
||||
if (tok == starttok) {
|
||||
num_levels++;
|
||||
} else if (tok == endtok) {
|
||||
if (--num_levels == 0) break;
|
||||
} else if (tok == SWIG_TOKEN_COMMENT) {
|
||||
char *loc = Char(s->text);
|
||||
if (strncmp(loc, "/*@SWIG", 7) == 0 && loc[Len(s->text)-3] == '@') {
|
||||
Scanner_locator(s, s->text);
|
||||
}
|
||||
} else if (tok == 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Delete(locator);
|
||||
|
||||
Delete(s->text);
|
||||
s->text = NewStringWithSize(Char(s->str) + position - 1,
|
||||
Tell(s->str) - position + 1);
|
||||
Char(s->text)[0] = startchar;
|
||||
Setfile(s->text, Getfile(s->str));
|
||||
Setline(s->text, old_line);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1684,105 +1613,66 @@ int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) {
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
String *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) {
|
||||
String *result = 0;
|
||||
char c;
|
||||
String *result = NULL;
|
||||
int old_line = s->line;
|
||||
String *old_text = Copy(s->text);
|
||||
long position = Tell(s->str);
|
||||
|
||||
int num_levels = 1;
|
||||
int state = 0;
|
||||
Clear(s->text);
|
||||
Setfile(s->text, Getfile(s->str));
|
||||
Setline(s->text, s->line);
|
||||
Putc((char)startchar, s->text);
|
||||
while (num_levels > 0) {
|
||||
if ((c = nextchar(s)) == 0) {
|
||||
Clear(s->text);
|
||||
Append(s->text, old_text);
|
||||
Delete(old_text);
|
||||
s->line = old_line;
|
||||
return 0;
|
||||
}
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (c == startchar)
|
||||
num_levels++;
|
||||
else if (c == endchar)
|
||||
num_levels--;
|
||||
else if (c == '/')
|
||||
state = 10;
|
||||
else if (c == '\"')
|
||||
state = 20;
|
||||
else if (c == '\'')
|
||||
state = 30;
|
||||
int starttok, endtok;
|
||||
switch (endchar) {
|
||||
case '}':
|
||||
starttok = SWIG_TOKEN_LBRACE;
|
||||
endtok = SWIG_TOKEN_RBRACE;
|
||||
break;
|
||||
case 10:
|
||||
if (c == '/')
|
||||
state = 11;
|
||||
else if (c == '*')
|
||||
state = 12;
|
||||
else if (c == startchar) {
|
||||
state = 0;
|
||||
num_levels++;
|
||||
}
|
||||
else
|
||||
state = 0;
|
||||
case ')':
|
||||
starttok = SWIG_TOKEN_LPAREN;
|
||||
endtok = SWIG_TOKEN_RPAREN;
|
||||
break;
|
||||
case 11:
|
||||
if (c == '\n')
|
||||
state = 0;
|
||||
else
|
||||
state = 11;
|
||||
case ']':
|
||||
starttok = SWIG_TOKEN_LBRACKET;
|
||||
endtok = SWIG_TOKEN_RBRACKET;
|
||||
break;
|
||||
case 12: /* first character inside C comment */
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
else
|
||||
state = 13;
|
||||
break;
|
||||
case 13:
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
break;
|
||||
case 14: /* possible end of C comment */
|
||||
if (c == '*')
|
||||
state = 14;
|
||||
else if (c == '/')
|
||||
state = 0;
|
||||
else
|
||||
state = 13;
|
||||
break;
|
||||
case 20:
|
||||
if (c == '\"')
|
||||
state = 0;
|
||||
else if (c == '\\')
|
||||
state = 21;
|
||||
break;
|
||||
case 21:
|
||||
state = 20;
|
||||
break;
|
||||
case 30:
|
||||
if (c == '\'')
|
||||
state = 0;
|
||||
else if (c == '\\')
|
||||
state = 31;
|
||||
break;
|
||||
case 31:
|
||||
state = 30;
|
||||
case '>':
|
||||
starttok = SWIG_TOKEN_LESSTHAN;
|
||||
endtok = SWIG_TOKEN_GREATERTHAN;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int tok = Scanner_token(s);
|
||||
if (tok == starttok) {
|
||||
num_levels++;
|
||||
} else if (tok == endtok) {
|
||||
if (--num_levels == 0) {
|
||||
result = NewStringWithSize(Char(s->str) + position - 1,
|
||||
Tell(s->str) - position + 1);
|
||||
Char(result)[0] = startchar;
|
||||
Setfile(result, Getfile(s->str));
|
||||
Setline(result, old_line);
|
||||
break;
|
||||
}
|
||||
} else if (tok == SWIG_TOKEN_COMMENT) {
|
||||
char *loc = Char(s->text);
|
||||
if (strncmp(loc, "/*@SWIG", 7) == 0 && loc[Len(s->text)-3] == '@') {
|
||||
Scanner_locator(s, s->text);
|
||||
}
|
||||
} else if (tok == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the scanner state. */
|
||||
Seek(s->str, position, SEEK_SET);
|
||||
result = Copy(s->text);
|
||||
Clear(s->text);
|
||||
Append(s->text, old_text);
|
||||
Delete(old_text);
|
||||
Delete(s->text);
|
||||
s->text = old_text;
|
||||
s->line = old_line;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Scanner_isoperator()
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue