]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/SWIG/scanner.cxx
1 /*******************************************************************************
2 * Simplified Wrapper and Interface Generator (SWIG)
4 * Author : David Beazley
6 * Department of Computer Science
7 * University of Chicago
10 * beazley@cs.uchicago.edu
12 * Please read the file LICENSE for the copyright and terms by which SWIG
13 * can be used and distributed.
14 *******************************************************************************/
16 /*************************************************************************
23 * Input scanner. This scanner finds and returns tokens
24 * for the wrapper generator. Since using lex/flex from
25 * C++ is so F'ed up, I've written this function to replace
26 * them entirely. It's not as fast, but hopefully it will
27 * eliminate alot of compilation problems.
29 *************************************************************************/
48 // This structure is used for managing code fragments as
49 // might be used by the %inline directive and handling of
63 static String comment
;
64 String CCode
; // String containing C code
65 static char *yybuffer
;
66 static int lex_pos
= 0;
67 static int lex_len
= 0;
68 static char *inline_yybuffer
= 0;
69 static int inline_lex_pos
= 0;
70 static int inline_lex_len
= 0;
71 static int inline_line_number
= 0;
72 static CodeFragment
*fragments
= 0; // Code fragments
82 static int comment_start
;
83 static int scan_init
= 0;
84 static int num_brace
= 0;
85 static int last_brace
= 0;
86 static int in_define
= 0;
87 static int define_first_id
= 0; /* Set when looking for first identifier of a define */
91 /**************************************************************
95 **************************************************************/
99 yybuffer
= (char *) malloc(YYBSIZE
);
103 /**************************************************************
104 * scanner_file(FILE *f)
106 * Start reading from new file
107 **************************************************************/
108 void scanner_file(FILE *f
) {
113 in
->in_file
= input_file
;
114 in
->extern_mode
= WrapExtern
;
115 in
->force_extern
= ForceExtern
;
116 if (in_head
) in_head
->line_number
= line_number
+1;
117 if (!in_head
) in
->prev
= 0;
118 else in
->prev
= in_head
;
124 /**************************************************************
127 * Close current input file and go to next
128 **************************************************************/
130 void scanner_close() {
133 static int lib_insert
= 0;
135 if (!in_head
) return;
139 line_number
= p
->line_number
;
140 input_file
= p
->in_file
;
141 WrapExtern
= p
->extern_mode
;
142 if (!WrapExtern
) remove_symbol("SWIGEXTERN");
143 ForceExtern
= p
->force_extern
;
150 // if LEX_in is NULL it means we're done with the interface file. We're now
151 // going to grab all of the library files.
153 if ((!LEX_in
) && (!lib_insert
)) {
160 /**************************************************************
163 * gets next character from input.
164 * If we're in inlining mode, we actually retrieve a character
165 * from inline_yybuffer instead.
166 **************************************************************/
173 if (inline_lex_pos
>= inline_lex_len
) {
174 // Done with inlined code. Check to see if we have any
175 // new code fragments. If so, switch to them.
176 delete inline_yybuffer
;
179 inline_yybuffer
= fragments
->text
;
181 inline_lex_len
= strlen(fragments
->text
);
182 line_number
= fragments
->line_number
;
186 c
= inline_yybuffer
[0];
190 line_number
= inline_line_number
; // Restore old line number
194 c
= inline_yybuffer
[inline_lex_pos
-1];
198 if (lex_pos
>= lex_len
) {
202 while(fgets(yybuffer
, YYBSIZE
, LEX_in
) == NULL
) {
203 scanner_close(); // Close current input file
204 if (!LEX_in
) return 0; // No more, we're outta here
206 lex_len
= strlen(yybuffer
);
211 c
= yybuffer
[lex_pos
-1];
214 if (yylen
>= YYBSIZE
) {
215 fprintf(stderr
,"** FATAL ERROR. Buffer overflow in scanner.cxx.\nReport this to swig@cs.utah.edu.\n");
229 void retract(int n
) {
232 for (i
= 0; i
< n
; i
++) {
235 if (inline_lex_pos
< 0) {
236 fprintf(stderr
,"Internal scanner error. inline_lex_pos < 0\n");
244 if (yytext
[yylen
] == '\n') {
246 // Figure out what column we're in
250 if (yytext
[c
] == '\n') break;
258 if (yylen
< 0) yylen
= 0;
261 /**************************************************************
262 * start_inline(char *text, int line)
264 * This grabs a chunk of text and tries to inline it into
265 * the current file. (This is kind of wild, but cool when
268 * If we're already in inlining mode, we will save the code
270 **************************************************************/
272 void start_inline(char *text
, int line
) {
276 // Already processing a code fragment, simply hang on
277 // to this one for later.
281 // Add a new code fragment to our list
282 f
= new CodeFragment
;
283 f
->text
= copy_string(text
);
284 f
->line_number
= line
;
286 if (!fragments
) fragments
= f
;
289 while (f1
->next
) f1
= f1
->next
;
294 // Switch our scanner over to process text from a string.
295 // Save current line number and other information however.
297 inline_yybuffer
= copy_string(text
);
298 inline_lex_len
= strlen(text
);
300 inline_line_number
= line_number
; // Make copy of old line number
306 /**************************************************************
307 * yycomment(char *, int line)
309 * Inserts a comment into a documentation entry.
310 **************************************************************/
312 void yycomment(char *s
, int line
, int col
) {
313 comment_handler
->add_comment(s
,line
,col
,input_file
);
316 /**************************************************************
317 * void skip_brace(void)
320 * Skip all characters until we find a matching closed }.
322 * This function is used to skip over inlined C code and other
323 * garbage found in interface files.
324 ***************************************************************/
326 void skip_brace(void) {
330 while (num_brace
> last_brace
) {
331 if ((c
= nextchar()) == 0) {
332 fprintf(stderr
,"%s : Line %d. Missing '}'. Reached end of input.\n",
333 input_file
, line_number
);
338 if (c
== '{') num_brace
++;
339 if (c
== '}') num_brace
--;
345 /**************************************************************
346 * void skip_template(void)
349 * Skip all characters until we find a matching closed >.
351 * This function is used to skip over C++ templated types
352 * and objective-C protocols.
353 ***************************************************************/
355 void skip_template(void) {
361 if ((c
= nextchar()) == 0) {
362 fprintf(stderr
,"%s : Line %d. Missing '>'. Reached end of input.\n",
363 input_file
, line_number
);
368 if (c
== '<') num_lt
++;
369 if (c
== '>') num_lt
--;
374 /**************************************************************
375 * void skip_to_end(void)
377 * Skips to the @end directive in a Objective-C definition
378 **************************************************************/
380 void skip_to_end(void) {
384 while ((c
= nextchar())){
387 if (c
== '@') state
= 1;
392 if (strncmp(yytext
,"@end",4) == 0) return;
403 fprintf(stderr
,"%s : EOF. Missing @end. Reached end of input.\n",
409 /**************************************************************
410 * void skip_decl(void)
412 * This tries to skip over an entire declaration. For example
414 * friend ostream& operator<<(ostream&, const char *s);
417 * friend ostream& operator<<(ostream&, const char *s) { };
419 **************************************************************/
421 void skip_decl(void) {
425 if ((c
= nextchar()) == 0) {
426 fprintf(stderr
,"%s : Line %d. Missing semicolon. Reached end of input.\n",
427 input_file
, line_number
);
432 last_brace
= num_brace
;
437 if (c
== ';') done
= 1;
440 while (num_brace
> last_brace
) {
441 if ((c
= nextchar()) == 0) {
442 fprintf(stderr
,"%s : Line %d. Missing '}'. Reached end of input.\n",
443 input_file
, line_number
);
447 if (c
== '{') num_brace
++;
448 if (c
== '}') num_brace
--;
454 /**************************************************************
455 * void skip_define(void)
457 * Skips to the end of a #define statement.
459 **************************************************************/
461 void skip_define(void) {
464 if ((c
= nextchar()) == 0) return;
465 if (c
== '\\') in_define
= 2;
467 if (in_define
== 2) {
469 } else if (in_define
== 1) {
477 /**************************************************************
478 * int skip_cond(int inthen)
480 * Skips the false portion of an #ifdef directive. Looks
481 * for either a matching #else or #endif
483 * inthen is 0 or 1 depending on whether or not we're
484 * handling the "then" or "else" part of a conditional.
486 * Returns 1 if the else part of the #if-#endif block was
487 * reached. Returns 0 otherwise. Returns -1 on error.
488 **************************************************************/
490 int skip_cond(int inthen
) {
491 int level
= 0; /* Used to handled nested if-then-else */
497 file
= copy_string(input_file
);
498 start_line
= line_number
;
504 if ((c
= nextchar()) == 0) {
505 fprintf(stderr
,"%s : Line %d. Unterminated #if-else directive.\n", file
, start_line
);
507 return -1; /* Error */
509 if ((c
== '#') || (c
== '%')) {
511 } else if (isspace(c
)) {
515 /* Some non-whitespace character. Look for line end */
521 /* Beginning of a C preprocessor statement */
522 if ((c
= nextchar()) == 0) {
523 fprintf(stderr
,"%s : Line %d. Unterminated #if-else directive.\n", file
, start_line
);
525 return -1; /* Error */
531 else if (isspace(c
)) {
540 if ((c
= nextchar()) == 0) {
541 fprintf(stderr
,"%s : Line %d. Unterminated #if-else directive.\n", file
, start_line
);
543 return -1; /* Error */
545 if ((c
== ' ') || (c
== '\t') || (c
=='\n')) {
547 if ((strcmp(yytext
,"#ifdef") == 0) || (strcmp(yytext
,"%ifdef") == 0)) {
550 } else if ((strcmp(yytext
,"#ifndef") == 0) || (strcmp(yytext
,"%ifndef") == 0)) {
553 } else if ((strcmp(yytext
,"#if") == 0) || (strcmp(yytext
,"%if") == 0)) {
556 } else if ((strcmp(yytext
,"#else") == 0) || (strcmp(yytext
,"%else") == 0)) {
557 if (level
== 0) { /* Found matching else. exit */
559 /* Hmmm. We've got an "extra #else" directive here */
560 fprintf(stderr
,"%s : Line %d. Misplaced #else.\n", input_file
, line_number
);
573 } else if ((strcmp(yytext
,"#endif") == 0) || (strcmp(yytext
,"%endif") == 0)) {
574 if (level
<= 0) { /* Found matching endif. exit */
583 } else if ((strcmp(yytext
,"#elif") == 0) || (strcmp(yytext
,"%elif") == 0)) {
585 // If we come across this, we pop it back onto the input queue and return
600 /* Non-white space. Look for line break */
601 if ((c
= nextchar()) == 0) {
602 fprintf(stderr
,"%s : Line %d. Unterminated #if directive.\n", file
, start_line
);
604 return -1; /* Error */
618 /**************************************************************
622 * See Aho,Sethi, and Ullman, pg. 106
623 **************************************************************/
634 /* printf("State = %d\n", state); */
638 if((c
= nextchar()) == 0) return(0);
640 /* Process delimeters */
645 if (in_define
== 1) {
648 } else if (in_define
== 2) {
651 } else if (isspace(c
)) {
656 /* Look for single character symbols */
658 else if (c
== '(') return (LPAREN
);
659 else if (c
== ')') return (RPAREN
);
660 else if (c
== ';') return (SEMI
);
661 else if (c
== ',') return (COMMA
);
662 else if (c
== '*') return (STAR
);
666 fprintf(stderr
,"%s : Line %d. Error. Extraneous '}' (Ignored)\n",
667 input_file
, line_number
);
675 last_brace
= num_brace
;
679 else if (c
== '=') return (EQUAL
);
680 else if (c
== '+') return (PLUS
);
681 else if (c
== '-') return (MINUS
);
682 else if (c
== '&') return (AND
);
683 else if (c
== '|') return (OR
);
684 else if (c
== '^') return (XOR
);
685 else if (c
== '<') state
= 60;
686 else if (c
== '>') state
= 61;
687 else if (c
== '~') return (NOT
);
688 else if (c
== '!') return (LNOT
);
689 else if (c
== '\\') {
690 if (in_define
== 1) {
696 else if (c
== '[') return (LBRACKET
);
697 else if (c
== ']') return (RBRACKET
);
699 /* Look for multi-character sequences */
701 else if (c
== '/') state
= 1; // Comment (maybe)
702 else if (c
== '\"') state
= 2; // Possibly a string
703 else if (c
== '#') state
= 3; // CPP
704 else if (c
== '%') state
= 4; // Directive
705 else if (c
== '@') state
= 4; // Objective C keyword
706 else if (c
== ':') state
= 5; // maybe double colon
707 else if (c
== '0') state
= 83; // An octal or hex value
708 else if (c
== '\'') state
= 9; // A character constant
709 else if (c
== '.') state
= 100; // Maybe a number, maybe just a period
710 else if (isdigit(c
)) state
= 8; // A numerical value
711 else if ((isalpha(c
)) || (c
== '_') || (c
== '$')) state
= 7;
714 case 1: /* Comment block */
715 if ((c
= nextchar()) == 0) return(0);
717 comment_start
= line_number
;
718 column_start
= column
;
720 state
= 10; // C++ style comment
721 } else if (c
== '*') {
722 comment_start
= line_number
;
723 column_start
= column
;
725 state
= 11; // C style comment
731 case 10: /* C++ style comment */
732 if ((c
= nextchar()) == 0) {
733 fprintf(stderr
,"%s : EOF. Unterminated comment detected.\n",input_file
);
739 // Add the comment to documentation
740 yycomment(comment
.get(),comment_start
, column_start
);
743 if (in_define
== 1) {
753 case 11: /* C style comment block */
754 if ((c
= nextchar()) == 0) {
755 fprintf(stderr
,"%s : EOF. Unterminated comment detected.\n", input_file
);
767 case 12: /* Still in C style comment */
768 if ((c
= nextchar()) == 0) {
769 fprintf(stderr
,"%s : EOF. Unterminated comment detected.\n", input_file
);
776 } else if (c
== '/') {
778 yycomment(comment
.get(),comment_start
,column_start
);
788 case 2: /* Processing a string */
789 if ((c
= nextchar()) == 0) {
790 fprintf(stderr
,"%s : EOF. Unterminated string detected.\n", input_file
);
796 yylval
.id
= copy_string(yytext
+1);
798 } else if (c
== '\\') {
799 state
= 21; /* Possibly an escape sequence. */
803 case 21: /* An escape sequence. get next character, then go
804 back to processing strings */
806 if ((c
= nextchar()) == 0) return 0;
810 case 3: /* a CPP directive */
812 if (( c
= nextchar()) == 0) return 0;
818 } else if ((c
== ' ') || (c
== '\t')) { // Ignore white space after # symbol
828 if ((c
= nextchar()) == 0) return 0;
829 if ((c
== ' ') || (c
== '\t') || (c
=='\n')) {
832 if (strcmp(yytext
,"#define") == 0) {
836 } else if (strcmp(yytext
,"#ifdef") == 0) {
838 } else if (strcmp(yytext
,"#ifndef") == 0) {
840 } else if (strcmp(yytext
,"#else") == 0) {
842 } else if (strcmp(yytext
,"#endif") == 0) {
844 } else if (strcmp(yytext
,"#undef") == 0) {
846 } else if (strcmp(yytext
,"#if") == 0) {
848 } else if (strcmp(yytext
,"#elif") == 0) {
851 /* Some kind of "unknown CPP directive. Skip to end of the line */
857 if ((c
= nextchar()) == 0) return 0;
867 case 4: /* A wrapper generator directive (maybe) */
868 if (( c
= nextchar()) == 0) return 0;
870 state
= 40; /* Include block */
872 start_line
= line_number
;
874 else if ((isalpha(c
)) || (c
== '_')) state
= 7;
881 case 40: /* Process an include block */
882 if ((c
= nextchar()) == 0) {
883 fprintf(stderr
,"%s : EOF. Unterminated include block detected.\n", input_file
);
888 if (c
== '%') state
= 41;
895 case 41: /* Still processing include block */
896 if ((c
= nextchar()) == 0) {
897 fprintf(stderr
,"%s : EOF. Unterminated include block detected.\n", input_file
);
902 yylval
.id
= header
.get();
912 case 5: /* Maybe a double colon */
914 if (( c
= nextchar()) == 0) return 0;
915 if ( c
== ':') return DCOLON
;
922 case 60: /* shift operators */
923 if ((c
= nextchar()) == 0) return (0);
924 if (c
== '<') return LSHIFT
;
931 if ((c
= nextchar()) == 0) return (0);
932 if (c
== '>') return RSHIFT
;
938 case 7: /* Identifier */
939 if ((c
= nextchar()) == 0) return(0);
940 if (isalnum(c
) || (c
== '_') || (c
== '.') || (c
== '$'))
941 // || (c == '.') || (c == '-'))
944 /* We might just be in a CPP macro definition. Better check */
945 if ((in_define
) && (define_first_id
)) {
946 /* Yep. We're going to ignore the rest of it */
961 case 8: /* A numerical digit */
962 if ((c
= nextchar()) == 0) return(0);
963 if (c
== '.') {state
= 81;}
964 else if ((c
== 'e') || (c
== 'E')) {state
= 86;}
965 else if ((c
== 'f') || (c
== 'F')) {
967 yylval
.id
= copy_string(yytext
);
970 else if (isdigit(c
)) { state
= 8;}
971 else if ((c
== 'l') || (c
== 'L')) {
973 } else if ((c
== 'u') || (c
== 'U')) {
978 yylval
.id
= copy_string(yytext
);
982 case 81: /* A floating pointer number of some sort */
983 if ((c
= nextchar()) == 0) return(0);
984 if (isdigit(c
)) state
= 81;
985 else if ((c
== 'e') || (c
== 'E')) state
= 82;
986 else if ((c
== 'f') || (c
== 'F') || (c
== 'l') || (c
== 'L')) {
988 yylval
.id
= copy_string(yytext
);
993 yylval
.id
= copy_string(yytext
);
998 if ((c
= nextchar()) == 0) return(0);
999 if ((isdigit(c
)) || (c
== '-') || (c
== '+')) state
= 86;
1002 yytext
[yylen
-1] = 0;
1003 yylval
.id
= copy_string(yytext
);
1008 /* Might be a hexidecimal or octal number */
1009 if ((c
= nextchar()) == 0) return(0);
1010 if (isdigit(c
)) state
= 84;
1011 else if ((c
== 'x') || (c
== 'X')) state
= 85;
1012 else if (c
== '.') state
= 81;
1013 else if ((c
== 'l') || (c
== 'L')) {
1015 } else if ((c
== 'u') || (c
== 'U')) {
1020 yylval
.id
= copy_string(yytext
);
1025 /* This is an octal number */
1026 if ((c
= nextchar()) == 0) return (0);
1027 if (isdigit(c
)) state
= 84;
1028 else if ((c
== 'l') || (c
== 'L')) {
1030 } else if ((c
== 'u') || (c
== 'U')) {
1035 yylval
.id
= copy_string(yytext
);
1040 /* This is an hex number */
1041 if ((c
= nextchar()) == 0) return (0);
1042 if ((isdigit(c
)) || (c
=='a') || (c
=='b') || (c
=='c') ||
1043 (c
=='d') || (c
=='e') || (c
=='f') || (c
=='A') ||
1044 (c
=='B') || (c
=='C') || (c
=='D') || (c
=='E') ||
1047 else if ((c
== 'l') || (c
== 'L')) {
1049 } else if ((c
== 'u') || (c
== 'U')) {
1054 yylval
.id
= copy_string(yytext
);
1060 /* Rest of floating point number */
1062 if ((c
= nextchar()) == 0) return (0);
1063 if (isdigit(c
)) state
= 86;
1064 else if ((c
== 'f') || (c
== 'F') || (c
== 'l') || (c
== 'L')) {
1066 yylval
.id
= copy_string(yytext
);
1071 yylval
.id
= copy_string(yytext
);
1074 /* Parse a character constant. ie. 'a' */
1078 /* A long integer of some sort */
1079 if ((c
= nextchar()) == 0) return (0);
1080 if ((c
== 'u') || (c
== 'U')) {
1082 yylval
.id
= copy_string(yytext
);
1087 yylval
.id
= copy_string(yytext
);
1092 /* An unsigned integer of some sort */
1093 if ((c
= nextchar()) == 0) return (0);
1094 if ((c
== 'l') || (c
== 'L')) {
1096 yylval
.id
= copy_string(yytext
);
1101 yylval
.id
= copy_string(yytext
);
1102 return(NUM_UNSIGNED
);
1106 if ((c
= nextchar()) == 0) return (0);
1108 yytext
[yylen
-1] = 0;
1109 yylval
.id
= copy_string(yytext
+1);
1115 if ((c
= nextchar()) == 0) return (0);
1116 if (isdigit(c
)) state
= 81;
1124 fprintf(stderr
,"%s : Line %d ::Illegal character '%c'=%d.\n",input_file
, line_number
,c
,c
);
1134 static int check_typedef
= 0;
1136 void scanner_check_typedef() {
1140 void scanner_ignore_typedef() {
1145 /**************************************************************
1148 * Gets the lexene and returns tokens.
1149 *************************************************************/
1151 extern "C" int yylex(void) {
1157 // if (LEX_in == NULL) LEX_in = stdin;
1158 // scanner_file(LEX_in);
1163 /* We got some sort of non-white space object. We set the start_line
1164 variable unless it has already been set */
1167 start_line
= line_number
;
1170 /* Copy the lexene */
1174 /* Hack to support ignoring of CPP macros */
1177 define_first_id
= 0;
1184 /* Look for keywords now */
1186 if (strcmp(yytext
,"int") == 0) {
1187 yylval
.type
= new DataType
;
1188 yylval
.type
->type
= T_INT
;
1189 strcpy(yylval
.type
->name
,yytext
);
1192 if (strcmp(yytext
,"double") == 0) {
1193 yylval
.type
= new DataType
;
1194 yylval
.type
->type
= T_DOUBLE
;
1195 strcpy(yylval
.type
->name
,yytext
);
1196 return(TYPE_DOUBLE
);
1198 if (strcmp(yytext
,"void") == 0) {
1199 yylval
.type
= new DataType
;
1200 yylval
.type
->type
= T_VOID
;
1201 strcpy(yylval
.type
->name
,yytext
);
1204 if (strcmp(yytext
,"char") == 0) {
1205 yylval
.type
= new DataType
;
1206 yylval
.type
->type
= T_CHAR
;
1207 strcpy(yylval
.type
->name
,yytext
);
1210 if (strcmp(yytext
,"short") == 0) {
1211 yylval
.type
= new DataType
;
1212 yylval
.type
->type
= T_SHORT
;
1213 strcpy(yylval
.type
->name
,yytext
);
1216 if (strcmp(yytext
,"long") == 0) {
1217 yylval
.type
= new DataType
;
1218 yylval
.type
->type
= T_LONG
;
1219 strcpy(yylval
.type
->name
,yytext
);
1222 if (strcmp(yytext
,"float") == 0) {
1223 yylval
.type
= new DataType
;
1224 yylval
.type
->type
= T_FLOAT
;
1225 strcpy(yylval
.type
->name
,yytext
);
1228 if (strcmp(yytext
,"signed") == 0) {
1229 yylval
.type
= new DataType
;
1230 yylval
.type
->type
= T_SINT
;
1231 strcpy(yylval
.type
->name
,yytext
);
1232 return(TYPE_SIGNED
);
1234 if (strcmp(yytext
,"unsigned") == 0) {
1235 yylval
.type
= new DataType
;
1236 yylval
.type
->type
= T_UINT
;
1237 strcpy(yylval
.type
->name
,yytext
);
1238 return(TYPE_UNSIGNED
);
1240 if (strcmp(yytext
,"bool") == 0) {
1241 yylval
.type
= new DataType
;
1242 yylval
.type
->type
= T_BOOL
;
1243 strcpy(yylval
.type
->name
,yytext
);
1249 if (strcmp(yytext
,"class") == 0) return(CLASS
);
1250 if (strcmp(yytext
,"private") == 0) return(PRIVATE
);
1251 if (strcmp(yytext
,"public") == 0) return(PUBLIC
);
1252 if (strcmp(yytext
,"protected") == 0) return(PROTECTED
);
1253 if (strcmp(yytext
,"friend") == 0) return(FRIEND
);
1254 if (strcmp(yytext
,"virtual") == 0) return(VIRTUAL
);
1255 if (strcmp(yytext
,"operator") == 0) return(OPERATOR
);
1256 if (strcmp(yytext
,"throw") == 0) return(THROW
);
1257 if (strcmp(yytext
,"inline") == 0) return(yylex());
1258 if (strcmp(yytext
,"template") == 0) return(TEMPLATE
);
1261 // Objective-C keywords
1263 if (strcmp(yytext
,"@interface") == 0) return (OC_INTERFACE
);
1264 if (strcmp(yytext
,"@end") == 0) return (OC_END
);
1265 if (strcmp(yytext
,"@public") == 0) return (OC_PUBLIC
);
1266 if (strcmp(yytext
,"@private") == 0) return (OC_PRIVATE
);
1267 if (strcmp(yytext
,"@protected") == 0) return (OC_PROTECTED
);
1268 if (strcmp(yytext
,"@class") == 0) return(OC_CLASS
);
1269 if (strcmp(yytext
,"@implementation") == 0) return(OC_IMPLEMENT
);
1270 if (strcmp(yytext
,"@protocol") == 0) return(OC_PROTOCOL
);
1275 if (strcmp(yytext
,"static") == 0) return(STATIC
);
1276 if (strcmp(yytext
,"extern") == 0) return(EXTERN
);
1277 if (strcmp(yytext
,"const") == 0) return(CONST
);
1278 if (strcmp(yytext
,"struct") == 0) return(STRUCT
);
1279 if (strcmp(yytext
,"union") == 0) return(UNION
);
1280 if (strcmp(yytext
,"enum") == 0) return(ENUM
);
1281 if (strcmp(yytext
,"sizeof") == 0) return(SIZEOF
);
1282 if (strcmp(yytext
,"defined") == 0) return(DEFINED
);
1286 if (strcmp(yytext
,"volatile") == 0) return(yylex());
1290 if (strcmp(yytext
,"%module") == 0) return(MODULE
);
1291 if (strcmp(yytext
,"%init") == 0) return(INIT
);
1292 if (strcmp(yytext
,"%wrapper") == 0) return(WRAPPER
);
1293 if (strcmp(yytext
,"%readonly") == 0) return(READONLY
);
1294 if (strcmp(yytext
,"%readwrite") == 0) return(READWRITE
);
1295 if (strcmp(yytext
,"%name") == 0) return(NAME
);
1296 if (strcmp(yytext
,"%rename") == 0) return(RENAME
);
1297 if (strcmp(yytext
,"%include") == 0) return(INCLUDE
);
1298 if (strcmp(yytext
,"%extern") == 0) return(WEXTERN
);
1299 if (strcmp(yytext
,"%checkout") == 0) return(CHECKOUT
);
1300 if (strcmp(yytext
,"%val") == 0) return(CVALUE
);
1301 if (strcmp(yytext
,"%out") == 0) return(COUT
);
1303 if (strcmp(yytext
,"%section") == 0) {
1304 yylval
.ivalue
= line_number
;
1307 if (strcmp(yytext
,"%subsection") == 0) {
1308 yylval
.ivalue
= line_number
;
1311 if (strcmp(yytext
,"%subsubsection") == 0) {
1312 yylval
.ivalue
= line_number
;
1313 return (SUBSUBSECTION
);
1315 if (strcmp(yytext
,"%title") == 0) {
1316 yylval
.ivalue
= line_number
;
1319 if (strcmp(yytext
,"%style") == 0) return(STYLE
);
1320 if (strcmp(yytext
,"%localstyle") == 0) return(LOCALSTYLE
);
1321 if (strcmp(yytext
,"%typedef") == 0) {
1325 if (strcmp(yytext
,"typedef") == 0) {
1329 if (strcmp(yytext
,"%alpha") == 0) return(ALPHA_MODE
);
1330 if (strcmp(yytext
,"%raw") == 0) return(RAW_MODE
);
1331 if (strcmp(yytext
,"%text") == 0) return(TEXT
);
1332 if (strcmp(yytext
,"%native") == 0) return(NATIVE
);
1333 if (strcmp(yytext
,"%disabledoc") == 0) return(DOC_DISABLE
);
1334 if (strcmp(yytext
,"%enabledoc") == 0) return(DOC_ENABLE
);
1335 if (strcmp(yytext
,"%ifdef") == 0) return(IFDEF
);
1336 if (strcmp(yytext
,"%else") == 0) return(ELSE
);
1337 if (strcmp(yytext
,"%ifndef") == 0) return(IFNDEF
);
1338 if (strcmp(yytext
,"%endif") == 0) return(ENDIF
);
1339 if (strcmp(yytext
,"%if") == 0) return(IF
);
1340 if (strcmp(yytext
,"%elif") == 0) return(ELIF
);
1341 if (strcmp(yytext
,"%pragma") == 0) return(PRAGMA
);
1342 if (strcmp(yytext
,"%addmethods") == 0) return(ADDMETHODS
);
1343 if (strcmp(yytext
,"%inline") == 0) return(INLINE
);
1344 if (strcmp(yytext
,"%typemap") == 0) return(TYPEMAP
);
1345 if (strcmp(yytext
,"%except") == 0) return(EXCEPT
);
1346 if (strcmp(yytext
,"%import") == 0) return(IMPORT
);
1347 if (strcmp(yytext
,"%echo") == 0) return(ECHO
);
1348 if (strcmp(yytext
,"%new") == 0) return(NEW
);
1349 if (strcmp(yytext
,"%apply") == 0) return(APPLY
);
1350 if (strcmp(yytext
,"%clear") == 0) return(CLEAR
);
1351 if (strcmp(yytext
,"%doconly") == 0) return(DOCONLY
);
1353 // Have an unknown identifier, as a last step, we'll
1354 // do a typedef lookup on it.
1356 if (check_typedef
) {
1357 if (DataType::is_typedef(yytext
)) {
1358 yylval
.type
= new DataType
;
1359 yylval
.type
->type
= T_USER
;
1360 strcpy(yylval
.type
->name
,yytext
);
1361 yylval
.type
->typedef_resolve();
1362 return(TYPE_TYPEDEF
);
1366 yylval
.id
= copy_string(yytext
);
1373 // --------------------------------------------------------------
1374 // scanner_clear_start()
1376 // Clears the start of a declaration
1377 // --------------------------------------------------------------
1379 void scanner_clear_start() {