2 /*============================================================================
3 CMake - Cross Platform Makefile Generator
4 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
6 Distributed under the OSI-approved BSD License (the "License");
7 see accompanying file Copyright.txt for details.
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 ============================================================================*/
15 This file must be translated to C and modified to build everywhere.
19 flex --prefix=cmListFileLexer_yy -ocmListFileLexer.c cmListFileLexer.in.l
21 Modify cmListFileLexer.c:
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
31 #include "cmStandardLexer.h"
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)
37 #include "cmListFileLexer.h"
39 /*--------------------------------------------------------------------------*/
40 struct cmListFileLexer_s
42 cmListFileLexer_Token token;
48 char* string_position;
53 static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
55 static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
57 static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
59 static void cmListFileLexerInit(cmListFileLexer* lexer);
60 static void cmListFileLexerDestroy(cmListFileLexer* lexer);
62 /* Replace the lexer input function. */
64 #define YY_INPUT(buf, result, max_size) \
65 { result = cmListFileLexerInput(cmListFileLexer_yyget_extra(yyscanner), buf, max_size); }
67 /*--------------------------------------------------------------------------*/
76 MAKEVAR \$\([A-Za-z0-9_]*\)
81 lexer->token.type = cmListFileLexer_Token_Newline;
82 cmListFileLexerSetToken(lexer, yytext, yyleng);
89 lexer->column += yyleng;
93 lexer->token.type = cmListFileLexer_Token_ParenLeft;
94 cmListFileLexerSetToken(lexer, yytext, yyleng);
95 lexer->column += yyleng;
100 lexer->token.type = cmListFileLexer_Token_ParenRight;
101 cmListFileLexerSetToken(lexer, yytext, yyleng);
102 lexer->column += yyleng;
106 [A-Za-z_][A-Za-z0-9_]+ {
107 lexer->token.type = cmListFileLexer_Token_Identifier;
108 cmListFileLexerSetToken(lexer, yytext, yyleng);
109 lexer->column += yyleng;
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;
121 lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
122 cmListFileLexerSetToken(lexer, "", 0);
123 lexer->column += yyleng;
127 <STRING>([^\\\n\"]|\\(.|\n))+ {
128 cmListFileLexerAppend(lexer, yytext, yyleng);
129 lexer->column += yyleng;
133 cmListFileLexerAppend(lexer, yytext, yyleng);
139 lexer->column += yyleng;
145 cmListFileLexerAppend(lexer, yytext, yyleng);
146 lexer->column += yyleng;
150 lexer->token.type = cmListFileLexer_Token_BadString;
156 lexer->column += yyleng;
160 lexer->token.type = cmListFileLexer_Token_BadCharacter;
161 cmListFileLexerSetToken(lexer, yytext, yyleng);
162 lexer->column += yyleng;
167 lexer->token.type = cmListFileLexer_Token_None;
168 cmListFileLexerSetToken(lexer, 0, 0);
174 /*--------------------------------------------------------------------------*/
175 static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
178 /* Set the token line and column number. */
179 lexer->token.line = lexer->line;
180 lexer->token.column = lexer->column;
182 /* Use the same buffer if possible. */
183 if(lexer->token.text)
185 if(text && length < lexer->size)
187 strcpy(lexer->token.text, text);
188 lexer->token.length = length;
191 free(lexer->token.text);
192 lexer->token.text = 0;
196 /* Need to extend the buffer. */
199 lexer->token.text = strdup(text);
200 lexer->token.length = length;
201 lexer->size = length+1;
205 lexer->token.length = 0;
209 /*--------------------------------------------------------------------------*/
210 static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
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)
220 strcpy(lexer->token.text+lexer->token.length, text);
221 lexer->token.length += length;
225 /* We need to extend the buffer. */
226 temp = malloc(newSize);
227 if(lexer->token.text)
229 memcpy(temp, lexer->token.text, lexer->token.length);
230 free(lexer->token.text);
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;
239 /*--------------------------------------------------------------------------*/
240 static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
247 return (int)fread(buffer, 1, bufferSize, lexer->file);
249 else if(lexer->string_left)
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;
262 /*--------------------------------------------------------------------------*/
263 static void cmListFileLexerInit(cmListFileLexer* lexer)
265 if(lexer->file || lexer->string_buffer)
267 cmListFileLexer_yylex_init(&lexer->scanner);
268 cmListFileLexer_yyset_extra(lexer, lexer->scanner);
272 /*--------------------------------------------------------------------------*/
273 static void cmListFileLexerDestroy(cmListFileLexer* lexer)
275 if(lexer->file || lexer->string_buffer)
277 cmListFileLexer_yylex_destroy(lexer->scanner);
283 if(lexer->string_buffer)
285 free(lexer->string_buffer);
286 lexer->string_buffer = 0;
287 lexer->string_left = 0;
288 lexer->string_position = 0;
293 /*--------------------------------------------------------------------------*/
294 cmListFileLexer* cmListFileLexer_New()
296 cmListFileLexer* lexer = (cmListFileLexer*)malloc(sizeof(cmListFileLexer));
301 memset(lexer, 0, sizeof(*lexer));
307 /*--------------------------------------------------------------------------*/
308 void cmListFileLexer_Delete(cmListFileLexer* lexer)
310 cmListFileLexer_SetFileName(lexer, 0);
314 /*--------------------------------------------------------------------------*/
315 int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
318 cmListFileLexerDestroy(lexer);
321 lexer->file = fopen(name, "r");
327 cmListFileLexerInit(lexer);
331 /*--------------------------------------------------------------------------*/
332 int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
335 cmListFileLexerDestroy(lexer);
338 int length = (int)strlen(text);
339 lexer->string_buffer = (char*)malloc(length+1);
340 if(lexer->string_buffer)
342 strcpy(lexer->string_buffer, text);
343 lexer->string_position = lexer->string_buffer;
344 lexer->string_left = length;
351 cmListFileLexerInit(lexer);
355 /*--------------------------------------------------------------------------*/
356 cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
362 if(cmListFileLexer_yylex(lexer->scanner, lexer))
364 return &lexer->token;
368 cmListFileLexer_SetFileName(lexer, 0);
373 /*--------------------------------------------------------------------------*/
374 long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
386 /*--------------------------------------------------------------------------*/
387 long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
391 return lexer->column;
399 /*--------------------------------------------------------------------------*/
400 const char* cmListFileLexer_GetTypeAsString(cmListFileLexer* lexer,
401 cmListFileLexer_Type type)
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";
416 return "unknown token";