dtc-lexer.l revision 204488
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 *                                                                   USA
19 */
20
21%option noyywrap nounput noinput yylineno
22
23%x INCLUDE
24%x BYTESTRING
25%x PROPNODENAME
26%s V1
27
28PROPNODECHAR	[a-zA-Z0-9,._+*#?@-]
29PATHCHAR	({PROPNODECHAR}|[/])
30LABEL		[a-zA-Z_][a-zA-Z0-9_]*
31STRING		\"([^\\"]|\\.)*\"
32WS		[[:space:]]
33COMMENT		"/*"([^*]|\*+[^*/])*\*+"/"
34LINECOMMENT	"//".*\n
35
36%{
37#include "dtc.h"
38#include "srcpos.h"
39#include "dtc-parser.tab.h"
40
41#define	YY_USER_ACTION \
42	{ \
43		yylloc.file = srcpos_file; \
44		yylloc.first_line = yylineno; \
45	}
46
47/*#define LEXDEBUG	1*/
48
49#ifdef LEXDEBUG
50#define DPRINT(fmt, ...)	fprintf(stderr, fmt, ##__VA_ARGS__)
51#else
52#define DPRINT(fmt, ...)	do { } while (0)
53#endif
54
55static int dts_version = 1;
56
57#define BEGIN_DEFAULT()		DPRINT("<V1>\n"); \
58				BEGIN(V1); \
59
60static void push_input_file(const char *filename);
61static int pop_input_file(void);
62%}
63
64%%
65<*>"/include/"{WS}*{STRING} {
66			char *name = strchr(yytext, '\"') + 1;
67			yytext[yyleng-1] = '\0';
68			push_input_file(name);
69		}
70
71<*><<EOF>>		{
72			if (!pop_input_file()) {
73				yyterminate();
74			}
75		}
76
77<*>{STRING}	{
78			DPRINT("String: %s\n", yytext);
79			yylval.data = data_copy_escape_string(yytext+1,
80					yyleng-2);
81			return DT_STRING;
82		}
83
84<*>"/dts-v1/"	{
85			DPRINT("Keyword: /dts-v1/\n");
86			dts_version = 1;
87			BEGIN_DEFAULT();
88			return DT_V1;
89		}
90
91<*>"/memreserve/"	{
92			DPRINT("Keyword: /memreserve/\n");
93			BEGIN_DEFAULT();
94			return DT_MEMRESERVE;
95		}
96
97<*>{LABEL}:	{
98			DPRINT("Label: %s\n", yytext);
99			yylval.labelref = xstrdup(yytext);
100			yylval.labelref[yyleng-1] = '\0';
101			return DT_LABEL;
102		}
103
104<V1>[0-9]+|0[xX][0-9a-fA-F]+      {
105			yylval.literal = xstrdup(yytext);
106			DPRINT("Literal: '%s'\n", yylval.literal);
107			return DT_LITERAL;
108		}
109
110\&{LABEL}	{	/* label reference */
111			DPRINT("Ref: %s\n", yytext+1);
112			yylval.labelref = xstrdup(yytext+1);
113			return DT_REF;
114		}
115
116"&{/"{PATHCHAR}+\}	{	/* new-style path reference */
117			yytext[yyleng-1] = '\0';
118			DPRINT("Ref: %s\n", yytext+2);
119			yylval.labelref = xstrdup(yytext+2);
120			return DT_REF;
121		}
122
123<BYTESTRING>[0-9a-fA-F]{2} {
124			yylval.byte = strtol(yytext, NULL, 16);
125			DPRINT("Byte: %02x\n", (int)yylval.byte);
126			return DT_BYTE;
127		}
128
129<BYTESTRING>"]"	{
130			DPRINT("/BYTESTRING\n");
131			BEGIN_DEFAULT();
132			return ']';
133		}
134
135<PROPNODENAME>{PROPNODECHAR}+ {
136			DPRINT("PropNodeName: %s\n", yytext);
137			yylval.propnodename = xstrdup(yytext);
138			BEGIN_DEFAULT();
139			return DT_PROPNODENAME;
140		}
141
142"/incbin/"	{
143			DPRINT("Binary Include\n");
144			return DT_INCBIN;
145		}
146
147<*>{WS}+	/* eat whitespace */
148<*>{COMMENT}+	/* eat C-style comments */
149<*>{LINECOMMENT}+ /* eat C++-style comments */
150
151<*>.		{
152			DPRINT("Char: %c (\\x%02x)\n", yytext[0],
153				(unsigned)yytext[0]);
154			if (yytext[0] == '[') {
155				DPRINT("<BYTESTRING>\n");
156				BEGIN(BYTESTRING);
157			}
158			if ((yytext[0] == '{')
159			    || (yytext[0] == ';')) {
160				DPRINT("<PROPNODENAME>\n");
161				BEGIN(PROPNODENAME);
162			}
163			return yytext[0];
164		}
165
166%%
167
168
169/*
170 * Stack of nested include file contexts.
171 */
172
173struct incl_file {
174	struct dtc_file *file;
175	YY_BUFFER_STATE yy_prev_buf;
176	int yy_prev_lineno;
177	struct incl_file *prev;
178};
179
180static struct incl_file *incl_file_stack;
181
182
183/*
184 * Detect infinite include recursion.
185 */
186#define MAX_INCLUDE_DEPTH	(100)
187
188static int incl_depth = 0;
189
190
191static void push_input_file(const char *filename)
192{
193	struct incl_file *incl_file;
194	struct dtc_file *newfile;
195	struct search_path search, *searchptr = NULL;
196
197	assert(filename);
198
199	if (incl_depth++ >= MAX_INCLUDE_DEPTH)
200		die("Includes nested too deeply");
201
202	if (srcpos_file) {
203		search.dir = srcpos_file->dir;
204		search.next = NULL;
205		search.prev = NULL;
206		searchptr = &search;
207	}
208
209	newfile = dtc_open_file(filename, searchptr);
210
211	incl_file = xmalloc(sizeof(struct incl_file));
212
213	/*
214	 * Save current context.
215	 */
216	incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
217	incl_file->yy_prev_lineno = yylineno;
218	incl_file->file = srcpos_file;
219	incl_file->prev = incl_file_stack;
220
221	incl_file_stack = incl_file;
222
223	/*
224	 * Establish new context.
225	 */
226	srcpos_file = newfile;
227	yylineno = 1;
228	yyin = newfile->file;
229	yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
230}
231
232
233static int pop_input_file(void)
234{
235	struct incl_file *incl_file;
236
237	if (incl_file_stack == 0)
238		return 0;
239
240	dtc_close_file(srcpos_file);
241
242	/*
243	 * Pop.
244	 */
245	--incl_depth;
246	incl_file = incl_file_stack;
247	incl_file_stack = incl_file->prev;
248
249	/*
250	 * Recover old context.
251	 */
252	yy_delete_buffer(YY_CURRENT_BUFFER);
253	yy_switch_to_buffer(incl_file->yy_prev_buf);
254	yylineno = incl_file->yy_prev_lineno;
255	srcpos_file = incl_file->file;
256	yyin = incl_file->file ? incl_file->file->file : NULL;
257
258	/*
259	 * Free old state.
260	 */
261	free(incl_file);
262
263	return 1;
264}
265