Added support for custom string delimiters.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2009-matevz@11328 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
0f2786aa54
commit
ee8bebb668
2 changed files with 122 additions and 35 deletions
|
|
@ -16,15 +16,27 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
string a="ABC";
|
int L = 100;
|
||||||
wstring wide=L"ABC";
|
int u8 = 100;
|
||||||
string c=u8"ABC";
|
int u = 100;
|
||||||
string b=u"ABC";
|
int U = 100;
|
||||||
string d=U"ABC";
|
|
||||||
|
int R = 100;
|
||||||
|
int LR = 100;
|
||||||
|
int u8R = 100;
|
||||||
|
int uR = 100;
|
||||||
|
int UR = 100;
|
||||||
|
|
||||||
|
string a ="ABC";
|
||||||
|
wstring wide =L"ABC";
|
||||||
|
string b =u8"ABC";
|
||||||
|
string c =u"ABC";
|
||||||
|
string d =U"ABC";
|
||||||
|
|
||||||
|
string e =R"XXX[to be or "not" to be [these are parenthesis], this is the question!]XXX";
|
||||||
|
wstring wide2 =LR"XXX[to be or "not" to be [these are parenthesis], this is the question!]XXX";
|
||||||
|
string f =u8R"XXX[to be or "not" to be [these are parenthesis], this is the question!]XXX";
|
||||||
|
string g =uR"XXX[to be or "not" to be [these are parenthesis], this is the question!]XXX";
|
||||||
|
string h =UR"XXX[to be or "not" to be [these are parenthesis], this is the question!]XXX";
|
||||||
|
|
||||||
/*string e=R"XXX[ABC"blah]XXX";
|
|
||||||
string g=u8R"XXX[ABC"blah]XXX";
|
|
||||||
string f=uR"XXX[ABC"blah]XXX";
|
|
||||||
string h=UR"XXX[ABC"blah]XXX";
|
|
||||||
*/
|
|
||||||
%}
|
%}
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,6 @@ struct Scanner {
|
||||||
int error_line; /* Error line number */
|
int error_line; /* Error line number */
|
||||||
int freeze_line; /* Suspend line number updates */
|
int freeze_line; /* Suspend line number updates */
|
||||||
List *brackets; /* Current level of < > brackets on each level */
|
List *brackets; /* Current level of < > brackets on each level */
|
||||||
int str_delimiter; /* Custom string delimiter: true, false */
|
|
||||||
String *str_delimiter_val; /* Custom string delimiter. eg. R"XXX[my custom string "value"]XXX" */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void Scanner_push_brackets(Scanner*);
|
void Scanner_push_brackets(Scanner*);
|
||||||
|
|
@ -60,8 +58,6 @@ Scanner *NewScanner(void) {
|
||||||
s->error = 0;
|
s->error = 0;
|
||||||
s->freeze_line = 0;
|
s->freeze_line = 0;
|
||||||
s->brackets = NewList();
|
s->brackets = NewList();
|
||||||
s->str_delimiter = 0;
|
|
||||||
s->str_delimiter_val = NewStringEmpty();
|
|
||||||
Scanner_push_brackets(s);
|
Scanner_push_brackets(s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +76,6 @@ void DelScanner(Scanner * s) {
|
||||||
Delete(s->file);
|
Delete(s->file);
|
||||||
Delete(s->error);
|
Delete(s->error);
|
||||||
Delete(s->str);
|
Delete(s->str);
|
||||||
Delete(s->str_delimiter_val);
|
|
||||||
free(s->idstart);
|
free(s->idstart);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
@ -98,8 +93,6 @@ void Scanner_clear(Scanner * s) {
|
||||||
Clear(s->scanobjs);
|
Clear(s->scanobjs);
|
||||||
Scanner_clear_brackets(s);
|
Scanner_clear_brackets(s);
|
||||||
Delete(s->error);
|
Delete(s->error);
|
||||||
Clear(s->str_delimiter_val);
|
|
||||||
s->str_delimiter = 0;
|
|
||||||
s->error = 0;
|
s->error = 0;
|
||||||
s->line = 1;
|
s->line = 1;
|
||||||
s->nexttoken = -1;
|
s->nexttoken = -1;
|
||||||
|
|
@ -475,13 +468,15 @@ static void get_escape(Scanner *s) {
|
||||||
* ----------------------------------------------------------------------------- */
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int look(Scanner * s) {
|
static int look(Scanner * s) {
|
||||||
int state;
|
int state = 0;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
String *str_delimiter = 0;
|
||||||
|
|
||||||
state = 0;
|
|
||||||
Clear(s->text);
|
Clear(s->text);
|
||||||
s->start_line = s->line;
|
s->start_line = s->line;
|
||||||
Setfile(s->text, Getfile(s->str));
|
Setfile(s->text, Getfile(s->str));
|
||||||
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -507,7 +502,7 @@ static int look(Scanner * s) {
|
||||||
if (c == '%')
|
if (c == '%')
|
||||||
state = 4; /* Possibly a SWIG directive */
|
state = 4; /* Possibly a SWIG directive */
|
||||||
|
|
||||||
/* Look for possible identifiers or unicode strings */
|
/* Look for possible identifiers or unicode/delimiter strings */
|
||||||
|
|
||||||
else if ((isalpha(c)) || (c == '_') ||
|
else if ((isalpha(c)) || (c == '_') ||
|
||||||
(s->idstart && strchr(s->idstart, c))) {
|
(s->idstart && strchr(s->idstart, c))) {
|
||||||
|
|
@ -583,7 +578,7 @@ static int look(Scanner * s) {
|
||||||
else if (c == '0')
|
else if (c == '0')
|
||||||
state = 83; /* An octal or hex value */
|
state = 83; /* An octal or hex value */
|
||||||
else if (c == '\"') {
|
else if (c == '\"') {
|
||||||
state = 2; /* A string or Unicode string constant */
|
state = 2; /* A string constant */
|
||||||
s->start_line = s->line;
|
s->start_line = s->line;
|
||||||
Clear(s->text);
|
Clear(s->text);
|
||||||
}
|
}
|
||||||
|
|
@ -665,18 +660,63 @@ static int look(Scanner * s) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* Processing a string */
|
case 2: /* Processing a string */
|
||||||
|
if (!str_delimiter) {
|
||||||
|
state=20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((c = nextchar(s)) == 0) {
|
if ((c = nextchar(s)) == 0) {
|
||||||
Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
|
Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
|
||||||
return SWIG_TOKEN_ERROR;
|
return SWIG_TOKEN_ERROR;
|
||||||
}
|
}
|
||||||
if (c == '\"') {
|
else if (c == '[') {
|
||||||
Delitem(s->text, DOH_END);
|
state = 20;
|
||||||
return SWIG_TOKEN_STRING;
|
}
|
||||||
} else if (c == '\\') {
|
else {
|
||||||
Delitem(s->text, DOH_END);
|
char temp[2] = { 0, 0 };
|
||||||
get_escape(s);
|
temp[0] = c;
|
||||||
} else
|
Append( str_delimiter, temp );
|
||||||
state = 2;
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 20: /* Inside the string */
|
||||||
|
if ((c = nextchar(s)) == 0) {
|
||||||
|
Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
|
||||||
|
return SWIG_TOKEN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!str_delimiter) { /* Ordinary string: "value" */
|
||||||
|
if (c == '\"') {
|
||||||
|
Delitem(s->text, DOH_END);
|
||||||
|
return SWIG_TOKEN_STRING;
|
||||||
|
} else if (c == '\\') {
|
||||||
|
Delitem(s->text, DOH_END);
|
||||||
|
get_escape(s);
|
||||||
|
}
|
||||||
|
} else { /* Custom delimiter string: R"XXXX[value]XXXX" */
|
||||||
|
if (c==']') {
|
||||||
|
int i=0;
|
||||||
|
String *end_delimiter = NewStringEmpty();
|
||||||
|
while ((c = nextchar(s)) != 0 && c!='\"') {
|
||||||
|
char temp[2] = { 0, 0 };
|
||||||
|
temp[0] = c;
|
||||||
|
Append( end_delimiter, temp );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strcmp( str_delimiter, end_delimiter )==0) {
|
||||||
|
Delete( end_delimiter ); /* Correct end delimiter ]XXXX" occured */
|
||||||
|
Delete( str_delimiter );
|
||||||
|
str_delimiter = 0;
|
||||||
|
return SWIG_TOKEN_STRING;
|
||||||
|
} else { /* Incorrect end delimiter occured */
|
||||||
|
retract( s, i );
|
||||||
|
Delete( end_delimiter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* Maybe a not equals */
|
case 3: /* Maybe a not equals */
|
||||||
|
|
@ -819,8 +859,13 @@ static int look(Scanner * s) {
|
||||||
return SWIG_TOKEN_GREATERTHAN;
|
return SWIG_TOKEN_GREATERTHAN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: /* Identifier or unicode string */
|
|
||||||
if (c!='u' && c!='U' && c!='L') { /* Definitely an identifier */
|
case 7: /* Identifier or unicode/custom delimiter string */
|
||||||
|
if (c=='R') { /* Possibly CUSTOM DELIMITER string */
|
||||||
|
state = 72;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c!='u' && c!='U' && c!='L') { /* Definitely an identifier */
|
||||||
state = 70;
|
state = 70;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -828,18 +873,19 @@ static int look(Scanner * s) {
|
||||||
if ((c = nextchar(s)) == 0) {
|
if ((c = nextchar(s)) == 0) {
|
||||||
return SWIG_TOKEN_ID;
|
return SWIG_TOKEN_ID;
|
||||||
}
|
}
|
||||||
else if (c=='\"') { /* u or U string */
|
else if (c=='\"') { /* Definitely u, U or L string */
|
||||||
retract(s, 1);
|
retract(s, 1);
|
||||||
state = 1000;
|
state = 1000;
|
||||||
}
|
}
|
||||||
|
else if (c=='R') { /* Possibly CUSTOM DELIMITER u, U, L string */
|
||||||
|
state = 73;
|
||||||
|
}
|
||||||
else if (c=='8') { /* Possibly u8 string */
|
else if (c=='8') { /* Possibly u8 string */
|
||||||
state = 71;
|
state = 71;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
retract(s, 1); /* Definitely an identifier */
|
retract(s, 1); /* Definitely an identifier */
|
||||||
state = 70;
|
state = 70;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -859,9 +905,12 @@ static int look(Scanner * s) {
|
||||||
return SWIG_TOKEN_ID;
|
return SWIG_TOKEN_ID;
|
||||||
}
|
}
|
||||||
if (c=='\"') {
|
if (c=='\"') {
|
||||||
retract(s, 1);
|
retract(s, 1); /* Definitely u8 string */
|
||||||
state = 1000;
|
state = 1000;
|
||||||
}
|
}
|
||||||
|
else if (c=='R') {
|
||||||
|
state = 74; /* Possibly CUSTOM DELIMITER u8 string */
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
retract(s, 2); /* Definitely an identifier. Retract 8" */
|
retract(s, 2); /* Definitely an identifier. Retract 8" */
|
||||||
state = 70;
|
state = 70;
|
||||||
|
|
@ -869,6 +918,32 @@ static int look(Scanner * s) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 72: /* Possibly CUSTOM DELIMITER string */
|
||||||
|
case 73:
|
||||||
|
case 74:
|
||||||
|
if ((c = nextchar(s)) == 0) {
|
||||||
|
return SWIG_TOKEN_ID;
|
||||||
|
}
|
||||||
|
if (c=='\"') {
|
||||||
|
retract(s, 1); /* Definitely custom delimiter u, U or L string */
|
||||||
|
str_delimiter = NewStringEmpty();
|
||||||
|
state = 1000;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (state==72) {
|
||||||
|
retract(s, 1); /* Definitely an identifier. Retract ? */
|
||||||
|
}
|
||||||
|
else if (state==73) {
|
||||||
|
retract(s, 2); /* Definitely an identifier. Retract R? */
|
||||||
|
}
|
||||||
|
else if (state==74) {
|
||||||
|
retract(s, 3); /* Definitely an identifier. Retract 8R? */
|
||||||
|
}
|
||||||
|
state = 70;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case 75: /* Special identifier $ */
|
case 75: /* Special identifier $ */
|
||||||
if ((c = nextchar(s)) == 0)
|
if ((c = nextchar(s)) == 0)
|
||||||
return SWIG_TOKEN_DOLLAR;
|
return SWIG_TOKEN_DOLLAR;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue