File: include_finder.l

package info (click to toggle)
codelite 2.6.0.4189~dfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 30,868 kB
  • ctags: 32,563
  • sloc: cpp: 237,275; ansic: 20,775; lex: 2,114; yacc: 2,007; xml: 1,274; sh: 1,064; makefile: 566; python: 163
file content (122 lines) | stat: -rw-r--r-- 2,345 bytes parent folder | download
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;
}