summaryrefslogtreecommitdiff
path: root/Source/Swig/scanner.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Swig/scanner.c')
-rw-r--r--Source/Swig/scanner.c1227
1 files changed, 1227 insertions, 0 deletions
diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c
new file mode 100644
index 0000000..328a491
--- /dev/null
+++ b/Source/Swig/scanner.c
@@ -0,0 +1,1227 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.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.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_scanner_c[] = "$Id: scanner.c 11470 2009-07-29 20:50:39Z wsfulton $";
+
+#include "swig.h"
+#include <ctype.h>
+
+extern String *cparse_file;
+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 */
+};
+
+/* -----------------------------------------------------------------------------
+ * 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->freeze_line = 0;
+ return s;
+}
+
+/* -----------------------------------------------------------------------------
+ * DelScanner()
+ *
+ * Delete a scanner object.
+ * ----------------------------------------------------------------------------- */
+
+void DelScanner(Scanner * s) {
+ assert(s);
+ Delete(s->scanobjs);
+ 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);
+ Delete(s->error);
+ s->str = 0;
+ s->error = 0;
+ s->line = 1;
+ s->nexttoken = -1;
+ s->start_line = 0;
+ s->yylen = 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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);
+ if (s->str) {
+ 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;
+}
+
+/* -----------------------------------------------------------------------------
+ * Scanner_freeze_line()
+ *
+ * Freezes the current line number.
+ * ----------------------------------------------------------------------------- */
+
+void
+Scanner_freeze_line(Scanner *s, int val) {
+ s->freeze_line = val;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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--;
+ }
+ 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;
+ int c = 0;
+
+ state = 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 */
+
+ else if ((isalpha(c)) || (c == '_') ||
+ (s->idstart && strchr(s->idstart, c)))
+ state = 7;
+
+ /* Look for single character symbols */
+
+ else if (c == '(')
+ return SWIG_TOKEN_LPAREN;
+ else if (c == ')')
+ return SWIG_TOKEN_RPAREN;
+ else if (c == ';')
+ 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 == '{')
+ 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_LBRACKET;
+ else if (c == ']')
+ return SWIG_TOKEN_RBRACKET;
+ 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 = 2; /* Possibly a string */
+ s->start_line = s->line;
+ Clear(s->text);
+ }
+
+ else if (c == ':')
+ state = 5; /* maybe double colon */
+ else if (c == '0')
+ state = 83; /* An octal or hex value */
+ 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 just a period */
+ 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 ((c = nextchar(s)) == 0) {
+ Swig_error(cparse_file, cparse_start_line, "Unterminated string\n");
+ return SWIG_TOKEN_ERROR;
+ }
+ if (c == '\"') {
+ Delitem(s->text, DOH_END);
+ return SWIG_TOKEN_STRING;
+ } else if (c == '\\') {
+ Delitem(s->text, DOH_END);
+ get_escape(s);
+ } else
+ state = 2;
+ 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 {
+ 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)
+ return SWIG_TOKEN_LESSTHAN;
+ if (c == '<')
+ state = 240;
+ else if (c == '=')
+ return SWIG_TOKEN_LTEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_LESSTHAN;
+ }
+ break;
+ case 61:
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_GREATERTHAN;
+ if (c == '>')
+ state = 250;
+ else if (c == '=')
+ return SWIG_TOKEN_GTEQUAL;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_GREATERTHAN;
+ }
+ break;
+ case 7: /* Identifier */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_ID;
+ if (isalnum(c) || (c == '_') || (c == '$')) {
+ state = 7;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_ID;
+ }
+ break;
+
+ case 75: /* Special identifier $ */
+ if ((c = nextchar(s)) == 0)
+ return SWIG_TOKEN_DOLLAR;
+ if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) {
+ state = 7;
+ } else {
+ retract(s,1);
+ if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR;
+ return SWIG_TOKEN_ID;
+ }
+ 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) {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ if ((isdigit(c)) || (c == '-') || (c == '+'))
+ state = 86;
+ else {
+ retract(s, 2);
+ return (SWIG_TOKEN_INT);
+ }
+ break;
+ case 820:
+ /* Like case 82, but we've seen a decimal point. */
+ if ((c = nextchar(s)) == 0) {
+ retract(s, 1);
+ return SWIG_TOKEN_DOUBLE;
+ }
+ if ((isdigit(c)) || (c == '-') || (c == '+'))
+ state = 86;
+ else {
+ retract(s, 2);
+ return (SWIG_TOKEN_DOUBLE);
+ }
+ 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 == 'x') || (c == 'X'))
+ state = 85;
+ 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 == '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 == 'l') || (c == 'L')) {
+ state = 87;
+ } else if ((c == 'u') || (c == 'U')) {
+ state = 88;
+ } else {
+ retract(s, 1);
+ return SWIG_TOKEN_INT;
+ }
+ 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 maybe a floating point number */
+
+ case 100:
+ if ((c = nextchar(s)) == 0)
+ return (0);
+ if (isdigit(c))
+ state = 81;
+ else {
+ retract(s, 1);
+ return SWIG_TOKEN_PERIOD;
+ }
+ 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 == '\\') {
+ 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 l;
+ int state = 0;
+ char temp[2] = { 0, 0 };
+ l = s->line;
+ 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) {
+ 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
+ state = 0;
+ break;
+ case 11:
+ if (c == '\n')
+ state = 0;
+ else
+ state = 11;
+ break;
+ case 12:
+ if (c == '*')
+ state = 13;
+ break;
+ case 13:
+ if (c == '*')
+ state = 13;
+ else if (c == '/')
+ state = 0;
+ else
+ state = 12;
+ 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;
+ }
+ }
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * 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;
+}