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)
|
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
|
2023-06-02: mmomtchev
|
||||||
[Javascript] #2622 Fix support for %typemap(default) and improve
|
[Javascript] #2622 Fix support for %typemap(default) and improve
|
||||||
support for default arguments in general.
|
support for default arguments in general.
|
||||||
|
|
|
@ -9,4 +9,8 @@
|
||||||
%inline %{
|
%inline %{
|
||||||
#include <vector>
|
#include <vector>
|
||||||
auto templated_lambda = []<typename T>(std::vector<T> t){};
|
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) {
|
int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) {
|
||||||
char c;
|
int old_line = s->line;
|
||||||
int num_levels = 1;
|
long position = Tell(s->str);
|
||||||
int state = 0;
|
|
||||||
String *locator = 0;
|
|
||||||
Clear(s->text);
|
|
||||||
Setfile(s->text, Getfile(s->str));
|
|
||||||
Setline(s->text, s->line);
|
|
||||||
|
|
||||||
Putc((char)startchar, s->text);
|
int num_levels = 1;
|
||||||
while (num_levels > 0) {
|
int starttok, endtok;
|
||||||
if ((c = nextchar(s)) == 0) {
|
switch (endchar) {
|
||||||
Delete(locator);
|
case '}':
|
||||||
return -1;
|
starttok = SWIG_TOKEN_LBRACE;
|
||||||
}
|
endtok = SWIG_TOKEN_RBRACE;
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
case 10:
|
case ')':
|
||||||
if (c == '/')
|
starttok = SWIG_TOKEN_LPAREN;
|
||||||
state = 11;
|
endtok = SWIG_TOKEN_RPAREN;
|
||||||
else if (c == '*')
|
|
||||||
state = 12;
|
|
||||||
else if (c == startchar) {
|
|
||||||
state = 0;
|
|
||||||
num_levels++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
state = 0;
|
|
||||||
break;
|
break;
|
||||||
case 11:
|
case ']':
|
||||||
if (c == '\n')
|
starttok = SWIG_TOKEN_LBRACKET;
|
||||||
state = 0;
|
endtok = SWIG_TOKEN_RBRACKET;
|
||||||
else
|
|
||||||
state = 11;
|
|
||||||
break;
|
break;
|
||||||
case 12: /* first character inside C comment */
|
case '>':
|
||||||
if (c == '*')
|
starttok = SWIG_TOKEN_LESSTHAN;
|
||||||
state = 14;
|
endtok = SWIG_TOKEN_GREATERTHAN;
|
||||||
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;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
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 *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) {
|
||||||
String *result = 0;
|
String *result = NULL;
|
||||||
char c;
|
|
||||||
int old_line = s->line;
|
int old_line = s->line;
|
||||||
String *old_text = Copy(s->text);
|
String *old_text = Copy(s->text);
|
||||||
long position = Tell(s->str);
|
long position = Tell(s->str);
|
||||||
|
|
||||||
int num_levels = 1;
|
int num_levels = 1;
|
||||||
int state = 0;
|
int starttok, endtok;
|
||||||
Clear(s->text);
|
switch (endchar) {
|
||||||
Setfile(s->text, Getfile(s->str));
|
case '}':
|
||||||
Setline(s->text, s->line);
|
starttok = SWIG_TOKEN_LBRACE;
|
||||||
Putc((char)startchar, s->text);
|
endtok = SWIG_TOKEN_RBRACE;
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
case 10:
|
case ')':
|
||||||
if (c == '/')
|
starttok = SWIG_TOKEN_LPAREN;
|
||||||
state = 11;
|
endtok = SWIG_TOKEN_RPAREN;
|
||||||
else if (c == '*')
|
|
||||||
state = 12;
|
|
||||||
else if (c == startchar) {
|
|
||||||
state = 0;
|
|
||||||
num_levels++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
state = 0;
|
|
||||||
break;
|
break;
|
||||||
case 11:
|
case ']':
|
||||||
if (c == '\n')
|
starttok = SWIG_TOKEN_LBRACKET;
|
||||||
state = 0;
|
endtok = SWIG_TOKEN_RBRACKET;
|
||||||
else
|
|
||||||
state = 11;
|
|
||||||
break;
|
break;
|
||||||
case 12: /* first character inside C comment */
|
case '>':
|
||||||
if (c == '*')
|
starttok = SWIG_TOKEN_LESSTHAN;
|
||||||
state = 14;
|
endtok = SWIG_TOKEN_GREATERTHAN;
|
||||||
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;
|
break;
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset the scanner state. */
|
||||||
Seek(s->str, position, SEEK_SET);
|
Seek(s->str, position, SEEK_SET);
|
||||||
result = Copy(s->text);
|
Delete(s->text);
|
||||||
Clear(s->text);
|
s->text = old_text;
|
||||||
Append(s->text, old_text);
|
|
||||||
Delete(old_text);
|
|
||||||
s->line = old_line;
|
s->line = old_line;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Scanner_isoperator()
|
* Scanner_isoperator()
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue