aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/swig/Source/Swig/scanner.c
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@ydb.tech>2023-11-30 13:26:22 +0300
committervitalyisaev <vitalyisaev@ydb.tech>2023-11-30 15:44:45 +0300
commit0a98fece5a9b54f16afeb3a94b3eb3105e9c3962 (patch)
tree291d72dbd7e9865399f668c84d11ed86fb190bbf /contrib/tools/swig/Source/Swig/scanner.c
parentcb2c8d75065e5b3c47094067cb4aa407d4813298 (diff)
downloadydb-0a98fece5a9b54f16afeb3a94b3eb3105e9c3962.tar.gz
YQ Connector:Use docker-compose in integrational tests
Diffstat (limited to 'contrib/tools/swig/Source/Swig/scanner.c')
-rw-r--r--contrib/tools/swig/Source/Swig/scanner.c1898
1 files changed, 1898 insertions, 0 deletions
diff --git a/contrib/tools/swig/Source/Swig/scanner.c b/contrib/tools/swig/Source/Swig/scanner.c
new file mode 100644
index 0000000000..9dbb353648
--- /dev/null
+++ b/contrib/tools/swig/Source/Swig/scanner.c
@@ -0,0 +1,1898 @@
+/* -----------------------------------------------------------------------------
+ * This file is part of SWIG, which is licensed as a whole under version 3
+ * (or any later version) of the GNU General Public License. Some additional
+ * terms also apply to certain portions of SWIG. The full details of the SWIG
+ * license and copyrights can be found in the LICENSE and COPYRIGHT files
+ * included with the SWIG source code as distributed by the SWIG developers
+ * and at https://www.swig.org/legal.html.
+ *
+ * scanner.c
+ *
+ * This file implements a general purpose C/C++ compatible lexical scanner.
+ * This scanner isn't intended to be plugged directly into a parser built
+ * with yacc. Rather, it contains a lot of generic code that could be used
+ * to easily construct yacc-compatible scanners.
+ * ----------------------------------------------------------------------------- */
+
+#include "swig.h"
+#include <ctype.h>
+
+extern String *cparse_file;
+extern int cparse_line;
+extern int cparse_cplusplus;
+extern int cparse_start_line;
+
+struct Scanner {
+ String *text; /* Current token value */
+ List *scanobjs; /* Objects being scanned */
+ String *str; /* Current object being scanned */
+ char *idstart; /* Optional identifier start characters */
+ int nexttoken; /* Next token to be returned */
+ int start_line; /* Starting line of certain declarations */
+ int line;
+ int yylen; /* Length of text pushed into text */
+ String *file;
+ String *error; /* Last error message (if any) */
+ int error_line; /* Error line number */
+ int freeze_line; /* Suspend line number updates */
+ List *brackets; /* Current level of < > brackets on each level */
+};
+
+typedef struct Locator {
+ String *filename;
+ int line_number;
+ struct Locator *next;
+} Locator;
+static int follow_locators = 0;
+
+static void brackets_push(Scanner *);
+static void brackets_clear(Scanner *);
+
+/* -----------------------------------------------------------------------------
+ * NewScanner()
+ *
+ * Create a new scanner object
+ * ----------------------------------------------------------------------------- */
+
+Scanner *NewScanner(void) {
+ Scanner *s;
+ s = (Scanner *) Malloc(sizeof(Scanner));
+ s->line = 1;
+ s->file = 0;
+ s->nexttoken = -1;
+ s->start_line = 1;
+ s->yylen = 0;
+ s->idstart = NULL;
+ s->scanobjs = NewList();
+ s->text = NewStringEmpty();
+ s->str = 0;
+ s->error = 0;
+ s->error_line = 0;
+ s->freeze_line = 0;
+ s->brackets = NewList();
+ brackets_push(s);
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * DelScanner()
+ *
+ * Delete a scanner object.
+ * ----------------------------------------------------------------------------- */
+
+void DelScanner(Scanner *s) {
+ assert(s);
+ Delete(s->scanobjs);
+ Delete(s->brackets);
+ Delete(s->text);
+ Delete(s->file);
+ Delete(s->error);
+ Delete(s->str);
+ Free(s->idstart);
+ Free(s);
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_clear()
+ *
+ * Clear the contents of a scanner object.
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_clear(Scanner *s) {
+ assert(s);
+ Delete(s->str);
+ Clear(s->text);
+ Clear(s->scanobjs);
+ brackets_clear(s);
+ Delete(s->error);
+ s->str = 0;
+ s->error = 0;
+ s->line = 1;
+ s->nexttoken = -1;
+ s->start_line = 0;
+ s->yylen = 0;
+ /* Should these be cleared too?
+ s->idstart;
+ s->file;
+ s->error_line;
+ s->freeze_line;
+ */
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_push()
+ *
+ * Push some new text into the scanner. The scanner will start parsing this text
+ * immediately before returning to the old text.
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_push(Scanner *s, String *txt) {
+ assert(s && txt);
+ Push(s->scanobjs, txt);
+ if (s->str) {
+ Setline(s->str,s->line);
+ Delete(s->str);
+ }
+ s->str = txt;
+ DohIncref(s->str);
+ s->line = Getline(txt);
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_pushtoken()
+ *
+ * Push a token into the scanner. This token will be returned on the next
+ * call to Scanner_token().
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_pushtoken(Scanner *s, int nt, const_String_or_char_ptr val) {
+ assert(s);
+ assert((nt >= 0) && (nt < SWIG_MAXTOKENS));
+ s->nexttoken = nt;
+ if ( Char(val) != Char(s->text) ) {
+ Clear(s->text);
+ Append(s->text,val);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_set_location()
+ *
+ * Set the file and line number location of the scanner.
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_set_location(Scanner *s, String *file, int line) {
+ Setline(s->str, line);
+ Setfile(s->str, file);
+ s->line = line;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_file()
+ *
+ * Get the current file.
+ * ----------------------------------------------------------------------------- */
+
+String *Scanner_file(Scanner *s) {
+ return Getfile(s->str);
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_line()
+ *
+ * Get the current line number
+ * ----------------------------------------------------------------------------- */
+int Scanner_line(Scanner *s) {
+ return s->line;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_start_line()
+ *
+ * Get the line number on which the current token starts
+ * ----------------------------------------------------------------------------- */
+int Scanner_start_line(Scanner *s) {
+ return s->start_line;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_idstart()
+ *
+ * Change the set of additional characters that can be used to start an identifier.
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_idstart(Scanner *s, const char *id) {
+ Free(s->idstart);
+ s->idstart = Swig_copy_string(id);
+}
+
+/* -----------------------------------------------------------------------------
+ * nextchar()
+ *
+ * Returns the next character from the scanner or 0 if end of the string.
+ * ----------------------------------------------------------------------------- */
+static char nextchar(Scanner *s) {
+ int nc;
+ if (!s->str)
+ return 0;
+ while ((nc = Getc(s->str)) == EOF) {
+ Delete(s->str);
+ s->str = 0;
+ Delitem(s->scanobjs, 0);
+ if (Len(s->scanobjs) == 0)
+ return 0;
+ s->str = Getitem(s->scanobjs, 0);
+ s->line = Getline(s->str);
+ DohIncref(s->str);
+ }
+ if ((nc == '\n') && (!s->freeze_line))
+ s->line++;
+ Putc(nc,s->text);
+ return (char)nc;
+}
+
+/* -----------------------------------------------------------------------------
+ * set_error()
+ *
+ * Sets error information on the scanner.
+ * ----------------------------------------------------------------------------- */
+
+static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) {
+ s->error_line = line;
+ s->error = NewString(msg);
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_errmsg()
+ * Scanner_errline()
+ *
+ * Returns error information (if any)
+ * ----------------------------------------------------------------------------- */
+
+String *Scanner_errmsg(Scanner *s) {
+ return s->error;
+}
+
+int Scanner_errline(Scanner *s) {
+ return s->error_line;
+}
+
+/* -----------------------------------------------------------------------------
+ * freeze_line()
+ *
+ * Freezes the current line number.
+ * ----------------------------------------------------------------------------- */
+
+static void freeze_line(Scanner *s, int val) {
+ s->freeze_line = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * brackets_count()
+ *
+ * Returns the number of brackets at the current depth.
+ * A syntax error with unbalanced ) brackets will result in a NULL pointer return.
+ * ----------------------------------------------------------------------------- */
+static int *brackets_count(Scanner *s) {
+ int *count;
+ if (Len(s->brackets) > 0)
+ count = (int *)Data(Getitem(s->brackets, 0));
+ else
+ count = 0;
+ return count;
+}
+
+/* -----------------------------------------------------------------------------
+ * brackets_clear()
+ *
+ * Resets the current depth and clears all brackets.
+ * Usually called at the end of statements;
+ * ----------------------------------------------------------------------------- */
+static void brackets_clear(Scanner *s) {
+ Clear(s->brackets);
+ brackets_push(s); /* base bracket count should always be created */
+}
+
+/* -----------------------------------------------------------------------------
+ * brackets_increment()
+ *
+ * Increases the number of brackets at the current depth.
+ * Usually called when a single '<' is found.
+ * ----------------------------------------------------------------------------- */
+static void brackets_increment(Scanner *s) {
+ int *count = brackets_count(s);
+ if (count)
+ (*count)++;
+}
+
+/* -----------------------------------------------------------------------------
+ * brackets_decrement()
+ *
+ * Decreases the number of brackets at the current depth.
+ * Usually called when a single '>' is found.
+ * ----------------------------------------------------------------------------- */
+static void brackets_decrement(Scanner *s) {
+ int *count = brackets_count(s);
+ if (count)
+ (*count)--;
+}
+
+/* -----------------------------------------------------------------------------
+ * brackets_reset()
+ *
+ * Sets the number of '<' brackets back to zero. Called at the point where
+ * it is no longer possible to have a matching closing >> pair for a template.
+ * ----------------------------------------------------------------------------- */
+static void brackets_reset(Scanner *s) {
+ int *count = brackets_count(s);
+ if (count)
+ *count = 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * brackets_push()
+ *
+ * Increases the depth of brackets.
+ * Usually called when '(' is found.
+ * ----------------------------------------------------------------------------- */
+static void brackets_push(Scanner *s) {
+ int *newInt = (int *)Malloc(sizeof(int));
+ *newInt = 0;
+ Push(s->brackets, NewVoid(newInt, Free));
+}
+
+/* -----------------------------------------------------------------------------
+ * brackets_pop()
+ *
+ * Decreases the depth of brackets.
+ * Usually called when ')' is found.
+ * ----------------------------------------------------------------------------- */
+static void brackets_pop(Scanner *s) {
+ if (Len(s->brackets) > 0) /* protect against unbalanced ')' brackets */
+ Delitem(s->brackets, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * brackets_allow_shift()
+ *
+ * Return 1 to allow shift (>>), or 0 if (>>) should be split into (> >).
+ * This is for C++11 template syntax for closing templates.
+ * ----------------------------------------------------------------------------- */
+static int brackets_allow_shift(Scanner *s) {
+ int *count = brackets_count(s);
+ return !count || (*count <= 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * retract()
+ *
+ * Retract n characters
+ * ----------------------------------------------------------------------------- */
+static void retract(Scanner *s, int n) {
+ int i, l;
+ char *str;
+
+ str = Char(s->text);
+ l = Len(s->text);
+ assert(n <= l);
+ for (i = 0; i < n; i++) {
+ if (str[l - 1] == '\n') {
+ if (!s->freeze_line) s->line--;
+ }
+ (void)Seek(s->str, -1, SEEK_CUR);
+ Delitem(s->text, DOH_END);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * get_escape()
+ *
+ * Get escape sequence. Called when a backslash is found in a string
+ * ----------------------------------------------------------------------------- */
+
+static void get_escape(Scanner *s) {
+ int result = 0;
+ int state = 0;
+ int c;
+
+ while (1) {
+ c = nextchar(s);
+ if (c == 0)
+ break;
+ switch (state) {
+ case 0:
+ if (c == 'n') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\n");
+ return;
+ }
+ if (c == 'r') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\r");
+ return;
+ }
+ if (c == 't') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\t");
+ return;
+ }
+ if (c == 'a') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\a");
+ return;
+ }
+ if (c == 'b') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\b");
+ return;
+ }
+ if (c == 'f') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\f");
+ return;
+ }
+ if (c == '\\') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\\");
+ return;
+ }
+ if (c == 'v') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\v");
+ return;
+ }
+ if (c == 'e') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\033");
+ return;
+ }
+ if (c == '\'') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\'");
+ return;
+ }
+ if (c == '\"') {
+ Delitem(s->text, DOH_END);
+ Append(s->text,"\"");
+ return;
+ }
+ if (c == '\n') {
+ Delitem(s->text, DOH_END);
+ return;
+ }
+ if (isdigit(c)) {
+ state = 10;
+ result = (c - '0');
+ Delitem(s->text, DOH_END);
+ } else if (c == 'x') {
+ state = 20;
+ Delitem(s->text, DOH_END);
+ } else {
+ char tmp[3];
+ tmp[0] = '\\';
+ tmp[1] = (char)c;
+ tmp[2] = 0;
+ Delitem(s->text, DOH_END);
+ Append(s->text, tmp);
+ return;
+ }
+ break;
+ case 10:
+ if (!isdigit(c)) {
+ retract(s,1);
+ Putc((char)result,s->text);
+ return;
+ }
+ result = (result << 3) + (c - '0');
+ Delitem(s->text, DOH_END);
+ break;
+ case 20:
+ if (!isxdigit(c)) {
+ retract(s,1);
+ Putc((char)result, s->text);
+ return;
+ }
+ if (isdigit(c))
+ result = (result << 4) + (c - '0');
+ else
+ result = (result << 4) + (10 + tolower(c) - 'a');
+ Delitem(s->text, DOH_END);
+ break;
+ }
+ }
+ return;
+}
+
+/* -----------------------------------------------------------------------------
+ * look()
+ *
+ * Return the raw value of the next token.
+ * ----------------------------------------------------------------------------- */
+
+static int look(Scanner *s) {
+ int state = 0;
+ int c = 0;
+ String *str_delimiter = 0;
+
+ Clear(s->text);
+ s->start_line = s->line;
+ Setfile(s->text, Getfile(s->str));
+
+
+ while (1) {
+ switch (state) {
+ case 0:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+
+ /* Process delimiters */
+
+ if (c == '\n') {
+ return SWIG_TOKEN_ENDLINE;
+ } else if (!isspace(c)) {
+ retract(s, 1);
+ state = 1000;
+ Clear(s->text);
+ Setline(s->text, s->line);
+ Setfile(s->text, Getfile(s->str));
+ }
+ break;
+
+ case 1000:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (c == '%')
+ state = 4; /* Possibly a SWIG directive */
+
+ /* Look for possible identifiers or unicode/delimiter strings */
+ else if ((isalpha(c)) || (c == '_') ||
+ (s->idstart && strchr(s->idstart, c))) {
+ state = 7;
+ }
+
+ /* Look for single character symbols */
+
+ else if (c == '(') {
+ brackets_push(s);
+ return SWIG_TOKEN_LPAREN;
+ }
+ else if (c == ')') {
+ brackets_pop(s);
+ return SWIG_TOKEN_RPAREN;
+ }
+ else if (c == ';') {
+ brackets_clear(s);
+ return SWIG_TOKEN_SEMI;
+ }
+ else if (c == ',')
+ return SWIG_TOKEN_COMMA;
+ else if (c == '*')
+ state = 220;
+ else if (c == '}')
+ return SWIG_TOKEN_RBRACE;
+ else if (c == '{') {
+ brackets_reset(s);
+ return SWIG_TOKEN_LBRACE;
+ }
+ else if (c == '=')
+ state = 33;
+ else if (c == '+')
+ state = 200;
+ else if (c == '-')
+ state = 210;
+ else if (c == '&')
+ state = 31;
+ else if (c == '|')
+ state = 32;
+ else if (c == '^')
+ state = 230;
+ else if (c == '<')
+ state = 60;
+ else if (c == '>')
+ state = 61;
+ else if (c == '~')
+ return SWIG_TOKEN_NOT;
+ else if (c == '!')
+ state = 3;
+ else if (c == '\\')
+ return SWIG_TOKEN_BACKSLASH;
+ else if (c == '@')
+ return SWIG_TOKEN_AT;
+ else if (c == '$')
+ state = 75;
+ else if (c == '#')
+ return SWIG_TOKEN_POUND;
+ else if (c == '?')
+ return SWIG_TOKEN_QUESTION;
+
+ /* Look for multi-character sequences */
+
+ else if (c == '/') {
+ state = 1; /* Comment (maybe) */
+ s->start_line = s->line;
+ }
+
+ else if (c == ':')
+ state = 5; /* maybe double colon */
+ else if (c == '0')
+ state = 83; /* An octal or hex value */
+ else if (c == '\"') {
+ state = 2; /* A string constant */
+ s->start_line = s->line;
+ Clear(s->text);
+ }
+ else if (c == '\'') {
+ s->start_line = s->line;
+ Clear(s->text);
+ state = 9; /* A character constant */
+ } else if (c == '`') {
+ s->start_line = s->line;
+ Clear(s->text);
+ state = 900;
+ }
+
+ else if (c == '.')
+ state = 100; /* Maybe a number, maybe ellipsis, just a period */
+ else if (c == '[')
+ state = 102; /* Maybe a bracket or a double bracket */
+ else if (c == ']')
+ state = 103; /* Maybe a bracket or a double bracket */
+ else if (isdigit(c))
+ state = 8; /* A numerical value */
+ else
+ state = 99; /* An error */
+ break;
+
+ case 1: /* Comment block */
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (c == '/') {
+ state = 10; /* C++ style comment */
+ Clear(s->text);
+ Setline(s->text, Getline(s->str));
+ Setfile(s->text, Getfile(s->str));
+ Append(s->text, "//");
+ } else if (c == '*') {
+ state = 11; /* C style comment */
+ Clear(s->text);
+ Setline(s->text, Getline(s->str));
+ Setfile(s->text, Getfile(s->str));
+ Append(s->text, "/*");
+ } else if (c == '=') {
+ return SWIG_TOKEN_DIVEQUAL;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_SLASH;
+ }
+ break;
+ case 10: /* C++ style comment */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '\n') {
+ retract(s,1);
+ return SWIG_TOKEN_COMMENT;
+ } else {
+ state = 10;
+ }
+ break;
+ case 11: /* C style comment block */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '*') {
+ state = 12;
+ } else {
+ state = 11;
+ }
+ break;
+ case 12: /* Still in C style comment */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '*') {
+ state = 12;
+ } else if (c == '/') {
+ return SWIG_TOKEN_COMMENT;
+ } else {
+ state = 11;
+ }
+ break;
+
+ case 2: /* Processing a string */
+ if (!str_delimiter) {
+ state=20;
+ break;
+ }
+
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ else if (c == '(') {
+ state = 20;
+ }
+ else {
+ char temp[2] = { 0, 0 };
+ temp[0] = c;
+ Append( str_delimiter, temp );
+ }
+
+ 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) {
+ int len = Len(s->text);
+ Delslice(s->text, len - 2 - Len(str_delimiter), len); /* Delete ending )XXXX" */
+ Delslice(s->text, 0, Len(str_delimiter) + 1); /* Delete starting XXXX( */
+ Delete( end_delimiter ); /* Correct end delimiter )XXXX" occurred */
+ Delete( str_delimiter );
+ str_delimiter = 0;
+ return SWIG_TOKEN_STRING;
+ } else { /* Incorrect end delimiter occurred */
+ if (c == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated raw string, started with R\"%s( is not terminated by )%s\"\n", str_delimiter, str_delimiter);
+ return SWIG_TOKEN_ERROR;
+ }
+ retract( s, i );
+ Delete( end_delimiter );
+ }
+ }
+ }
+
+ break;
+
+ case 3: /* Maybe a not equals */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_LNOT;
+ else if (c == '=')
+ return SWIG_TOKEN_NOTEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_LNOT;
+ }
+ break;
+
+ case 31: /* AND or Logical AND or ANDEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_AND;
+ else if (c == '&')
+ return SWIG_TOKEN_LAND;
+ else if (c == '=')
+ return SWIG_TOKEN_ANDEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_AND;
+ }
+ break;
+
+ case 32: /* OR or Logical OR */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_OR;
+ else if (c == '|')
+ return SWIG_TOKEN_LOR;
+ else if (c == '=')
+ return SWIG_TOKEN_OREQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_OR;
+ }
+ break;
+
+ case 33: /* EQUAL or EQUALTO */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_EQUAL;
+ else if (c == '=')
+ return SWIG_TOKEN_EQUALTO;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_EQUAL;
+ }
+ break;
+
+ case 4: /* A wrapper generator directive (maybe) */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_PERCENT;
+ if (c == '{') {
+ state = 40; /* Include block */
+ Clear(s->text);
+ Setline(s->text, Getline(s->str));
+ Setfile(s->text, Getfile(s->str));
+ s->start_line = s->line;
+ } else if (s->idstart && strchr(s->idstart, '%') &&
+ ((isalpha(c)) || (c == '_'))) {
+ state = 7;
+ } else if (c == '=') {
+ return SWIG_TOKEN_MODEQUAL;
+ } else if (c == '}') {
+ Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '%%}'\n");
+ Exit(EXIT_FAILURE);
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_PERCENT;
+ }
+ break;
+
+ case 40: /* Process an include block */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated block\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '%')
+ state = 41;
+ break;
+ case 41: /* Still processing include block */
+ if ((c = nextchar(s)) == 0) {
+ set_error(s,s->start_line,"Unterminated code block");
+ return 0;
+ }
+ if (c == '}') {
+ Delitem(s->text, DOH_END);
+ Delitem(s->text, DOH_END);
+ Seek(s->text,0,SEEK_SET);
+ return SWIG_TOKEN_CODEBLOCK;
+ } else {
+ state = 40;
+ }
+ break;
+
+ case 5: /* Maybe a double colon */
+
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_COLON;
+ if (c == ':')
+ state = 50;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_COLON;
+ }
+ break;
+
+ case 50: /* DCOLON, DCOLONSTAR */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DCOLON;
+ else if (c == '*')
+ return SWIG_TOKEN_DCOLONSTAR;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_DCOLON;
+ }
+ break;
+
+ case 60: /* shift operators */
+ if ((c = nextchar(s)) == 0) {
+ brackets_increment(s);
+ return SWIG_TOKEN_LESSTHAN;
+ }
+ if (c == '<')
+ state = 240;
+ else if (c == '=') {
+ if ((c = nextchar(s)) == 0) {
+ return SWIG_TOKEN_LTEQUAL;
+ } else if (c == '>' && cparse_cplusplus) { /* Spaceship operator */
+ return SWIG_TOKEN_LTEQUALGT;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_LTEQUAL;
+ }
+ } else {
+ retract(s, 1);
+ brackets_increment(s);
+ return SWIG_TOKEN_LESSTHAN;
+ }
+ break;
+ case 61:
+ if ((c = nextchar(s)) == 0) {
+ brackets_decrement(s);
+ return SWIG_TOKEN_GREATERTHAN;
+ }
+ if (c == '>' && brackets_allow_shift(s))
+ state = 250;
+ else if (c == '=')
+ return SWIG_TOKEN_GTEQUAL;
+ else {
+ retract(s, 1);
+ brackets_decrement(s);
+ return SWIG_TOKEN_GREATERTHAN;
+ }
+ break;
+
+ case 7: /* Identifier or true/false or unicode/custom delimiter string */
+ if (c == 'R') { /* Possibly CUSTOM DELIMITER string */
+ state = 72;
+ break;
+ }
+ else if (c == 'L') { /* Probably identifier but may be a wide string literal */
+ state = 77;
+ break;
+ }
+ else if (c != 'u' && c != 'U') { /* Definitely an identifier */
+ state = 70;
+ break;
+ }
+
+ if ((c = nextchar(s)) == 0) {
+ state = 76;
+ }
+ else if (c == '\"') { /* Definitely u, U or L string */
+ retract(s, 1);
+ state = 1000;
+ }
+ else if (c == '\'') { /* Definitely u, U or L char */
+ retract(s, 1);
+ state = 77;
+ }
+ else if (c == 'R') { /* Possibly CUSTOM DELIMITER u, U, L string */
+ state = 73;
+ }
+ else if (c == '8') { /* Possibly u8 string/char */
+ state = 71;
+ }
+ else {
+ retract(s, 1); /* Definitely an identifier */
+ state = 70;
+ }
+ break;
+
+ case 70: /* Identifier */
+ if ((c = nextchar(s)) == 0)
+ state = 76;
+ else if (isalnum(c) || (c == '_') || (c == '$')) {
+ state = 70;
+ } else {
+ retract(s, 1);
+ state = 76;
+ }
+ break;
+
+ case 71: /* Possibly u8 string/char */
+ if ((c = nextchar(s)) == 0) {
+ state = 76;
+ }
+ else if (c=='\"') {
+ retract(s, 1); /* Definitely u8 string */
+ state = 1000;
+ }
+ else if (c=='\'') {
+ retract(s, 1); /* Definitely u8 char */
+ state = 77;
+ }
+ else if (c=='R') {
+ state = 74; /* Possibly CUSTOM DELIMITER u8 string */
+ }
+ else {
+ retract(s, 2); /* Definitely an identifier. Retract 8" */
+ state = 70;
+ }
+
+ break;
+
+ case 72: /* Possibly CUSTOM DELIMITER string */
+ case 73:
+ case 74:
+ if ((c = nextchar(s)) == 0) {
+ state = 76;
+ }
+ else 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 $ */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DOLLAR;
+ if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) {
+ state = 70;
+ } else {
+ retract(s,1);
+ if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR;
+ state = 76;
+ }
+ break;
+
+ case 76: /* Identifier or true/false */
+ if (cparse_cplusplus) {
+ if (Strcmp(s->text, "true") == 0)
+ return SWIG_TOKEN_BOOL;
+ else if (Strcmp(s->text, "false") == 0)
+ return SWIG_TOKEN_BOOL;
+ }
+ return SWIG_TOKEN_ID;
+ break;
+
+ case 77: /*identifier or wide string literal*/
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_ID;
+ else if (c == '\"') {
+ s->start_line = s->line;
+ Clear(s->text);
+ state = 78;
+ }
+ else if (c == '\'') {
+ s->start_line = s->line;
+ Clear(s->text);
+ state = 79;
+ }
+ else if (isalnum(c) || (c == '_') || (c == '$'))
+ state = 7;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_ID;
+ }
+ break;
+
+ case 78: /* Processing a wide string literal*/
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '\"') {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_WSTRING;
+ } else if (c == '\\') {
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ }
+ break;
+
+ case 79: /* Processing a wide char literal */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated wide character constant\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '\'') {
+ Delitem(s->text, DOH_END);
+ return (SWIG_TOKEN_WCHAR);
+ } else if (c == '\\') {
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated wide character literal\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ }
+ break;
+
+ case 8: /* A numerical digit */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ if (c == '.') {
+ state = 81;
+ } else if ((c == 'e') || (c == 'E')) {
+ state = 82;
+ } else if ((c == 'f') || (c == 'F')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_FLOAT;
+ } else if (isdigit(c)) {
+ state = 8;
+ } else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+ case 81: /* A floating pointer number of some sort */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DOUBLE;
+ if (isdigit(c))
+ state = 81;
+ else if ((c == 'e') || (c == 'E'))
+ state = 820;
+ else if ((c == 'f') || (c == 'F')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_FLOAT;
+ } else if ((c == 'l') || (c == 'L')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_DOUBLE;
+ } else {
+ retract(s, 1);
+ return (SWIG_TOKEN_DOUBLE);
+ }
+ break;
+ case 82:
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if ((isdigit(c)) || (c == '-') || (c == '+'))
+ state = 86;
+ else {
+ retract(s, 2);
+ Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ break;
+ case 820:
+ /* Like case 82, but we've seen a decimal point. */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if ((isdigit(c)) || (c == '-') || (c == '+'))
+ state = 86;
+ else {
+ retract(s, 2);
+ Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ break;
+ case 83:
+ /* Might be a hexadecimal or octal number */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ if (isdigit(c))
+ state = 84;
+ else if ((c == 'e') || (c == 'E'))
+ state = 82;
+ else if ((c == 'x') || (c == 'X'))
+ state = 85;
+ else if ((c == 'b') || (c == 'B'))
+ state = 850;
+ else if (c == '.')
+ state = 81;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+ case 84:
+ /* This is an octal number */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ if (isdigit(c))
+ state = 84;
+ else if (c == '.')
+ state = 81;
+ else if ((c == 'e') || (c == 'E'))
+ state = 82;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+ case 85:
+ /* This is an hex number */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ if (isxdigit(c))
+ state = 85;
+ else if (c == '.') /* hexadecimal float */
+ state = 860;
+ else if ((c == 'p') || (c == 'P')) /* hexadecimal float */
+ state = 820;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+ case 850:
+ /* This is a binary number */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_INT;
+ if ((c == '0') || (c == '1'))
+ state = 850;
+ else if ((c == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ break;
+ case 860:
+ /* hexadecimal float */
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Hexadecimal floating literals require an exponent\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (isxdigit(c))
+ state = 860;
+ else if ((c == 'p') || (c == 'P'))
+ state = 820;
+ else {
+ retract(s, 2);
+ Swig_error(cparse_file, cparse_start_line, "Hexadecimal floating literals require an exponent\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ break;
+ case 86:
+ /* Rest of floating point number */
+
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DOUBLE;
+ if (isdigit(c))
+ state = 86;
+ else if ((c == 'f') || (c == 'F')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_FLOAT;
+ } else if ((c == 'l') || (c == 'L')) {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_DOUBLE;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_DOUBLE;
+ }
+ break;
+
+ case 87:
+ /* A long integer of some sort */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_LONG;
+ if ((c == 'u') || (c == 'U')) {
+ return SWIG_TOKEN_ULONG;
+ } else if ((c == 'l') || (c == 'L')) {
+ state = 870;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_LONG;
+ }
+ break;
+
+ /* A long long integer */
+
+ case 870:
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_LONGLONG;
+ if ((c == 'u') || (c == 'U')) {
+ return SWIG_TOKEN_ULONGLONG;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_LONGLONG;
+ }
+
+ /* An unsigned number */
+ case 88:
+
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_UINT;
+ if ((c == 'l') || (c == 'L')) {
+ state = 880;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_UINT;
+ }
+ break;
+
+ /* Possibly an unsigned long long or unsigned long */
+ case 880:
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_ULONG;
+ if ((c == 'l') || (c == 'L'))
+ return SWIG_TOKEN_ULONGLONG;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_ULONG;
+ }
+
+ /* A character constant */
+ case 9:
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '\'') {
+ Delitem(s->text, DOH_END);
+ return (SWIG_TOKEN_CHAR);
+ } else if (c == '\\') {
+ Delitem(s->text, DOH_END);
+ get_escape(s);
+ }
+ break;
+
+ /* A period or an ellipsis or maybe a floating point number */
+
+ case 100:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (isdigit(c))
+ state = 81;
+ else if (c == '.')
+ state = 101;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_PERIOD;
+ }
+ break;
+
+ /* An ellipsis */
+
+ case 101:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (c == '.') {
+ return SWIG_TOKEN_ELLIPSIS;
+ } else {
+ retract(s, 2);
+ return SWIG_TOKEN_PERIOD;
+ }
+ break;
+
+ /* A left bracket or a double left bracket */
+ case 102:
+
+ if ((c = nextchar(s)) == 0) {
+ return SWIG_TOKEN_LBRACKET;
+ } else if (c == '[') {
+ return SWIG_TOKEN_LLBRACKET;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_LBRACKET;
+ }
+ break;
+
+ /* a right bracket or a double right bracket */
+ case 103:
+ if ((c = nextchar(s)) == 0) {
+ return SWIG_TOKEN_RBRACKET;
+ } else if (c == ']') {
+ return SWIG_TOKEN_RRBRACKET;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_RBRACKET;
+ }
+ break;
+
+ case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_PLUS;
+ else if (c == '+')
+ return SWIG_TOKEN_PLUSPLUS;
+ else if (c == '=')
+ return SWIG_TOKEN_PLUSEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_PLUS;
+ }
+ break;
+
+ case 210: /* MINUS, MINUSMINUS, MINUSEQUAL, ARROW */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_MINUS;
+ else if (c == '-')
+ return SWIG_TOKEN_MINUSMINUS;
+ else if (c == '=')
+ return SWIG_TOKEN_MINUSEQUAL;
+ else if (c == '>')
+ state = 211;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_MINUS;
+ }
+ break;
+
+ case 211: /* ARROW, ARROWSTAR */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_ARROW;
+ else if (c == '*')
+ return SWIG_TOKEN_ARROWSTAR;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_ARROW;
+ }
+ break;
+
+
+ case 220: /* STAR, TIMESEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_STAR;
+ else if (c == '=')
+ return SWIG_TOKEN_TIMESEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_STAR;
+ }
+ break;
+
+ case 230: /* XOR, XOREQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_XOR;
+ else if (c == '=')
+ return SWIG_TOKEN_XOREQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_XOR;
+ }
+ break;
+
+ case 240: /* LSHIFT, LSEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_LSHIFT;
+ else if (c == '=')
+ return SWIG_TOKEN_LSEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_LSHIFT;
+ }
+ break;
+
+ case 250: /* RSHIFT, RSEQUAL */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_RSHIFT;
+ else if (c == '=')
+ return SWIG_TOKEN_RSEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_RSHIFT;
+ }
+ break;
+
+
+ /* An illegal character */
+
+ /* Reverse string */
+ case 900:
+ if ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '`') {
+ Delitem(s->text, DOH_END);
+ return (SWIG_TOKEN_RSTRING);
+ }
+ break;
+
+ default:
+ return SWIG_TOKEN_ILLEGAL;
+ }
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_token()
+ *
+ * Real entry point to return the next token. Returns 0 if at end of input.
+ * ----------------------------------------------------------------------------- */
+
+int Scanner_token(Scanner *s) {
+ int t;
+ Delete(s->error);
+ if (s->nexttoken >= 0) {
+ t = s->nexttoken;
+ s->nexttoken = -1;
+ return t;
+ }
+ s->start_line = 0;
+ t = look(s);
+ if (!s->start_line) {
+ Setline(s->text,s->line);
+ } else {
+ Setline(s->text,s->start_line);
+ }
+ return t;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_text()
+ *
+ * Return the lexene associated with the last returned token.
+ * ----------------------------------------------------------------------------- */
+
+String *Scanner_text(Scanner *s) {
+ return s->text;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_skip_line()
+ *
+ * Skips to the end of a line
+ * ----------------------------------------------------------------------------- */
+
+void Scanner_skip_line(Scanner *s) {
+ char c;
+ int done = 0;
+ Clear(s->text);
+ Setfile(s->text, Getfile(s->str));
+ Setline(s->text, s->line);
+ while (!done) {
+ if ((c = nextchar(s)) == 0)
+ return;
+ if (c == '\\') {
+ nextchar(s);
+ } else if (c == '\n') {
+ done = 1;
+ }
+ }
+ return;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_skip_balanced()
+ *
+ * Skips a piece of code enclosed in begin/end symbols such as '{...}' or
+ * (...). Ignores symbols inside comments or strings.
+ * ----------------------------------------------------------------------------- */
+
+int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) {
+ char c;
+ int num_levels = 1;
+ int state = 0;
+ char temp[2] = { 0, 0 };
+ String *locator = 0;
+ temp[0] = (char) startchar;
+ Clear(s->text);
+ Setfile(s->text, Getfile(s->str));
+ Setline(s->text, s->line);
+
+ Append(s->text, temp);
+ 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;
+ break;
+ case 10:
+ if (c == '/')
+ state = 11;
+ else if (c == '*')
+ state = 12;
+ else if (c == startchar) {
+ state = 0;
+ num_levels++;
+ }
+ else
+ state = 0;
+ break;
+ case 11:
+ if (c == '\n')
+ state = 0;
+ else
+ state = 11;
+ 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;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ Delete(locator);
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_get_raw_text_balanced()
+ *
+ * Returns raw text between 2 braces, does not change scanner state in any way
+ * ----------------------------------------------------------------------------- */
+
+String *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) {
+ String *result = 0;
+ char c;
+ int old_line = s->line;
+ String *old_text = Copy(s->text);
+ long position = Tell(s->str);
+
+ int num_levels = 1;
+ int state = 0;
+ char temp[2] = { 0, 0 };
+ temp[0] = (char) startchar;
+ Clear(s->text);
+ Setfile(s->text, Getfile(s->str));
+ Setline(s->text, s->line);
+ Append(s->text, temp);
+ 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;
+ case 10:
+ if (c == '/')
+ state = 11;
+ else if (c == '*')
+ state = 12;
+ else if (c == startchar) {
+ state = 0;
+ num_levels++;
+ }
+ else
+ state = 0;
+ break;
+ case 11:
+ if (c == '\n')
+ state = 0;
+ else
+ state = 11;
+ 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;
+ break;
+ default:
+ break;
+ }
+ }
+ Seek(s->str, position, SEEK_SET);
+ result = Copy(s->text);
+ Clear(s->text);
+ Append(s->text, old_text);
+ Delete(old_text);
+ s->line = old_line;
+ return result;
+}
+/* -----------------------------------------------------------------------------
+ * Scanner_isoperator()
+ *
+ * Returns 0 or 1 depending on whether or not a token corresponds to a C/C++
+ * operator.
+ * ----------------------------------------------------------------------------- */
+
+int Scanner_isoperator(int tokval) {
+ if (tokval >= 100) return 1;
+ return 0;
+}
+
+/* ----------------------------------------------------------------------
+ * locator()
+ *
+ * Support for locator strings. These are strings of the form
+ * @SWIG:filename,line,id@ emitted by the SWIG preprocessor. They
+ * are primarily used for macro line number reporting.
+ * We just use the locator to mark when to activate/deactivate linecounting.
+ * ---------------------------------------------------------------------- */
+
+
+void Scanner_locator(Scanner *s, String *loc) {
+ static Locator *locs = 0;
+ static int expanding_macro = 0;
+
+ if (!follow_locators) {
+ if (Equal(loc, "/*@SWIG@*/")) {
+ /* End locator. */
+ if (expanding_macro)
+ --expanding_macro;
+ } else {
+ /* Begin locator. */
+ ++expanding_macro;
+ }
+ /* Freeze line number processing in Scanner */
+ freeze_line(s,expanding_macro);
+ } else {
+ int c;
+ Locator *l;
+ (void)Seek(loc, 7, SEEK_SET);
+ c = Getc(loc);
+ if (c == '@') {
+ /* Empty locator. We pop the last location off */
+ if (locs) {
+ Scanner_set_location(s, locs->filename, locs->line_number);
+ cparse_file = locs->filename;
+ cparse_line = locs->line_number;
+ l = locs->next;
+ Free(locs);
+ locs = l;
+ }
+ return;
+ }
+
+ /* We're going to push a new location */
+ l = (Locator *) Malloc(sizeof(Locator));
+ l->filename = cparse_file;
+ l->line_number = cparse_line;
+ l->next = locs;
+ locs = l;
+
+ /* Now, parse the new location out of the locator string */
+ {
+ String *fn = NewStringEmpty();
+ /* Putc(c, fn); */
+
+ while ((c = Getc(loc)) != EOF) {
+ if ((c == '@') || (c == ','))
+ break;
+ Putc(c, fn);
+ }
+ cparse_file = Swig_copy_string(Char(fn));
+ Clear(fn);
+ cparse_line = 1;
+ /* Get the line number */
+ while ((c = Getc(loc)) != EOF) {
+ if ((c == '@') || (c == ','))
+ break;
+ Putc(c, fn);
+ }
+ cparse_line = atoi(Char(fn));
+ Clear(fn);
+
+ /* Get the rest of it */
+ while ((c = Getc(loc)) != EOF) {
+ if (c == '@')
+ break;
+ Putc(c, fn);
+ }
+ /* Swig_diagnostic(cparse_file, cparse_line, "Scanner_set_location\n"); */
+ Scanner_set_location(s, cparse_file, cparse_line);
+ Delete(fn);
+ }
+ }
+}
+
+void Swig_cparse_follow_locators(int v) {
+ follow_locators = v;
+}
+
+