aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/dtc-lexer.l
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2009-04-30 01:25:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-05-02 19:52:26 -0400
commit9fffb55f66127b52c937ede5196ebfa0c0d50bce (patch)
tree11664fb82734ba8dcde9556b8d47e780451a740a /scripts/dtc/dtc-lexer.l
parentafc1e702e8e8355faa712d4e90d9afe26a4995a5 (diff)
Move dtc and libfdt sources from arch/powerpc/boot to scripts/dtc
The powerpc kernel always requires an Open Firmware like device tree to supply device information. On systems without OF, this comes from a flattened device tree blob. This blob is usually generated by dtc, a tool which compiles a text description of the device tree into the flattened format used by the kernel. Sometimes, the bootwrapper makes small changes to the pre-compiled device tree blob (e.g. filling in the size of RAM). To do this it uses the libfdt library. Because these are only used on powerpc, the code for both these tools is included under arch/powerpc/boot (these were imported and are periodically updated from the upstream dtc tree). However, the microblaze architecture, currently being prepared for merging to mainline also uses dtc to produce device tree blobs. A few other archs have also mentioned some interest in using dtc. Therefore, this patch moves dtc and libfdt from arch/powerpc into scripts, where it can be used by any architecture. The vast bulk of this patch is a literal move, the rest is adjusting the various Makefiles to use dtc and libfdt correctly from their new locations. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts/dtc/dtc-lexer.l')
-rw-r--r--scripts/dtc/dtc-lexer.l320
1 files changed, 320 insertions, 0 deletions
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
new file mode 100644
index 000000000000..44dbfd3f0976
--- /dev/null
+++ b/scripts/dtc/dtc-lexer.l
@@ -0,0 +1,320 @@
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 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
42/*#define LEXDEBUG 1*/
43
44#ifdef LEXDEBUG
45#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
46#else
47#define DPRINT(fmt, ...) do { } while (0)
48#endif
49
50static int dts_version; /* = 0 */
51
52#define BEGIN_DEFAULT() if (dts_version == 0) { \
53 DPRINT("<INITIAL>\n"); \
54 BEGIN(INITIAL); \
55 } else { \
56 DPRINT("<V1>\n"); \
57 BEGIN(V1); \
58 }
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 yylloc.file = srcpos_file;
79 yylloc.first_line = yylineno;
80 DPRINT("String: %s\n", yytext);
81 yylval.data = data_copy_escape_string(yytext+1,
82 yyleng-2);
83 yylloc.first_line = yylineno;
84 return DT_STRING;
85 }
86
87<*>"/dts-v1/" {
88 yylloc.file = srcpos_file;
89 yylloc.first_line = yylineno;
90 DPRINT("Keyword: /dts-v1/\n");
91 dts_version = 1;
92 BEGIN_DEFAULT();
93 return DT_V1;
94 }
95
96<*>"/memreserve/" {
97 yylloc.file = srcpos_file;
98 yylloc.first_line = yylineno;
99 DPRINT("Keyword: /memreserve/\n");
100 BEGIN_DEFAULT();
101 return DT_MEMRESERVE;
102 }
103
104<*>{LABEL}: {
105 yylloc.file = srcpos_file;
106 yylloc.first_line = yylineno;
107 DPRINT("Label: %s\n", yytext);
108 yylval.labelref = strdup(yytext);
109 yylval.labelref[yyleng-1] = '\0';
110 return DT_LABEL;
111 }
112
113<INITIAL>[bodh]# {
114 yylloc.file = srcpos_file;
115 yylloc.first_line = yylineno;
116 if (*yytext == 'b')
117 yylval.cbase = 2;
118 else if (*yytext == 'o')
119 yylval.cbase = 8;
120 else if (*yytext == 'd')
121 yylval.cbase = 10;
122 else
123 yylval.cbase = 16;
124 DPRINT("Base: %d\n", yylval.cbase);
125 return DT_BASE;
126 }
127
128<INITIAL>[0-9a-fA-F]+ {
129 yylloc.file = srcpos_file;
130 yylloc.first_line = yylineno;
131 yylval.literal = strdup(yytext);
132 DPRINT("Literal: '%s'\n", yylval.literal);
133 return DT_LEGACYLITERAL;
134 }
135
136<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
137 yylloc.file = srcpos_file;
138 yylloc.first_line = yylineno;
139 yylval.literal = strdup(yytext);
140 DPRINT("Literal: '%s'\n", yylval.literal);
141 return DT_LITERAL;
142 }
143
144\&{LABEL} { /* label reference */
145 yylloc.file = srcpos_file;
146 yylloc.first_line = yylineno;
147 DPRINT("Ref: %s\n", yytext+1);
148 yylval.labelref = strdup(yytext+1);
149 return DT_REF;
150 }
151
152"&{/"{PATHCHAR}+\} { /* new-style path reference */
153 yylloc.file = srcpos_file;
154 yylloc.first_line = yylineno;
155 yytext[yyleng-1] = '\0';
156 DPRINT("Ref: %s\n", yytext+2);
157 yylval.labelref = strdup(yytext+2);
158 return DT_REF;
159 }
160
161<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
162 yylloc.file = srcpos_file;
163 yylloc.first_line = yylineno;
164 DPRINT("Ref: %s\n", yytext+1);
165 yylval.labelref = strdup(yytext+1);
166 return DT_REF;
167 }
168
169<BYTESTRING>[0-9a-fA-F]{2} {
170 yylloc.file = srcpos_file;
171 yylloc.first_line = yylineno;
172 yylval.byte = strtol(yytext, NULL, 16);
173 DPRINT("Byte: %02x\n", (int)yylval.byte);
174 return DT_BYTE;
175 }
176
177<BYTESTRING>"]" {
178 yylloc.file = srcpos_file;
179 yylloc.first_line = yylineno;
180 DPRINT("/BYTESTRING\n");
181 BEGIN_DEFAULT();
182 return ']';
183 }
184
185<PROPNODENAME>{PROPNODECHAR}+ {
186 yylloc.file = srcpos_file;
187 yylloc.first_line = yylineno;
188 DPRINT("PropNodeName: %s\n", yytext);
189 yylval.propnodename = strdup(yytext);
190 BEGIN_DEFAULT();
191 return DT_PROPNODENAME;
192 }
193
194"/incbin/" {
195 yylloc.file = srcpos_file;
196 yylloc.first_line = yylineno;
197 DPRINT("Binary Include\n");
198 return DT_INCBIN;
199 }
200
201<*>{WS}+ /* eat whitespace */
202<*>{COMMENT}+ /* eat C-style comments */
203<*>{LINECOMMENT}+ /* eat C++-style comments */
204
205<*>. {
206 yylloc.file = srcpos_file;
207 yylloc.first_line = yylineno;
208 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
209 (unsigned)yytext[0]);
210 if (yytext[0] == '[') {
211 DPRINT("<BYTESTRING>\n");
212 BEGIN(BYTESTRING);
213 }
214 if ((yytext[0] == '{')
215 || (yytext[0] == ';')) {
216 DPRINT("<PROPNODENAME>\n");
217 BEGIN(PROPNODENAME);
218 }
219 return yytext[0];
220 }
221
222%%
223
224
225/*
226 * Stack of nested include file contexts.
227 */
228
229struct incl_file {
230 struct dtc_file *file;
231 YY_BUFFER_STATE yy_prev_buf;
232 int yy_prev_lineno;
233 struct incl_file *prev;
234};
235
236static struct incl_file *incl_file_stack;
237
238
239/*
240 * Detect infinite include recursion.
241 */
242#define MAX_INCLUDE_DEPTH (100)
243
244static int incl_depth = 0;
245
246
247static void push_input_file(const char *filename)
248{
249 struct incl_file *incl_file;
250 struct dtc_file *newfile;
251 struct search_path search, *searchptr = NULL;
252
253 assert(filename);
254
255 if (incl_depth++ >= MAX_INCLUDE_DEPTH)
256 die("Includes nested too deeply");
257
258 if (srcpos_file) {
259 search.dir = srcpos_file->dir;
260 search.next = NULL;
261 search.prev = NULL;
262 searchptr = &search;
263 }
264
265 newfile = dtc_open_file(filename, searchptr);
266
267 incl_file = xmalloc(sizeof(struct incl_file));
268
269 /*
270 * Save current context.
271 */
272 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
273 incl_file->yy_prev_lineno = yylineno;
274 incl_file->file = srcpos_file;
275 incl_file->prev = incl_file_stack;
276
277 incl_file_stack = incl_file;
278
279 /*
280 * Establish new context.
281 */
282 srcpos_file = newfile;
283 yylineno = 1;
284 yyin = newfile->file;
285 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
286}
287
288
289static int pop_input_file(void)
290{
291 struct incl_file *incl_file;
292
293 if (incl_file_stack == 0)
294 return 0;
295
296 dtc_close_file(srcpos_file);
297
298 /*
299 * Pop.
300 */
301 --incl_depth;
302 incl_file = incl_file_stack;
303 incl_file_stack = incl_file->prev;
304
305 /*
306 * Recover old context.
307 */
308 yy_delete_buffer(YY_CURRENT_BUFFER);
309 yy_switch_to_buffer(incl_file->yy_prev_buf);
310 yylineno = incl_file->yy_prev_lineno;
311 srcpos_file = incl_file->file;
312 yyin = incl_file->file ? incl_file->file->file : NULL;
313
314 /*
315 * Free old state.
316 */
317 free(incl_file);
318
319 return 1;
320}