diff options
Diffstat (limited to 'Source/CParse/cscanner.c')
| -rw-r--r-- | Source/CParse/cscanner.c | 930 |
1 files changed, 930 insertions, 0 deletions
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c new file mode 100644 index 0000000..9128a2b --- /dev/null +++ b/Source/CParse/cscanner.c @@ -0,0 +1,930 @@ +/* ----------------------------------------------------------------------------- + * 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 + * + * SWIG tokenizer. This file is a wrapper around the generic C scanner + * found in Swig/scanner.c. Extra logic is added both to accomodate the + * bison-based grammar and certain peculiarities of C++ parsing (e.g., + * operator overloading, typedef resolution, etc.). This code also splits + * C identifiers up into keywords and SWIG directives. + * ----------------------------------------------------------------------------- */ + +char cvsroot_cscanner_c[] = "$Id: cscanner.c 11123 2009-02-08 22:30:10Z wsfulton $"; + +#include "cparse.h" +#include "parser.h" +#include <string.h> +#include <ctype.h> + +/* Scanner object */ +static Scanner *scan = 0; + +/* Global string containing C code. Used by the parser to grab code blocks */ +String *scanner_ccode = 0; + +/* The main file being parsed */ +static String *main_input_file = 0; + +/* Error reporting/location information */ +int cparse_line = 1; +String *cparse_file = 0; +int cparse_start_line = 0; + +/* C++ mode */ +int cparse_cplusplus = 0; + +/* Private vars */ +static int scan_init = 0; +static int num_brace = 0; +static int last_brace = 0; +static int last_id = 0; +static int rename_active = 0; +static int expanding_macro = 0; +static int follow_locators = 0; + +/* ----------------------------------------------------------------------------- + * Swig_cparse_cplusplus() + * ----------------------------------------------------------------------------- */ + +void Swig_cparse_cplusplus(int v) { + cparse_cplusplus = v; +} + +/* ---------------------------------------------------------------------- + * 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 + * ---------------------------------------------------------------------- */ + +typedef struct Locator { + String *filename; + int line_number; + struct Locator *next; +} Locator; + +static Locator *locs = 0; + +/* we just use the locator to mark when active/deactive the linecounting */ + +static void scanner_locator(String *loc) { + 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 */ + Scanner_freeze_line(scan,expanding_macro); + } else { + int c; + Locator *l; + Seek(loc, 7, SEEK_SET); + c = Getc(loc); + if (c == '@') { + /* Empty locator. We pop the last location off */ + if (locs) { + Scanner_set_location(scan,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); + } + /* Printf(stderr,"location: %s:%d\n",cparse_file,cparse_line); */ + Scanner_set_location(scan,cparse_file,cparse_line); + Delete(fn); + } + } +} + +void Swig_cparse_follow_locators(int v) { + follow_locators = v; +} + + +/* ---------------------------------------------------------------------------- + * scanner_init() + * + * Initialize buffers + * ------------------------------------------------------------------------- */ + +void scanner_init() { + scan = NewScanner(); + Scanner_idstart(scan,"%"); + scan_init = 1; + scanner_ccode = NewStringEmpty(); +} + +/* ---------------------------------------------------------------------------- + * scanner_file(DOHFile *f) + * + * Start reading from new file + * ------------------------------------------------------------------------- */ +void scanner_file(DOHFile * f) { + if (!scan_init) scanner_init(); + Scanner_clear(scan); + Scanner_push(scan,f); +} + +/* ---------------------------------------------------------------------------- + * start_inline(char *text, int line) + * + * Take a chunk of text and recursively feed it back into the scanner. Used + * by the %inline directive. + * ------------------------------------------------------------------------- */ + +void start_inline(char *text, int line) { + String *stext = NewString(text); + + Seek(stext,0,SEEK_SET); + Setfile(stext,cparse_file); + Setline(stext,line); + Scanner_push(scan,stext); + Delete(stext); +} + +/* ----------------------------------------------------------------------------- + * skip_balanced() + * + * Skips a piece of code enclosed in begin/end symbols such as '{...}' or + * (...). Ignores symbols inside comments or strings. + * ----------------------------------------------------------------------------- */ + +void skip_balanced(int startchar, int endchar) { + Clear(scanner_ccode); + + if (Scanner_skip_balanced(scan,startchar,endchar) < 0) { + Swig_error(Scanner_file(scan),Scanner_errline(scan), "Missing '%c'. Reached end of input.\n", endchar); + return; + } + + cparse_line = Scanner_line(scan); + cparse_file = Scanner_file(scan); + + Append(scanner_ccode, Scanner_text(scan)); + if (endchar == '}') + num_brace--; + return; +} + +/* ---------------------------------------------------------------------------- + * void skip_decl(void) + * + * This tries to skip over an entire declaration. For example + * + * friend ostream& operator<<(ostream&, const char *s); + * + * or + * friend ostream& operator<<(ostream&, const char *s) { }; + * + * ------------------------------------------------------------------------- */ + +void skip_decl(void) { + int tok; + int done = 0; + int start_line = Scanner_line(scan); + + while (!done) { + tok = Scanner_token(scan); + if (tok == 0) { + if (!Swig_error_count()) { + Swig_error(cparse_file, start_line, "Missing semicolon. Reached end of input.\n"); + } + return; + } + if (tok == SWIG_TOKEN_LBRACE) { + if (Scanner_skip_balanced(scan,'{','}') < 0) { + Swig_error(cparse_file, start_line, "Missing '}'. Reached end of input.\n"); + } + break; + } + if (tok == SWIG_TOKEN_SEMI) { + done = 1; + } + } + cparse_file = Scanner_file(scan); + cparse_line = Scanner_line(scan); +} + +/* ---------------------------------------------------------------------------- + * int yylook() + * + * Lexical scanner. + * ------------------------------------------------------------------------- */ + +int yylook(void) { + + int tok = 0; + + while (1) { + if ((tok = Scanner_token(scan)) == 0) + return 0; + if (tok == SWIG_TOKEN_ERROR) + return 0; + cparse_start_line = Scanner_start_line(scan); + cparse_line = Scanner_line(scan); + cparse_file = Scanner_file(scan); + + switch(tok) { + case SWIG_TOKEN_ID: + return ID; + case SWIG_TOKEN_LPAREN: + return LPAREN; + case SWIG_TOKEN_RPAREN: + return RPAREN; + case SWIG_TOKEN_SEMI: + return SEMI; + case SWIG_TOKEN_COMMA: + return COMMA; + case SWIG_TOKEN_STAR: + return STAR; + case SWIG_TOKEN_RBRACE: + num_brace--; + if (num_brace < 0) { + Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '}'\n"); + num_brace = 0; + } else { + return RBRACE; + } + break; + case SWIG_TOKEN_LBRACE: + last_brace = num_brace; + num_brace++; + return LBRACE; + case SWIG_TOKEN_EQUAL: + return EQUAL; + case SWIG_TOKEN_EQUALTO: + return EQUALTO; + case SWIG_TOKEN_PLUS: + return PLUS; + case SWIG_TOKEN_MINUS: + return MINUS; + case SWIG_TOKEN_SLASH: + return SLASH; + case SWIG_TOKEN_AND: + return AND; + case SWIG_TOKEN_LAND: + return LAND; + case SWIG_TOKEN_OR: + return OR; + case SWIG_TOKEN_LOR: + return LOR; + case SWIG_TOKEN_XOR: + return XOR; + case SWIG_TOKEN_NOT: + return NOT; + case SWIG_TOKEN_LNOT: + return LNOT; + case SWIG_TOKEN_NOTEQUAL: + return NOTEQUALTO; + case SWIG_TOKEN_LBRACKET: + return LBRACKET; + case SWIG_TOKEN_RBRACKET: + return RBRACKET; + case SWIG_TOKEN_QUESTION: + return QUESTIONMARK; + case SWIG_TOKEN_LESSTHAN: + return LESSTHAN; + case SWIG_TOKEN_LTEQUAL: + return LESSTHANOREQUALTO; + case SWIG_TOKEN_LSHIFT: + return LSHIFT; + case SWIG_TOKEN_GREATERTHAN: + return GREATERTHAN; + case SWIG_TOKEN_GTEQUAL: + return GREATERTHANOREQUALTO; + case SWIG_TOKEN_RSHIFT: + return RSHIFT; + case SWIG_TOKEN_PERIOD: + return PERIOD; + case SWIG_TOKEN_MODULO: + return MODULO; + case SWIG_TOKEN_COLON: + return COLON; + case SWIG_TOKEN_DCOLONSTAR: + return DSTAR; + + case SWIG_TOKEN_DCOLON: + { + int nexttok = Scanner_token(scan); + if (nexttok == SWIG_TOKEN_STAR) { + return DSTAR; + } else if (nexttok == SWIG_TOKEN_NOT) { + return DCNOT; + } else { + Scanner_pushtoken(scan,nexttok,Scanner_text(scan)); + if (!last_id) { + scanner_next_token(DCOLON); + return NONID; + } else { + return DCOLON; + } + } + } + break; + + /* Look for multi-character sequences */ + + case SWIG_TOKEN_RSTRING: + yylval.type = NewString(Scanner_text(scan)); + return TYPE_RAW; + + case SWIG_TOKEN_STRING: + yylval.id = Swig_copy_string(Char(Scanner_text(scan))); + return STRING; + + case SWIG_TOKEN_CHAR: + yylval.str = NewString(Scanner_text(scan)); + if (Len(yylval.str) == 0) { + Swig_error(cparse_file, cparse_line, "Empty character constant\n"); + Printf(stdout,"%d\n", Len(Scanner_text(scan))); + } + return CHARCONST; + + /* Numbers */ + + case SWIG_TOKEN_INT: + return NUM_INT; + + case SWIG_TOKEN_UINT: + return NUM_UNSIGNED; + + case SWIG_TOKEN_LONG: + return NUM_LONG; + + case SWIG_TOKEN_ULONG: + return NUM_ULONG; + + case SWIG_TOKEN_LONGLONG: + return NUM_LONGLONG; + + case SWIG_TOKEN_ULONGLONG: + return NUM_ULONGLONG; + + case SWIG_TOKEN_DOUBLE: + case SWIG_TOKEN_FLOAT: + return NUM_FLOAT; + + case SWIG_TOKEN_POUND: + Scanner_skip_line(scan); + yylval.id = Swig_copy_string(Char(Scanner_text(scan))); + return POUND; + break; + + case SWIG_TOKEN_CODEBLOCK: + yylval.str = NewString(Scanner_text(scan)); + return HBLOCK; + + case SWIG_TOKEN_COMMENT: + { + String *cmt = Scanner_text(scan); + char *loc = Char(cmt); + if ((strncmp(loc,"/*@SWIG",7) == 0) && (loc[Len(cmt)-3] == '@')) { + scanner_locator(cmt); + } + } + break; + case SWIG_TOKEN_ENDLINE: + break; + case SWIG_TOKEN_BACKSLASH: + break; + default: + Swig_error(cparse_file, cparse_line, "Illegal token '%s'.\n", Scanner_text(scan)); + return (ILLEGAL); + } + } +} + +static int check_typedef = 0; + +void scanner_set_location(String *file, int line) { + Scanner_set_location(scan,file,line-1); +} + +void scanner_check_typedef() { + check_typedef = 1; +} + +void scanner_ignore_typedef() { + check_typedef = 0; +} + +void scanner_last_id(int x) { + last_id = x; +} + +void scanner_clear_rename() { + rename_active = 0; +} + +/* Used to push a ficticious token into the scanner */ +static int next_token = 0; +void scanner_next_token(int tok) { + next_token = tok; +} + +void scanner_set_main_input_file(String *file) { + main_input_file = file; +} + +String *scanner_get_main_input_file() { + return main_input_file; +} + +/* ---------------------------------------------------------------------------- + * int yylex() + * + * Gets the lexene and returns tokens. + * ------------------------------------------------------------------------- */ + +int yylex(void) { + + int l; + char *yytext; + + if (!scan_init) { + scanner_init(); + } + + if (next_token) { + l = next_token; + next_token = 0; + return l; + } + + l = yylook(); + + /* Printf(stdout, "%s:%d:::%d: '%s'\n", cparse_file, cparse_line, l, Scanner_text(scan)); */ + + if (l == NONID) { + last_id = 1; + } else { + last_id = 0; + } + + /* We got some sort of non-white space object. We set the start_line + variable unless it has already been set */ + + if (!cparse_start_line) { + cparse_start_line = cparse_line; + } + + /* Copy the lexene */ + + switch (l) { + + case NUM_INT: + case NUM_FLOAT: + case NUM_ULONG: + case NUM_LONG: + case NUM_UNSIGNED: + case NUM_LONGLONG: + case NUM_ULONGLONG: + if (l == NUM_INT) + yylval.dtype.type = T_INT; + if (l == NUM_FLOAT) + yylval.dtype.type = T_DOUBLE; + if (l == NUM_ULONG) + yylval.dtype.type = T_ULONG; + if (l == NUM_LONG) + yylval.dtype.type = T_LONG; + if (l == NUM_UNSIGNED) + yylval.dtype.type = T_UINT; + if (l == NUM_LONGLONG) + yylval.dtype.type = T_LONGLONG; + if (l == NUM_ULONGLONG) + yylval.dtype.type = T_ULONGLONG; + yylval.dtype.val = NewString(Scanner_text(scan)); + yylval.dtype.bitfield = 0; + yylval.dtype.throws = 0; + return (l); + + case ID: + yytext = Char(Scanner_text(scan)); + if (yytext[0] != '%') { + /* Look for keywords now */ + + if (strcmp(yytext, "int") == 0) { + yylval.type = NewSwigType(T_INT); + return (TYPE_INT); + } + if (strcmp(yytext, "double") == 0) { + yylval.type = NewSwigType(T_DOUBLE); + return (TYPE_DOUBLE); + } + if (strcmp(yytext, "void") == 0) { + yylval.type = NewSwigType(T_VOID); + return (TYPE_VOID); + } + if (strcmp(yytext, "char") == 0) { + yylval.type = NewSwigType(T_CHAR); + return (TYPE_CHAR); + } + if (strcmp(yytext, "wchar_t") == 0) { + yylval.type = NewSwigType(T_WCHAR); + return (TYPE_WCHAR); + } + if (strcmp(yytext, "short") == 0) { + yylval.type = NewSwigType(T_SHORT); + return (TYPE_SHORT); + } + if (strcmp(yytext, "long") == 0) { + yylval.type = NewSwigType(T_LONG); + return (TYPE_LONG); + } + if (strcmp(yytext, "float") == 0) { + yylval.type = NewSwigType(T_FLOAT); + return (TYPE_FLOAT); + } + if (strcmp(yytext, "signed") == 0) { + yylval.type = NewSwigType(T_INT); + return (TYPE_SIGNED); + } + if (strcmp(yytext, "unsigned") == 0) { + yylval.type = NewSwigType(T_UINT); + return (TYPE_UNSIGNED); + } + if (strcmp(yytext, "bool") == 0) { + yylval.type = NewSwigType(T_BOOL); + return (TYPE_BOOL); + } + + /* Non ISO (Windows) C extensions */ + if (strcmp(yytext, "__int8") == 0) { + yylval.type = NewString(yytext); + return (TYPE_NON_ISO_INT8); + } + if (strcmp(yytext, "__int16") == 0) { + yylval.type = NewString(yytext); + return (TYPE_NON_ISO_INT16); + } + if (strcmp(yytext, "__int32") == 0) { + yylval.type = NewString(yytext); + return (TYPE_NON_ISO_INT32); + } + if (strcmp(yytext, "__int64") == 0) { + yylval.type = NewString(yytext); + return (TYPE_NON_ISO_INT64); + } + + /* C++ keywords */ + if (cparse_cplusplus) { + if (strcmp(yytext, "and") == 0) + return (LAND); + if (strcmp(yytext, "or") == 0) + return (LOR); + if (strcmp(yytext, "not") == 0) + return (LNOT); + if (strcmp(yytext, "class") == 0) + return (CLASS); + if (strcmp(yytext, "private") == 0) + return (PRIVATE); + if (strcmp(yytext, "public") == 0) + return (PUBLIC); + if (strcmp(yytext, "protected") == 0) + return (PROTECTED); + if (strcmp(yytext, "friend") == 0) + return (FRIEND); + if (strcmp(yytext, "virtual") == 0) + return (VIRTUAL); + if (strcmp(yytext, "operator") == 0) { + int nexttok; + String *s = NewString("operator "); + + /* If we have an operator, we have to collect the operator symbol and attach it to + the operator identifier. To do this, we need to scan ahead by several tokens. + Cases include: + + (1) If the next token is an operator as determined by Scanner_isoperator(), + it means that the operator applies to one of the standard C++ mathematical, + assignment, or logical operator symbols (e.g., '+','<=','==','&', etc.) + In this case, we merely append the symbol text to the operator string above. + + (2) If the next token is (, we look for ). This is operator (). + (3) If the next token is [, we look for ]. This is operator []. + (4) If the next token is an identifier. The operator is possibly a conversion operator. + (a) Must check for special case new[] and delete[] + + Error handling is somewhat tricky here. We'll try to back out gracefully if we can. + + */ + + nexttok = Scanner_token(scan); + if (Scanner_isoperator(nexttok)) { + /* One of the standard C/C++ symbolic operators */ + Append(s,Scanner_text(scan)); + yylval.str = s; + return OPERATOR; + } else if (nexttok == SWIG_TOKEN_LPAREN) { + /* Function call operator. The next token MUST be a RPAREN */ + nexttok = Scanner_token(scan); + if (nexttok != SWIG_TOKEN_RPAREN) { + Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n"); + } else { + Append(s,"()"); + yylval.str = s; + return OPERATOR; + } + } else if (nexttok == SWIG_TOKEN_LBRACKET) { + /* Array access operator. The next token MUST be a RBRACKET */ + nexttok = Scanner_token(scan); + if (nexttok != SWIG_TOKEN_RBRACKET) { + Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n"); + } else { + Append(s,"[]"); + yylval.str = s; + return OPERATOR; + } + } else if (nexttok == SWIG_TOKEN_ID) { + /* We have an identifier. This could be any number of things. It could be a named version of + an operator (e.g., 'and_eq') or it could be a conversion operator. To deal with this, we're + going to read tokens until we encounter a ( or ;. Some care is needed for formatting. */ + int needspace = 1; + int termtoken = 0; + const char *termvalue = 0; + + Append(s,Scanner_text(scan)); + while (1) { + + nexttok = Scanner_token(scan); + if (nexttok <= 0) { + Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n"); + } + if (nexttok == SWIG_TOKEN_LPAREN) { + termtoken = SWIG_TOKEN_LPAREN; + termvalue = "("; + break; + } else if (nexttok == SWIG_TOKEN_CODEBLOCK) { + termtoken = SWIG_TOKEN_CODEBLOCK; + termvalue = Char(Scanner_text(scan)); + break; + } else if (nexttok == SWIG_TOKEN_LBRACE) { + termtoken = SWIG_TOKEN_LBRACE; + termvalue = "{"; + break; + } else if (nexttok == SWIG_TOKEN_SEMI) { + termtoken = SWIG_TOKEN_SEMI; + termvalue = ";"; + break; + } else if (nexttok == SWIG_TOKEN_STRING) { + termtoken = SWIG_TOKEN_STRING; + termvalue = Swig_copy_string(Char(Scanner_text(scan))); + break; + } else if (nexttok == SWIG_TOKEN_ID) { + if (needspace) { + Append(s," "); + } + Append(s,Scanner_text(scan)); + } else { + Append(s,Scanner_text(scan)); + needspace = 0; + } + } + yylval.str = s; + if (!rename_active) { + String *cs; + char *t = Char(s) + 9; + if (!((strcmp(t, "new") == 0) + || (strcmp(t, "delete") == 0) + || (strcmp(t, "new[]") == 0) + || (strcmp(t, "delete[]") == 0) + || (strcmp(t, "and") == 0) + || (strcmp(t, "and_eq") == 0) + || (strcmp(t, "bitand") == 0) + || (strcmp(t, "bitor") == 0) + || (strcmp(t, "compl") == 0) + || (strcmp(t, "not") == 0) + || (strcmp(t, "not_eq") == 0) + || (strcmp(t, "or") == 0) + || (strcmp(t, "or_eq") == 0) + || (strcmp(t, "xor") == 0) + || (strcmp(t, "xor_eq") == 0) + )) { + /* retract(strlen(t)); */ + + /* The operator is a conversion operator. In order to deal with this, we need to feed the + type information back into the parser. For now this is a hack. Needs to be cleaned up later. */ + cs = NewString(t); + if (termtoken) Append(cs,termvalue); + Seek(cs,0,SEEK_SET); + Setline(cs,cparse_line); + Setfile(cs,cparse_file); + Scanner_push(scan,cs); + Delete(cs); + return COPERATOR; + } + } + if (termtoken) + Scanner_pushtoken(scan, termtoken, termvalue); + return (OPERATOR); + } + } + if (strcmp(yytext, "throw") == 0) + return (THROW); + if (strcmp(yytext, "try") == 0) + return (yylex()); + if (strcmp(yytext, "catch") == 0) + return (CATCH); + if (strcmp(yytext, "inline") == 0) + return (yylex()); + if (strcmp(yytext, "mutable") == 0) + return (yylex()); + if (strcmp(yytext, "explicit") == 0) + return (EXPLICIT); + if (strcmp(yytext, "export") == 0) + return (yylex()); + if (strcmp(yytext, "typename") == 0) + return (TYPENAME); + if (strcmp(yytext, "template") == 0) { + yylval.ivalue = cparse_line; + return (TEMPLATE); + } + if (strcmp(yytext, "delete") == 0) { + return (DELETE_KW); + } + if (strcmp(yytext, "using") == 0) { + return (USING); + } + if (strcmp(yytext, "namespace") == 0) { + return (NAMESPACE); + } + } else { + if (strcmp(yytext, "class") == 0) { + Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n"); + } + if (strcmp(yytext, "complex") == 0) { + yylval.type = NewSwigType(T_COMPLEX); + return (TYPE_COMPLEX); + } + if (strcmp(yytext, "restrict") == 0) + return (yylex()); + } + + /* Misc keywords */ + + if (strcmp(yytext, "extern") == 0) + return (EXTERN); + if (strcmp(yytext, "const") == 0) + return (CONST_QUAL); + if (strcmp(yytext, "static") == 0) + return (STATIC); + if (strcmp(yytext, "struct") == 0) + return (STRUCT); + if (strcmp(yytext, "union") == 0) + return (UNION); + if (strcmp(yytext, "enum") == 0) + return (ENUM); + if (strcmp(yytext, "sizeof") == 0) + return (SIZEOF); + + if (strcmp(yytext, "typedef") == 0) { + yylval.ivalue = 0; + return (TYPEDEF); + } + + /* Ignored keywords */ + + if (strcmp(yytext, "volatile") == 0) + return (VOLATILE); + if (strcmp(yytext, "register") == 0) + return (REGISTER); + if (strcmp(yytext, "inline") == 0) + return (yylex()); + + /* SWIG directives */ + } else { + if (strcmp(yytext, "%module") == 0) + return (MODULE); + if (strcmp(yytext, "%insert") == 0) + return (INSERT); + if (strcmp(yytext, "%name") == 0) + return (NAME); + if (strcmp(yytext, "%rename") == 0) { + rename_active = 1; + return (RENAME); + } + if (strcmp(yytext, "%namewarn") == 0) { + rename_active = 1; + return (NAMEWARN); + } + if (strcmp(yytext, "%includefile") == 0) + return (INCLUDE); + if (strcmp(yytext, "%val") == 0) { + Swig_warning(WARN_DEPRECATED_VAL, cparse_file, cparse_line, "%%val directive deprecated (ignored).\n"); + return (yylex()); + } + if (strcmp(yytext, "%out") == 0) { + Swig_warning(WARN_DEPRECATED_OUT, cparse_file, cparse_line, "%%out directive deprecated (ignored).\n"); + return (yylex()); + } + if (strcmp(yytext, "%constant") == 0) + return (CONSTANT); + if (strcmp(yytext, "%typedef") == 0) { + yylval.ivalue = 1; + return (TYPEDEF); + } + if (strcmp(yytext, "%native") == 0) + return (NATIVE); + if (strcmp(yytext, "%pragma") == 0) + return (PRAGMA); + if (strcmp(yytext, "%extend") == 0) + return (EXTEND); + if (strcmp(yytext, "%fragment") == 0) + return (FRAGMENT); + if (strcmp(yytext, "%inline") == 0) + return (INLINE); + if (strcmp(yytext, "%typemap") == 0) + return (TYPEMAP); + if (strcmp(yytext, "%feature") == 0) { + /* The rename_active indicates we don't need the information of the + * following function's return type. This applied for %rename, so do + * %feature. + */ + rename_active = 1; + return (FEATURE); + } + if (strcmp(yytext, "%except") == 0) + return (EXCEPT); + if (strcmp(yytext, "%importfile") == 0) + return (IMPORT); + if (strcmp(yytext, "%echo") == 0) + return (ECHO); + if (strcmp(yytext, "%apply") == 0) + return (APPLY); + if (strcmp(yytext, "%clear") == 0) + return (CLEAR); + if (strcmp(yytext, "%types") == 0) + return (TYPES); + if (strcmp(yytext, "%parms") == 0) + return (PARMS); + if (strcmp(yytext, "%varargs") == 0) + return (VARARGS); + if (strcmp(yytext, "%template") == 0) { + return (SWIGTEMPLATE); + } + if (strcmp(yytext, "%warn") == 0) + return (WARN); + } + /* Have an unknown identifier, as a last step, we'll do a typedef lookup on it. */ + + /* Need to fix this */ + if (check_typedef) { + if (SwigType_istypedef(yytext)) { + yylval.type = NewString(yytext); + return (TYPE_TYPEDEF); + } + } + yylval.id = Swig_copy_string(yytext); + last_id = 1; + return (ID); + case POUND: + return yylex(); + default: + return (l); + } +} |
