Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmListFileLexer.in.l
1 %{
2 /*============================================================================
3   CMake - Cross Platform Makefile Generator
4   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5
6   Distributed under the OSI-approved BSD License (the "License");
7   see accompanying file Copyright.txt for details.
8
9   This software is distributed WITHOUT ANY WARRANTY; without even the
10   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11   See the License for more information.
12 ============================================================================*/
13 /*
14
15 This file must be translated to C and modified to build everywhere.
16
17 Run flex like this:
18
19   flex --prefix=cmListFileLexer_yy -ocmListFileLexer.c cmListFileLexer.in.l
20
21 Modify cmListFileLexer.c:
22   - remove TABs
23   - remove the yyunput function
24   - add a statement "(void)yyscanner;" to the top of these methods:
25       yy_fatal_error, cmListFileLexer_yyalloc, cmListFileLexer_yyrealloc, cmListFileLexer_yyfree
26   - remove all YY_BREAK lines occurring right after return statements
27   - remove the isatty forward declaration
28
29 */
30
31 #include "cmStandardLexer.h"
32
33 /* Setup the proper cmListFileLexer_yylex declaration.  */
34 #define YY_EXTRA_TYPE cmListFileLexer*
35 #define YY_DECL int cmListFileLexer_yylex (yyscan_t yyscanner, cmListFileLexer* lexer)
36
37 #include "cmListFileLexer.h"
38
39 /*--------------------------------------------------------------------------*/
40 struct cmListFileLexer_s
41 {
42   cmListFileLexer_Token token;
43   int line;
44   int column;
45   int size;
46   FILE* file;
47   char* string_buffer;
48   char* string_position;
49   int string_left;
50   yyscan_t scanner;
51 };
52
53 static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
54                                     int length);
55 static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
56                                   int length);
57 static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
58                                 size_t bufferSize);
59 static void cmListFileLexerInit(cmListFileLexer* lexer);
60 static void cmListFileLexerDestroy(cmListFileLexer* lexer);
61
62 /* Replace the lexer input function.  */
63 #undef YY_INPUT
64 #define YY_INPUT(buf, result, max_size) \
65   { result = cmListFileLexerInput(cmListFileLexer_yyget_extra(yyscanner), buf, max_size); }
66
67 /*--------------------------------------------------------------------------*/
68 %}
69
70 %option reentrant
71 %option yylineno
72 %option noyywrap
73 %pointer
74 %x STRING
75
76 MAKEVAR \$\([A-Za-z0-9_]*\)
77
78 %%
79
80 \n {
81   lexer->token.type = cmListFileLexer_Token_Newline;
82   cmListFileLexerSetToken(lexer, yytext, yyleng);
83   ++lexer->line;
84   lexer->column = 1;
85   return 1;
86 }
87
88 #.* {
89   lexer->column += yyleng;
90 }
91
92 \( {
93   lexer->token.type = cmListFileLexer_Token_ParenLeft;
94   cmListFileLexerSetToken(lexer, yytext, yyleng);
95   lexer->column += yyleng;
96   return 1;
97 }
98
99 \) {
100   lexer->token.type = cmListFileLexer_Token_ParenRight;
101   cmListFileLexerSetToken(lexer, yytext, yyleng);
102   lexer->column += yyleng;
103   return 1;
104 }
105
106 [A-Za-z_][A-Za-z0-9_]+ {
107   lexer->token.type = cmListFileLexer_Token_Identifier;
108   cmListFileLexerSetToken(lexer, yytext, yyleng);
109   lexer->column += yyleng;
110   return 1;
111 }
112
113 ({MAKEVAR}|[^ \t\r\n\(\)#\\\"]|\\.)({MAKEVAR}|[^ \t\r\n\(\)#\\\"]|\\.|\"({MAKEVAR}|[^\r\n\(\)#\\\"]|\\.)*\")* {
114   lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
115   cmListFileLexerSetToken(lexer, yytext, yyleng);
116   lexer->column += yyleng;
117   return 1;
118 }
119
120 \" {
121   lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
122   cmListFileLexerSetToken(lexer, "", 0);
123   lexer->column += yyleng;
124   BEGIN(STRING);
125 }
126
127 <STRING>([^\\\n\"]|\\(.|\n))+ {
128   cmListFileLexerAppend(lexer, yytext, yyleng);
129   lexer->column += yyleng;
130 }
131
132 <STRING>\n {
133   cmListFileLexerAppend(lexer, yytext, yyleng);
134   ++lexer->line;
135   lexer->column = 1;
136 }
137
138 <STRING>\" {
139   lexer->column += yyleng;
140   BEGIN(INITIAL);
141   return 1;
142 }
143
144 <STRING>. {
145   cmListFileLexerAppend(lexer, yytext, yyleng);
146   lexer->column += yyleng;
147 }
148
149 <STRING><<EOF>> {
150   lexer->token.type = cmListFileLexer_Token_BadString;
151   BEGIN(INITIAL);
152   return 1;
153 }
154
155 [ \t\r] {
156   lexer->column += yyleng;
157 }
158
159 . {
160   lexer->token.type = cmListFileLexer_Token_BadCharacter;
161   cmListFileLexerSetToken(lexer, yytext, yyleng);
162   lexer->column += yyleng;
163   return 1;
164 }
165
166 <<EOF>> {
167   lexer->token.type = cmListFileLexer_Token_None;
168   cmListFileLexerSetToken(lexer, 0, 0);
169   return 0;
170 }
171
172 %%
173
174 /*--------------------------------------------------------------------------*/
175 static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
176                                     int length)
177 {
178   /* Set the token line and column number.  */
179   lexer->token.line = lexer->line;
180   lexer->token.column = lexer->column;
181
182   /* Use the same buffer if possible.  */
183   if(lexer->token.text)
184     {
185     if(text && length < lexer->size)
186       {
187       strcpy(lexer->token.text, text);
188       lexer->token.length = length;
189       return;
190       }
191     free(lexer->token.text);
192     lexer->token.text = 0;
193     lexer->size = 0;
194     }
195
196   /* Need to extend the buffer.  */
197   if(text)
198     {
199     lexer->token.text = strdup(text);
200     lexer->token.length = length;
201     lexer->size = length+1;
202     }
203   else
204     {
205     lexer->token.length = 0;
206     }
207 }
208
209 /*--------------------------------------------------------------------------*/
210 static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
211                                   int length)
212 {
213   char* temp;
214   int newSize;
215
216   /* If the appended text will fit in the buffer, do not reallocate.  */
217   newSize = lexer->token.length + length + 1;
218   if(lexer->token.text && newSize <= lexer->size)
219     {
220     strcpy(lexer->token.text+lexer->token.length, text);
221     lexer->token.length += length;
222     return;
223     }
224
225   /* We need to extend the buffer.  */
226   temp = malloc(newSize);
227   if(lexer->token.text)
228     {
229     memcpy(temp, lexer->token.text, lexer->token.length);
230     free(lexer->token.text);
231     }
232   memcpy(temp+lexer->token.length, text, length);
233   temp[lexer->token.length+length] = 0;
234   lexer->token.text = temp;
235   lexer->token.length += length;
236   lexer->size = newSize;
237 }
238
239 /*--------------------------------------------------------------------------*/
240 static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
241                                 size_t bufferSize)
242 {
243   if(lexer)
244     {
245     if(lexer->file)
246       {
247       return (int)fread(buffer, 1, bufferSize, lexer->file);
248       }
249     else if(lexer->string_left)
250       {
251       int length = lexer->string_left;
252       if((int)bufferSize < length) { length = (int)bufferSize; }
253       memcpy(buffer, lexer->string_position, length);
254       lexer->string_position += length;
255       lexer->string_left -= length;
256       return length;
257       }
258     }
259   return 0;
260 }
261
262 /*--------------------------------------------------------------------------*/
263 static void cmListFileLexerInit(cmListFileLexer* lexer)
264 {
265   if(lexer->file || lexer->string_buffer)
266     {
267     cmListFileLexer_yylex_init(&lexer->scanner);
268     cmListFileLexer_yyset_extra(lexer, lexer->scanner);
269     }
270 }
271
272 /*--------------------------------------------------------------------------*/
273 static void cmListFileLexerDestroy(cmListFileLexer* lexer)
274 {
275   if(lexer->file || lexer->string_buffer)
276     {
277     cmListFileLexer_yylex_destroy(lexer->scanner);
278     if(lexer->file)
279       {
280       fclose(lexer->file);
281       lexer->file = 0;
282       }
283     if(lexer->string_buffer)
284       {
285       free(lexer->string_buffer);
286       lexer->string_buffer = 0;
287       lexer->string_left = 0;
288       lexer->string_position = 0;
289       }
290     }
291 }
292
293 /*--------------------------------------------------------------------------*/
294 cmListFileLexer* cmListFileLexer_New()
295 {
296   cmListFileLexer* lexer = (cmListFileLexer*)malloc(sizeof(cmListFileLexer));
297   if(!lexer)
298     {
299     return 0;
300     }
301   memset(lexer, 0, sizeof(*lexer));
302   lexer->line = 1;
303   lexer->column = 1;
304   return lexer;
305 }
306
307 /*--------------------------------------------------------------------------*/
308 void cmListFileLexer_Delete(cmListFileLexer* lexer)
309 {
310   cmListFileLexer_SetFileName(lexer, 0);
311   free(lexer);
312 }
313
314 /*--------------------------------------------------------------------------*/
315 int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
316 {
317   int result = 1;
318   cmListFileLexerDestroy(lexer);
319   if(name)
320     {
321     lexer->file = fopen(name, "r");
322     if(!lexer->file)
323       {
324       result = 0;
325       }
326     }
327   cmListFileLexerInit(lexer);
328   return result;
329 }
330
331 /*--------------------------------------------------------------------------*/
332 int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
333 {
334   int result = 1;
335   cmListFileLexerDestroy(lexer);
336   if(text)
337     {
338     int length = (int)strlen(text);
339     lexer->string_buffer = (char*)malloc(length+1);
340     if(lexer->string_buffer)
341       {
342       strcpy(lexer->string_buffer, text);
343       lexer->string_position = lexer->string_buffer;
344       lexer->string_left = length;
345       }
346     else
347       {
348       result = 0;
349       }
350     }
351   cmListFileLexerInit(lexer);
352   return result;
353 }
354
355 /*--------------------------------------------------------------------------*/
356 cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
357 {
358   if(!lexer->file)
359     {
360     return 0;
361     }
362   if(cmListFileLexer_yylex(lexer->scanner, lexer))
363     {
364     return &lexer->token;
365     }
366   else
367     {
368     cmListFileLexer_SetFileName(lexer, 0);
369     return 0;
370     }
371 }
372
373 /*--------------------------------------------------------------------------*/
374 long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
375 {
376   if(lexer->file)
377     {
378     return lexer->line;
379     }
380   else
381     {
382     return 0;
383     }
384 }
385
386 /*--------------------------------------------------------------------------*/
387 long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
388 {
389   if(lexer->file)
390     {
391     return lexer->column;
392     }
393   else
394     {
395     return 0;
396     }
397 }
398
399 /*--------------------------------------------------------------------------*/
400 const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
401                                             cmListFileLexer_Type type)
402 {
403   (void)lexer;
404   switch(type)
405     {
406     case cmListFileLexer_Token_None: return "nothing";
407     case cmListFileLexer_Token_Newline: return "newline";
408     case cmListFileLexer_Token_Identifier: return "identifier";
409     case cmListFileLexer_Token_ParenLeft: return "left paren";
410     case cmListFileLexer_Token_ParenRight: return "right paren";
411     case cmListFileLexer_Token_ArgumentUnquoted: return "unquoted argument";
412     case cmListFileLexer_Token_ArgumentQuoted: return "quoted argument";
413     case cmListFileLexer_Token_BadCharacter: return "bad character";
414     case cmListFileLexer_Token_BadString: return "unterminated string";
415     }
416   return "unknown token";
417 }