cmListFileLexer.l 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. %{
  2. /*=========================================================================
  3. Program: CMake - Cross-Platform Makefile Generator
  4. Module: $RCSfile$
  5. Language: C++
  6. Date: $Date$
  7. Version: $Revision$
  8. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  9. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  10. This software is distributed WITHOUT ANY WARRANTY; without even
  11. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE. See the above copyright notices for more information.
  13. =========================================================================*/
  14. /*
  15. This file must be translated to C and modified to build everywhere.
  16. Run flex like this:
  17. flex -ocmListFileLexer.c cmListFileLexer.l
  18. Modify cmListFileLexer.c:
  19. - remove TABs
  20. - remove the yyunput function
  21. - add a statement "(void)yyscanner;" to the top of these methods:
  22. yy_fatal_error, yyalloc, yyrealloc, yyfree
  23. */
  24. /* Disable features we do not need. */
  25. #define YY_NEVER_INTERACTIVE 1
  26. #define YY_NO_UNPUT 1
  27. #define ECHO
  28. /* Setup the proper yylex declaration. */
  29. #define YY_DECL int yylex (yyscan_t yyscanner, cmListFileLexer* lexer)
  30. /* Disable some warnings. */
  31. #if defined(_MSC_VER)
  32. # pragma warning ( disable : 4127 )
  33. # pragma warning ( disable : 4131 )
  34. # pragma warning ( disable : 4244 )
  35. # pragma warning ( disable : 4251 )
  36. # pragma warning ( disable : 4267 )
  37. # pragma warning ( disable : 4305 )
  38. # pragma warning ( disable : 4309 )
  39. # pragma warning ( disable : 4706 )
  40. # pragma warning ( disable : 4786 )
  41. #endif
  42. #include "cmListFileLexer.h"
  43. /*--------------------------------------------------------------------------*/
  44. struct cmListFileLexer_s
  45. {
  46. cmListFileLexer_Token token;
  47. int line;
  48. int column;
  49. int size;
  50. FILE* file;
  51. yyscan_t scanner;
  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. /*--------------------------------------------------------------------------*/
  58. %}
  59. %option reentrant
  60. %option yylineno
  61. %option noyywrap
  62. %pointer
  63. %x STRING
  64. %%
  65. \n {
  66. lexer->token.type = cmListFileLexer_Token_Newline;
  67. cmListFileLexerSetToken(lexer, yytext, yyleng);
  68. ++lexer->line;
  69. lexer->column = 1;
  70. return 1;
  71. }
  72. #.* {
  73. lexer->column += yyleng;
  74. }
  75. \( {
  76. lexer->token.type = cmListFileLexer_Token_ParenLeft;
  77. cmListFileLexerSetToken(lexer, yytext, yyleng);
  78. lexer->column += yyleng;
  79. return 1;
  80. }
  81. \) {
  82. lexer->token.type = cmListFileLexer_Token_ParenRight;
  83. cmListFileLexerSetToken(lexer, yytext, yyleng);
  84. lexer->column += yyleng;
  85. return 1;
  86. }
  87. [A-Za-z_][A-Za-z0-9_]+ {
  88. lexer->token.type = cmListFileLexer_Token_Identifier;
  89. cmListFileLexerSetToken(lexer, yytext, yyleng);
  90. lexer->column += yyleng;
  91. return 1;
  92. }
  93. ([^ \t\r\n\(\)\"\\]|\\.)+ {
  94. lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
  95. cmListFileLexerSetToken(lexer, yytext, yyleng);
  96. lexer->column += yyleng;
  97. return 1;
  98. }
  99. \" {
  100. lexer->token.type = cmListFileLexer_Token_ArgumentQuoted;
  101. cmListFileLexerSetToken(lexer, "", 0);
  102. lexer->column += yyleng;
  103. BEGIN(STRING);
  104. }
  105. <STRING>([^\\\n\"]|\\(.|\n))+ {
  106. cmListFileLexerAppend(lexer, yytext, yyleng);
  107. lexer->column += yyleng;
  108. }
  109. <STRING>\n {
  110. cmListFileLexerAppend(lexer, yytext, yyleng);
  111. ++lexer->line;
  112. lexer->column = 1;
  113. }
  114. <STRING>\" {
  115. lexer->column += yyleng;
  116. BEGIN(INITIAL);
  117. return 1;
  118. }
  119. <STRING>. {
  120. cmListFileLexerAppend(lexer, yytext, yyleng);
  121. lexer->column += yyleng;
  122. }
  123. [ \t\r] {
  124. lexer->column += yyleng;
  125. }
  126. . {
  127. lexer->token.type = cmListFileLexer_Token_Error;
  128. cmListFileLexerSetToken(lexer, yytext, yyleng);
  129. lexer->column += yyleng;
  130. return 1;
  131. }
  132. <<EOF>> {
  133. lexer->token.type = cmListFileLexer_Token_None;
  134. cmListFileLexerSetToken(lexer, 0, 0);
  135. return 0;
  136. }
  137. %%
  138. /*--------------------------------------------------------------------------*/
  139. void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
  140. int length)
  141. {
  142. /* Set the token line and column number. */
  143. lexer->token.line = lexer->line;
  144. lexer->token.column = lexer->column;
  145. /* Use the same buffer if possible. */
  146. if(lexer->token.text)
  147. {
  148. if(text && length < lexer->size)
  149. {
  150. strcpy(lexer->token.text, text);
  151. lexer->token.length = length;
  152. return;
  153. }
  154. free(lexer->token.text);
  155. lexer->token.text = 0;
  156. lexer->size = 0;
  157. }
  158. /* Need to extend the buffer. */
  159. if(text)
  160. {
  161. lexer->token.text = strdup(text);
  162. lexer->token.length = length;
  163. lexer->size = length+1;
  164. }
  165. else
  166. {
  167. lexer->token.length = 0;
  168. }
  169. }
  170. /*--------------------------------------------------------------------------*/
  171. void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
  172. int length)
  173. {
  174. char* temp;
  175. int newSize;
  176. /* If the appended text will fit in the buffer, do not reallocate. */
  177. newSize = lexer->token.length + length + 1;
  178. if(lexer->token.text && newSize <= lexer->size)
  179. {
  180. strcpy(lexer->token.text+lexer->token.length, text);
  181. lexer->token.length += length;
  182. return;
  183. }
  184. /* We need to extend the buffer. */
  185. temp = malloc(newSize);
  186. if(lexer->token.text)
  187. {
  188. memcpy(temp, lexer->token.text, lexer->token.length);
  189. free(lexer->token.text);
  190. }
  191. memcpy(temp+lexer->token.length, text, length);
  192. temp[lexer->token.length+length] = 0;
  193. lexer->token.text = temp;
  194. lexer->token.length += length;
  195. lexer->size = newSize;
  196. }
  197. /*--------------------------------------------------------------------------*/
  198. cmListFileLexer* cmListFileLexer_New()
  199. {
  200. cmListFileLexer* lexer = (cmListFileLexer*)malloc(sizeof(cmListFileLexer));
  201. if(!lexer)
  202. {
  203. return 0;
  204. }
  205. memset(lexer, 0, sizeof(*lexer));
  206. lexer->line = 1;
  207. lexer->column = 1;
  208. return lexer;
  209. }
  210. /*--------------------------------------------------------------------------*/
  211. void cmListFileLexer_Delete(cmListFileLexer* lexer)
  212. {
  213. cmListFileLexer_SetFileName(lexer, 0);
  214. free(lexer);
  215. }
  216. /*--------------------------------------------------------------------------*/
  217. int cmListFileLexer_SetFileName(cmListFileLexer* lexer, const char* name)
  218. {
  219. int result = 1;
  220. if(lexer->file)
  221. {
  222. yylex_destroy(lexer->scanner);
  223. fclose(lexer->file);
  224. lexer->file = 0;
  225. }
  226. if(name)
  227. {
  228. lexer->file = fopen(name, "r");
  229. if(!lexer->file)
  230. {
  231. result = 0;
  232. }
  233. }
  234. if(lexer->file)
  235. {
  236. yylex_init(&lexer->scanner);
  237. yyset_in(lexer->file, lexer->scanner);
  238. }
  239. return result;
  240. }
  241. /*--------------------------------------------------------------------------*/
  242. cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
  243. {
  244. if(!lexer->file)
  245. {
  246. return 0;
  247. }
  248. if(yylex(lexer->scanner, lexer))
  249. {
  250. return &lexer->token;
  251. }
  252. else
  253. {
  254. cmListFileLexer_SetFileName(lexer, 0);
  255. return 0;
  256. }
  257. }
  258. /*--------------------------------------------------------------------------*/
  259. long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
  260. {
  261. if(lexer->file)
  262. {
  263. return lexer->line;
  264. }
  265. else
  266. {
  267. return 0;
  268. }
  269. }
  270. /*--------------------------------------------------------------------------*/
  271. long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
  272. {
  273. if(lexer->file)
  274. {
  275. return lexer->column;
  276. }
  277. else
  278. {
  279. return 0;
  280. }
  281. }