1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
/**
* the "incl" state is used for picking up the name
* of an include file
*/
%x incl
%x c_comment
%x cpp_comment
simple_escape [abfnrtv'"?\\]
octal_escape [0-7]{1,3}
hex_escape "x"[0-9a-fA-F]+
escape_sequence [\\]({simple_escape}|{octal_escape}|{hex_escape})
c_char [^'\\\n]|{escape_sequence}
s_char [^"\\\n]|{escape_sequence}
%{
// Avoid spam output
#ifdef ECHO
#undef ECHO
#endif
#define ECHO
// Never exit
#ifdef YY_FATAL_ERROR
#undef YY_FATAL_ERROR
#endif
#define YY_FATAL_ERROR(msg)
#include <list>
#include "include_finder.h"
static std::vector<IncludeStatement>* pIncludes = NULL;
static std::string currentFile;
%}
%option yylineno
%%
"//" {
BEGIN(cpp_comment);
}
"/*" {
BEGIN(c_comment);
}
"L"?[']{c_char}+['] {/* eat a string */}
"L"?["]{s_char}*["] {/* eat a string */}
#[ \t]*include {BEGIN(incl);}
. {}
<incl>\n {BEGIN(INITIAL);}
<incl>[ \t]* {} /* eat the whitespace */
<incl>["<][^ \t\n]+[">] { /* got the include file name */
std::string mod_path ( inclf_text );
static std::string trimString("\"<> \t");
mod_path.erase(0, mod_path.find_first_not_of(trimString));
mod_path.erase(mod_path.find_last_not_of (trimString)+1);
IncludeStatement includeStatement;
includeStatement.line = inclf_lineno;
includeStatement.file = mod_path;
includeStatement.includedFrom = currentFile;
includeStatement.pattern = inclf_text;
pIncludes->push_back( includeStatement );
}
<cpp_comment>\n {
BEGIN(INITIAL);
}
<cpp_comment>. {} /* do nothing */
<c_comment>"*/" {
BEGIN(INITIAL);
}
<c_comment>. {}
<<EOF>> {
if ( YY_CURRENT_BUFFER->yy_input_file ) {
fclose( YY_CURRENT_BUFFER->yy_input_file );
YY_CURRENT_BUFFER->yy_input_file = NULL;
}
yy_delete_buffer ( YY_CURRENT_BUFFER );
yyterminate();
}
%%
int yywrap() {
return 1;
}
int IncludeFinder( const char* filePath, std::vector<IncludeStatement> &includes )
{
BEGIN INITIAL;
inclf_lineno = 1;
FILE* fp = fopen(filePath, "r");
if ( fp == NULL ) {
return -1;
}
currentFile = filePath;
pIncludes = &includes;
yy_switch_to_buffer( yy_create_buffer(fp, YY_BUF_SIZE) );
inclf_in = fp;
int rc = inclf_lex();
yy_delete_buffer ( YY_CURRENT_BUFFER );
// Cleanup
pIncludes = NULL;
currentFile.clear();
return rc;
}
|