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;
List *scanobjs;
String *str;
char *idstart;
int nexttoken;
int start_line;
int line;
int yylen;
String *file;
String *error;
int error_line;
int freeze_line;
};
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;
}
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);
}
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;
}
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);
}
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);
}
}
void Scanner_set_location(Scanner * s, String *file, int line) {
Setline(s->str, line);
Setfile(s->str, file);
s->line = line;
}
String *Scanner_file(Scanner * s) {
return Getfile(s->str);
}
int Scanner_line(Scanner * s) {
return s->line;
}
int Scanner_start_line(Scanner * s) {
return s->start_line;
}
void Scanner_idstart(Scanner * s, const char *id) {
free(s->idstart);
s->idstart = Swig_copy_string(id);
}
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;
}
static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) {
s->error_line = line;
s->error = NewString(msg);
}
String *
Scanner_errmsg(Scanner *s) {
return s->error;
}
int
Scanner_errline(Scanner *s) {
return s->error_line;
}
void
Scanner_freeze_line(Scanner *s, int val) {
s->freeze_line = val;
}
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);
}
}
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;
}
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);
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;
else if ((isalpha(c)) || (c == '_') ||
(s->idstart && strchr(s->idstart, c)))
state = 7;
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;
else if (c == '/') {
state = 1;
s->start_line = s->line;
}
else if (c == '\"') {
state = 2;
s->start_line = s->line;
Clear(s->text);
}
else if (c == ':')
state = 5;
else if (c == '0')
state = 83;
else if (c == '\'') {
s->start_line = s->line;
Clear(s->text);
state = 9;
} else if (c == '`') {
s->start_line = s->line;
Clear(s->text);
state = 900;
}
else if (c == '.')
state = 100;
else if (isdigit(c))
state = 8;
else
state = 99;
break;
case 1:
if ((c = nextchar(s)) == 0)
return (0);
if (c == '/') {
state = 10;
Clear(s->text);
Setline(s->text, Getline(s->str));
Setfile(s->text, Getfile(s->str));
Append(s->text, "//");
} else if (c == '*') {
state = 11;
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:
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:
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:
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:
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:
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:
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:
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:
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:
if ((c = nextchar(s)) == 0)
return SWIG_TOKEN_PERCENT;
if (c == '{') {
state = 40;
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:
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:
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:
if ((c = nextchar(s)) == 0)
return SWIG_TOKEN_COLON;
if (c == ':')
state = 50;
else {
retract(s, 1);
return SWIG_TOKEN_COLON;
}
break;
case 50:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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;
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;
}
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;
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;
}
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;
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:
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:
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:
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:
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:
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:
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:
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;
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;
}
}
}
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;
}
String *Scanner_text(Scanner * s) {
return s->text;
}
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;
}
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;
}
int
Scanner_isoperator(int tokval) {
if (tokval >= 100) return 1;
return 0;
}