cmListFileLexer.in.l 12 KB

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