3 * Copyright (C) 2000-2006 Erik Edelmann <Erik.Edelmann@iki.fi>
5 * This program is free software; you can redistribute it
6 * and/or modify it under the terms of the GNU General Public
7 * License version 2 as published by the Free Software
10 * This program is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307 USA
27 #include "errormesg.h"
32 void yy_push_state(int new_state);
37 static YY_BUFFER_STATE include_stack[INCLUDE_RECURSION_LIMIT];
38 static int line_num_stack[INCLUDE_RECURSION_LIMIT];
39 static int incl_buff = 0;
41 static char string_buf[MAX_STRING_LEN];
42 static char *string_buf_ptr;
44 static int old_startcond;
46 static int last_returned;
48 #define RETURN(n) last_returned = n; return n;
61 \" { string_buf_ptr = string_buf; old_startcond = YY_START;
63 ' { string_buf_ptr = string_buf; old_startcond = YY_START;
69 *string_buf_ptr = '\0';
70 yylval.string = xstrdup(string_buf);
71 DEBUG_PRINT("string: '%s'\n", yylval.string);
75 <str_dq,str_sq>&[ \t]*\n |
76 <str_dq,str_sq>&[ \t]*\n[ \t]*& /* Ignore (continued strings, free fmt) */
78 <str_dq,str_sq>\n[ ]{5}[^ \t\n] {
79 if (old_startcond == fixed_fmt)
80 ; /* Ignore (cont. strings, fixed fmt) */
82 unput(yytext[strlen(yytext)-1]);
88 yylval.number = yylineno;
89 RETURN(UNTERMINATED_STRING);
92 <str_sq,str_dq>. { *string_buf_ptr++ = yytext[0]; }
97 !.* { RETURN(EOSTMT); } /* Treat comments like */
98 <fixed_fmt>^[cC*dD].*\n { RETURN(EOSTMT); } /* empty lines */
100 #[ \t]*include { RETURN(CPP_INCLUDE); }
101 \$[ \t]*include { RETURN(F90PPR_INCLUDE); }
102 \?\?[ \t]*include { RETURN(COCO_INCLUDE); }
104 #[ \t]*define { RETURN(CPP_DEFINE); }
105 \$[ \t]*DEFINE { RETURN(F90PPR_DEFINE); }
107 #[ \t]*undef { RETURN(CPP_UNDEF); }
108 \$[ \t]*UNDEF { RETURN(F90PPR_UNDEF); }
110 #[ \t]*ifdef { RETURN(CPP_IFDEF); }
111 #[ \t]*ifndef { RETURN(CPP_IFNDEF); }
112 #[ \t]*if[ \t].* { RETURN(CPP_IF); }
113 #[ \t]*elif[ \t].* { RETURN(CPP_ELIF); }
114 #[ \t]*else { RETURN(CPP_ELSE); }
115 #[ \t]*endif { RETURN(CPP_ENDIF); }
117 $[ \t]*ifdef { RETURN(F90PPR_IFDEF); }
118 $[ \t]*ifndef { RETURN(F90PPR_IFNDEF); }
119 $[ \t]*if { RETURN(F90PPR_IF); }
120 $[ \t]*elif { RETURN(F90PPR_ELIF); }
121 $[ \t]*else { RETURN(F90PPR_ELSE); }
122 $[ \t]*endif { RETURN(F90PPR_ENDIF); }
124 /* Line continuations, possible involving comments. */
128 <fixed_fmt>\n[ ]{5}[^ ] { RETURN(GARBAGE); }
130 =|=> { RETURN(ASSIGNMENT_OP); }
132 [a-zA-Z_][a-zA-Z_0-9]* { ;yylval.string = xstrdup(yytext); RETURN(WORD); }
134 [^ \t\n\r;,!'"a-zA-Z=&]+ { RETURN(GARBAGE); }
136 ;|\n { RETURN(EOSTMT); }
138 [ \t\r,] /* Ignore */
139 \\[ \t]*\n /* Ignore line-endings preceeded by \ */
141 . { RETURN(*yytext); }
145 DEBUG_PRINT("EOF reached %i\n", incl_buff);
148 if (last_returned == EOSTMT) {
152 /* "EOF without \n first" cases. */
157 yy_delete_buffer(YY_CURRENT_BUFFER);
158 yy_switch_to_buffer (include_stack[incl_buff]);
159 yylineno = line_num_stack[incl_buff];
167 /* "Include" file 'incfile' here. Return false for failure, true for success. */
169 bool lex_include_file(const char *incfile)
173 DEBUG_PRINT("'%s'\n", incfile);
175 if (incl_buff >= INCLUDE_RECURSION_LIMIT) {
176 warning("Recursion limit reached in file '%s'", incfile);
181 yyin = open_src_file(incfile, options.src_path);
183 if (errno == ENOENT) {
184 if (options.warn_missing)
185 warning("Include file '%s' not found", incfile);
187 warning("Skipping include file '%s': %s", incfile, strerror(errno));
193 include_stack[incl_buff] = YY_CURRENT_BUFFER;
194 yy_switch_to_buffer(yy_create_buffer (yyin, YY_BUF_SIZE));
196 line_num_stack[incl_buff++] = yylineno;
203 void lex_set_format(SourceFmt fmt)
208 BEGIN(free_fmt); break;
210 BEGIN(fixed_fmt); break;