aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2007-12-17 23:06:42 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-20 00:17:52 -0500
commita4da2e3ec84cda635ac441efbe781a38d2ee41ee (patch)
tree47fa696faaf092920ee0c0226ddc7557fa743d4d /arch/powerpc/boot
parent70e47528aa0eb5ef63fef6ee0d30065d9e09f3e5 (diff)
[POWERPC] Merge dtc upstream source
This incorporates a copy of dtc into the kernel source, in arch/powerpc/boot/dtc-src. This commit only imports the upstream sources verbatim, a later commit will actually link it into the kernel Makefiles and use the embedded code during the kernel build. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/boot')
-rw-r--r--arch/powerpc/boot/dtc-src/Makefile.dtc25
-rw-r--r--arch/powerpc/boot/dtc-src/checks.c750
-rw-r--r--arch/powerpc/boot/dtc-src/data.c321
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-lexer.l328
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped2174
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped1983
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped111
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.y336
-rw-r--r--arch/powerpc/boot/dtc-src/dtc.c231
-rw-r--r--arch/powerpc/boot/dtc-src/dtc.h269
-rw-r--r--arch/powerpc/boot/dtc-src/flattree.c968
-rw-r--r--arch/powerpc/boot/dtc-src/fstree.c94
-rw-r--r--arch/powerpc/boot/dtc-src/livetree.c305
-rw-r--r--arch/powerpc/boot/dtc-src/srcpos.c105
-rw-r--r--arch/powerpc/boot/dtc-src/srcpos.h75
-rw-r--r--arch/powerpc/boot/dtc-src/treesource.c275
-rw-r--r--arch/powerpc/boot/dtc-src/version_gen.h1
17 files changed, 8351 insertions, 0 deletions
diff --git a/arch/powerpc/boot/dtc-src/Makefile.dtc b/arch/powerpc/boot/dtc-src/Makefile.dtc
new file mode 100644
index 000000000000..d607fdb8df8d
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/Makefile.dtc
@@ -0,0 +1,25 @@
1# Makefile.dtc
2#
3# This is not a complete Makefile of itself. Instead, it is designed to
4# be easily embeddable into other systems of Makefiles.
5#
6DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
7 checks.c
8DTC_EXTRA = dtc.h srcpos.h
9DTC_LEXFILES = dtc-lexer.l
10DTC_BISONFILES = dtc-parser.y
11
12DTC_LEX_SRCS = $(DTC_LEXFILES:%.l=%.lex.c)
13DTC_BISON_SRCS = $(DTC_BISONFILES:%.y=%.tab.c)
14DTC_BISON_INCLUDES = $(DTC_BISONFILES:%.y=%.tab.h)
15
16DTC_GEN_SRCS = $(DTC_LEX_SRCS) $(DTC_BISON_SRCS)
17DTC_GEN_ALL = $(DTC_GEN_SRCS) $(DTC_BISON_INCLUDES)
18DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
19
20DTC_CLEANFILES = $(DTC_GEN_ALL)
21
22# We assume the containing Makefile system can do auto-dependencies for most
23# things, but we supply the dependencies on generated header files explicitly
24
25$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES))
diff --git a/arch/powerpc/boot/dtc-src/checks.c b/arch/powerpc/boot/dtc-src/checks.c
new file mode 100644
index 000000000000..2ce961cd414d
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/checks.c
@@ -0,0 +1,750 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007.
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#include "dtc.h"
22
23#ifdef TRACE_CHECKS
24#define TRACE(c, ...) \
25 do { \
26 fprintf(stderr, "=== %s: ", (c)->name); \
27 fprintf(stderr, __VA_ARGS__); \
28 fprintf(stderr, "\n"); \
29 } while (0)
30#else
31#define TRACE(c, fmt, ...) do { } while (0)
32#endif
33
34enum checklevel {
35 IGNORE = 0,
36 WARN = 1,
37 ERROR = 2,
38};
39
40enum checkstatus {
41 UNCHECKED = 0,
42 PREREQ,
43 PASSED,
44 FAILED,
45};
46
47struct check;
48
49typedef void (*tree_check_fn)(struct check *c, struct node *dt);
50typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node);
51typedef void (*prop_check_fn)(struct check *c, struct node *dt,
52 struct node *node, struct property *prop);
53
54struct check {
55 const char *name;
56 tree_check_fn tree_fn;
57 node_check_fn node_fn;
58 prop_check_fn prop_fn;
59 void *data;
60 enum checklevel level;
61 enum checkstatus status;
62 int inprogress;
63 int num_prereqs;
64 struct check **prereq;
65};
66
67#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \
68 static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
69 static struct check nm = { \
70 .name = #nm, \
71 .tree_fn = (tfn), \
72 .node_fn = (nfn), \
73 .prop_fn = (pfn), \
74 .data = (d), \
75 .level = (lvl), \
76 .status = UNCHECKED, \
77 .num_prereqs = ARRAY_SIZE(nm##_prereqs), \
78 .prereq = nm##_prereqs, \
79 };
80
81#define TREE_CHECK(nm, d, lvl, ...) \
82 CHECK(nm, check_##nm, NULL, NULL, d, lvl, __VA_ARGS__)
83#define NODE_CHECK(nm, d, lvl, ...) \
84 CHECK(nm, NULL, check_##nm, NULL, d, lvl, __VA_ARGS__)
85#define PROP_CHECK(nm, d, lvl, ...) \
86 CHECK(nm, NULL, NULL, check_##nm, d, lvl, __VA_ARGS__)
87#define BATCH_CHECK(nm, lvl, ...) \
88 CHECK(nm, NULL, NULL, NULL, NULL, lvl, __VA_ARGS__)
89
90#ifdef __GNUC__
91static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
92#endif
93static inline void check_msg(struct check *c, const char *fmt, ...)
94{
95 va_list ap;
96 va_start(ap, fmt);
97
98 if ((c->level < WARN) || (c->level <= quiet))
99 return; /* Suppress message */
100
101 fprintf(stderr, "%s (%s): ",
102 (c->level == ERROR) ? "ERROR" : "Warning", c->name);
103 vfprintf(stderr, fmt, ap);
104 fprintf(stderr, "\n");
105}
106
107#define FAIL(c, ...) \
108 do { \
109 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
110 (c)->status = FAILED; \
111 check_msg((c), __VA_ARGS__); \
112 } while (0)
113
114static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
115{
116 struct node *child;
117 struct property *prop;
118
119 TRACE(c, "%s", node->fullpath);
120 if (c->node_fn)
121 c->node_fn(c, dt, node);
122
123 if (c->prop_fn)
124 for_each_property(node, prop) {
125 TRACE(c, "%s\t'%s'", node->fullpath, prop->name);
126 c->prop_fn(c, dt, node, prop);
127 }
128
129 for_each_child(node, child)
130 check_nodes_props(c, dt, child);
131}
132
133static int run_check(struct check *c, struct node *dt)
134{
135 int error = 0;
136 int i;
137
138 assert(!c->inprogress);
139
140 if (c->status != UNCHECKED)
141 goto out;
142
143 c->inprogress = 1;
144
145 for (i = 0; i < c->num_prereqs; i++) {
146 struct check *prq = c->prereq[i];
147 error |= run_check(prq, dt);
148 if (prq->status != PASSED) {
149 c->status = PREREQ;
150 check_msg(c, "Failed prerequisite '%s'",
151 c->prereq[i]->name);
152 }
153 }
154
155 if (c->status != UNCHECKED)
156 goto out;
157
158 if (c->node_fn || c->prop_fn)
159 check_nodes_props(c, dt, dt);
160
161 if (c->tree_fn)
162 c->tree_fn(c, dt);
163 if (c->status == UNCHECKED)
164 c->status = PASSED;
165
166 TRACE(c, "\tCompleted, status %d", c->status);
167
168out:
169 c->inprogress = 0;
170 if ((c->status != PASSED) && (c->level == ERROR))
171 error = 1;
172 return error;
173}
174
175/*
176 * Utility check functions
177 */
178
179static void check_is_string(struct check *c, struct node *root,
180 struct node *node)
181{
182 struct property *prop;
183 char *propname = c->data;
184
185 prop = get_property(node, propname);
186 if (!prop)
187 return; /* Not present, assumed ok */
188
189 if (!data_is_one_string(prop->val))
190 FAIL(c, "\"%s\" property in %s is not a string",
191 propname, node->fullpath);
192}
193#define CHECK_IS_STRING(nm, propname, lvl) \
194 CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl))
195
196static void check_is_cell(struct check *c, struct node *root,
197 struct node *node)
198{
199 struct property *prop;
200 char *propname = c->data;
201
202 prop = get_property(node, propname);
203 if (!prop)
204 return; /* Not present, assumed ok */
205
206 if (prop->val.len != sizeof(cell_t))
207 FAIL(c, "\"%s\" property in %s is not a single cell",
208 propname, node->fullpath);
209}
210#define CHECK_IS_CELL(nm, propname, lvl) \
211 CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl))
212
213/*
214 * Structural check functions
215 */
216
217static void check_duplicate_node_names(struct check *c, struct node *dt,
218 struct node *node)
219{
220 struct node *child, *child2;
221
222 for_each_child(node, child)
223 for (child2 = child->next_sibling;
224 child2;
225 child2 = child2->next_sibling)
226 if (streq(child->name, child2->name))
227 FAIL(c, "Duplicate node name %s",
228 child->fullpath);
229}
230NODE_CHECK(duplicate_node_names, NULL, ERROR);
231
232static void check_duplicate_property_names(struct check *c, struct node *dt,
233 struct node *node)
234{
235 struct property *prop, *prop2;
236
237 for_each_property(node, prop)
238 for (prop2 = prop->next; prop2; prop2 = prop2->next)
239 if (streq(prop->name, prop2->name))
240 FAIL(c, "Duplicate property name %s in %s",
241 prop->name, node->fullpath);
242}
243NODE_CHECK(duplicate_property_names, NULL, ERROR);
244
245static void check_explicit_phandles(struct check *c, struct node *root,
246 struct node *node)
247{
248 struct property *prop;
249 struct node *other;
250 cell_t phandle;
251
252 prop = get_property(node, "linux,phandle");
253 if (! prop)
254 return; /* No phandle, that's fine */
255
256 if (prop->val.len != sizeof(cell_t)) {
257 FAIL(c, "%s has bad length (%d) linux,phandle property",
258 node->fullpath, prop->val.len);
259 return;
260 }
261
262 phandle = propval_cell(prop);
263 if ((phandle == 0) || (phandle == -1)) {
264 FAIL(c, "%s has invalid linux,phandle value 0x%x",
265 node->fullpath, phandle);
266 return;
267 }
268
269 other = get_node_by_phandle(root, phandle);
270 if (other) {
271 FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
272 node->fullpath, phandle, other->fullpath);
273 return;
274 }
275
276 node->phandle = phandle;
277}
278NODE_CHECK(explicit_phandles, NULL, ERROR);
279
280static void check_name_properties(struct check *c, struct node *root,
281 struct node *node)
282{
283 struct property *prop;
284
285 prop = get_property(node, "name");
286 if (!prop)
287 return; /* No name property, that's fine */
288
289 if ((prop->val.len != node->basenamelen+1)
290 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0))
291 FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
292 " of base node name)", node->fullpath, prop->val.val);
293}
294CHECK_IS_STRING(name_is_string, "name", ERROR);
295NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
296
297/*
298 * Reference fixup functions
299 */
300
301static void fixup_phandle_references(struct check *c, struct node *dt,
302 struct node *node, struct property *prop)
303{
304 struct marker *m = prop->val.markers;
305 struct node *refnode;
306 cell_t phandle;
307
308 for_each_marker_of_type(m, REF_PHANDLE) {
309 assert(m->offset + sizeof(cell_t) <= prop->val.len);
310
311 refnode = get_node_by_ref(dt, m->ref);
312 if (! refnode) {
313 FAIL(c, "Reference to non-existent node or label \"%s\"\n",
314 m->ref);
315 continue;
316 }
317
318 phandle = get_node_phandle(dt, refnode);
319 *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle);
320 }
321}
322CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
323 &duplicate_node_names, &explicit_phandles);
324
325static void fixup_path_references(struct check *c, struct node *dt,
326 struct node *node, struct property *prop)
327{
328 struct marker *m = prop->val.markers;
329 struct node *refnode;
330 char *path;
331
332 for_each_marker_of_type(m, REF_PATH) {
333 assert(m->offset <= prop->val.len);
334
335 refnode = get_node_by_ref(dt, m->ref);
336 if (!refnode) {
337 FAIL(c, "Reference to non-existent node or label \"%s\"\n",
338 m->ref);
339 continue;
340 }
341
342 path = refnode->fullpath;
343 prop->val = data_insert_at_marker(prop->val, m, path,
344 strlen(path) + 1);
345 }
346}
347CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR,
348 &duplicate_node_names);
349
350/*
351 * Semantic checks
352 */
353CHECK_IS_CELL(address_cells_is_cell, "#address-cells", WARN);
354CHECK_IS_CELL(size_cells_is_cell, "#size-cells", WARN);
355CHECK_IS_CELL(interrupt_cells_is_cell, "#interrupt-cells", WARN);
356
357CHECK_IS_STRING(device_type_is_string, "device_type", WARN);
358CHECK_IS_STRING(model_is_string, "model", WARN);
359CHECK_IS_STRING(status_is_string, "status", WARN);
360
361static void fixup_addr_size_cells(struct check *c, struct node *dt,
362 struct node *node)
363{
364 struct property *prop;
365
366 node->addr_cells = -1;
367 node->size_cells = -1;
368
369 prop = get_property(node, "#address-cells");
370 if (prop)
371 node->addr_cells = propval_cell(prop);
372
373 prop = get_property(node, "#size-cells");
374 if (prop)
375 node->size_cells = propval_cell(prop);
376}
377CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN,
378 &address_cells_is_cell, &size_cells_is_cell);
379
380#define node_addr_cells(n) \
381 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
382#define node_size_cells(n) \
383 (((n)->size_cells == -1) ? 1 : (n)->size_cells)
384
385static void check_reg_format(struct check *c, struct node *dt,
386 struct node *node)
387{
388 struct property *prop;
389 int addr_cells, size_cells, entrylen;
390
391 prop = get_property(node, "reg");
392 if (!prop)
393 return; /* No "reg", that's fine */
394
395 if (!node->parent) {
396 FAIL(c, "Root node has a \"reg\" property");
397 return;
398 }
399
400 if (prop->val.len == 0)
401 FAIL(c, "\"reg\" property in %s is empty", node->fullpath);
402
403 addr_cells = node_addr_cells(node->parent);
404 size_cells = node_size_cells(node->parent);
405 entrylen = (addr_cells + size_cells) * sizeof(cell_t);
406
407 if ((prop->val.len % entrylen) != 0)
408 FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
409 "(#address-cells == %d, #size-cells == %d)",
410 node->fullpath, prop->val.len, addr_cells, size_cells);
411}
412NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells);
413
414static void check_ranges_format(struct check *c, struct node *dt,
415 struct node *node)
416{
417 struct property *prop;
418 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
419
420 prop = get_property(node, "ranges");
421 if (!prop)
422 return;
423
424 if (!node->parent) {
425 FAIL(c, "Root node has a \"ranges\" property");
426 return;
427 }
428
429 p_addr_cells = node_addr_cells(node->parent);
430 p_size_cells = node_size_cells(node->parent);
431 c_addr_cells = node_addr_cells(node);
432 c_size_cells = node_size_cells(node);
433 entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t);
434
435 if (prop->val.len == 0) {
436 if (p_addr_cells != c_addr_cells)
437 FAIL(c, "%s has empty \"ranges\" property but its "
438 "#address-cells (%d) differs from %s (%d)",
439 node->fullpath, c_addr_cells, node->parent->fullpath,
440 p_addr_cells);
441 if (p_size_cells != c_size_cells)
442 FAIL(c, "%s has empty \"ranges\" property but its "
443 "#size-cells (%d) differs from %s (%d)",
444 node->fullpath, c_size_cells, node->parent->fullpath,
445 p_size_cells);
446 } else if ((prop->val.len % entrylen) != 0) {
447 FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) "
448 "(parent #address-cells == %d, child #address-cells == %d, "
449 "#size-cells == %d)", node->fullpath, prop->val.len,
450 p_addr_cells, c_addr_cells, c_size_cells);
451 }
452}
453NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells);
454
455/*
456 * Style checks
457 */
458static void check_avoid_default_addr_size(struct check *c, struct node *dt,
459 struct node *node)
460{
461 struct property *reg, *ranges;
462
463 if (!node->parent)
464 return; /* Ignore root node */
465
466 reg = get_property(node, "reg");
467 ranges = get_property(node, "ranges");
468
469 if (!reg && !ranges)
470 return;
471
472 if ((node->parent->addr_cells == -1))
473 FAIL(c, "Relying on default #address-cells value for %s",
474 node->fullpath);
475
476 if ((node->parent->size_cells == -1))
477 FAIL(c, "Relying on default #size-cells value for %s",
478 node->fullpath);
479}
480NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
481
482static void check_obsolete_chosen_interrupt_controller(struct check *c,
483 struct node *dt)
484{
485 struct node *chosen;
486 struct property *prop;
487
488 chosen = get_node_by_path(dt, "/chosen");
489 if (!chosen)
490 return;
491
492 prop = get_property(chosen, "interrupt-controller");
493 if (prop)
494 FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
495 "property");
496}
497TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
498
499static struct check *check_table[] = {
500 &duplicate_node_names, &duplicate_property_names,
501 &name_is_string, &name_properties,
502 &explicit_phandles,
503 &phandle_references, &path_references,
504
505 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
506 &device_type_is_string, &model_is_string, &status_is_string,
507
508 &addr_size_cells, &reg_format, &ranges_format,
509
510 &avoid_default_addr_size,
511 &obsolete_chosen_interrupt_controller,
512};
513
514int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
515
516void process_checks(int force, struct boot_info *bi,
517 int checkflag, int outversion, int boot_cpuid_phys)
518{
519 struct node *dt = bi->dt;
520 int i;
521 int error = 0;
522
523 for (i = 0; i < ARRAY_SIZE(check_table); i++) {
524 struct check *c = check_table[i];
525
526 if (c->level != IGNORE)
527 error = error || run_check(c, dt);
528 }
529
530 if (error) {
531 if (!force) {
532 fprintf(stderr, "ERROR: Input tree has errors, aborting "
533 "(use -f to force output)\n");
534 exit(2);
535 } else if (quiet < 3) {
536 fprintf(stderr, "Warning: Input tree has errors, "
537 "output forced\n");
538 }
539 }
540
541 if (checkflag) {
542 if (error) {
543 fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n");
544 } else {
545 if (!check_semantics(bi->dt, outversion,
546 boot_cpuid_phys))
547 fprintf(stderr, "Warning: Input tree has semantic errors\n");
548 }
549 }
550}
551
552/*
553 * Semantic check functions
554 */
555
556#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__)
557#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__)
558
559#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
560
561#define CHECK_HAVE(node, propname) \
562 do { \
563 if (! (prop = get_property((node), (propname)))) \
564 DO_ERR("Missing \"%s\" property in %s\n", (propname), \
565 (node)->fullpath); \
566 } while (0);
567
568#define CHECK_HAVE_WARN(node, propname) \
569 do { \
570 if (! (prop = get_property((node), (propname)))) \
571 WARNMSG("%s has no \"%s\" property\n", \
572 (node)->fullpath, (propname)); \
573 } while (0)
574
575#define CHECK_HAVE_STRING(node, propname) \
576 do { \
577 CHECK_HAVE((node), (propname)); \
578 if (prop && !data_is_one_string(prop->val)) \
579 DO_ERR("\"%s\" property in %s is not a string\n", \
580 (propname), (node)->fullpath); \
581 } while (0)
582
583#define CHECK_HAVE_STREQ(node, propname, value) \
584 do { \
585 CHECK_HAVE_STRING((node), (propname)); \
586 if (prop && !streq(prop->val.val, (value))) \
587 DO_ERR("%s has wrong %s, %s (should be %s\n", \
588 (node)->fullpath, (propname), \
589 prop->val.val, (value)); \
590 } while (0)
591
592#define CHECK_HAVE_ONECELL(node, propname) \
593 do { \
594 CHECK_HAVE((node), (propname)); \
595 if (prop && (prop->val.len != sizeof(cell_t))) \
596 DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
597 } while (0)
598
599#define CHECK_HAVE_WARN_ONECELL(node, propname) \
600 do { \
601 CHECK_HAVE_WARN((node), (propname)); \
602 if (prop && (prop->val.len != sizeof(cell_t))) \
603 DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
604 } while (0)
605
606#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
607 do { \
608 struct node *ref; \
609 CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
610 if (prop) {\
611 cell_t phandle = propval_cell(prop); \
612 if ((phandle == 0) || (phandle == -1)) { \
613 DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \
614 } else { \
615 ref = get_node_by_phandle((root), propval_cell(prop)); \
616 if (! ref) \
617 DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
618 } \
619 } \
620 } while (0)
621
622#define CHECK_HAVE_WARN_STRING(node, propname) \
623 do { \
624 CHECK_HAVE_WARN((node), (propname)); \
625 if (prop && !data_is_one_string(prop->val)) \
626 DO_ERR("\"%s\" property in %s is not a string\n", \
627 (propname), (node)->fullpath); \
628 } while (0)
629
630static int check_root(struct node *root)
631{
632 struct property *prop;
633 int ok = 1;
634
635 CHECK_HAVE_STRING(root, "model");
636 CHECK_HAVE_WARN(root, "compatible");
637
638 return ok;
639}
640
641static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
642{
643 struct node *cpus, *cpu;
644 struct property *prop;
645 struct node *bootcpu = NULL;
646 int ok = 1;
647
648 cpus = get_subnode(root, "cpus");
649 if (! cpus) {
650 ERRMSG("Missing /cpus node\n");
651 return 0;
652 }
653
654 if (cpus->addr_cells != 1)
655 DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
656 cpus->fullpath, cpus->addr_cells);
657 if (cpus->size_cells != 0)
658 DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
659 cpus->fullpath, cpus->size_cells);
660
661 for_each_child(cpus, cpu) {
662 CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
663
664 CHECK_HAVE_ONECELL(cpu, "reg");
665 if (prop) {
666 cell_t unitnum;
667 char *eptr;
668
669 unitnum = strtol(get_unitname(cpu), &eptr, 16);
670 if (*eptr) {
671 WARNMSG("%s has bad format unit name %s (should be CPU number\n",
672 cpu->fullpath, get_unitname(cpu));
673 } else if (unitnum != propval_cell(prop)) {
674 WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n",
675 cpu->fullpath, get_unitname(cpu),
676 propval_cell(prop));
677 }
678 }
679
680/* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */
681/* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */
682 CHECK_HAVE_ONECELL(cpu, "d-cache-size");
683 CHECK_HAVE_ONECELL(cpu, "i-cache-size");
684
685 CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
686 CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
687
688 prop = get_property(cpu, "linux,boot-cpu");
689 if (prop) {
690 if (prop->val.len)
691 WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
692 cpu->fullpath);
693 if (bootcpu)
694 DO_ERR("Multiple boot cpus (%s and %s)\n",
695 bootcpu->fullpath, cpu->fullpath);
696 else
697 bootcpu = cpu;
698 }
699 }
700
701 if (outversion < 2) {
702 if (! bootcpu)
703 WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
704 } else {
705 if (bootcpu)
706 WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n");
707 if (boot_cpuid_phys == 0xfeedbeef)
708 WARNMSG("physical boot CPU not set. Use -b option to set\n");
709 }
710
711 return ok;
712}
713
714static int check_memory(struct node *root)
715{
716 struct node *mem;
717 struct property *prop;
718 int nnodes = 0;
719 int ok = 1;
720
721 for_each_child(root, mem) {
722 if (! strneq(mem->name, "memory", mem->basenamelen))
723 continue;
724
725 nnodes++;
726
727 CHECK_HAVE_STREQ(mem, "device_type", "memory");
728 CHECK_HAVE(mem, "reg");
729 }
730
731 if (nnodes == 0) {
732 ERRMSG("No memory nodes\n");
733 return 0;
734 }
735
736 return ok;
737}
738
739int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
740{
741 int ok = 1;
742
743 ok = ok && check_root(dt);
744 ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
745 ok = ok && check_memory(dt);
746 if (! ok)
747 return 0;
748
749 return 1;
750}
diff --git a/arch/powerpc/boot/dtc-src/data.c b/arch/powerpc/boot/dtc-src/data.c
new file mode 100644
index 000000000000..a94718c731a9
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/data.c
@@ -0,0 +1,321 @@
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#include "dtc.h"
22
23void data_free(struct data d)
24{
25 struct marker *m, *nm;
26
27 m = d.markers;
28 while (m) {
29 nm = m->next;
30 free(m->ref);
31 free(m);
32 m = nm;
33 }
34
35 assert(!d.val || d.asize);
36
37 if (d.val)
38 free(d.val);
39}
40
41struct data data_grow_for(struct data d, int xlen)
42{
43 struct data nd;
44 int newsize;
45
46 /* we must start with an allocated datum */
47 assert(!d.val || d.asize);
48
49 if (xlen == 0)
50 return d;
51
52 nd = d;
53
54 newsize = xlen;
55
56 while ((d.len + xlen) > newsize)
57 newsize *= 2;
58
59 nd.asize = newsize;
60 nd.val = xrealloc(d.val, newsize);
61
62 assert(nd.asize >= (d.len + xlen));
63
64 return nd;
65}
66
67struct data data_copy_mem(const char *mem, int len)
68{
69 struct data d;
70
71 d = data_grow_for(empty_data, len);
72
73 d.len = len;
74 memcpy(d.val, mem, len);
75
76 return d;
77}
78
79static char get_oct_char(const char *s, int *i)
80{
81 char x[4];
82 char *endx;
83 long val;
84
85 x[3] = '\0';
86 x[0] = s[(*i)];
87 if (x[0]) {
88 x[1] = s[(*i)+1];
89 if (x[1])
90 x[2] = s[(*i)+2];
91 }
92
93 val = strtol(x, &endx, 8);
94 if ((endx - x) == 0)
95 fprintf(stderr, "Empty \\nnn escape\n");
96
97 (*i) += endx - x;
98 return val;
99}
100
101static char get_hex_char(const char *s, int *i)
102{
103 char x[3];
104 char *endx;
105 long val;
106
107 x[2] = '\0';
108 x[0] = s[(*i)];
109 if (x[0])
110 x[1] = s[(*i)+1];
111
112 val = strtol(x, &endx, 16);
113 if ((endx - x) == 0)
114 fprintf(stderr, "Empty \\x escape\n");
115
116 (*i) += endx - x;
117 return val;
118}
119
120struct data data_copy_escape_string(const char *s, int len)
121{
122 int i = 0;
123 struct data d;
124 char *q;
125
126 d = data_grow_for(empty_data, strlen(s)+1);
127
128 q = d.val;
129 while (i < len) {
130 char c = s[i++];
131
132 if (c != '\\') {
133 q[d.len++] = c;
134 continue;
135 }
136
137 c = s[i++];
138 assert(c);
139 switch (c) {
140 case 'a':
141 q[d.len++] = '\a';
142 break;
143 case 'b':
144 q[d.len++] = '\b';
145 break;
146 case 't':
147 q[d.len++] = '\t';
148 break;
149 case 'n':
150 q[d.len++] = '\n';
151 break;
152 case 'v':
153 q[d.len++] = '\v';
154 break;
155 case 'f':
156 q[d.len++] = '\f';
157 break;
158 case 'r':
159 q[d.len++] = '\r';
160 break;
161 case '0':
162 case '1':
163 case '2':
164 case '3':
165 case '4':
166 case '5':
167 case '6':
168 case '7':
169 i--; /* need to re-read the first digit as
170 * part of the octal value */
171 q[d.len++] = get_oct_char(s, &i);
172 break;
173 case 'x':
174 q[d.len++] = get_hex_char(s, &i);
175 break;
176 default:
177 q[d.len++] = c;
178 }
179 }
180
181 q[d.len++] = '\0';
182 return d;
183}
184
185struct data data_copy_file(FILE *f, size_t len)
186{
187 struct data d;
188
189 d = data_grow_for(empty_data, len);
190
191 d.len = len;
192 fread(d.val, len, 1, f);
193
194 return d;
195}
196
197struct data data_append_data(struct data d, const void *p, int len)
198{
199 d = data_grow_for(d, len);
200 memcpy(d.val + d.len, p, len);
201 d.len += len;
202 return d;
203}
204
205struct data data_insert_at_marker(struct data d, struct marker *m,
206 const void *p, int len)
207{
208 d = data_grow_for(d, len);
209 memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
210 memcpy(d.val + m->offset, p, len);
211 d.len += len;
212
213 /* Adjust all markers after the one we're inserting at */
214 m = m->next;
215 for_each_marker(m)
216 m->offset += len;
217 return d;
218}
219
220struct data data_append_markers(struct data d, struct marker *m)
221{
222 struct marker **mp = &d.markers;
223
224 /* Find the end of the markerlist */
225 while (*mp)
226 mp = &((*mp)->next);
227 *mp = m;
228 return d;
229}
230
231struct data data_merge(struct data d1, struct data d2)
232{
233 struct data d;
234 struct marker *m2 = d2.markers;
235
236 d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
237
238 /* Adjust for the length of d1 */
239 for_each_marker(m2)
240 m2->offset += d1.len;
241
242 d2.markers = NULL; /* So data_free() doesn't clobber them */
243 data_free(d2);
244
245 return d;
246}
247
248struct data data_append_cell(struct data d, cell_t word)
249{
250 cell_t beword = cpu_to_be32(word);
251
252 return data_append_data(d, &beword, sizeof(beword));
253}
254
255struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
256{
257 struct fdt_reserve_entry bere;
258
259 bere.address = cpu_to_be64(re->address);
260 bere.size = cpu_to_be64(re->size);
261
262 return data_append_data(d, &bere, sizeof(bere));
263}
264
265struct data data_append_addr(struct data d, u64 addr)
266{
267 u64 beaddr = cpu_to_be64(addr);
268
269 return data_append_data(d, &beaddr, sizeof(beaddr));
270}
271
272struct data data_append_byte(struct data d, uint8_t byte)
273{
274 return data_append_data(d, &byte, 1);
275}
276
277struct data data_append_zeroes(struct data d, int len)
278{
279 d = data_grow_for(d, len);
280
281 memset(d.val + d.len, 0, len);
282 d.len += len;
283 return d;
284}
285
286struct data data_append_align(struct data d, int align)
287{
288 int newlen = ALIGN(d.len, align);
289 return data_append_zeroes(d, newlen - d.len);
290}
291
292struct data data_add_marker(struct data d, enum markertype type, char *ref)
293{
294 struct marker *m;
295
296 m = xmalloc(sizeof(*m));
297 m->offset = d.len;
298 m->type = type;
299 m->ref = ref;
300 m->next = NULL;
301
302 return data_append_markers(d, m);
303}
304
305int data_is_one_string(struct data d)
306{
307 int i;
308 int len = d.len;
309
310 if (len == 0)
311 return 0;
312
313 for (i = 0; i < len-1; i++)
314 if (d.val[i] == '\0')
315 return 0;
316
317 if (d.val[len-1] != '\0')
318 return 0;
319
320 return 1;
321}
diff --git a/arch/powerpc/boot/dtc-src/dtc-lexer.l b/arch/powerpc/boot/dtc-src/dtc-lexer.l
new file mode 100644
index 000000000000..c811b221b31e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.l
@@ -0,0 +1,328 @@
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_]*
31
32%{
33#include "dtc.h"
34#include "srcpos.h"
35#include "dtc-parser.tab.h"
36
37
38/*#define LEXDEBUG 1*/
39
40#ifdef LEXDEBUG
41#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
42#else
43#define DPRINT(fmt, ...) do { } while (0)
44#endif
45
46static int dts_version; /* = 0 */
47
48#define BEGIN_DEFAULT() if (dts_version == 0) { \
49 DPRINT("<INITIAL>\n"); \
50 BEGIN(INITIAL); \
51 } else { \
52 DPRINT("<V1>\n"); \
53 BEGIN(V1); \
54 }
55%}
56
57%%
58<*>"/include/" BEGIN(INCLUDE);
59
60<INCLUDE>\"[^"\n]*\" {
61 yytext[strlen(yytext) - 1] = 0;
62 if (!push_input_file(yytext + 1)) {
63 /* Some unrecoverable error.*/
64 exit(1);
65 }
66 BEGIN_DEFAULT();
67 }
68
69
70<*><<EOF>> {
71 if (!pop_input_file()) {
72 yyterminate();
73 }
74 }
75
76<*>\"([^\\"]|\\.)*\" {
77 yylloc.filenum = srcpos_filenum;
78 yylloc.first_line = yylineno;
79 DPRINT("String: %s\n", yytext);
80 yylval.data = data_copy_escape_string(yytext+1,
81 yyleng-2);
82 yylloc.first_line = yylineno;
83 return DT_STRING;
84 }
85
86<*>"/dts-v1/" {
87 yylloc.filenum = srcpos_filenum;
88 yylloc.first_line = yylineno;
89 DPRINT("Keyword: /dts-v1/\n");
90 dts_version = 1;
91 BEGIN_DEFAULT();
92 return DT_V1;
93 }
94
95<*>"/memreserve/" {
96 yylloc.filenum = srcpos_filenum;
97 yylloc.first_line = yylineno;
98 DPRINT("Keyword: /memreserve/\n");
99 BEGIN_DEFAULT();
100 return DT_MEMRESERVE;
101 }
102
103<*>{LABEL}: {
104 yylloc.filenum = srcpos_filenum;
105 yylloc.first_line = yylineno;
106 DPRINT("Label: %s\n", yytext);
107 yylval.labelref = strdup(yytext);
108 yylval.labelref[yyleng-1] = '\0';
109 return DT_LABEL;
110 }
111
112<INITIAL>[bodh]# {
113 yylloc.filenum = srcpos_filenum;
114 yylloc.first_line = yylineno;
115 if (*yytext == 'b')
116 yylval.cbase = 2;
117 else if (*yytext == 'o')
118 yylval.cbase = 8;
119 else if (*yytext == 'd')
120 yylval.cbase = 10;
121 else
122 yylval.cbase = 16;
123 DPRINT("Base: %d\n", yylval.cbase);
124 return DT_BASE;
125 }
126
127<INITIAL>[0-9a-fA-F]+ {
128 yylloc.filenum = srcpos_filenum;
129 yylloc.first_line = yylineno;
130 yylval.literal = strdup(yytext);
131 DPRINT("Literal: '%s'\n", yylval.literal);
132 return DT_LEGACYLITERAL;
133 }
134
135<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
136 yylloc.filenum = srcpos_filenum;
137 yylloc.first_line = yylineno;
138 yylval.literal = strdup(yytext);
139 DPRINT("Literal: '%s'\n", yylval.literal);
140 return DT_LITERAL;
141 }
142
143\&{LABEL} { /* label reference */
144 yylloc.filenum = srcpos_filenum;
145 yylloc.first_line = yylineno;
146 DPRINT("Ref: %s\n", yytext+1);
147 yylval.labelref = strdup(yytext+1);
148 return DT_REF;
149 }
150
151"&{/"{PATHCHAR}+\} { /* new-style path reference */
152 yylloc.filenum = srcpos_filenum;
153 yylloc.first_line = yylineno;
154 yytext[yyleng-1] = '\0';
155 DPRINT("Ref: %s\n", yytext+2);
156 yylval.labelref = strdup(yytext+2);
157 return DT_REF;
158 }
159
160<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
161 yylloc.filenum = srcpos_filenum;
162 yylloc.first_line = yylineno;
163 DPRINT("Ref: %s\n", yytext+1);
164 yylval.labelref = strdup(yytext+1);
165 return DT_REF;
166 }
167
168<BYTESTRING>[0-9a-fA-F]{2} {
169 yylloc.filenum = srcpos_filenum;
170 yylloc.first_line = yylineno;
171 yylval.byte = strtol(yytext, NULL, 16);
172 DPRINT("Byte: %02x\n", (int)yylval.byte);
173 return DT_BYTE;
174 }
175
176<BYTESTRING>"]" {
177 yylloc.filenum = srcpos_filenum;
178 yylloc.first_line = yylineno;
179 DPRINT("/BYTESTRING\n");
180 BEGIN_DEFAULT();
181 return ']';
182 }
183
184<PROPNODENAME>{PROPNODECHAR}+ {
185 yylloc.filenum = srcpos_filenum;
186 yylloc.first_line = yylineno;
187 DPRINT("PropNodeName: %s\n", yytext);
188 yylval.propnodename = strdup(yytext);
189 BEGIN_DEFAULT();
190 return DT_PROPNODENAME;
191 }
192
193
194<*>[[:space:]]+ /* eat whitespace */
195
196<*>"/*"([^*]|\*+[^*/])*\*+"/" {
197 yylloc.filenum = srcpos_filenum;
198 yylloc.first_line = yylineno;
199 DPRINT("Comment: %s\n", yytext);
200 /* eat comments */
201 }
202
203<*>"//".*\n /* eat line comments */
204
205<*>. {
206 yylloc.filenum = srcpos_filenum;
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 int filenum;
231 FILE *file;
232 YY_BUFFER_STATE yy_prev_buf;
233 int yy_prev_lineno;
234 struct incl_file *prev;
235};
236
237struct incl_file *incl_file_stack;
238
239
240/*
241 * Detect infinite include recursion.
242 */
243#define MAX_INCLUDE_DEPTH (100)
244
245static int incl_depth = 0;
246
247
248int push_input_file(const char *filename)
249{
250 FILE *f;
251 struct incl_file *incl_file;
252
253 if (!filename) {
254 yyerror("No include file name given.");
255 return 0;
256 }
257
258 if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
259 yyerror("Includes nested too deeply");
260 return 0;
261 }
262
263 f = dtc_open_file(filename);
264
265 incl_file = malloc(sizeof(struct incl_file));
266 if (!incl_file) {
267 yyerror("Can not allocate include file space.");
268 return 0;
269 }
270
271 /*
272 * Save current context.
273 */
274 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
275 incl_file->yy_prev_lineno = yylineno;
276 incl_file->filenum = srcpos_filenum;
277 incl_file->file = yyin;
278 incl_file->prev = incl_file_stack;
279
280 incl_file_stack = incl_file;
281
282 /*
283 * Establish new context.
284 */
285 srcpos_filenum = lookup_file_name(filename, 0);
286 yylineno = 1;
287 yyin = f;
288 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
289
290 return 1;
291}
292
293
294int pop_input_file(void)
295{
296 struct incl_file *incl_file;
297
298 if (incl_file_stack == 0)
299 return 0;
300
301 fclose(yyin);
302
303 /*
304 * Pop.
305 */
306 --incl_depth;
307 incl_file = incl_file_stack;
308 incl_file_stack = incl_file->prev;
309
310 /*
311 * Recover old context.
312 */
313 yy_delete_buffer(YY_CURRENT_BUFFER);
314 yy_switch_to_buffer(incl_file->yy_prev_buf);
315 yylineno = incl_file->yy_prev_lineno;
316 srcpos_filenum = incl_file->filenum;
317 yyin = incl_file->file;
318
319 /*
320 * Free old state.
321 */
322 free(incl_file);
323
324 if (YY_CURRENT_BUFFER == 0)
325 return 0;
326
327 return 1;
328}
diff --git a/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped b/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
new file mode 100644
index 000000000000..d0f742460f92
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
@@ -0,0 +1,2174 @@
1#line 2 "dtc-lexer.lex.c"
2
3#line 4 "dtc-lexer.lex.c"
4
5#define YY_INT_ALIGNED short int
6
7/* A lexical scanner generated by flex */
8
9#define FLEX_SCANNER
10#define YY_FLEX_MAJOR_VERSION 2
11#define YY_FLEX_MINOR_VERSION 5
12#define YY_FLEX_SUBMINOR_VERSION 33
13#if YY_FLEX_SUBMINOR_VERSION > 0
14#define FLEX_BETA
15#endif
16
17/* First, we deal with platform-specific or compiler-specific issues. */
18
19/* begin standard C headers. */
20#include <stdio.h>
21#include <string.h>
22#include <errno.h>
23#include <stdlib.h>
24
25/* end standard C headers. */
26
27/* flex integer type definitions */
28
29#ifndef FLEXINT_H
30#define FLEXINT_H
31
32/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
33
34#if __STDC_VERSION__ >= 199901L
35
36/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
37 * if you want the limit (max/min) macros for int types.
38 */
39#ifndef __STDC_LIMIT_MACROS
40#define __STDC_LIMIT_MACROS 1
41#endif
42
43#include <inttypes.h>
44typedef int8_t flex_int8_t;
45typedef uint8_t flex_uint8_t;
46typedef int16_t flex_int16_t;
47typedef uint16_t flex_uint16_t;
48typedef int32_t flex_int32_t;
49typedef uint32_t flex_uint32_t;
50#else
51typedef signed char flex_int8_t;
52typedef short int flex_int16_t;
53typedef int flex_int32_t;
54typedef unsigned char flex_uint8_t;
55typedef unsigned short int flex_uint16_t;
56typedef unsigned int flex_uint32_t;
57#endif /* ! C99 */
58
59/* Limits of integral types. */
60#ifndef INT8_MIN
61#define INT8_MIN (-128)
62#endif
63#ifndef INT16_MIN
64#define INT16_MIN (-32767-1)
65#endif
66#ifndef INT32_MIN
67#define INT32_MIN (-2147483647-1)
68#endif
69#ifndef INT8_MAX
70#define INT8_MAX (127)
71#endif
72#ifndef INT16_MAX
73#define INT16_MAX (32767)
74#endif
75#ifndef INT32_MAX
76#define INT32_MAX (2147483647)
77#endif
78#ifndef UINT8_MAX
79#define UINT8_MAX (255U)
80#endif
81#ifndef UINT16_MAX
82#define UINT16_MAX (65535U)
83#endif
84#ifndef UINT32_MAX
85#define UINT32_MAX (4294967295U)
86#endif
87
88#endif /* ! FLEXINT_H */
89
90#ifdef __cplusplus
91
92/* The "const" storage-class-modifier is valid. */
93#define YY_USE_CONST
94
95#else /* ! __cplusplus */
96
97#if __STDC__
98
99#define YY_USE_CONST
100
101#endif /* __STDC__ */
102#endif /* ! __cplusplus */
103
104#ifdef YY_USE_CONST
105#define yyconst const
106#else
107#define yyconst
108#endif
109
110/* Returned upon end-of-file. */
111#define YY_NULL 0
112
113/* Promotes a possibly negative, possibly signed char to an unsigned
114 * integer for use as an array index. If the signed char is negative,
115 * we want to instead treat it as an 8-bit unsigned char, hence the
116 * double cast.
117 */
118#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
119
120/* Enter a start condition. This macro really ought to take a parameter,
121 * but we do it the disgusting crufty way forced on us by the ()-less
122 * definition of BEGIN.
123 */
124#define BEGIN (yy_start) = 1 + 2 *
125
126/* Translate the current start state into a value that can be later handed
127 * to BEGIN to return to the state. The YYSTATE alias is for lex
128 * compatibility.
129 */
130#define YY_START (((yy_start) - 1) / 2)
131#define YYSTATE YY_START
132
133/* Action number for EOF rule of a given start state. */
134#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
135
136/* Special action meaning "start processing a new file". */
137#define YY_NEW_FILE yyrestart(yyin )
138
139#define YY_END_OF_BUFFER_CHAR 0
140
141/* Size of default input buffer. */
142#ifndef YY_BUF_SIZE
143#define YY_BUF_SIZE 16384
144#endif
145
146/* The state buf must be large enough to hold one state per character in the main buffer.
147 */
148#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
149
150#ifndef YY_TYPEDEF_YY_BUFFER_STATE
151#define YY_TYPEDEF_YY_BUFFER_STATE
152typedef struct yy_buffer_state *YY_BUFFER_STATE;
153#endif
154
155extern int yyleng;
156
157extern FILE *yyin, *yyout;
158
159#define EOB_ACT_CONTINUE_SCAN 0
160#define EOB_ACT_END_OF_FILE 1
161#define EOB_ACT_LAST_MATCH 2
162
163 /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
164 * access to the local variable yy_act. Since yyless() is a macro, it would break
165 * existing scanners that call yyless() from OUTSIDE yylex.
166 * One obvious solution it to make yy_act a global. I tried that, and saw
167 * a 5% performance hit in a non-yylineno scanner, because yy_act is
168 * normally declared as a register variable-- so it is not worth it.
169 */
170 #define YY_LESS_LINENO(n) \
171 do { \
172 int yyl;\
173 for ( yyl = n; yyl < yyleng; ++yyl )\
174 if ( yytext[yyl] == '\n' )\
175 --yylineno;\
176 }while(0)
177
178/* Return all but the first "n" matched characters back to the input stream. */
179#define yyless(n) \
180 do \
181 { \
182 /* Undo effects of setting up yytext. */ \
183 int yyless_macro_arg = (n); \
184 YY_LESS_LINENO(yyless_macro_arg);\
185 *yy_cp = (yy_hold_char); \
186 YY_RESTORE_YY_MORE_OFFSET \
187 (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
188 YY_DO_BEFORE_ACTION; /* set up yytext again */ \
189 } \
190 while ( 0 )
191
192#define unput(c) yyunput( c, (yytext_ptr) )
193
194/* The following is because we cannot portably get our hands on size_t
195 * (without autoconf's help, which isn't available because we want
196 * flex-generated scanners to compile on their own).
197 */
198
199#ifndef YY_TYPEDEF_YY_SIZE_T
200#define YY_TYPEDEF_YY_SIZE_T
201typedef unsigned int yy_size_t;
202#endif
203
204#ifndef YY_STRUCT_YY_BUFFER_STATE
205#define YY_STRUCT_YY_BUFFER_STATE
206struct yy_buffer_state
207 {
208 FILE *yy_input_file;
209
210 char *yy_ch_buf; /* input buffer */
211 char *yy_buf_pos; /* current position in input buffer */
212
213 /* Size of input buffer in bytes, not including room for EOB
214 * characters.
215 */
216 yy_size_t yy_buf_size;
217
218 /* Number of characters read into yy_ch_buf, not including EOB
219 * characters.
220 */
221 int yy_n_chars;
222
223 /* Whether we "own" the buffer - i.e., we know we created it,
224 * and can realloc() it to grow it, and should free() it to
225 * delete it.
226 */
227 int yy_is_our_buffer;
228
229 /* Whether this is an "interactive" input source; if so, and
230 * if we're using stdio for input, then we want to use getc()
231 * instead of fread(), to make sure we stop fetching input after
232 * each newline.
233 */
234 int yy_is_interactive;
235
236 /* Whether we're considered to be at the beginning of a line.
237 * If so, '^' rules will be active on the next match, otherwise
238 * not.
239 */
240 int yy_at_bol;
241
242 int yy_bs_lineno; /**< The line count. */
243 int yy_bs_column; /**< The column count. */
244
245 /* Whether to try to fill the input buffer when we reach the
246 * end of it.
247 */
248 int yy_fill_buffer;
249
250 int yy_buffer_status;
251
252#define YY_BUFFER_NEW 0
253#define YY_BUFFER_NORMAL 1
254 /* When an EOF's been seen but there's still some text to process
255 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
256 * shouldn't try reading from the input source any more. We might
257 * still have a bunch of tokens to match, though, because of
258 * possible backing-up.
259 *
260 * When we actually see the EOF, we change the status to "new"
261 * (via yyrestart()), so that the user can continue scanning by
262 * just pointing yyin at a new input file.
263 */
264#define YY_BUFFER_EOF_PENDING 2
265
266 };
267#endif /* !YY_STRUCT_YY_BUFFER_STATE */
268
269/* Stack of input buffers. */
270static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
271static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
272static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
273
274/* We provide macros for accessing buffer states in case in the
275 * future we want to put the buffer states in a more general
276 * "scanner state".
277 *
278 * Returns the top of the stack, or NULL.
279 */
280#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
281 ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
282 : NULL)
283
284/* Same as previous macro, but useful when we know that the buffer stack is not
285 * NULL or when we need an lvalue. For internal use only.
286 */
287#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
288
289/* yy_hold_char holds the character lost when yytext is formed. */
290static char yy_hold_char;
291static int yy_n_chars; /* number of characters read into yy_ch_buf */
292int yyleng;
293
294/* Points to current character in buffer. */
295static char *yy_c_buf_p = (char *) 0;
296static int yy_init = 0; /* whether we need to initialize */
297static int yy_start = 0; /* start state number */
298
299/* Flag which is used to allow yywrap()'s to do buffer switches
300 * instead of setting up a fresh yyin. A bit of a hack ...
301 */
302static int yy_did_buffer_switch_on_eof;
303
304void yyrestart (FILE *input_file );
305void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
306YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
307void yy_delete_buffer (YY_BUFFER_STATE b );
308void yy_flush_buffer (YY_BUFFER_STATE b );
309void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
310void yypop_buffer_state (void );
311
312static void yyensure_buffer_stack (void );
313static void yy_load_buffer_state (void );
314static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
315
316#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
317
318YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
319YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
320YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
321
322void *yyalloc (yy_size_t );
323void *yyrealloc (void *,yy_size_t );
324void yyfree (void * );
325
326#define yy_new_buffer yy_create_buffer
327
328#define yy_set_interactive(is_interactive) \
329 { \
330 if ( ! YY_CURRENT_BUFFER ){ \
331 yyensure_buffer_stack (); \
332 YY_CURRENT_BUFFER_LVALUE = \
333 yy_create_buffer(yyin,YY_BUF_SIZE ); \
334 } \
335 YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
336 }
337
338#define yy_set_bol(at_bol) \
339 { \
340 if ( ! YY_CURRENT_BUFFER ){\
341 yyensure_buffer_stack (); \
342 YY_CURRENT_BUFFER_LVALUE = \
343 yy_create_buffer(yyin,YY_BUF_SIZE ); \
344 } \
345 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
346 }
347
348#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
349
350/* Begin user sect3 */
351
352#define yywrap() 1
353#define YY_SKIP_YYWRAP
354
355typedef unsigned char YY_CHAR;
356
357FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
358
359typedef int yy_state_type;
360
361extern int yylineno;
362
363int yylineno = 1;
364
365extern char *yytext;
366#define yytext_ptr yytext
367
368static yy_state_type yy_get_previous_state (void );
369static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
370static int yy_get_next_buffer (void );
371static void yy_fatal_error (yyconst char msg[] );
372
373/* Done after the current pattern has been matched and before the
374 * corresponding action - sets up yytext.
375 */
376#define YY_DO_BEFORE_ACTION \
377 (yytext_ptr) = yy_bp; \
378 yyleng = (size_t) (yy_cp - yy_bp); \
379 (yy_hold_char) = *yy_cp; \
380 *yy_cp = '\0'; \
381 (yy_c_buf_p) = yy_cp;
382
383#define YY_NUM_RULES 20
384#define YY_END_OF_BUFFER 21
385/* This struct is not used in this scanner,
386 but its presence is necessary. */
387struct yy_trans_info
388 {
389 flex_int32_t yy_verify;
390 flex_int32_t yy_nxt;
391 };
392static yyconst flex_int16_t yy_accept[94] =
393 { 0,
394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
395 21, 19, 16, 16, 19, 19, 19, 8, 8, 19,
396 8, 19, 19, 19, 19, 14, 15, 15, 19, 9,
397 9, 16, 0, 3, 0, 0, 10, 0, 0, 0,
398 0, 0, 0, 8, 8, 6, 0, 7, 0, 2,
399 0, 13, 13, 15, 15, 9, 0, 12, 10, 0,
400 0, 0, 0, 18, 0, 0, 0, 2, 9, 0,
401 17, 0, 0, 0, 11, 0, 0, 0, 0, 0,
402 0, 0, 0, 0, 4, 0, 0, 1, 0, 0,
403 0, 5, 0
404
405 } ;
406
407static yyconst flex_int32_t yy_ec[256] =
408 { 0,
409 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
410 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
411 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
412 1, 2, 1, 4, 5, 1, 1, 6, 1, 1,
413 1, 7, 8, 8, 9, 8, 10, 11, 12, 13,
414 13, 13, 13, 13, 13, 13, 13, 14, 1, 1,
415 1, 1, 8, 8, 15, 15, 15, 15, 15, 15,
416 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
417 16, 16, 16, 16, 16, 16, 16, 17, 16, 16,
418 1, 18, 19, 1, 16, 1, 15, 20, 21, 22,
419
420 23, 15, 16, 24, 25, 16, 16, 26, 27, 28,
421 24, 16, 16, 29, 30, 31, 32, 33, 16, 17,
422 16, 16, 34, 1, 35, 1, 1, 1, 1, 1,
423 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
424 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
425 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
426 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
427 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
428 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
429 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
430
431 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
432 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
433 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
434 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
435 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
436 1, 1, 1, 1, 1
437 } ;
438
439static yyconst flex_int32_t yy_meta[36] =
440 { 0,
441 1, 1, 1, 1, 2, 1, 2, 2, 2, 3,
442 4, 4, 4, 5, 6, 7, 7, 1, 1, 6,
443 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
444 7, 7, 7, 8, 1
445 } ;
446
447static yyconst flex_int16_t yy_base[107] =
448 { 0,
449 0, 0, 32, 0, 53, 0, 76, 0, 108, 111,
450 280, 288, 37, 39, 33, 36, 106, 0, 123, 146,
451 255, 251, 45, 0, 159, 288, 0, 53, 108, 172,
452 114, 127, 158, 288, 245, 0, 0, 234, 235, 236,
453 197, 195, 199, 0, 0, 288, 0, 288, 160, 288,
454 183, 288, 0, 0, 183, 182, 0, 0, 0, 0,
455 204, 189, 207, 288, 179, 187, 180, 194, 0, 171,
456 288, 196, 178, 174, 288, 169, 169, 177, 165, 153,
457 143, 155, 137, 118, 288, 122, 42, 288, 36, 36,
458 40, 288, 288, 212, 218, 223, 229, 234, 239, 245,
459
460 251, 255, 262, 270, 275, 280
461 } ;
462
463static yyconst flex_int16_t yy_def[107] =
464 { 0,
465 93, 1, 1, 3, 3, 5, 93, 7, 3, 3,
466 93, 93, 93, 93, 94, 95, 93, 96, 93, 19,
467 19, 20, 97, 98, 20, 93, 99, 100, 95, 93,
468 93, 93, 94, 93, 94, 101, 102, 93, 103, 104,
469 93, 93, 93, 96, 19, 93, 20, 93, 97, 93,
470 97, 93, 20, 99, 100, 93, 105, 101, 102, 106,
471 103, 103, 104, 93, 93, 93, 93, 94, 105, 106,
472 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
473 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
474 93, 93, 0, 93, 93, 93, 93, 93, 93, 93,
475
476 93, 93, 93, 93, 93, 93
477 } ;
478
479static yyconst flex_int16_t yy_nxt[324] =
480 { 0,
481 12, 13, 14, 15, 12, 16, 12, 12, 12, 17,
482 18, 18, 18, 12, 19, 20, 20, 12, 12, 21,
483 19, 21, 19, 22, 20, 20, 20, 20, 20, 20,
484 20, 20, 20, 12, 12, 23, 34, 12, 32, 32,
485 32, 32, 12, 12, 12, 36, 20, 33, 50, 92,
486 35, 20, 20, 20, 20, 20, 15, 54, 91, 54,
487 54, 54, 51, 24, 24, 24, 46, 25, 90, 38,
488 89, 26, 25, 25, 25, 25, 12, 13, 14, 15,
489 27, 12, 27, 27, 27, 17, 27, 27, 27, 12,
490 28, 28, 28, 12, 12, 28, 28, 28, 28, 28,
491
492 28, 28, 28, 28, 28, 28, 28, 28, 28, 12,
493 12, 15, 39, 29, 15, 40, 29, 93, 30, 31,
494 31, 30, 31, 31, 56, 56, 56, 41, 32, 32,
495 42, 88, 43, 45, 45, 45, 46, 45, 47, 47,
496 87, 38, 45, 45, 45, 45, 47, 47, 47, 47,
497 47, 47, 47, 47, 47, 47, 47, 47, 47, 86,
498 47, 34, 33, 50, 85, 47, 47, 47, 47, 53,
499 53, 53, 84, 53, 83, 35, 82, 51, 53, 53,
500 53, 53, 56, 56, 56, 93, 68, 54, 57, 54,
501 54, 54, 56, 56, 56, 62, 46, 34, 71, 81,
502
503 80, 79, 78, 77, 76, 75, 74, 73, 72, 64,
504 62, 35, 33, 33, 33, 33, 33, 33, 33, 33,
505 37, 67, 66, 37, 37, 37, 44, 65, 44, 49,
506 49, 49, 49, 49, 49, 49, 49, 52, 64, 52,
507 54, 62, 54, 60, 54, 54, 55, 93, 55, 55,
508 55, 55, 58, 58, 58, 48, 58, 58, 59, 48,
509 59, 59, 61, 61, 61, 61, 61, 61, 61, 61,
510 63, 63, 63, 63, 63, 63, 63, 63, 69, 93,
511 69, 70, 70, 70, 93, 70, 70, 11, 93, 93,
512 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
513
514 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
515 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
516 93, 93, 93
517 } ;
518
519static yyconst flex_int16_t yy_chk[324] =
520 { 0,
521 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
522 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
523 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
524 1, 1, 1, 1, 1, 3, 15, 3, 13, 13,
525 14, 14, 3, 3, 3, 16, 3, 23, 23, 91,
526 15, 3, 3, 3, 3, 3, 5, 28, 90, 28,
527 28, 28, 23, 5, 5, 5, 28, 5, 89, 16,
528 87, 5, 5, 5, 5, 5, 7, 7, 7, 7,
529 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
530 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
531
532 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
533 7, 9, 17, 9, 10, 17, 10, 29, 9, 9,
534 9, 10, 10, 10, 31, 31, 31, 17, 32, 32,
535 17, 86, 17, 19, 19, 19, 19, 19, 19, 19,
536 84, 29, 19, 19, 19, 19, 19, 19, 19, 19,
537 19, 19, 19, 19, 19, 19, 20, 20, 20, 83,
538 20, 33, 49, 49, 82, 20, 20, 20, 20, 25,
539 25, 25, 81, 25, 80, 33, 79, 49, 25, 25,
540 25, 25, 30, 30, 30, 51, 51, 55, 30, 55,
541 55, 55, 56, 56, 56, 62, 55, 68, 62, 78,
542
543 77, 76, 74, 73, 72, 70, 67, 66, 65, 63,
544 61, 68, 94, 94, 94, 94, 94, 94, 94, 94,
545 95, 43, 42, 95, 95, 95, 96, 41, 96, 97,
546 97, 97, 97, 97, 97, 97, 97, 98, 40, 98,
547 99, 39, 99, 38, 99, 99, 100, 35, 100, 100,
548 100, 100, 101, 101, 101, 22, 101, 101, 102, 21,
549 102, 102, 103, 103, 103, 103, 103, 103, 103, 103,
550 104, 104, 104, 104, 104, 104, 104, 104, 105, 11,
551 105, 106, 106, 106, 0, 106, 106, 93, 93, 93,
552 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
553
554 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
555 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
556 93, 93, 93
557 } ;
558
559/* Table of booleans, true if rule could match eol. */
560static yyconst flex_int32_t yy_rule_can_match_eol[21] =
561 { 0,
5620, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
563 0, };
564
565static yy_state_type yy_last_accepting_state;
566static char *yy_last_accepting_cpos;
567
568extern int yy_flex_debug;
569int yy_flex_debug = 0;
570
571/* The intent behind this definition is that it'll catch
572 * any uses of REJECT which flex missed.
573 */
574#define REJECT reject_used_but_not_detected
575#define yymore() yymore_used_but_not_detected
576#define YY_MORE_ADJ 0
577#define YY_RESTORE_YY_MORE_OFFSET
578char *yytext;
579#line 1 "dtc-lexer.l"
580/*
581 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
582 *
583 *
584 * This program is free software; you can redistribute it and/or
585 * modify it under the terms of the GNU General Public License as
586 * published by the Free Software Foundation; either version 2 of the
587 * License, or (at your option) any later version.
588 *
589 * This program is distributed in the hope that it will be useful,
590 * but WITHOUT ANY WARRANTY; without even the implied warranty of
591 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
592 * General Public License for more details.
593 *
594 * You should have received a copy of the GNU General Public License
595 * along with this program; if not, write to the Free Software
596 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
597 * USA
598 */
599
600
601
602
603#line 33 "dtc-lexer.l"
604#include "dtc.h"
605#include "srcpos.h"
606#include "dtc-parser.tab.h"
607
608
609/*#define LEXDEBUG 1*/
610
611#ifdef LEXDEBUG
612#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
613#else
614#define DPRINT(fmt, ...) do { } while (0)
615#endif
616
617static int dts_version; /* = 0 */
618
619#define BEGIN_DEFAULT() if (dts_version == 0) { \
620 DPRINT("<INITIAL>\n"); \
621 BEGIN(INITIAL); \
622 } else { \
623 DPRINT("<V1>\n"); \
624 BEGIN(V1); \
625 }
626#line 627 "dtc-lexer.lex.c"
627
628#define INITIAL 0
629#define INCLUDE 1
630#define BYTESTRING 2
631#define PROPNODENAME 3
632#define V1 4
633
634#ifndef YY_NO_UNISTD_H
635/* Special case for "unistd.h", since it is non-ANSI. We include it way
636 * down here because we want the user's section 1 to have been scanned first.
637 * The user has a chance to override it with an option.
638 */
639#include <unistd.h>
640#endif
641
642#ifndef YY_EXTRA_TYPE
643#define YY_EXTRA_TYPE void *
644#endif
645
646static int yy_init_globals (void );
647
648/* Macros after this point can all be overridden by user definitions in
649 * section 1.
650 */
651
652#ifndef YY_SKIP_YYWRAP
653#ifdef __cplusplus
654extern "C" int yywrap (void );
655#else
656extern int yywrap (void );
657#endif
658#endif
659
660#ifndef yytext_ptr
661static void yy_flex_strncpy (char *,yyconst char *,int );
662#endif
663
664#ifdef YY_NEED_STRLEN
665static int yy_flex_strlen (yyconst char * );
666#endif
667
668#ifndef YY_NO_INPUT
669
670#ifdef __cplusplus
671static int yyinput (void );
672#else
673static int input (void );
674#endif
675
676#endif
677
678/* Amount of stuff to slurp up with each read. */
679#ifndef YY_READ_BUF_SIZE
680#define YY_READ_BUF_SIZE 8192
681#endif
682
683/* Copy whatever the last rule matched to the standard output. */
684#ifndef ECHO
685/* This used to be an fputs(), but since the string might contain NUL's,
686 * we now use fwrite().
687 */
688#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
689#endif
690
691/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
692 * is returned in "result".
693 */
694#ifndef YY_INPUT
695#define YY_INPUT(buf,result,max_size) \
696 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
697 { \
698 int c = '*'; \
699 size_t n; \
700 for ( n = 0; n < max_size && \
701 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
702 buf[n] = (char) c; \
703 if ( c == '\n' ) \
704 buf[n++] = (char) c; \
705 if ( c == EOF && ferror( yyin ) ) \
706 YY_FATAL_ERROR( "input in flex scanner failed" ); \
707 result = n; \
708 } \
709 else \
710 { \
711 errno=0; \
712 while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
713 { \
714 if( errno != EINTR) \
715 { \
716 YY_FATAL_ERROR( "input in flex scanner failed" ); \
717 break; \
718 } \
719 errno=0; \
720 clearerr(yyin); \
721 } \
722 }\
723\
724
725#endif
726
727/* No semi-colon after return; correct usage is to write "yyterminate();" -
728 * we don't want an extra ';' after the "return" because that will cause
729 * some compilers to complain about unreachable statements.
730 */
731#ifndef yyterminate
732#define yyterminate() return YY_NULL
733#endif
734
735/* Number of entries by which start-condition stack grows. */
736#ifndef YY_START_STACK_INCR
737#define YY_START_STACK_INCR 25
738#endif
739
740/* Report a fatal error. */
741#ifndef YY_FATAL_ERROR
742#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
743#endif
744
745/* end tables serialization structures and prototypes */
746
747/* Default declaration of generated scanner - a define so the user can
748 * easily add parameters.
749 */
750#ifndef YY_DECL
751#define YY_DECL_IS_OURS 1
752
753extern int yylex (void);
754
755#define YY_DECL int yylex (void)
756#endif /* !YY_DECL */
757
758/* Code executed at the beginning of each rule, after yytext and yyleng
759 * have been set up.
760 */
761#ifndef YY_USER_ACTION
762#define YY_USER_ACTION
763#endif
764
765/* Code executed at the end of each rule. */
766#ifndef YY_BREAK
767#define YY_BREAK break;
768#endif
769
770#define YY_RULE_SETUP \
771 YY_USER_ACTION
772
773/** The main scanner function which does all the work.
774 */
775YY_DECL
776{
777 register yy_state_type yy_current_state;
778 register char *yy_cp, *yy_bp;
779 register int yy_act;
780
781#line 57 "dtc-lexer.l"
782
783#line 784 "dtc-lexer.lex.c"
784
785 if ( !(yy_init) )
786 {
787 (yy_init) = 1;
788
789#ifdef YY_USER_INIT
790 YY_USER_INIT;
791#endif
792
793 if ( ! (yy_start) )
794 (yy_start) = 1; /* first start state */
795
796 if ( ! yyin )
797 yyin = stdin;
798
799 if ( ! yyout )
800 yyout = stdout;
801
802 if ( ! YY_CURRENT_BUFFER ) {
803 yyensure_buffer_stack ();
804 YY_CURRENT_BUFFER_LVALUE =
805 yy_create_buffer(yyin,YY_BUF_SIZE );
806 }
807
808 yy_load_buffer_state( );
809 }
810
811 while ( 1 ) /* loops until end-of-file is reached */
812 {
813 yy_cp = (yy_c_buf_p);
814
815 /* Support of yytext. */
816 *yy_cp = (yy_hold_char);
817
818 /* yy_bp points to the position in yy_ch_buf of the start of
819 * the current run.
820 */
821 yy_bp = yy_cp;
822
823 yy_current_state = (yy_start);
824yy_match:
825 do
826 {
827 register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
828 if ( yy_accept[yy_current_state] )
829 {
830 (yy_last_accepting_state) = yy_current_state;
831 (yy_last_accepting_cpos) = yy_cp;
832 }
833 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
834 {
835 yy_current_state = (int) yy_def[yy_current_state];
836 if ( yy_current_state >= 94 )
837 yy_c = yy_meta[(unsigned int) yy_c];
838 }
839 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
840 ++yy_cp;
841 }
842 while ( yy_base[yy_current_state] != 288 );
843
844yy_find_action:
845 yy_act = yy_accept[yy_current_state];
846 if ( yy_act == 0 )
847 { /* have to back up */
848 yy_cp = (yy_last_accepting_cpos);
849 yy_current_state = (yy_last_accepting_state);
850 yy_act = yy_accept[yy_current_state];
851 }
852
853 YY_DO_BEFORE_ACTION;
854
855 if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
856 {
857 int yyl;
858 for ( yyl = 0; yyl < yyleng; ++yyl )
859 if ( yytext[yyl] == '\n' )
860
861 yylineno++;
862;
863 }
864
865do_action: /* This label is used only to access EOF actions. */
866
867 switch ( yy_act )
868 { /* beginning of action switch */
869 case 0: /* must back up */
870 /* undo the effects of YY_DO_BEFORE_ACTION */
871 *yy_cp = (yy_hold_char);
872 yy_cp = (yy_last_accepting_cpos);
873 yy_current_state = (yy_last_accepting_state);
874 goto yy_find_action;
875
876case 1:
877YY_RULE_SETUP
878#line 58 "dtc-lexer.l"
879BEGIN(INCLUDE);
880 YY_BREAK
881case 2:
882YY_RULE_SETUP
883#line 60 "dtc-lexer.l"
884{
885 yytext[strlen(yytext) - 1] = 0;
886 if (!push_input_file(yytext + 1)) {
887 /* Some unrecoverable error.*/
888 exit(1);
889 }
890 BEGIN_DEFAULT();
891 }
892 YY_BREAK
893case YY_STATE_EOF(INITIAL):
894case YY_STATE_EOF(INCLUDE):
895case YY_STATE_EOF(BYTESTRING):
896case YY_STATE_EOF(PROPNODENAME):
897case YY_STATE_EOF(V1):
898#line 70 "dtc-lexer.l"
899{
900 if (!pop_input_file()) {
901 yyterminate();
902 }
903 }
904 YY_BREAK
905case 3:
906/* rule 3 can match eol */
907YY_RULE_SETUP
908#line 76 "dtc-lexer.l"
909{
910 yylloc.filenum = srcpos_filenum;
911 yylloc.first_line = yylineno;
912 DPRINT("String: %s\n", yytext);
913 yylval.data = data_copy_escape_string(yytext+1,
914 yyleng-2);
915 yylloc.first_line = yylineno;
916 return DT_STRING;
917 }
918 YY_BREAK
919case 4:
920YY_RULE_SETUP
921#line 86 "dtc-lexer.l"
922{
923 yylloc.filenum = srcpos_filenum;
924 yylloc.first_line = yylineno;
925 DPRINT("Keyword: /dts-v1/\n");
926 dts_version = 1;
927 BEGIN_DEFAULT();
928 return DT_V1;
929 }
930 YY_BREAK
931case 5:
932YY_RULE_SETUP
933#line 95 "dtc-lexer.l"
934{
935 yylloc.filenum = srcpos_filenum;
936 yylloc.first_line = yylineno;
937 DPRINT("Keyword: /memreserve/\n");
938 BEGIN_DEFAULT();
939 return DT_MEMRESERVE;
940 }
941 YY_BREAK
942case 6:
943YY_RULE_SETUP
944#line 103 "dtc-lexer.l"
945{
946 yylloc.filenum = srcpos_filenum;
947 yylloc.first_line = yylineno;
948 DPRINT("Label: %s\n", yytext);
949 yylval.labelref = strdup(yytext);
950 yylval.labelref[yyleng-1] = '\0';
951 return DT_LABEL;
952 }
953 YY_BREAK
954case 7:
955YY_RULE_SETUP
956#line 112 "dtc-lexer.l"
957{
958 yylloc.filenum = srcpos_filenum;
959 yylloc.first_line = yylineno;
960 if (*yytext == 'b')
961 yylval.cbase = 2;
962 else if (*yytext == 'o')
963 yylval.cbase = 8;
964 else if (*yytext == 'd')
965 yylval.cbase = 10;
966 else
967 yylval.cbase = 16;
968 DPRINT("Base: %d\n", yylval.cbase);
969 return DT_BASE;
970 }
971 YY_BREAK
972case 8:
973YY_RULE_SETUP
974#line 127 "dtc-lexer.l"
975{
976 yylloc.filenum = srcpos_filenum;
977 yylloc.first_line = yylineno;
978 yylval.literal = strdup(yytext);
979 DPRINT("Literal: '%s'\n", yylval.literal);
980 return DT_LEGACYLITERAL;
981 }
982 YY_BREAK
983case 9:
984YY_RULE_SETUP
985#line 135 "dtc-lexer.l"
986{
987 yylloc.filenum = srcpos_filenum;
988 yylloc.first_line = yylineno;
989 yylval.literal = strdup(yytext);
990 DPRINT("Literal: '%s'\n", yylval.literal);
991 return DT_LITERAL;
992 }
993 YY_BREAK
994case 10:
995YY_RULE_SETUP
996#line 143 "dtc-lexer.l"
997{ /* label reference */
998 yylloc.filenum = srcpos_filenum;
999 yylloc.first_line = yylineno;
1000 DPRINT("Ref: %s\n", yytext+1);
1001 yylval.labelref = strdup(yytext+1);
1002 return DT_REF;
1003 }
1004 YY_BREAK
1005case 11:
1006YY_RULE_SETUP
1007#line 151 "dtc-lexer.l"
1008{ /* new-style path reference */
1009 yylloc.filenum = srcpos_filenum;
1010 yylloc.first_line = yylineno;
1011 yytext[yyleng-1] = '\0';
1012 DPRINT("Ref: %s\n", yytext+2);
1013 yylval.labelref = strdup(yytext+2);
1014 return DT_REF;
1015 }
1016 YY_BREAK
1017case 12:
1018YY_RULE_SETUP
1019#line 160 "dtc-lexer.l"
1020{ /* old-style path reference */
1021 yylloc.filenum = srcpos_filenum;
1022 yylloc.first_line = yylineno;
1023 DPRINT("Ref: %s\n", yytext+1);
1024 yylval.labelref = strdup(yytext+1);
1025 return DT_REF;
1026 }
1027 YY_BREAK
1028case 13:
1029YY_RULE_SETUP
1030#line 168 "dtc-lexer.l"
1031{
1032 yylloc.filenum = srcpos_filenum;
1033 yylloc.first_line = yylineno;
1034 yylval.byte = strtol(yytext, NULL, 16);
1035 DPRINT("Byte: %02x\n", (int)yylval.byte);
1036 return DT_BYTE;
1037 }
1038 YY_BREAK
1039case 14:
1040YY_RULE_SETUP
1041#line 176 "dtc-lexer.l"
1042{
1043 yylloc.filenum = srcpos_filenum;
1044 yylloc.first_line = yylineno;
1045 DPRINT("/BYTESTRING\n");
1046 BEGIN_DEFAULT();
1047 return ']';
1048 }
1049 YY_BREAK
1050case 15:
1051YY_RULE_SETUP
1052#line 184 "dtc-lexer.l"
1053{
1054 yylloc.filenum = srcpos_filenum;
1055 yylloc.first_line = yylineno;
1056 DPRINT("PropNodeName: %s\n", yytext);
1057 yylval.propnodename = strdup(yytext);
1058 BEGIN_DEFAULT();
1059 return DT_PROPNODENAME;
1060 }
1061 YY_BREAK
1062case 16:
1063/* rule 16 can match eol */
1064YY_RULE_SETUP
1065#line 194 "dtc-lexer.l"
1066/* eat whitespace */
1067 YY_BREAK
1068case 17:
1069/* rule 17 can match eol */
1070YY_RULE_SETUP
1071#line 196 "dtc-lexer.l"
1072{
1073 yylloc.filenum = srcpos_filenum;
1074 yylloc.first_line = yylineno;
1075 DPRINT("Comment: %s\n", yytext);
1076 /* eat comments */
1077 }
1078 YY_BREAK
1079case 18:
1080/* rule 18 can match eol */
1081YY_RULE_SETUP
1082#line 203 "dtc-lexer.l"
1083/* eat line comments */
1084 YY_BREAK
1085case 19:
1086YY_RULE_SETUP
1087#line 205 "dtc-lexer.l"
1088{
1089 yylloc.filenum = srcpos_filenum;
1090 yylloc.first_line = yylineno;
1091 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
1092 (unsigned)yytext[0]);
1093 if (yytext[0] == '[') {
1094 DPRINT("<BYTESTRING>\n");
1095 BEGIN(BYTESTRING);
1096 }
1097 if ((yytext[0] == '{')
1098 || (yytext[0] == ';')) {
1099 DPRINT("<PROPNODENAME>\n");
1100 BEGIN(PROPNODENAME);
1101 }
1102 return yytext[0];
1103 }
1104 YY_BREAK
1105case 20:
1106YY_RULE_SETUP
1107#line 222 "dtc-lexer.l"
1108ECHO;
1109 YY_BREAK
1110#line 1111 "dtc-lexer.lex.c"
1111
1112 case YY_END_OF_BUFFER:
1113 {
1114 /* Amount of text matched not including the EOB char. */
1115 int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
1116
1117 /* Undo the effects of YY_DO_BEFORE_ACTION. */
1118 *yy_cp = (yy_hold_char);
1119 YY_RESTORE_YY_MORE_OFFSET
1120
1121 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
1122 {
1123 /* We're scanning a new file or input source. It's
1124 * possible that this happened because the user
1125 * just pointed yyin at a new source and called
1126 * yylex(). If so, then we have to assure
1127 * consistency between YY_CURRENT_BUFFER and our
1128 * globals. Here is the right place to do so, because
1129 * this is the first action (other than possibly a
1130 * back-up) that will match for the new input source.
1131 */
1132 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1133 YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
1134 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
1135 }
1136
1137 /* Note that here we test for yy_c_buf_p "<=" to the position
1138 * of the first EOB in the buffer, since yy_c_buf_p will
1139 * already have been incremented past the NUL character
1140 * (since all states make transitions on EOB to the
1141 * end-of-buffer state). Contrast this with the test
1142 * in input().
1143 */
1144 if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1145 { /* This was really a NUL. */
1146 yy_state_type yy_next_state;
1147
1148 (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
1149
1150 yy_current_state = yy_get_previous_state( );
1151
1152 /* Okay, we're now positioned to make the NUL
1153 * transition. We couldn't have
1154 * yy_get_previous_state() go ahead and do it
1155 * for us because it doesn't know how to deal
1156 * with the possibility of jamming (and we don't
1157 * want to build jamming into it because then it
1158 * will run more slowly).
1159 */
1160
1161 yy_next_state = yy_try_NUL_trans( yy_current_state );
1162
1163 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1164
1165 if ( yy_next_state )
1166 {
1167 /* Consume the NUL. */
1168 yy_cp = ++(yy_c_buf_p);
1169 yy_current_state = yy_next_state;
1170 goto yy_match;
1171 }
1172
1173 else
1174 {
1175 yy_cp = (yy_c_buf_p);
1176 goto yy_find_action;
1177 }
1178 }
1179
1180 else switch ( yy_get_next_buffer( ) )
1181 {
1182 case EOB_ACT_END_OF_FILE:
1183 {
1184 (yy_did_buffer_switch_on_eof) = 0;
1185
1186 if ( yywrap( ) )
1187 {
1188 /* Note: because we've taken care in
1189 * yy_get_next_buffer() to have set up
1190 * yytext, we can now set up
1191 * yy_c_buf_p so that if some total
1192 * hoser (like flex itself) wants to
1193 * call the scanner after we return the
1194 * YY_NULL, it'll still work - another
1195 * YY_NULL will get returned.
1196 */
1197 (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
1198
1199 yy_act = YY_STATE_EOF(YY_START);
1200 goto do_action;
1201 }
1202
1203 else
1204 {
1205 if ( ! (yy_did_buffer_switch_on_eof) )
1206 YY_NEW_FILE;
1207 }
1208 break;
1209 }
1210
1211 case EOB_ACT_CONTINUE_SCAN:
1212 (yy_c_buf_p) =
1213 (yytext_ptr) + yy_amount_of_matched_text;
1214
1215 yy_current_state = yy_get_previous_state( );
1216
1217 yy_cp = (yy_c_buf_p);
1218 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1219 goto yy_match;
1220
1221 case EOB_ACT_LAST_MATCH:
1222 (yy_c_buf_p) =
1223 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
1224
1225 yy_current_state = yy_get_previous_state( );
1226
1227 yy_cp = (yy_c_buf_p);
1228 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1229 goto yy_find_action;
1230 }
1231 break;
1232 }
1233
1234 default:
1235 YY_FATAL_ERROR(
1236 "fatal flex scanner internal error--no action found" );
1237 } /* end of action switch */
1238 } /* end of scanning one token */
1239} /* end of yylex */
1240
1241/* yy_get_next_buffer - try to read in a new buffer
1242 *
1243 * Returns a code representing an action:
1244 * EOB_ACT_LAST_MATCH -
1245 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
1246 * EOB_ACT_END_OF_FILE - end of file
1247 */
1248static int yy_get_next_buffer (void)
1249{
1250 register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
1251 register char *source = (yytext_ptr);
1252 register int number_to_move, i;
1253 int ret_val;
1254
1255 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
1256 YY_FATAL_ERROR(
1257 "fatal flex scanner internal error--end of buffer missed" );
1258
1259 if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
1260 { /* Don't try to fill the buffer, so this is an EOF. */
1261 if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
1262 {
1263 /* We matched a single character, the EOB, so
1264 * treat this as a final EOF.
1265 */
1266 return EOB_ACT_END_OF_FILE;
1267 }
1268
1269 else
1270 {
1271 /* We matched some text prior to the EOB, first
1272 * process it.
1273 */
1274 return EOB_ACT_LAST_MATCH;
1275 }
1276 }
1277
1278 /* Try to read more data. */
1279
1280 /* First move last chars to start of buffer. */
1281 number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
1282
1283 for ( i = 0; i < number_to_move; ++i )
1284 *(dest++) = *(source++);
1285
1286 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
1287 /* don't do the read, it's not guaranteed to return an EOF,
1288 * just force an EOF
1289 */
1290 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
1291
1292 else
1293 {
1294 int num_to_read =
1295 YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
1296
1297 while ( num_to_read <= 0 )
1298 { /* Not enough room in the buffer - grow it. */
1299
1300 /* just a shorter name for the current buffer */
1301 YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
1302
1303 int yy_c_buf_p_offset =
1304 (int) ((yy_c_buf_p) - b->yy_ch_buf);
1305
1306 if ( b->yy_is_our_buffer )
1307 {
1308 int new_size = b->yy_buf_size * 2;
1309
1310 if ( new_size <= 0 )
1311 b->yy_buf_size += b->yy_buf_size / 8;
1312 else
1313 b->yy_buf_size *= 2;
1314
1315 b->yy_ch_buf = (char *)
1316 /* Include room in for 2 EOB chars. */
1317 yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
1318 }
1319 else
1320 /* Can't grow it, we don't own it. */
1321 b->yy_ch_buf = 0;
1322
1323 if ( ! b->yy_ch_buf )
1324 YY_FATAL_ERROR(
1325 "fatal error - scanner input buffer overflow" );
1326
1327 (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
1328
1329 num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
1330 number_to_move - 1;
1331
1332 }
1333
1334 if ( num_to_read > YY_READ_BUF_SIZE )
1335 num_to_read = YY_READ_BUF_SIZE;
1336
1337 /* Read in more data. */
1338 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
1339 (yy_n_chars), (size_t) num_to_read );
1340
1341 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1342 }
1343
1344 if ( (yy_n_chars) == 0 )
1345 {
1346 if ( number_to_move == YY_MORE_ADJ )
1347 {
1348 ret_val = EOB_ACT_END_OF_FILE;
1349 yyrestart(yyin );
1350 }
1351
1352 else
1353 {
1354 ret_val = EOB_ACT_LAST_MATCH;
1355 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
1356 YY_BUFFER_EOF_PENDING;
1357 }
1358 }
1359
1360 else
1361 ret_val = EOB_ACT_CONTINUE_SCAN;
1362
1363 (yy_n_chars) += number_to_move;
1364 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
1365 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
1366
1367 (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
1368
1369 return ret_val;
1370}
1371
1372/* yy_get_previous_state - get the state just before the EOB char was reached */
1373
1374 static yy_state_type yy_get_previous_state (void)
1375{
1376 register yy_state_type yy_current_state;
1377 register char *yy_cp;
1378
1379 yy_current_state = (yy_start);
1380
1381 for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
1382 {
1383 register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
1384 if ( yy_accept[yy_current_state] )
1385 {
1386 (yy_last_accepting_state) = yy_current_state;
1387 (yy_last_accepting_cpos) = yy_cp;
1388 }
1389 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1390 {
1391 yy_current_state = (int) yy_def[yy_current_state];
1392 if ( yy_current_state >= 94 )
1393 yy_c = yy_meta[(unsigned int) yy_c];
1394 }
1395 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1396 }
1397
1398 return yy_current_state;
1399}
1400
1401/* yy_try_NUL_trans - try to make a transition on the NUL character
1402 *
1403 * synopsis
1404 * next_state = yy_try_NUL_trans( current_state );
1405 */
1406 static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
1407{
1408 register int yy_is_jam;
1409 register char *yy_cp = (yy_c_buf_p);
1410
1411 register YY_CHAR yy_c = 1;
1412 if ( yy_accept[yy_current_state] )
1413 {
1414 (yy_last_accepting_state) = yy_current_state;
1415 (yy_last_accepting_cpos) = yy_cp;
1416 }
1417 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1418 {
1419 yy_current_state = (int) yy_def[yy_current_state];
1420 if ( yy_current_state >= 94 )
1421 yy_c = yy_meta[(unsigned int) yy_c];
1422 }
1423 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1424 yy_is_jam = (yy_current_state == 93);
1425
1426 return yy_is_jam ? 0 : yy_current_state;
1427}
1428
1429#ifndef YY_NO_INPUT
1430#ifdef __cplusplus
1431 static int yyinput (void)
1432#else
1433 static int input (void)
1434#endif
1435
1436{
1437 int c;
1438
1439 *(yy_c_buf_p) = (yy_hold_char);
1440
1441 if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
1442 {
1443 /* yy_c_buf_p now points to the character we want to return.
1444 * If this occurs *before* the EOB characters, then it's a
1445 * valid NUL; if not, then we've hit the end of the buffer.
1446 */
1447 if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1448 /* This was really a NUL. */
1449 *(yy_c_buf_p) = '\0';
1450
1451 else
1452 { /* need more input */
1453 int offset = (yy_c_buf_p) - (yytext_ptr);
1454 ++(yy_c_buf_p);
1455
1456 switch ( yy_get_next_buffer( ) )
1457 {
1458 case EOB_ACT_LAST_MATCH:
1459 /* This happens because yy_g_n_b()
1460 * sees that we've accumulated a
1461 * token and flags that we need to
1462 * try matching the token before
1463 * proceeding. But for input(),
1464 * there's no matching to consider.
1465 * So convert the EOB_ACT_LAST_MATCH
1466 * to EOB_ACT_END_OF_FILE.
1467 */
1468
1469 /* Reset buffer status. */
1470 yyrestart(yyin );
1471
1472 /*FALLTHROUGH*/
1473
1474 case EOB_ACT_END_OF_FILE:
1475 {
1476 if ( yywrap( ) )
1477 return EOF;
1478
1479 if ( ! (yy_did_buffer_switch_on_eof) )
1480 YY_NEW_FILE;
1481#ifdef __cplusplus
1482 return yyinput();
1483#else
1484 return input();
1485#endif
1486 }
1487
1488 case EOB_ACT_CONTINUE_SCAN:
1489 (yy_c_buf_p) = (yytext_ptr) + offset;
1490 break;
1491 }
1492 }
1493 }
1494
1495 c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
1496 *(yy_c_buf_p) = '\0'; /* preserve yytext */
1497 (yy_hold_char) = *++(yy_c_buf_p);
1498
1499 if ( c == '\n' )
1500
1501 yylineno++;
1502;
1503
1504 return c;
1505}
1506#endif /* ifndef YY_NO_INPUT */
1507
1508/** Immediately switch to a different input stream.
1509 * @param input_file A readable stream.
1510 *
1511 * @note This function does not reset the start condition to @c INITIAL .
1512 */
1513 void yyrestart (FILE * input_file )
1514{
1515
1516 if ( ! YY_CURRENT_BUFFER ){
1517 yyensure_buffer_stack ();
1518 YY_CURRENT_BUFFER_LVALUE =
1519 yy_create_buffer(yyin,YY_BUF_SIZE );
1520 }
1521
1522 yy_init_buffer(YY_CURRENT_BUFFER,input_file );
1523 yy_load_buffer_state( );
1524}
1525
1526/** Switch to a different input buffer.
1527 * @param new_buffer The new input buffer.
1528 *
1529 */
1530 void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
1531{
1532
1533 /* TODO. We should be able to replace this entire function body
1534 * with
1535 * yypop_buffer_state();
1536 * yypush_buffer_state(new_buffer);
1537 */
1538 yyensure_buffer_stack ();
1539 if ( YY_CURRENT_BUFFER == new_buffer )
1540 return;
1541
1542 if ( YY_CURRENT_BUFFER )
1543 {
1544 /* Flush out information for old buffer. */
1545 *(yy_c_buf_p) = (yy_hold_char);
1546 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1547 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1548 }
1549
1550 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1551 yy_load_buffer_state( );
1552
1553 /* We don't actually know whether we did this switch during
1554 * EOF (yywrap()) processing, but the only time this flag
1555 * is looked at is after yywrap() is called, so it's safe
1556 * to go ahead and always set it.
1557 */
1558 (yy_did_buffer_switch_on_eof) = 1;
1559}
1560
1561static void yy_load_buffer_state (void)
1562{
1563 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1564 (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
1565 yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
1566 (yy_hold_char) = *(yy_c_buf_p);
1567}
1568
1569/** Allocate and initialize an input buffer state.
1570 * @param file A readable stream.
1571 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
1572 *
1573 * @return the allocated buffer state.
1574 */
1575 YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
1576{
1577 YY_BUFFER_STATE b;
1578
1579 b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1580 if ( ! b )
1581 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1582
1583 b->yy_buf_size = size;
1584
1585 /* yy_ch_buf has to be 2 characters longer than the size given because
1586 * we need to put in 2 end-of-buffer characters.
1587 */
1588 b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
1589 if ( ! b->yy_ch_buf )
1590 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1591
1592 b->yy_is_our_buffer = 1;
1593
1594 yy_init_buffer(b,file );
1595
1596 return b;
1597}
1598
1599/** Destroy the buffer.
1600 * @param b a buffer created with yy_create_buffer()
1601 *
1602 */
1603 void yy_delete_buffer (YY_BUFFER_STATE b )
1604{
1605
1606 if ( ! b )
1607 return;
1608
1609 if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
1610 YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
1611
1612 if ( b->yy_is_our_buffer )
1613 yyfree((void *) b->yy_ch_buf );
1614
1615 yyfree((void *) b );
1616}
1617
1618#ifndef __cplusplus
1619extern int isatty (int );
1620#endif /* __cplusplus */
1621
1622/* Initializes or reinitializes a buffer.
1623 * This function is sometimes called more than once on the same buffer,
1624 * such as during a yyrestart() or at EOF.
1625 */
1626 static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
1627
1628{
1629 int oerrno = errno;
1630
1631 yy_flush_buffer(b );
1632
1633 b->yy_input_file = file;
1634 b->yy_fill_buffer = 1;
1635
1636 /* If b is the current buffer, then yy_init_buffer was _probably_
1637 * called from yyrestart() or through yy_get_next_buffer.
1638 * In that case, we don't want to reset the lineno or column.
1639 */
1640 if (b != YY_CURRENT_BUFFER){
1641 b->yy_bs_lineno = 1;
1642 b->yy_bs_column = 0;
1643 }
1644
1645 b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
1646
1647 errno = oerrno;
1648}
1649
1650/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
1651 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
1652 *
1653 */
1654 void yy_flush_buffer (YY_BUFFER_STATE b )
1655{
1656 if ( ! b )
1657 return;
1658
1659 b->yy_n_chars = 0;
1660
1661 /* We always need two end-of-buffer characters. The first causes
1662 * a transition to the end-of-buffer state. The second causes
1663 * a jam in that state.
1664 */
1665 b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
1666 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
1667
1668 b->yy_buf_pos = &b->yy_ch_buf[0];
1669
1670 b->yy_at_bol = 1;
1671 b->yy_buffer_status = YY_BUFFER_NEW;
1672
1673 if ( b == YY_CURRENT_BUFFER )
1674 yy_load_buffer_state( );
1675}
1676
1677/** Pushes the new state onto the stack. The new state becomes
1678 * the current state. This function will allocate the stack
1679 * if necessary.
1680 * @param new_buffer The new state.
1681 *
1682 */
1683void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
1684{
1685 if (new_buffer == NULL)
1686 return;
1687
1688 yyensure_buffer_stack();
1689
1690 /* This block is copied from yy_switch_to_buffer. */
1691 if ( YY_CURRENT_BUFFER )
1692 {
1693 /* Flush out information for old buffer. */
1694 *(yy_c_buf_p) = (yy_hold_char);
1695 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1696 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1697 }
1698
1699 /* Only push if top exists. Otherwise, replace top. */
1700 if (YY_CURRENT_BUFFER)
1701 (yy_buffer_stack_top)++;
1702 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1703
1704 /* copied from yy_switch_to_buffer. */
1705 yy_load_buffer_state( );
1706 (yy_did_buffer_switch_on_eof) = 1;
1707}
1708
1709/** Removes and deletes the top of the stack, if present.
1710 * The next element becomes the new top.
1711 *
1712 */
1713void yypop_buffer_state (void)
1714{
1715 if (!YY_CURRENT_BUFFER)
1716 return;
1717
1718 yy_delete_buffer(YY_CURRENT_BUFFER );
1719 YY_CURRENT_BUFFER_LVALUE = NULL;
1720 if ((yy_buffer_stack_top) > 0)
1721 --(yy_buffer_stack_top);
1722
1723 if (YY_CURRENT_BUFFER) {
1724 yy_load_buffer_state( );
1725 (yy_did_buffer_switch_on_eof) = 1;
1726 }
1727}
1728
1729/* Allocates the stack if it does not exist.
1730 * Guarantees space for at least one push.
1731 */
1732static void yyensure_buffer_stack (void)
1733{
1734 int num_to_alloc;
1735
1736 if (!(yy_buffer_stack)) {
1737
1738 /* First allocation is just for 2 elements, since we don't know if this
1739 * scanner will even need a stack. We use 2 instead of 1 to avoid an
1740 * immediate realloc on the next call.
1741 */
1742 num_to_alloc = 1;
1743 (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
1744 (num_to_alloc * sizeof(struct yy_buffer_state*)
1745 );
1746
1747 memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
1748
1749 (yy_buffer_stack_max) = num_to_alloc;
1750 (yy_buffer_stack_top) = 0;
1751 return;
1752 }
1753
1754 if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
1755
1756 /* Increase the buffer to prepare for a possible push. */
1757 int grow_size = 8 /* arbitrary grow size */;
1758
1759 num_to_alloc = (yy_buffer_stack_max) + grow_size;
1760 (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
1761 ((yy_buffer_stack),
1762 num_to_alloc * sizeof(struct yy_buffer_state*)
1763 );
1764
1765 /* zero only the new slots.*/
1766 memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
1767 (yy_buffer_stack_max) = num_to_alloc;
1768 }
1769}
1770
1771/** Setup the input buffer state to scan directly from a user-specified character buffer.
1772 * @param base the character buffer
1773 * @param size the size in bytes of the character buffer
1774 *
1775 * @return the newly allocated buffer state object.
1776 */
1777YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
1778{
1779 YY_BUFFER_STATE b;
1780
1781 if ( size < 2 ||
1782 base[size-2] != YY_END_OF_BUFFER_CHAR ||
1783 base[size-1] != YY_END_OF_BUFFER_CHAR )
1784 /* They forgot to leave room for the EOB's. */
1785 return 0;
1786
1787 b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1788 if ( ! b )
1789 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
1790
1791 b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
1792 b->yy_buf_pos = b->yy_ch_buf = base;
1793 b->yy_is_our_buffer = 0;
1794 b->yy_input_file = 0;
1795 b->yy_n_chars = b->yy_buf_size;
1796 b->yy_is_interactive = 0;
1797 b->yy_at_bol = 1;
1798 b->yy_fill_buffer = 0;
1799 b->yy_buffer_status = YY_BUFFER_NEW;
1800
1801 yy_switch_to_buffer(b );
1802
1803 return b;
1804}
1805
1806/** Setup the input buffer state to scan a string. The next call to yylex() will
1807 * scan from a @e copy of @a str.
1808 * @param yystr a NUL-terminated string to scan
1809 *
1810 * @return the newly allocated buffer state object.
1811 * @note If you want to scan bytes that may contain NUL values, then use
1812 * yy_scan_bytes() instead.
1813 */
1814YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1815{
1816
1817 return yy_scan_bytes(yystr,strlen(yystr) );
1818}
1819
1820/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
1821 * scan from a @e copy of @a bytes.
1822 * @param bytes the byte buffer to scan
1823 * @param len the number of bytes in the buffer pointed to by @a bytes.
1824 *
1825 * @return the newly allocated buffer state object.
1826 */
1827YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
1828{
1829 YY_BUFFER_STATE b;
1830 char *buf;
1831 yy_size_t n;
1832 int i;
1833
1834 /* Get memory for full buffer, including space for trailing EOB's. */
1835 n = _yybytes_len + 2;
1836 buf = (char *) yyalloc(n );
1837 if ( ! buf )
1838 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
1839
1840 for ( i = 0; i < _yybytes_len; ++i )
1841 buf[i] = yybytes[i];
1842
1843 buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
1844
1845 b = yy_scan_buffer(buf,n );
1846 if ( ! b )
1847 YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
1848
1849 /* It's okay to grow etc. this buffer, and we should throw it
1850 * away when we're done.
1851 */
1852 b->yy_is_our_buffer = 1;
1853
1854 return b;
1855}
1856
1857#ifndef YY_EXIT_FAILURE
1858#define YY_EXIT_FAILURE 2
1859#endif
1860
1861static void yy_fatal_error (yyconst char* msg )
1862{
1863 (void) fprintf( stderr, "%s\n", msg );
1864 exit( YY_EXIT_FAILURE );
1865}
1866
1867/* Redefine yyless() so it works in section 3 code. */
1868
1869#undef yyless
1870#define yyless(n) \
1871 do \
1872 { \
1873 /* Undo effects of setting up yytext. */ \
1874 int yyless_macro_arg = (n); \
1875 YY_LESS_LINENO(yyless_macro_arg);\
1876 yytext[yyleng] = (yy_hold_char); \
1877 (yy_c_buf_p) = yytext + yyless_macro_arg; \
1878 (yy_hold_char) = *(yy_c_buf_p); \
1879 *(yy_c_buf_p) = '\0'; \
1880 yyleng = yyless_macro_arg; \
1881 } \
1882 while ( 0 )
1883
1884/* Accessor methods (get/set functions) to struct members. */
1885
1886/** Get the current line number.
1887 *
1888 */
1889int yyget_lineno (void)
1890{
1891
1892 return yylineno;
1893}
1894
1895/** Get the input stream.
1896 *
1897 */
1898FILE *yyget_in (void)
1899{
1900 return yyin;
1901}
1902
1903/** Get the output stream.
1904 *
1905 */
1906FILE *yyget_out (void)
1907{
1908 return yyout;
1909}
1910
1911/** Get the length of the current token.
1912 *
1913 */
1914int yyget_leng (void)
1915{
1916 return yyleng;
1917}
1918
1919/** Get the current token.
1920 *
1921 */
1922
1923char *yyget_text (void)
1924{
1925 return yytext;
1926}
1927
1928/** Set the current line number.
1929 * @param line_number
1930 *
1931 */
1932void yyset_lineno (int line_number )
1933{
1934
1935 yylineno = line_number;
1936}
1937
1938/** Set the input stream. This does not discard the current
1939 * input buffer.
1940 * @param in_str A readable stream.
1941 *
1942 * @see yy_switch_to_buffer
1943 */
1944void yyset_in (FILE * in_str )
1945{
1946 yyin = in_str ;
1947}
1948
1949void yyset_out (FILE * out_str )
1950{
1951 yyout = out_str ;
1952}
1953
1954int yyget_debug (void)
1955{
1956 return yy_flex_debug;
1957}
1958
1959void yyset_debug (int bdebug )
1960{
1961 yy_flex_debug = bdebug ;
1962}
1963
1964static int yy_init_globals (void)
1965{
1966 /* Initialization is the same as for the non-reentrant scanner.
1967 * This function is called from yylex_destroy(), so don't allocate here.
1968 */
1969
1970 /* We do not touch yylineno unless the option is enabled. */
1971 yylineno = 1;
1972
1973 (yy_buffer_stack) = 0;
1974 (yy_buffer_stack_top) = 0;
1975 (yy_buffer_stack_max) = 0;
1976 (yy_c_buf_p) = (char *) 0;
1977 (yy_init) = 0;
1978 (yy_start) = 0;
1979
1980/* Defined in main.c */
1981#ifdef YY_STDINIT
1982 yyin = stdin;
1983 yyout = stdout;
1984#else
1985 yyin = (FILE *) 0;
1986 yyout = (FILE *) 0;
1987#endif
1988
1989 /* For future reference: Set errno on error, since we are called by
1990 * yylex_init()
1991 */
1992 return 0;
1993}
1994
1995/* yylex_destroy is for both reentrant and non-reentrant scanners. */
1996int yylex_destroy (void)
1997{
1998
1999 /* Pop the buffer stack, destroying each element. */
2000 while(YY_CURRENT_BUFFER){
2001 yy_delete_buffer(YY_CURRENT_BUFFER );
2002 YY_CURRENT_BUFFER_LVALUE = NULL;
2003 yypop_buffer_state();
2004 }
2005
2006 /* Destroy the stack itself. */
2007 yyfree((yy_buffer_stack) );
2008 (yy_buffer_stack) = NULL;
2009
2010 /* Reset the globals. This is important in a non-reentrant scanner so the next time
2011 * yylex() is called, initialization will occur. */
2012 yy_init_globals( );
2013
2014 return 0;
2015}
2016
2017/*
2018 * Internal utility routines.
2019 */
2020
2021#ifndef yytext_ptr
2022static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
2023{
2024 register int i;
2025 for ( i = 0; i < n; ++i )
2026 s1[i] = s2[i];
2027}
2028#endif
2029
2030#ifdef YY_NEED_STRLEN
2031static int yy_flex_strlen (yyconst char * s )
2032{
2033 register int n;
2034 for ( n = 0; s[n]; ++n )
2035 ;
2036
2037 return n;
2038}
2039#endif
2040
2041void *yyalloc (yy_size_t size )
2042{
2043 return (void *) malloc( size );
2044}
2045
2046void *yyrealloc (void * ptr, yy_size_t size )
2047{
2048 /* The cast to (char *) in the following accommodates both
2049 * implementations that use char* generic pointers, and those
2050 * that use void* generic pointers. It works with the latter
2051 * because both ANSI C and C++ allow castless assignment from
2052 * any pointer type to void*, and deal with argument conversions
2053 * as though doing an assignment.
2054 */
2055 return (void *) realloc( (char *) ptr, size );
2056}
2057
2058void yyfree (void * ptr )
2059{
2060 free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
2061}
2062
2063#define YYTABLES_NAME "yytables"
2064
2065#line 222 "dtc-lexer.l"
2066
2067
2068
2069
2070/*
2071 * Stack of nested include file contexts.
2072 */
2073
2074struct incl_file {
2075 int filenum;
2076 FILE *file;
2077 YY_BUFFER_STATE yy_prev_buf;
2078 int yy_prev_lineno;
2079 struct incl_file *prev;
2080};
2081
2082struct incl_file *incl_file_stack;
2083
2084
2085/*
2086 * Detect infinite include recursion.
2087 */
2088#define MAX_INCLUDE_DEPTH (100)
2089
2090static int incl_depth = 0;
2091
2092
2093int push_input_file(const char *filename)
2094{
2095 FILE *f;
2096 struct incl_file *incl_file;
2097
2098 if (!filename) {
2099 yyerror("No include file name given.");
2100 return 0;
2101 }
2102
2103 if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
2104 yyerror("Includes nested too deeply");
2105 return 0;
2106 }
2107
2108 f = dtc_open_file(filename);
2109
2110 incl_file = malloc(sizeof(struct incl_file));
2111 if (!incl_file) {
2112 yyerror("Can not allocate include file space.");
2113 return 0;
2114 }
2115
2116 /*
2117 * Save current context.
2118 */
2119 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
2120 incl_file->yy_prev_lineno = yylineno;
2121 incl_file->filenum = srcpos_filenum;
2122 incl_file->file = yyin;
2123 incl_file->prev = incl_file_stack;
2124
2125 incl_file_stack = incl_file;
2126
2127 /*
2128 * Establish new context.
2129 */
2130 srcpos_filenum = lookup_file_name(filename, 0);
2131 yylineno = 1;
2132 yyin = f;
2133 yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
2134
2135 return 1;
2136}
2137
2138
2139int pop_input_file(void)
2140{
2141 struct incl_file *incl_file;
2142
2143 if (incl_file_stack == 0)
2144 return 0;
2145
2146 fclose(yyin);
2147
2148 /*
2149 * Pop.
2150 */
2151 --incl_depth;
2152 incl_file = incl_file_stack;
2153 incl_file_stack = incl_file->prev;
2154
2155 /*
2156 * Recover old context.
2157 */
2158 yy_delete_buffer(YY_CURRENT_BUFFER);
2159 yy_switch_to_buffer(incl_file->yy_prev_buf);
2160 yylineno = incl_file->yy_prev_lineno;
2161 srcpos_filenum = incl_file->filenum;
2162 yyin = incl_file->file;
2163
2164 /*
2165 * Free old state.
2166 */
2167 free(incl_file);
2168
2169 if (YY_CURRENT_BUFFER == 0)
2170 return 0;
2171
2172 return 1;
2173}
2174
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped b/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
new file mode 100644
index 000000000000..28e6ec0296a1
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
@@ -0,0 +1,1983 @@
1/* A Bison parser, made by GNU Bison 2.3. */
2
3/* Skeleton implementation for Bison's Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23/* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work
25 under terms of your choice, so long as that work isn't itself a
26 parser generator using the skeleton or a modified version thereof
27 as a parser skeleton. Alternatively, if you modify or redistribute
28 the parser skeleton itself, you may (at your option) remove this
29 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public
31 License without this special exception.
32
33 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */
35
36/* C LALR(1) parser skeleton written by Richard Stallman, by
37 simplifying the original so-called "semantic" parser. */
38
39/* All symbols defined below should begin with yy or YY, to avoid
40 infringing on user name space. This should be done even for local
41 variables, as they might otherwise be expanded by user macros.
42 There are some unavoidable exceptions within include files to
43 define necessary library symbols; they are noted "INFRINGES ON
44 USER NAME SPACE" below. */
45
46/* Identify Bison output. */
47#define YYBISON 1
48
49/* Bison version. */
50#define YYBISON_VERSION "2.3"
51
52/* Skeleton name. */
53#define YYSKELETON_NAME "yacc.c"
54
55/* Pure parsers. */
56#define YYPURE 0
57
58/* Using locations. */
59#define YYLSP_NEEDED 1
60
61
62
63/* Tokens. */
64#ifndef YYTOKENTYPE
65# define YYTOKENTYPE
66 /* Put the tokens into the symbol table, so that GDB and other debuggers
67 know about them. */
68 enum yytokentype {
69 DT_V1 = 258,
70 DT_MEMRESERVE = 259,
71 DT_PROPNODENAME = 260,
72 DT_LITERAL = 261,
73 DT_LEGACYLITERAL = 262,
74 DT_BASE = 263,
75 DT_BYTE = 264,
76 DT_STRING = 265,
77 DT_LABEL = 266,
78 DT_REF = 267
79 };
80#endif
81/* Tokens. */
82#define DT_V1 258
83#define DT_MEMRESERVE 259
84#define DT_PROPNODENAME 260
85#define DT_LITERAL 261
86#define DT_LEGACYLITERAL 262
87#define DT_BASE 263
88#define DT_BYTE 264
89#define DT_STRING 265
90#define DT_LABEL 266
91#define DT_REF 267
92
93
94
95
96/* Copy the first part of user declarations. */
97#line 23 "dtc-parser.y"
98
99#include "dtc.h"
100#include "srcpos.h"
101
102int yylex(void);
103unsigned long long eval_literal(const char *s, int base, int bits);
104
105extern struct boot_info *the_boot_info;
106
107
108
109/* Enabling traces. */
110#ifndef YYDEBUG
111# define YYDEBUG 0
112#endif
113
114/* Enabling verbose error messages. */
115#ifdef YYERROR_VERBOSE
116# undef YYERROR_VERBOSE
117# define YYERROR_VERBOSE 1
118#else
119# define YYERROR_VERBOSE 0
120#endif
121
122/* Enabling the token table. */
123#ifndef YYTOKEN_TABLE
124# define YYTOKEN_TABLE 0
125#endif
126
127#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
128typedef union YYSTYPE
129#line 34 "dtc-parser.y"
130{
131 char *propnodename;
132 char *literal;
133 char *labelref;
134 unsigned int cbase;
135 u8 byte;
136 struct data data;
137
138 u64 addr;
139 cell_t cell;
140 struct property *prop;
141 struct property *proplist;
142 struct node *node;
143 struct node *nodelist;
144 struct reserve_info *re;
145}
146/* Line 187 of yacc.c. */
147#line 148 "dtc-parser.tab.c"
148 YYSTYPE;
149# define yystype YYSTYPE /* obsolescent; will be withdrawn */
150# define YYSTYPE_IS_DECLARED 1
151# define YYSTYPE_IS_TRIVIAL 1
152#endif
153
154#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
155typedef struct YYLTYPE
156{
157 int first_line;
158 int first_column;
159 int last_line;
160 int last_column;
161} YYLTYPE;
162# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
163# define YYLTYPE_IS_DECLARED 1
164# define YYLTYPE_IS_TRIVIAL 1
165#endif
166
167
168/* Copy the second part of user declarations. */
169
170
171/* Line 216 of yacc.c. */
172#line 173 "dtc-parser.tab.c"
173
174#ifdef short
175# undef short
176#endif
177
178#ifdef YYTYPE_UINT8
179typedef YYTYPE_UINT8 yytype_uint8;
180#else
181typedef unsigned char yytype_uint8;
182#endif
183
184#ifdef YYTYPE_INT8
185typedef YYTYPE_INT8 yytype_int8;
186#elif (defined __STDC__ || defined __C99__FUNC__ \
187 || defined __cplusplus || defined _MSC_VER)
188typedef signed char yytype_int8;
189#else
190typedef short int yytype_int8;
191#endif
192
193#ifdef YYTYPE_UINT16
194typedef YYTYPE_UINT16 yytype_uint16;
195#else
196typedef unsigned short int yytype_uint16;
197#endif
198
199#ifdef YYTYPE_INT16
200typedef YYTYPE_INT16 yytype_int16;
201#else
202typedef short int yytype_int16;
203#endif
204
205#ifndef YYSIZE_T
206# ifdef __SIZE_TYPE__
207# define YYSIZE_T __SIZE_TYPE__
208# elif defined size_t
209# define YYSIZE_T size_t
210# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
211 || defined __cplusplus || defined _MSC_VER)
212# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
213# define YYSIZE_T size_t
214# else
215# define YYSIZE_T unsigned int
216# endif
217#endif
218
219#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
220
221#ifndef YY_
222# if YYENABLE_NLS
223# if ENABLE_NLS
224# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
225# define YY_(msgid) dgettext ("bison-runtime", msgid)
226# endif
227# endif
228# ifndef YY_
229# define YY_(msgid) msgid
230# endif
231#endif
232
233/* Suppress unused-variable warnings by "using" E. */
234#if ! defined lint || defined __GNUC__
235# define YYUSE(e) ((void) (e))
236#else
237# define YYUSE(e) /* empty */
238#endif
239
240/* Identity function, used to suppress warnings about constant conditions. */
241#ifndef lint
242# define YYID(n) (n)
243#else
244#if (defined __STDC__ || defined __C99__FUNC__ \
245 || defined __cplusplus || defined _MSC_VER)
246static int
247YYID (int i)
248#else
249static int
250YYID (i)
251 int i;
252#endif
253{
254 return i;
255}
256#endif
257
258#if ! defined yyoverflow || YYERROR_VERBOSE
259
260/* The parser invokes alloca or malloc; define the necessary symbols. */
261
262# ifdef YYSTACK_USE_ALLOCA
263# if YYSTACK_USE_ALLOCA
264# ifdef __GNUC__
265# define YYSTACK_ALLOC __builtin_alloca
266# elif defined __BUILTIN_VA_ARG_INCR
267# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
268# elif defined _AIX
269# define YYSTACK_ALLOC __alloca
270# elif defined _MSC_VER
271# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
272# define alloca _alloca
273# else
274# define YYSTACK_ALLOC alloca
275# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
276 || defined __cplusplus || defined _MSC_VER)
277# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
278# ifndef _STDLIB_H
279# define _STDLIB_H 1
280# endif
281# endif
282# endif
283# endif
284# endif
285
286# ifdef YYSTACK_ALLOC
287 /* Pacify GCC's `empty if-body' warning. */
288# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
289# ifndef YYSTACK_ALLOC_MAXIMUM
290 /* The OS might guarantee only one guard page at the bottom of the stack,
291 and a page size can be as small as 4096 bytes. So we cannot safely
292 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
293 to allow for a few compiler-allocated temporary stack slots. */
294# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
295# endif
296# else
297# define YYSTACK_ALLOC YYMALLOC
298# define YYSTACK_FREE YYFREE
299# ifndef YYSTACK_ALLOC_MAXIMUM
300# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
301# endif
302# if (defined __cplusplus && ! defined _STDLIB_H \
303 && ! ((defined YYMALLOC || defined malloc) \
304 && (defined YYFREE || defined free)))
305# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
306# ifndef _STDLIB_H
307# define _STDLIB_H 1
308# endif
309# endif
310# ifndef YYMALLOC
311# define YYMALLOC malloc
312# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
313 || defined __cplusplus || defined _MSC_VER)
314void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
315# endif
316# endif
317# ifndef YYFREE
318# define YYFREE free
319# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
320 || defined __cplusplus || defined _MSC_VER)
321void free (void *); /* INFRINGES ON USER NAME SPACE */
322# endif
323# endif
324# endif
325#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
326
327
328#if (! defined yyoverflow \
329 && (! defined __cplusplus \
330 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
331 && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
332
333/* A type that is properly aligned for any stack member. */
334union yyalloc
335{
336 yytype_int16 yyss;
337 YYSTYPE yyvs;
338 YYLTYPE yyls;
339};
340
341/* The size of the maximum gap between one aligned stack and the next. */
342# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
343
344/* The size of an array large to enough to hold all stacks, each with
345 N elements. */
346# define YYSTACK_BYTES(N) \
347 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
348 + 2 * YYSTACK_GAP_MAXIMUM)
349
350/* Copy COUNT objects from FROM to TO. The source and destination do
351 not overlap. */
352# ifndef YYCOPY
353# if defined __GNUC__ && 1 < __GNUC__
354# define YYCOPY(To, From, Count) \
355 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
356# else
357# define YYCOPY(To, From, Count) \
358 do \
359 { \
360 YYSIZE_T yyi; \
361 for (yyi = 0; yyi < (Count); yyi++) \
362 (To)[yyi] = (From)[yyi]; \
363 } \
364 while (YYID (0))
365# endif
366# endif
367
368/* Relocate STACK from its old location to the new one. The
369 local variables YYSIZE and YYSTACKSIZE give the old and new number of
370 elements in the stack, and YYPTR gives the new location of the
371 stack. Advance YYPTR to a properly aligned location for the next
372 stack. */
373# define YYSTACK_RELOCATE(Stack) \
374 do \
375 { \
376 YYSIZE_T yynewbytes; \
377 YYCOPY (&yyptr->Stack, Stack, yysize); \
378 Stack = &yyptr->Stack; \
379 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
380 yyptr += yynewbytes / sizeof (*yyptr); \
381 } \
382 while (YYID (0))
383
384#endif
385
386/* YYFINAL -- State number of the termination state. */
387#define YYFINAL 9
388/* YYLAST -- Last index in YYTABLE. */
389#define YYLAST 60
390
391/* YYNTOKENS -- Number of terminals. */
392#define YYNTOKENS 24
393/* YYNNTS -- Number of nonterminals. */
394#define YYNNTS 20
395/* YYNRULES -- Number of rules. */
396#define YYNRULES 43
397/* YYNRULES -- Number of states. */
398#define YYNSTATES 67
399
400/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
401#define YYUNDEFTOK 2
402#define YYMAXUTOK 267
403
404#define YYTRANSLATE(YYX) \
405 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
406
407/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
408static const yytype_uint8 yytranslate[] =
409{
410 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
411 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
412 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
413 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
414 2, 2, 2, 2, 23, 14, 2, 15, 2, 2,
415 2, 2, 2, 2, 2, 2, 2, 2, 2, 13,
416 19, 18, 20, 2, 2, 2, 2, 2, 2, 2,
417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
419 2, 21, 2, 22, 2, 2, 2, 2, 2, 2,
420 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
421 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
422 2, 2, 2, 16, 2, 17, 2, 2, 2, 2,
423 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
424 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
425 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
426 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
427 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
428 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
429 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
430 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
431 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
432 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
433 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
434 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
435 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
436 5, 6, 7, 8, 9, 10, 11, 12
437};
438
439#if YYDEBUG
440/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
441 YYRHS. */
442static const yytype_uint8 yyprhs[] =
443{
444 0, 0, 3, 8, 11, 12, 15, 21, 22, 25,
445 27, 34, 36, 38, 41, 47, 48, 51, 57, 61,
446 64, 69, 74, 77, 80, 81, 84, 87, 88, 91,
447 94, 97, 98, 100, 102, 105, 106, 109, 112, 113,
448 116, 119, 123, 124
449};
450
451/* YYRHS -- A `-1'-separated list of the rules' RHS. */
452static const yytype_int8 yyrhs[] =
453{
454 25, 0, -1, 3, 13, 26, 31, -1, 28, 31,
455 -1, -1, 27, 26, -1, 43, 4, 30, 30, 13,
456 -1, -1, 29, 28, -1, 27, -1, 43, 4, 30,
457 14, 30, 13, -1, 6, -1, 7, -1, 15, 32,
458 -1, 16, 33, 41, 17, 13, -1, -1, 33, 34,
459 -1, 43, 5, 18, 35, 13, -1, 43, 5, 13,
460 -1, 36, 10, -1, 36, 19, 37, 20, -1, 36,
461 21, 40, 22, -1, 36, 12, -1, 35, 11, -1,
462 -1, 35, 23, -1, 36, 11, -1, -1, 37, 39,
463 -1, 37, 12, -1, 37, 11, -1, -1, 8, -1,
464 6, -1, 38, 7, -1, -1, 40, 9, -1, 40,
465 11, -1, -1, 42, 41, -1, 42, 34, -1, 43,
466 5, 32, -1, -1, 11, -1
467};
468
469/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
470static const yytype_uint16 yyrline[] =
471{
472 0, 85, 85, 89, 97, 100, 107, 115, 118, 125,
473 129, 136, 140, 147, 154, 162, 165, 172, 176, 183,
474 187, 191, 195, 199, 207, 210, 214, 222, 225, 229,
475 234, 242, 245, 249, 253, 261, 264, 268, 276, 279,
476 283, 291, 299, 302
477};
478#endif
479
480#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
481/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
482 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
483static const char *const yytname[] =
484{
485 "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
486 "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE",
487 "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "';'", "'-'", "'/'", "'{'",
488 "'}'", "'='", "'<'", "'>'", "'['", "']'", "','", "$accept", "sourcefile",
489 "memreserves", "memreserve", "v0_memreserves", "v0_memreserve", "addr",
490 "devicetree", "nodedef", "proplist", "propdef", "propdata",
491 "propdataprefix", "celllist", "cellbase", "cellval", "bytestring",
492 "subnodes", "subnode", "label", 0
493};
494#endif
495
496# ifdef YYPRINT
497/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
498 token YYLEX-NUM. */
499static const yytype_uint16 yytoknum[] =
500{
501 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
502 265, 266, 267, 59, 45, 47, 123, 125, 61, 60,
503 62, 91, 93, 44
504};
505# endif
506
507/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
508static const yytype_uint8 yyr1[] =
509{
510 0, 24, 25, 25, 26, 26, 27, 28, 28, 29,
511 29, 30, 30, 31, 32, 33, 33, 34, 34, 35,
512 35, 35, 35, 35, 36, 36, 36, 37, 37, 37,
513 37, 38, 38, 39, 39, 40, 40, 40, 41, 41,
514 41, 42, 43, 43
515};
516
517/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
518static const yytype_uint8 yyr2[] =
519{
520 0, 2, 4, 2, 0, 2, 5, 0, 2, 1,
521 6, 1, 1, 2, 5, 0, 2, 5, 3, 2,
522 4, 4, 2, 2, 0, 2, 2, 0, 2, 2,
523 2, 0, 1, 1, 2, 0, 2, 2, 0, 2,
524 2, 3, 0, 1
525};
526
527/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
528 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
529 means the default is an error. */
530static const yytype_uint8 yydefact[] =
531{
532 7, 0, 43, 0, 9, 0, 7, 0, 4, 1,
533 0, 3, 8, 0, 0, 4, 0, 15, 13, 11,
534 12, 0, 2, 5, 0, 38, 0, 0, 0, 16,
535 0, 38, 0, 0, 6, 0, 40, 39, 0, 10,
536 14, 18, 24, 41, 0, 0, 23, 17, 25, 19,
537 26, 22, 27, 35, 31, 0, 33, 32, 30, 29,
538 20, 0, 28, 36, 37, 21, 34
539};
540
541/* YYDEFGOTO[NTERM-NUM]. */
542static const yytype_int8 yydefgoto[] =
543{
544 -1, 3, 14, 4, 5, 6, 27, 11, 18, 25,
545 29, 44, 45, 54, 61, 62, 55, 30, 31, 7
546};
547
548/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
549 STATE-NUM. */
550#define YYPACT_NINF -13
551static const yytype_int8 yypact[] =
552{
553 23, 11, -13, 37, -13, -4, 18, 39, 18, -13,
554 28, -13, -13, 34, -4, 18, 41, -13, -13, -13,
555 -13, 25, -13, -13, 34, -3, 34, 33, 34, -13,
556 30, -3, 43, 36, -13, 38, -13, -13, 20, -13,
557 -13, -13, -13, -13, 2, 9, -13, -13, -13, -13,
558 -13, -13, -13, -13, -2, -6, -13, -13, -13, -13,
559 -13, 45, -13, -13, -13, -13, -13
560};
561
562/* YYPGOTO[NTERM-NUM]. */
563static const yytype_int8 yypgoto[] =
564{
565 -13, -13, 35, 27, 47, -13, -12, 40, 17, -13,
566 26, -13, -13, -13, -13, -13, -13, 29, -13, -8
567};
568
569/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
570 positive, shift that token. If negative, reduce the rule which
571 number is the opposite. If zero, do what YYDEFACT says.
572 If YYTABLE_NINF, syntax error. */
573#define YYTABLE_NINF -43
574static const yytype_int8 yytable[] =
575{
576 16, 21, -42, 63, 56, 64, 57, 16, 2, 58,
577 59, 10, 28, 46, 33, 47, 65, 32, 60, 49,
578 50, 51, -42, 32, 8, 48, 1, -42, 52, 2,
579 53, 19, 20, 41, 2, 15, 17, 9, 42, 26,
580 19, 20, 15, 13, 17, 24, 34, 35, 38, 39,
581 23, 40, 66, 12, 22, 43, 0, 36, 0, 0,
582 37
583};
584
585static const yytype_int8 yycheck[] =
586{
587 8, 13, 5, 9, 6, 11, 8, 15, 11, 11,
588 12, 15, 24, 11, 26, 13, 22, 25, 20, 10,
589 11, 12, 4, 31, 13, 23, 3, 4, 19, 11,
590 21, 6, 7, 13, 11, 8, 16, 0, 18, 14,
591 6, 7, 15, 4, 16, 4, 13, 17, 5, 13,
592 15, 13, 7, 6, 14, 38, -1, 31, -1, -1,
593 31
594};
595
596/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
597 symbol of state STATE-NUM. */
598static const yytype_uint8 yystos[] =
599{
600 0, 3, 11, 25, 27, 28, 29, 43, 13, 0,
601 15, 31, 28, 4, 26, 27, 43, 16, 32, 6,
602 7, 30, 31, 26, 4, 33, 14, 30, 30, 34,
603 41, 42, 43, 30, 13, 17, 34, 41, 5, 13,
604 13, 13, 18, 32, 35, 36, 11, 13, 23, 10,
605 11, 12, 19, 21, 37, 40, 6, 8, 11, 12,
606 20, 38, 39, 9, 11, 22, 7
607};
608
609#define yyerrok (yyerrstatus = 0)
610#define yyclearin (yychar = YYEMPTY)
611#define YYEMPTY (-2)
612#define YYEOF 0
613
614#define YYACCEPT goto yyacceptlab
615#define YYABORT goto yyabortlab
616#define YYERROR goto yyerrorlab
617
618
619/* Like YYERROR except do call yyerror. This remains here temporarily
620 to ease the transition to the new meaning of YYERROR, for GCC.
621 Once GCC version 2 has supplanted version 1, this can go. */
622
623#define YYFAIL goto yyerrlab
624
625#define YYRECOVERING() (!!yyerrstatus)
626
627#define YYBACKUP(Token, Value) \
628do \
629 if (yychar == YYEMPTY && yylen == 1) \
630 { \
631 yychar = (Token); \
632 yylval = (Value); \
633 yytoken = YYTRANSLATE (yychar); \
634 YYPOPSTACK (1); \
635 goto yybackup; \
636 } \
637 else \
638 { \
639 yyerror (YY_("syntax error: cannot back up")); \
640 YYERROR; \
641 } \
642while (YYID (0))
643
644
645#define YYTERROR 1
646#define YYERRCODE 256
647
648
649/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
650 If N is 0, then set CURRENT to the empty location which ends
651 the previous symbol: RHS[0] (always defined). */
652
653#define YYRHSLOC(Rhs, K) ((Rhs)[K])
654#ifndef YYLLOC_DEFAULT
655# define YYLLOC_DEFAULT(Current, Rhs, N) \
656 do \
657 if (YYID (N)) \
658 { \
659 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
660 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
661 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
662 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
663 } \
664 else \
665 { \
666 (Current).first_line = (Current).last_line = \
667 YYRHSLOC (Rhs, 0).last_line; \
668 (Current).first_column = (Current).last_column = \
669 YYRHSLOC (Rhs, 0).last_column; \
670 } \
671 while (YYID (0))
672#endif
673
674
675/* YY_LOCATION_PRINT -- Print the location on the stream.
676 This macro was not mandated originally: define only if we know
677 we won't break user code: when these are the locations we know. */
678
679#ifndef YY_LOCATION_PRINT
680# if YYLTYPE_IS_TRIVIAL
681# define YY_LOCATION_PRINT(File, Loc) \
682 fprintf (File, "%d.%d-%d.%d", \
683 (Loc).first_line, (Loc).first_column, \
684 (Loc).last_line, (Loc).last_column)
685# else
686# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
687# endif
688#endif
689
690
691/* YYLEX -- calling `yylex' with the right arguments. */
692
693#ifdef YYLEX_PARAM
694# define YYLEX yylex (YYLEX_PARAM)
695#else
696# define YYLEX yylex ()
697#endif
698
699/* Enable debugging if requested. */
700#if YYDEBUG
701
702# ifndef YYFPRINTF
703# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
704# define YYFPRINTF fprintf
705# endif
706
707# define YYDPRINTF(Args) \
708do { \
709 if (yydebug) \
710 YYFPRINTF Args; \
711} while (YYID (0))
712
713# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
714do { \
715 if (yydebug) \
716 { \
717 YYFPRINTF (stderr, "%s ", Title); \
718 yy_symbol_print (stderr, \
719 Type, Value, Location); \
720 YYFPRINTF (stderr, "\n"); \
721 } \
722} while (YYID (0))
723
724
725/*--------------------------------.
726| Print this symbol on YYOUTPUT. |
727`--------------------------------*/
728
729/*ARGSUSED*/
730#if (defined __STDC__ || defined __C99__FUNC__ \
731 || defined __cplusplus || defined _MSC_VER)
732static void
733yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
734#else
735static void
736yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
737 FILE *yyoutput;
738 int yytype;
739 YYSTYPE const * const yyvaluep;
740 YYLTYPE const * const yylocationp;
741#endif
742{
743 if (!yyvaluep)
744 return;
745 YYUSE (yylocationp);
746# ifdef YYPRINT
747 if (yytype < YYNTOKENS)
748 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
749# else
750 YYUSE (yyoutput);
751# endif
752 switch (yytype)
753 {
754 default:
755 break;
756 }
757}
758
759
760/*--------------------------------.
761| Print this symbol on YYOUTPUT. |
762`--------------------------------*/
763
764#if (defined __STDC__ || defined __C99__FUNC__ \
765 || defined __cplusplus || defined _MSC_VER)
766static void
767yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
768#else
769static void
770yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
771 FILE *yyoutput;
772 int yytype;
773 YYSTYPE const * const yyvaluep;
774 YYLTYPE const * const yylocationp;
775#endif
776{
777 if (yytype < YYNTOKENS)
778 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
779 else
780 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
781
782 YY_LOCATION_PRINT (yyoutput, *yylocationp);
783 YYFPRINTF (yyoutput, ": ");
784 yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
785 YYFPRINTF (yyoutput, ")");
786}
787
788/*------------------------------------------------------------------.
789| yy_stack_print -- Print the state stack from its BOTTOM up to its |
790| TOP (included). |
791`------------------------------------------------------------------*/
792
793#if (defined __STDC__ || defined __C99__FUNC__ \
794 || defined __cplusplus || defined _MSC_VER)
795static void
796yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
797#else
798static void
799yy_stack_print (bottom, top)
800 yytype_int16 *bottom;
801 yytype_int16 *top;
802#endif
803{
804 YYFPRINTF (stderr, "Stack now");
805 for (; bottom <= top; ++bottom)
806 YYFPRINTF (stderr, " %d", *bottom);
807 YYFPRINTF (stderr, "\n");
808}
809
810# define YY_STACK_PRINT(Bottom, Top) \
811do { \
812 if (yydebug) \
813 yy_stack_print ((Bottom), (Top)); \
814} while (YYID (0))
815
816
817/*------------------------------------------------.
818| Report that the YYRULE is going to be reduced. |
819`------------------------------------------------*/
820
821#if (defined __STDC__ || defined __C99__FUNC__ \
822 || defined __cplusplus || defined _MSC_VER)
823static void
824yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
825#else
826static void
827yy_reduce_print (yyvsp, yylsp, yyrule)
828 YYSTYPE *yyvsp;
829 YYLTYPE *yylsp;
830 int yyrule;
831#endif
832{
833 int yynrhs = yyr2[yyrule];
834 int yyi;
835 unsigned long int yylno = yyrline[yyrule];
836 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
837 yyrule - 1, yylno);
838 /* The symbols being reduced. */
839 for (yyi = 0; yyi < yynrhs; yyi++)
840 {
841 fprintf (stderr, " $%d = ", yyi + 1);
842 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
843 &(yyvsp[(yyi + 1) - (yynrhs)])
844 , &(yylsp[(yyi + 1) - (yynrhs)]) );
845 fprintf (stderr, "\n");
846 }
847}
848
849# define YY_REDUCE_PRINT(Rule) \
850do { \
851 if (yydebug) \
852 yy_reduce_print (yyvsp, yylsp, Rule); \
853} while (YYID (0))
854
855/* Nonzero means print parse trace. It is left uninitialized so that
856 multiple parsers can coexist. */
857int yydebug;
858#else /* !YYDEBUG */
859# define YYDPRINTF(Args)
860# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
861# define YY_STACK_PRINT(Bottom, Top)
862# define YY_REDUCE_PRINT(Rule)
863#endif /* !YYDEBUG */
864
865
866/* YYINITDEPTH -- initial size of the parser's stacks. */
867#ifndef YYINITDEPTH
868# define YYINITDEPTH 200
869#endif
870
871/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
872 if the built-in stack extension method is used).
873
874 Do not make this value too large; the results are undefined if
875 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
876 evaluated with infinite-precision integer arithmetic. */
877
878#ifndef YYMAXDEPTH
879# define YYMAXDEPTH 10000
880#endif
881
882
883
884#if YYERROR_VERBOSE
885
886# ifndef yystrlen
887# if defined __GLIBC__ && defined _STRING_H
888# define yystrlen strlen
889# else
890/* Return the length of YYSTR. */
891#if (defined __STDC__ || defined __C99__FUNC__ \
892 || defined __cplusplus || defined _MSC_VER)
893static YYSIZE_T
894yystrlen (const char *yystr)
895#else
896static YYSIZE_T
897yystrlen (yystr)
898 const char *yystr;
899#endif
900{
901 YYSIZE_T yylen;
902 for (yylen = 0; yystr[yylen]; yylen++)
903 continue;
904 return yylen;
905}
906# endif
907# endif
908
909# ifndef yystpcpy
910# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
911# define yystpcpy stpcpy
912# else
913/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
914 YYDEST. */
915#if (defined __STDC__ || defined __C99__FUNC__ \
916 || defined __cplusplus || defined _MSC_VER)
917static char *
918yystpcpy (char *yydest, const char *yysrc)
919#else
920static char *
921yystpcpy (yydest, yysrc)
922 char *yydest;
923 const char *yysrc;
924#endif
925{
926 char *yyd = yydest;
927 const char *yys = yysrc;
928
929 while ((*yyd++ = *yys++) != '\0')
930 continue;
931
932 return yyd - 1;
933}
934# endif
935# endif
936
937# ifndef yytnamerr
938/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
939 quotes and backslashes, so that it's suitable for yyerror. The
940 heuristic is that double-quoting is unnecessary unless the string
941 contains an apostrophe, a comma, or backslash (other than
942 backslash-backslash). YYSTR is taken from yytname. If YYRES is
943 null, do not copy; instead, return the length of what the result
944 would have been. */
945static YYSIZE_T
946yytnamerr (char *yyres, const char *yystr)
947{
948 if (*yystr == '"')
949 {
950 YYSIZE_T yyn = 0;
951 char const *yyp = yystr;
952
953 for (;;)
954 switch (*++yyp)
955 {
956 case '\'':
957 case ',':
958 goto do_not_strip_quotes;
959
960 case '\\':
961 if (*++yyp != '\\')
962 goto do_not_strip_quotes;
963 /* Fall through. */
964 default:
965 if (yyres)
966 yyres[yyn] = *yyp;
967 yyn++;
968 break;
969
970 case '"':
971 if (yyres)
972 yyres[yyn] = '\0';
973 return yyn;
974 }
975 do_not_strip_quotes: ;
976 }
977
978 if (! yyres)
979 return yystrlen (yystr);
980
981 return yystpcpy (yyres, yystr) - yyres;
982}
983# endif
984
985/* Copy into YYRESULT an error message about the unexpected token
986 YYCHAR while in state YYSTATE. Return the number of bytes copied,
987 including the terminating null byte. If YYRESULT is null, do not
988 copy anything; just return the number of bytes that would be
989 copied. As a special case, return 0 if an ordinary "syntax error"
990 message will do. Return YYSIZE_MAXIMUM if overflow occurs during
991 size calculation. */
992static YYSIZE_T
993yysyntax_error (char *yyresult, int yystate, int yychar)
994{
995 int yyn = yypact[yystate];
996
997 if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
998 return 0;
999 else
1000 {
1001 int yytype = YYTRANSLATE (yychar);
1002 YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
1003 YYSIZE_T yysize = yysize0;
1004 YYSIZE_T yysize1;
1005 int yysize_overflow = 0;
1006 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1007 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1008 int yyx;
1009
1010# if 0
1011 /* This is so xgettext sees the translatable formats that are
1012 constructed on the fly. */
1013 YY_("syntax error, unexpected %s");
1014 YY_("syntax error, unexpected %s, expecting %s");
1015 YY_("syntax error, unexpected %s, expecting %s or %s");
1016 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1017 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1018# endif
1019 char *yyfmt;
1020 char const *yyf;
1021 static char const yyunexpected[] = "syntax error, unexpected %s";
1022 static char const yyexpecting[] = ", expecting %s";
1023 static char const yyor[] = " or %s";
1024 char yyformat[sizeof yyunexpected
1025 + sizeof yyexpecting - 1
1026 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1027 * (sizeof yyor - 1))];
1028 char const *yyprefix = yyexpecting;
1029
1030 /* Start YYX at -YYN if negative to avoid negative indexes in
1031 YYCHECK. */
1032 int yyxbegin = yyn < 0 ? -yyn : 0;
1033
1034 /* Stay within bounds of both yycheck and yytname. */
1035 int yychecklim = YYLAST - yyn + 1;
1036 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1037 int yycount = 1;
1038
1039 yyarg[0] = yytname[yytype];
1040 yyfmt = yystpcpy (yyformat, yyunexpected);
1041
1042 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1043 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1044 {
1045 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1046 {
1047 yycount = 1;
1048 yysize = yysize0;
1049 yyformat[sizeof yyunexpected - 1] = '\0';
1050 break;
1051 }
1052 yyarg[yycount++] = yytname[yyx];
1053 yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1054 yysize_overflow |= (yysize1 < yysize);
1055 yysize = yysize1;
1056 yyfmt = yystpcpy (yyfmt, yyprefix);
1057 yyprefix = yyor;
1058 }
1059
1060 yyf = YY_(yyformat);
1061 yysize1 = yysize + yystrlen (yyf);
1062 yysize_overflow |= (yysize1 < yysize);
1063 yysize = yysize1;
1064
1065 if (yysize_overflow)
1066 return YYSIZE_MAXIMUM;
1067
1068 if (yyresult)
1069 {
1070 /* Avoid sprintf, as that infringes on the user's name space.
1071 Don't have undefined behavior even if the translation
1072 produced a string with the wrong number of "%s"s. */
1073 char *yyp = yyresult;
1074 int yyi = 0;
1075 while ((*yyp = *yyf) != '\0')
1076 {
1077 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
1078 {
1079 yyp += yytnamerr (yyp, yyarg[yyi++]);
1080 yyf += 2;
1081 }
1082 else
1083 {
1084 yyp++;
1085 yyf++;
1086 }
1087 }
1088 }
1089 return yysize;
1090 }
1091}
1092#endif /* YYERROR_VERBOSE */
1093
1094
1095/*-----------------------------------------------.
1096| Release the memory associated to this symbol. |
1097`-----------------------------------------------*/
1098
1099/*ARGSUSED*/
1100#if (defined __STDC__ || defined __C99__FUNC__ \
1101 || defined __cplusplus || defined _MSC_VER)
1102static void
1103yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
1104#else
1105static void
1106yydestruct (yymsg, yytype, yyvaluep, yylocationp)
1107 const char *yymsg;
1108 int yytype;
1109 YYSTYPE *yyvaluep;
1110 YYLTYPE *yylocationp;
1111#endif
1112{
1113 YYUSE (yyvaluep);
1114 YYUSE (yylocationp);
1115
1116 if (!yymsg)
1117 yymsg = "Deleting";
1118 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1119
1120 switch (yytype)
1121 {
1122
1123 default:
1124 break;
1125 }
1126}
1127
1128
1129/* Prevent warnings from -Wmissing-prototypes. */
1130
1131#ifdef YYPARSE_PARAM
1132#if defined __STDC__ || defined __cplusplus
1133int yyparse (void *YYPARSE_PARAM);
1134#else
1135int yyparse ();
1136#endif
1137#else /* ! YYPARSE_PARAM */
1138#if defined __STDC__ || defined __cplusplus
1139int yyparse (void);
1140#else
1141int yyparse ();
1142#endif
1143#endif /* ! YYPARSE_PARAM */
1144
1145
1146
1147/* The look-ahead symbol. */
1148int yychar;
1149
1150/* The semantic value of the look-ahead symbol. */
1151YYSTYPE yylval;
1152
1153/* Number of syntax errors so far. */
1154int yynerrs;
1155/* Location data for the look-ahead symbol. */
1156YYLTYPE yylloc;
1157
1158
1159
1160/*----------.
1161| yyparse. |
1162`----------*/
1163
1164#ifdef YYPARSE_PARAM
1165#if (defined __STDC__ || defined __C99__FUNC__ \
1166 || defined __cplusplus || defined _MSC_VER)
1167int
1168yyparse (void *YYPARSE_PARAM)
1169#else
1170int
1171yyparse (YYPARSE_PARAM)
1172 void *YYPARSE_PARAM;
1173#endif
1174#else /* ! YYPARSE_PARAM */
1175#if (defined __STDC__ || defined __C99__FUNC__ \
1176 || defined __cplusplus || defined _MSC_VER)
1177int
1178yyparse (void)
1179#else
1180int
1181yyparse ()
1182
1183#endif
1184#endif
1185{
1186
1187 int yystate;
1188 int yyn;
1189 int yyresult;
1190 /* Number of tokens to shift before error messages enabled. */
1191 int yyerrstatus;
1192 /* Look-ahead token as an internal (translated) token number. */
1193 int yytoken = 0;
1194#if YYERROR_VERBOSE
1195 /* Buffer for error messages, and its allocated size. */
1196 char yymsgbuf[128];
1197 char *yymsg = yymsgbuf;
1198 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1199#endif
1200
1201 /* Three stacks and their tools:
1202 `yyss': related to states,
1203 `yyvs': related to semantic values,
1204 `yyls': related to locations.
1205
1206 Refer to the stacks thru separate pointers, to allow yyoverflow
1207 to reallocate them elsewhere. */
1208
1209 /* The state stack. */
1210 yytype_int16 yyssa[YYINITDEPTH];
1211 yytype_int16 *yyss = yyssa;
1212 yytype_int16 *yyssp;
1213
1214 /* The semantic value stack. */
1215 YYSTYPE yyvsa[YYINITDEPTH];
1216 YYSTYPE *yyvs = yyvsa;
1217 YYSTYPE *yyvsp;
1218
1219 /* The location stack. */
1220 YYLTYPE yylsa[YYINITDEPTH];
1221 YYLTYPE *yyls = yylsa;
1222 YYLTYPE *yylsp;
1223 /* The locations where the error started and ended. */
1224 YYLTYPE yyerror_range[2];
1225
1226#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
1227
1228 YYSIZE_T yystacksize = YYINITDEPTH;
1229
1230 /* The variables used to return semantic value and location from the
1231 action routines. */
1232 YYSTYPE yyval;
1233 YYLTYPE yyloc;
1234
1235 /* The number of symbols on the RHS of the reduced rule.
1236 Keep to zero when no symbol should be popped. */
1237 int yylen = 0;
1238
1239 YYDPRINTF ((stderr, "Starting parse\n"));
1240
1241 yystate = 0;
1242 yyerrstatus = 0;
1243 yynerrs = 0;
1244 yychar = YYEMPTY; /* Cause a token to be read. */
1245
1246 /* Initialize stack pointers.
1247 Waste one element of value and location stack
1248 so that they stay on the same level as the state stack.
1249 The wasted elements are never initialized. */
1250
1251 yyssp = yyss;
1252 yyvsp = yyvs;
1253 yylsp = yyls;
1254#if YYLTYPE_IS_TRIVIAL
1255 /* Initialize the default location before parsing starts. */
1256 yylloc.first_line = yylloc.last_line = 1;
1257 yylloc.first_column = yylloc.last_column = 0;
1258#endif
1259
1260 goto yysetstate;
1261
1262/*------------------------------------------------------------.
1263| yynewstate -- Push a new state, which is found in yystate. |
1264`------------------------------------------------------------*/
1265 yynewstate:
1266 /* In all cases, when you get here, the value and location stacks
1267 have just been pushed. So pushing a state here evens the stacks. */
1268 yyssp++;
1269
1270 yysetstate:
1271 *yyssp = yystate;
1272
1273 if (yyss + yystacksize - 1 <= yyssp)
1274 {
1275 /* Get the current used size of the three stacks, in elements. */
1276 YYSIZE_T yysize = yyssp - yyss + 1;
1277
1278#ifdef yyoverflow
1279 {
1280 /* Give user a chance to reallocate the stack. Use copies of
1281 these so that the &'s don't force the real ones into
1282 memory. */
1283 YYSTYPE *yyvs1 = yyvs;
1284 yytype_int16 *yyss1 = yyss;
1285 YYLTYPE *yyls1 = yyls;
1286
1287 /* Each stack pointer address is followed by the size of the
1288 data in use in that stack, in bytes. This used to be a
1289 conditional around just the two extra args, but that might
1290 be undefined if yyoverflow is a macro. */
1291 yyoverflow (YY_("memory exhausted"),
1292 &yyss1, yysize * sizeof (*yyssp),
1293 &yyvs1, yysize * sizeof (*yyvsp),
1294 &yyls1, yysize * sizeof (*yylsp),
1295 &yystacksize);
1296 yyls = yyls1;
1297 yyss = yyss1;
1298 yyvs = yyvs1;
1299 }
1300#else /* no yyoverflow */
1301# ifndef YYSTACK_RELOCATE
1302 goto yyexhaustedlab;
1303# else
1304 /* Extend the stack our own way. */
1305 if (YYMAXDEPTH <= yystacksize)
1306 goto yyexhaustedlab;
1307 yystacksize *= 2;
1308 if (YYMAXDEPTH < yystacksize)
1309 yystacksize = YYMAXDEPTH;
1310
1311 {
1312 yytype_int16 *yyss1 = yyss;
1313 union yyalloc *yyptr =
1314 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1315 if (! yyptr)
1316 goto yyexhaustedlab;
1317 YYSTACK_RELOCATE (yyss);
1318 YYSTACK_RELOCATE (yyvs);
1319 YYSTACK_RELOCATE (yyls);
1320# undef YYSTACK_RELOCATE
1321 if (yyss1 != yyssa)
1322 YYSTACK_FREE (yyss1);
1323 }
1324# endif
1325#endif /* no yyoverflow */
1326
1327 yyssp = yyss + yysize - 1;
1328 yyvsp = yyvs + yysize - 1;
1329 yylsp = yyls + yysize - 1;
1330
1331 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1332 (unsigned long int) yystacksize));
1333
1334 if (yyss + yystacksize - 1 <= yyssp)
1335 YYABORT;
1336 }
1337
1338 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1339
1340 goto yybackup;
1341
1342/*-----------.
1343| yybackup. |
1344`-----------*/
1345yybackup:
1346
1347 /* Do appropriate processing given the current state. Read a
1348 look-ahead token if we need one and don't already have one. */
1349
1350 /* First try to decide what to do without reference to look-ahead token. */
1351 yyn = yypact[yystate];
1352 if (yyn == YYPACT_NINF)
1353 goto yydefault;
1354
1355 /* Not known => get a look-ahead token if don't already have one. */
1356
1357 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1358 if (yychar == YYEMPTY)
1359 {
1360 YYDPRINTF ((stderr, "Reading a token: "));
1361 yychar = YYLEX;
1362 }
1363
1364 if (yychar <= YYEOF)
1365 {
1366 yychar = yytoken = YYEOF;
1367 YYDPRINTF ((stderr, "Now at end of input.\n"));
1368 }
1369 else
1370 {
1371 yytoken = YYTRANSLATE (yychar);
1372 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1373 }
1374
1375 /* If the proper action on seeing token YYTOKEN is to reduce or to
1376 detect an error, take that action. */
1377 yyn += yytoken;
1378 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1379 goto yydefault;
1380 yyn = yytable[yyn];
1381 if (yyn <= 0)
1382 {
1383 if (yyn == 0 || yyn == YYTABLE_NINF)
1384 goto yyerrlab;
1385 yyn = -yyn;
1386 goto yyreduce;
1387 }
1388
1389 if (yyn == YYFINAL)
1390 YYACCEPT;
1391
1392 /* Count tokens shifted since error; after three, turn off error
1393 status. */
1394 if (yyerrstatus)
1395 yyerrstatus--;
1396
1397 /* Shift the look-ahead token. */
1398 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1399
1400 /* Discard the shifted token unless it is eof. */
1401 if (yychar != YYEOF)
1402 yychar = YYEMPTY;
1403
1404 yystate = yyn;
1405 *++yyvsp = yylval;
1406 *++yylsp = yylloc;
1407 goto yynewstate;
1408
1409
1410/*-----------------------------------------------------------.
1411| yydefault -- do the default action for the current state. |
1412`-----------------------------------------------------------*/
1413yydefault:
1414 yyn = yydefact[yystate];
1415 if (yyn == 0)
1416 goto yyerrlab;
1417 goto yyreduce;
1418
1419
1420/*-----------------------------.
1421| yyreduce -- Do a reduction. |
1422`-----------------------------*/
1423yyreduce:
1424 /* yyn is the number of a rule to reduce with. */
1425 yylen = yyr2[yyn];
1426
1427 /* If YYLEN is nonzero, implement the default value of the action:
1428 `$$ = $1'.
1429
1430 Otherwise, the following line sets YYVAL to garbage.
1431 This behavior is undocumented and Bison
1432 users should not rely upon it. Assigning to YYVAL
1433 unconditionally makes the parser a bit smaller, and it avoids a
1434 GCC warning that YYVAL may be used uninitialized. */
1435 yyval = yyvsp[1-yylen];
1436
1437 /* Default location. */
1438 YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
1439 YY_REDUCE_PRINT (yyn);
1440 switch (yyn)
1441 {
1442 case 2:
1443#line 86 "dtc-parser.y"
1444 {
1445 the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node));
1446 ;}
1447 break;
1448
1449 case 3:
1450#line 90 "dtc-parser.y"
1451 {
1452 the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node));
1453 ;}
1454 break;
1455
1456 case 4:
1457#line 97 "dtc-parser.y"
1458 {
1459 (yyval.re) = NULL;
1460 ;}
1461 break;
1462
1463 case 5:
1464#line 101 "dtc-parser.y"
1465 {
1466 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
1467 ;}
1468 break;
1469
1470 case 6:
1471#line 108 "dtc-parser.y"
1472 {
1473 (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref));
1474 ;}
1475 break;
1476
1477 case 7:
1478#line 115 "dtc-parser.y"
1479 {
1480 (yyval.re) = NULL;
1481 ;}
1482 break;
1483
1484 case 8:
1485#line 119 "dtc-parser.y"
1486 {
1487 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
1488 ;}
1489 break;
1490
1491 case 9:
1492#line 126 "dtc-parser.y"
1493 {
1494 (yyval.re) = (yyvsp[(1) - (1)].re);
1495 ;}
1496 break;
1497
1498 case 10:
1499#line 130 "dtc-parser.y"
1500 {
1501 (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref));
1502 ;}
1503 break;
1504
1505 case 11:
1506#line 137 "dtc-parser.y"
1507 {
1508 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
1509 ;}
1510 break;
1511
1512 case 12:
1513#line 141 "dtc-parser.y"
1514 {
1515 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64);
1516 ;}
1517 break;
1518
1519 case 13:
1520#line 148 "dtc-parser.y"
1521 {
1522 (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL);
1523 ;}
1524 break;
1525
1526 case 14:
1527#line 155 "dtc-parser.y"
1528 {
1529 (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
1530 ;}
1531 break;
1532
1533 case 15:
1534#line 162 "dtc-parser.y"
1535 {
1536 (yyval.proplist) = NULL;
1537 ;}
1538 break;
1539
1540 case 16:
1541#line 166 "dtc-parser.y"
1542 {
1543 (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
1544 ;}
1545 break;
1546
1547 case 17:
1548#line 173 "dtc-parser.y"
1549 {
1550 (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref));
1551 ;}
1552 break;
1553
1554 case 18:
1555#line 177 "dtc-parser.y"
1556 {
1557 (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref));
1558 ;}
1559 break;
1560
1561 case 19:
1562#line 184 "dtc-parser.y"
1563 {
1564 (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
1565 ;}
1566 break;
1567
1568 case 20:
1569#line 188 "dtc-parser.y"
1570 {
1571 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1572 ;}
1573 break;
1574
1575 case 21:
1576#line 192 "dtc-parser.y"
1577 {
1578 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1579 ;}
1580 break;
1581
1582 case 22:
1583#line 196 "dtc-parser.y"
1584 {
1585 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
1586 ;}
1587 break;
1588
1589 case 23:
1590#line 200 "dtc-parser.y"
1591 {
1592 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1593 ;}
1594 break;
1595
1596 case 24:
1597#line 207 "dtc-parser.y"
1598 {
1599 (yyval.data) = empty_data;
1600 ;}
1601 break;
1602
1603 case 25:
1604#line 211 "dtc-parser.y"
1605 {
1606 (yyval.data) = (yyvsp[(1) - (2)].data);
1607 ;}
1608 break;
1609
1610 case 26:
1611#line 215 "dtc-parser.y"
1612 {
1613 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1614 ;}
1615 break;
1616
1617 case 27:
1618#line 222 "dtc-parser.y"
1619 {
1620 (yyval.data) = empty_data;
1621 ;}
1622 break;
1623
1624 case 28:
1625#line 226 "dtc-parser.y"
1626 {
1627 (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
1628 ;}
1629 break;
1630
1631 case 29:
1632#line 230 "dtc-parser.y"
1633 {
1634 (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
1635 (yyvsp[(2) - (2)].labelref)), -1);
1636 ;}
1637 break;
1638
1639 case 30:
1640#line 235 "dtc-parser.y"
1641 {
1642 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1643 ;}
1644 break;
1645
1646 case 31:
1647#line 242 "dtc-parser.y"
1648 {
1649 (yyval.cbase) = 16;
1650 ;}
1651 break;
1652
1653 case 33:
1654#line 250 "dtc-parser.y"
1655 {
1656 (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
1657 ;}
1658 break;
1659
1660 case 34:
1661#line 254 "dtc-parser.y"
1662 {
1663 (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32);
1664 ;}
1665 break;
1666
1667 case 35:
1668#line 261 "dtc-parser.y"
1669 {
1670 (yyval.data) = empty_data;
1671 ;}
1672 break;
1673
1674 case 36:
1675#line 265 "dtc-parser.y"
1676 {
1677 (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
1678 ;}
1679 break;
1680
1681 case 37:
1682#line 269 "dtc-parser.y"
1683 {
1684 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1685 ;}
1686 break;
1687
1688 case 38:
1689#line 276 "dtc-parser.y"
1690 {
1691 (yyval.nodelist) = NULL;
1692 ;}
1693 break;
1694
1695 case 39:
1696#line 280 "dtc-parser.y"
1697 {
1698 (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
1699 ;}
1700 break;
1701
1702 case 40:
1703#line 284 "dtc-parser.y"
1704 {
1705 yyerror("syntax error: properties must precede subnodes\n");
1706 YYERROR;
1707 ;}
1708 break;
1709
1710 case 41:
1711#line 292 "dtc-parser.y"
1712 {
1713 (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref));
1714 ;}
1715 break;
1716
1717 case 42:
1718#line 299 "dtc-parser.y"
1719 {
1720 (yyval.labelref) = NULL;
1721 ;}
1722 break;
1723
1724 case 43:
1725#line 303 "dtc-parser.y"
1726 {
1727 (yyval.labelref) = (yyvsp[(1) - (1)].labelref);
1728 ;}
1729 break;
1730
1731
1732/* Line 1267 of yacc.c. */
1733#line 1734 "dtc-parser.tab.c"
1734 default: break;
1735 }
1736 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1737
1738 YYPOPSTACK (yylen);
1739 yylen = 0;
1740 YY_STACK_PRINT (yyss, yyssp);
1741
1742 *++yyvsp = yyval;
1743 *++yylsp = yyloc;
1744
1745 /* Now `shift' the result of the reduction. Determine what state
1746 that goes to, based on the state we popped back to and the rule
1747 number reduced by. */
1748
1749 yyn = yyr1[yyn];
1750
1751 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1752 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1753 yystate = yytable[yystate];
1754 else
1755 yystate = yydefgoto[yyn - YYNTOKENS];
1756
1757 goto yynewstate;
1758
1759
1760/*------------------------------------.
1761| yyerrlab -- here on detecting error |
1762`------------------------------------*/
1763yyerrlab:
1764 /* If not already recovering from an error, report this error. */
1765 if (!yyerrstatus)
1766 {
1767 ++yynerrs;
1768#if ! YYERROR_VERBOSE
1769 yyerror (YY_("syntax error"));
1770#else
1771 {
1772 YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
1773 if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
1774 {
1775 YYSIZE_T yyalloc = 2 * yysize;
1776 if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
1777 yyalloc = YYSTACK_ALLOC_MAXIMUM;
1778 if (yymsg != yymsgbuf)
1779 YYSTACK_FREE (yymsg);
1780 yymsg = (char *) YYSTACK_ALLOC (yyalloc);
1781 if (yymsg)
1782 yymsg_alloc = yyalloc;
1783 else
1784 {
1785 yymsg = yymsgbuf;
1786 yymsg_alloc = sizeof yymsgbuf;
1787 }
1788 }
1789
1790 if (0 < yysize && yysize <= yymsg_alloc)
1791 {
1792 (void) yysyntax_error (yymsg, yystate, yychar);
1793 yyerror (yymsg);
1794 }
1795 else
1796 {
1797 yyerror (YY_("syntax error"));
1798 if (yysize != 0)
1799 goto yyexhaustedlab;
1800 }
1801 }
1802#endif
1803 }
1804
1805 yyerror_range[0] = yylloc;
1806
1807 if (yyerrstatus == 3)
1808 {
1809 /* If just tried and failed to reuse look-ahead token after an
1810 error, discard it. */
1811
1812 if (yychar <= YYEOF)
1813 {
1814 /* Return failure if at end of input. */
1815 if (yychar == YYEOF)
1816 YYABORT;
1817 }
1818 else
1819 {
1820 yydestruct ("Error: discarding",
1821 yytoken, &yylval, &yylloc);
1822 yychar = YYEMPTY;
1823 }
1824 }
1825
1826 /* Else will try to reuse look-ahead token after shifting the error
1827 token. */
1828 goto yyerrlab1;
1829
1830
1831/*---------------------------------------------------.
1832| yyerrorlab -- error raised explicitly by YYERROR. |
1833`---------------------------------------------------*/
1834yyerrorlab:
1835
1836 /* Pacify compilers like GCC when the user code never invokes
1837 YYERROR and the label yyerrorlab therefore never appears in user
1838 code. */
1839 if (/*CONSTCOND*/ 0)
1840 goto yyerrorlab;
1841
1842 yyerror_range[0] = yylsp[1-yylen];
1843 /* Do not reclaim the symbols of the rule which action triggered
1844 this YYERROR. */
1845 YYPOPSTACK (yylen);
1846 yylen = 0;
1847 YY_STACK_PRINT (yyss, yyssp);
1848 yystate = *yyssp;
1849 goto yyerrlab1;
1850
1851
1852/*-------------------------------------------------------------.
1853| yyerrlab1 -- common code for both syntax error and YYERROR. |
1854`-------------------------------------------------------------*/
1855yyerrlab1:
1856 yyerrstatus = 3; /* Each real token shifted decrements this. */
1857
1858 for (;;)
1859 {
1860 yyn = yypact[yystate];
1861 if (yyn != YYPACT_NINF)
1862 {
1863 yyn += YYTERROR;
1864 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1865 {
1866 yyn = yytable[yyn];
1867 if (0 < yyn)
1868 break;
1869 }
1870 }
1871
1872 /* Pop the current state because it cannot handle the error token. */
1873 if (yyssp == yyss)
1874 YYABORT;
1875
1876 yyerror_range[0] = *yylsp;
1877 yydestruct ("Error: popping",
1878 yystos[yystate], yyvsp, yylsp);
1879 YYPOPSTACK (1);
1880 yystate = *yyssp;
1881 YY_STACK_PRINT (yyss, yyssp);
1882 }
1883
1884 if (yyn == YYFINAL)
1885 YYACCEPT;
1886
1887 *++yyvsp = yylval;
1888
1889 yyerror_range[1] = yylloc;
1890 /* Using YYLLOC is tempting, but would change the location of
1891 the look-ahead. YYLOC is available though. */
1892 YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
1893 *++yylsp = yyloc;
1894
1895 /* Shift the error token. */
1896 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1897
1898 yystate = yyn;
1899 goto yynewstate;
1900
1901
1902/*-------------------------------------.
1903| yyacceptlab -- YYACCEPT comes here. |
1904`-------------------------------------*/
1905yyacceptlab:
1906 yyresult = 0;
1907 goto yyreturn;
1908
1909/*-----------------------------------.
1910| yyabortlab -- YYABORT comes here. |
1911`-----------------------------------*/
1912yyabortlab:
1913 yyresult = 1;
1914 goto yyreturn;
1915
1916#ifndef yyoverflow
1917/*-------------------------------------------------.
1918| yyexhaustedlab -- memory exhaustion comes here. |
1919`-------------------------------------------------*/
1920yyexhaustedlab:
1921 yyerror (YY_("memory exhausted"));
1922 yyresult = 2;
1923 /* Fall through. */
1924#endif
1925
1926yyreturn:
1927 if (yychar != YYEOF && yychar != YYEMPTY)
1928 yydestruct ("Cleanup: discarding lookahead",
1929 yytoken, &yylval, &yylloc);
1930 /* Do not reclaim the symbols of the rule which action triggered
1931 this YYABORT or YYACCEPT. */
1932 YYPOPSTACK (yylen);
1933 YY_STACK_PRINT (yyss, yyssp);
1934 while (yyssp != yyss)
1935 {
1936 yydestruct ("Cleanup: popping",
1937 yystos[*yyssp], yyvsp, yylsp);
1938 YYPOPSTACK (1);
1939 }
1940#ifndef yyoverflow
1941 if (yyss != yyssa)
1942 YYSTACK_FREE (yyss);
1943#endif
1944#if YYERROR_VERBOSE
1945 if (yymsg != yymsgbuf)
1946 YYSTACK_FREE (yymsg);
1947#endif
1948 /* Make sure YYID is used. */
1949 return YYID (yyresult);
1950}
1951
1952
1953#line 308 "dtc-parser.y"
1954
1955
1956void yyerror (char const *s)
1957{
1958 const char *fname = srcpos_filename_for_num(yylloc.filenum);
1959
1960 if (strcmp(fname, "-") == 0)
1961 fname = "stdin";
1962
1963 fprintf(stderr, "%s:%d %s\n",
1964 fname, yylloc.first_line, s);
1965}
1966
1967unsigned long long eval_literal(const char *s, int base, int bits)
1968{
1969 unsigned long long val;
1970 char *e;
1971
1972 errno = 0;
1973 val = strtoull(s, &e, base);
1974 if (*e)
1975 yyerror("bad characters in literal");
1976 else if ((errno == ERANGE)
1977 || ((bits < 64) && (val >= (1ULL << bits))))
1978 yyerror("literal out of range");
1979 else if (errno != 0)
1980 yyerror("bad literal");
1981 return val;
1982}
1983
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped b/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
new file mode 100644
index 000000000000..4707b029ed25
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
@@ -0,0 +1,111 @@
1/* A Bison parser, made by GNU Bison 2.3. */
2
3/* Skeleton interface for Bison's Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23/* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work
25 under terms of your choice, so long as that work isn't itself a
26 parser generator using the skeleton or a modified version thereof
27 as a parser skeleton. Alternatively, if you modify or redistribute
28 the parser skeleton itself, you may (at your option) remove this
29 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public
31 License without this special exception.
32
33 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */
35
36/* Tokens. */
37#ifndef YYTOKENTYPE
38# define YYTOKENTYPE
39 /* Put the tokens into the symbol table, so that GDB and other debuggers
40 know about them. */
41 enum yytokentype {
42 DT_V1 = 258,
43 DT_MEMRESERVE = 259,
44 DT_PROPNODENAME = 260,
45 DT_LITERAL = 261,
46 DT_LEGACYLITERAL = 262,
47 DT_BASE = 263,
48 DT_BYTE = 264,
49 DT_STRING = 265,
50 DT_LABEL = 266,
51 DT_REF = 267
52 };
53#endif
54/* Tokens. */
55#define DT_V1 258
56#define DT_MEMRESERVE 259
57#define DT_PROPNODENAME 260
58#define DT_LITERAL 261
59#define DT_LEGACYLITERAL 262
60#define DT_BASE 263
61#define DT_BYTE 264
62#define DT_STRING 265
63#define DT_LABEL 266
64#define DT_REF 267
65
66
67
68
69#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
70typedef union YYSTYPE
71#line 34 "dtc-parser.y"
72{
73 char *propnodename;
74 char *literal;
75 char *labelref;
76 unsigned int cbase;
77 u8 byte;
78 struct data data;
79
80 u64 addr;
81 cell_t cell;
82 struct property *prop;
83 struct property *proplist;
84 struct node *node;
85 struct node *nodelist;
86 struct reserve_info *re;
87}
88/* Line 1489 of yacc.c. */
89#line 90 "dtc-parser.tab.h"
90 YYSTYPE;
91# define yystype YYSTYPE /* obsolescent; will be withdrawn */
92# define YYSTYPE_IS_DECLARED 1
93# define YYSTYPE_IS_TRIVIAL 1
94#endif
95
96extern YYSTYPE yylval;
97
98#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
99typedef struct YYLTYPE
100{
101 int first_line;
102 int first_column;
103 int last_line;
104 int last_column;
105} YYLTYPE;
106# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
107# define YYLTYPE_IS_DECLARED 1
108# define YYLTYPE_IS_TRIVIAL 1
109#endif
110
111extern YYLTYPE yylloc;
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.y b/arch/powerpc/boot/dtc-src/dtc-parser.y
new file mode 100644
index 000000000000..002ea7fef184
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.y
@@ -0,0 +1,336 @@
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%locations
22
23%{
24#include "dtc.h"
25#include "srcpos.h"
26
27int yylex(void);
28unsigned long long eval_literal(const char *s, int base, int bits);
29
30extern struct boot_info *the_boot_info;
31
32%}
33
34%union {
35 char *propnodename;
36 char *literal;
37 char *labelref;
38 unsigned int cbase;
39 u8 byte;
40 struct data data;
41
42 u64 addr;
43 cell_t cell;
44 struct property *prop;
45 struct property *proplist;
46 struct node *node;
47 struct node *nodelist;
48 struct reserve_info *re;
49}
50
51%token DT_V1
52%token DT_MEMRESERVE
53%token <propnodename> DT_PROPNODENAME
54%token <literal> DT_LITERAL
55%token <literal> DT_LEGACYLITERAL
56%token <cbase> DT_BASE
57%token <byte> DT_BYTE
58%token <data> DT_STRING
59%token <labelref> DT_LABEL
60%token <labelref> DT_REF
61
62%type <data> propdata
63%type <data> propdataprefix
64%type <re> memreserve
65%type <re> memreserves
66%type <re> v0_memreserve
67%type <re> v0_memreserves
68%type <addr> addr
69%type <data> celllist
70%type <cbase> cellbase
71%type <cell> cellval
72%type <data> bytestring
73%type <prop> propdef
74%type <proplist> proplist
75
76%type <node> devicetree
77%type <node> nodedef
78%type <node> subnode
79%type <nodelist> subnodes
80%type <labelref> label
81
82%%
83
84sourcefile:
85 DT_V1 ';' memreserves devicetree
86 {
87 the_boot_info = build_boot_info($3, $4);
88 }
89 | v0_memreserves devicetree
90 {
91 the_boot_info = build_boot_info($1, $2);
92 }
93 ;
94
95memreserves:
96 /* empty */
97 {
98 $$ = NULL;
99 }
100 | memreserve memreserves
101 {
102 $$ = chain_reserve_entry($1, $2);
103 }
104 ;
105
106memreserve:
107 label DT_MEMRESERVE addr addr ';'
108 {
109 $$ = build_reserve_entry($3, $4, $1);
110 }
111 ;
112
113v0_memreserves:
114 /* empty */
115 {
116 $$ = NULL;
117 }
118 | v0_memreserve v0_memreserves
119 {
120 $$ = chain_reserve_entry($1, $2);
121 };
122 ;
123
124v0_memreserve:
125 memreserve
126 {
127 $$ = $1;
128 }
129 | label DT_MEMRESERVE addr '-' addr ';'
130 {
131 $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
132 }
133 ;
134
135addr:
136 DT_LITERAL
137 {
138 $$ = eval_literal($1, 0, 64);
139 }
140 | DT_LEGACYLITERAL
141 {
142 $$ = eval_literal($1, 16, 64);
143 }
144 ;
145
146devicetree:
147 '/' nodedef
148 {
149 $$ = name_node($2, "", NULL);
150 }
151 ;
152
153nodedef:
154 '{' proplist subnodes '}' ';'
155 {
156 $$ = build_node($2, $3);
157 }
158 ;
159
160proplist:
161 /* empty */
162 {
163 $$ = NULL;
164 }
165 | proplist propdef
166 {
167 $$ = chain_property($2, $1);
168 }
169 ;
170
171propdef:
172 label DT_PROPNODENAME '=' propdata ';'
173 {
174 $$ = build_property($2, $4, $1);
175 }
176 | label DT_PROPNODENAME ';'
177 {
178 $$ = build_property($2, empty_data, $1);
179 }
180 ;
181
182propdata:
183 propdataprefix DT_STRING
184 {
185 $$ = data_merge($1, $2);
186 }
187 | propdataprefix '<' celllist '>'
188 {
189 $$ = data_merge($1, $3);
190 }
191 | propdataprefix '[' bytestring ']'
192 {
193 $$ = data_merge($1, $3);
194 }
195 | propdataprefix DT_REF
196 {
197 $$ = data_add_marker($1, REF_PATH, $2);
198 }
199 | propdata DT_LABEL
200 {
201 $$ = data_add_marker($1, LABEL, $2);
202 }
203 ;
204
205propdataprefix:
206 /* empty */
207 {
208 $$ = empty_data;
209 }
210 | propdata ','
211 {
212 $$ = $1;
213 }
214 | propdataprefix DT_LABEL
215 {
216 $$ = data_add_marker($1, LABEL, $2);
217 }
218 ;
219
220celllist:
221 /* empty */
222 {
223 $$ = empty_data;
224 }
225 | celllist cellval
226 {
227 $$ = data_append_cell($1, $2);
228 }
229 | celllist DT_REF
230 {
231 $$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
232 $2), -1);
233 }
234 | celllist DT_LABEL
235 {
236 $$ = data_add_marker($1, LABEL, $2);
237 }
238 ;
239
240cellbase:
241 /* empty */
242 {
243 $$ = 16;
244 }
245 | DT_BASE
246 ;
247
248cellval:
249 DT_LITERAL
250 {
251 $$ = eval_literal($1, 0, 32);
252 }
253 | cellbase DT_LEGACYLITERAL
254 {
255 $$ = eval_literal($2, $1, 32);
256 }
257 ;
258
259bytestring:
260 /* empty */
261 {
262 $$ = empty_data;
263 }
264 | bytestring DT_BYTE
265 {
266 $$ = data_append_byte($1, $2);
267 }
268 | bytestring DT_LABEL
269 {
270 $$ = data_add_marker($1, LABEL, $2);
271 }
272 ;
273
274subnodes:
275 /* empty */
276 {
277 $$ = NULL;
278 }
279 | subnode subnodes
280 {
281 $$ = chain_node($1, $2);
282 }
283 | subnode propdef
284 {
285 yyerror("syntax error: properties must precede subnodes\n");
286 YYERROR;
287 }
288 ;
289
290subnode:
291 label DT_PROPNODENAME nodedef
292 {
293 $$ = name_node($3, $2, $1);
294 }
295 ;
296
297label:
298 /* empty */
299 {
300 $$ = NULL;
301 }
302 | DT_LABEL
303 {
304 $$ = $1;
305 }
306 ;
307
308%%
309
310void yyerror (char const *s)
311{
312 const char *fname = srcpos_filename_for_num(yylloc.filenum);
313
314 if (strcmp(fname, "-") == 0)
315 fname = "stdin";
316
317 fprintf(stderr, "%s:%d %s\n",
318 fname, yylloc.first_line, s);
319}
320
321unsigned long long eval_literal(const char *s, int base, int bits)
322{
323 unsigned long long val;
324 char *e;
325
326 errno = 0;
327 val = strtoull(s, &e, base);
328 if (*e)
329 yyerror("bad characters in literal");
330 else if ((errno == ERANGE)
331 || ((bits < 64) && (val >= (1ULL << bits))))
332 yyerror("literal out of range");
333 else if (errno != 0)
334 yyerror("bad literal");
335 return val;
336}
diff --git a/arch/powerpc/boot/dtc-src/dtc.c b/arch/powerpc/boot/dtc-src/dtc.c
new file mode 100644
index 000000000000..01131d7c2d5e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc.c
@@ -0,0 +1,231 @@
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#include "dtc.h"
22#include "srcpos.h"
23
24#include "version_gen.h"
25
26/*
27 * Command line options
28 */
29int quiet; /* Level of quietness */
30int reservenum; /* Number of memory reservation slots */
31int minsize; /* Minimum blob size */
32int padsize; /* Additional padding to blob */
33
34char *join_path(const char *path, const char *name)
35{
36 int lenp = strlen(path);
37 int lenn = strlen(name);
38 int len;
39 int needslash = 1;
40 char *str;
41
42 len = lenp + lenn + 2;
43 if ((lenp > 0) && (path[lenp-1] == '/')) {
44 needslash = 0;
45 len--;
46 }
47
48 str = xmalloc(len);
49 memcpy(str, path, lenp);
50 if (needslash) {
51 str[lenp] = '/';
52 lenp++;
53 }
54 memcpy(str+lenp, name, lenn+1);
55 return str;
56}
57
58void fill_fullpaths(struct node *tree, const char *prefix)
59{
60 struct node *child;
61 const char *unit;
62
63 tree->fullpath = join_path(prefix, tree->name);
64
65 unit = strchr(tree->name, '@');
66 if (unit)
67 tree->basenamelen = unit - tree->name;
68 else
69 tree->basenamelen = strlen(tree->name);
70
71 for_each_child(tree, child)
72 fill_fullpaths(child, tree->fullpath);
73}
74
75static void __attribute__ ((noreturn)) usage(void)
76{
77 fprintf(stderr, "Usage:\n");
78 fprintf(stderr, "\tdtc [options] <input file>\n");
79 fprintf(stderr, "\nOptions:\n");
80 fprintf(stderr, "\t-h\n");
81 fprintf(stderr, "\t\tThis help text\n");
82 fprintf(stderr, "\t-q\n");
83 fprintf(stderr, "\t\tQuiet: -q suppress warnings, -qq errors, -qqq all\n");
84 fprintf(stderr, "\t-I <input format>\n");
85 fprintf(stderr, "\t\tInput formats are:\n");
86 fprintf(stderr, "\t\t\tdts - device tree source text\n");
87 fprintf(stderr, "\t\t\tdtb - device tree blob\n");
88 fprintf(stderr, "\t\t\tfs - /proc/device-tree style directory\n");
89 fprintf(stderr, "\t-o <output file>\n");
90 fprintf(stderr, "\t-O <output format>\n");
91 fprintf(stderr, "\t\tOutput formats are:\n");
92 fprintf(stderr, "\t\t\tdts - device tree source text\n");
93 fprintf(stderr, "\t\t\tdtb - device tree blob\n");
94 fprintf(stderr, "\t\t\tasm - assembler source\n");
95 fprintf(stderr, "\t-V <output version>\n");
96 fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION);
97 fprintf(stderr, "\t-R <number>\n");
98 fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n");
99 fprintf(stderr, "\t-S <bytes>\n");
100 fprintf(stderr, "\t\tMake the blob at least <bytes> long (extra space)\n");
101 fprintf(stderr, "\t-p <bytes>\n");
102 fprintf(stderr, "\t\tAdd padding to the blob of <bytes> long (extra space)\n");
103 fprintf(stderr, "\t-b <number>\n");
104 fprintf(stderr, "\t\tSet the physical boot cpu\n");
105 fprintf(stderr, "\t-f\n");
106 fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
107 fprintf(stderr, "\t-v\n");
108 fprintf(stderr, "\t\tPrint DTC version and exit\n");
109 exit(2);
110}
111
112int main(int argc, char *argv[])
113{
114 struct boot_info *bi;
115 const char *inform = "dts";
116 const char *outform = "dts";
117 const char *outname = "-";
118 int force = 0, check = 0;
119 const char *arg;
120 int opt;
121 FILE *inf = NULL;
122 FILE *outf = NULL;
123 int outversion = DEFAULT_FDT_VERSION;
124 int boot_cpuid_phys = 0xfeedbeef;
125
126 quiet = 0;
127 reservenum = 0;
128 minsize = 0;
129 padsize = 0;
130
131 while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) {
132 switch (opt) {
133 case 'I':
134 inform = optarg;
135 break;
136 case 'O':
137 outform = optarg;
138 break;
139 case 'o':
140 outname = optarg;
141 break;
142 case 'V':
143 outversion = strtol(optarg, NULL, 0);
144 break;
145 case 'R':
146 reservenum = strtol(optarg, NULL, 0);
147 break;
148 case 'S':
149 minsize = strtol(optarg, NULL, 0);
150 break;
151 case 'p':
152 padsize = strtol(optarg, NULL, 0);
153 break;
154 case 'f':
155 force = 1;
156 break;
157 case 'c':
158 check = 1;
159 break;
160 case 'q':
161 quiet++;
162 break;
163 case 'b':
164 boot_cpuid_phys = strtol(optarg, NULL, 0);
165 break;
166 case 'v':
167 printf("Version: %s\n", DTC_VERSION);
168 exit(0);
169 case 'h':
170 default:
171 usage();
172 }
173 }
174
175 if (argc > (optind+1))
176 usage();
177 else if (argc < (optind+1))
178 arg = "-";
179 else
180 arg = argv[optind];
181
182 /* minsize and padsize are mutually exclusive */
183 if ((minsize) && (padsize)) {
184 die("Can't set both -p and -S\n");
185 }
186
187 fprintf(stderr, "DTC: %s->%s on file \"%s\"\n",
188 inform, outform, arg);
189
190 if (streq(inform, "dts")) {
191 bi = dt_from_source(arg);
192 } else if (streq(inform, "fs")) {
193 bi = dt_from_fs(arg);
194 } else if(streq(inform, "dtb")) {
195 inf = dtc_open_file(arg);
196 bi = dt_from_blob(inf);
197 } else {
198 die("Unknown input format \"%s\"\n", inform);
199 }
200
201 if (inf && (inf != stdin))
202 fclose(inf);
203
204 if (! bi || ! bi->dt)
205 die("Couldn't read input tree\n");
206
207 process_checks(force, bi, check, outversion, boot_cpuid_phys);
208
209 if (streq(outname, "-")) {
210 outf = stdout;
211 } else {
212 outf = fopen(outname, "w");
213 if (! outf)
214 die("Couldn't open output file %s: %s\n",
215 outname, strerror(errno));
216 }
217
218 if (streq(outform, "dts")) {
219 dt_to_source(outf, bi);
220 } else if (streq(outform, "dtb")) {
221 dt_to_blob(outf, bi, outversion, boot_cpuid_phys);
222 } else if (streq(outform, "asm")) {
223 dt_to_asm(outf, bi, outversion, boot_cpuid_phys);
224 } else if (streq(outform, "null")) {
225 /* do nothing */
226 } else {
227 die("Unknown output format \"%s\"\n", outform);
228 }
229
230 exit(0);
231}
diff --git a/arch/powerpc/boot/dtc-src/dtc.h b/arch/powerpc/boot/dtc-src/dtc.h
new file mode 100644
index 000000000000..65281777a167
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc.h
@@ -0,0 +1,269 @@
1#ifndef _DTC_H
2#define _DTC_H
3
4/*
5 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
6 *
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 */
23
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27#include <stdint.h>
28#include <stdarg.h>
29#include <assert.h>
30#include <ctype.h>
31#include <errno.h>
32#include <unistd.h>
33#include <netinet/in.h>
34#include <endian.h>
35#include <byteswap.h>
36
37#include <fdt.h>
38
39#define DEFAULT_FDT_VERSION 17
40/*
41 * Command line options
42 */
43extern int quiet; /* Level of quietness */
44extern int reservenum; /* Number of memory reservation slots */
45extern int minsize; /* Minimum blob size */
46extern int padsize; /* Additional padding to blob */
47
48static inline void __attribute__((noreturn)) die(char * str, ...)
49{
50 va_list ap;
51
52 va_start(ap, str);
53 fprintf(stderr, "FATAL ERROR: ");
54 vfprintf(stderr, str, ap);
55 exit(1);
56}
57
58static inline void *xmalloc(size_t len)
59{
60 void *new = malloc(len);
61
62 if (! new)
63 die("malloc() failed\n");
64
65 return new;
66}
67
68static inline void *xrealloc(void *p, size_t len)
69{
70 void *new = realloc(p, len);
71
72 if (! new)
73 die("realloc() failed (len=%d)\n", len);
74
75 return new;
76}
77
78typedef uint8_t u8;
79typedef uint16_t u16;
80typedef uint32_t u32;
81typedef uint64_t u64;
82typedef u32 cell_t;
83
84#define cpu_to_be16(x) htons(x)
85#define be16_to_cpu(x) ntohs(x)
86
87#define cpu_to_be32(x) htonl(x)
88#define be32_to_cpu(x) ntohl(x)
89
90#if __BYTE_ORDER == __BIG_ENDIAN
91#define cpu_to_be64(x) (x)
92#define be64_to_cpu(x) (x)
93#else
94#define cpu_to_be64(x) bswap_64(x)
95#define be64_to_cpu(x) bswap_64(x)
96#endif
97
98#define streq(a, b) (strcmp((a), (b)) == 0)
99#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
100
101#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
102#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
103
104/* Data blobs */
105enum markertype {
106 REF_PHANDLE,
107 REF_PATH,
108 LABEL,
109};
110
111struct marker {
112 enum markertype type;
113 int offset;
114 char *ref;
115 struct marker *next;
116};
117
118struct data {
119 int len;
120 char *val;
121 int asize;
122 struct marker *markers;
123};
124
125
126#define empty_data ((struct data){ /* all .members = 0 or NULL */ })
127
128#define for_each_marker(m) \
129 for (; (m); (m) = (m)->next)
130#define for_each_marker_of_type(m, t) \
131 for_each_marker(m) \
132 if ((m)->type == (t))
133
134void data_free(struct data d);
135
136struct data data_grow_for(struct data d, int xlen);
137
138struct data data_copy_mem(const char *mem, int len);
139struct data data_copy_escape_string(const char *s, int len);
140struct data data_copy_file(FILE *f, size_t len);
141
142struct data data_append_data(struct data d, const void *p, int len);
143struct data data_insert_at_marker(struct data d, struct marker *m,
144 const void *p, int len);
145struct data data_merge(struct data d1, struct data d2);
146struct data data_append_cell(struct data d, cell_t word);
147struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
148struct data data_append_addr(struct data d, u64 addr);
149struct data data_append_byte(struct data d, uint8_t byte);
150struct data data_append_zeroes(struct data d, int len);
151struct data data_append_align(struct data d, int align);
152
153struct data data_add_marker(struct data d, enum markertype type, char *ref);
154
155int data_is_one_string(struct data d);
156
157/* DT constraints */
158
159#define MAX_PROPNAME_LEN 31
160#define MAX_NODENAME_LEN 31
161
162/* Live trees */
163struct property {
164 char *name;
165 struct data val;
166
167 struct property *next;
168
169 char *label;
170};
171
172struct node {
173 char *name;
174 struct property *proplist;
175 struct node *children;
176
177 struct node *parent;
178 struct node *next_sibling;
179
180 char *fullpath;
181 int basenamelen;
182
183 cell_t phandle;
184 int addr_cells, size_cells;
185
186 char *label;
187};
188
189#define for_each_property(n, p) \
190 for ((p) = (n)->proplist; (p); (p) = (p)->next)
191
192#define for_each_child(n, c) \
193 for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
194
195struct property *build_property(char *name, struct data val, char *label);
196struct property *chain_property(struct property *first, struct property *list);
197struct property *reverse_properties(struct property *first);
198
199struct node *build_node(struct property *proplist, struct node *children);
200struct node *name_node(struct node *node, char *name, char *label);
201struct node *chain_node(struct node *first, struct node *list);
202
203void add_property(struct node *node, struct property *prop);
204void add_child(struct node *parent, struct node *child);
205
206const char *get_unitname(struct node *node);
207struct property *get_property(struct node *node, const char *propname);
208cell_t propval_cell(struct property *prop);
209struct node *get_subnode(struct node *node, const char *nodename);
210struct node *get_node_by_path(struct node *tree, const char *path);
211struct node *get_node_by_label(struct node *tree, const char *label);
212struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
213struct node *get_node_by_ref(struct node *tree, const char *ref);
214cell_t get_node_phandle(struct node *root, struct node *node);
215
216/* Boot info (tree plus memreserve information */
217
218struct reserve_info {
219 struct fdt_reserve_entry re;
220
221 struct reserve_info *next;
222
223 char *label;
224};
225
226struct reserve_info *build_reserve_entry(u64 start, u64 len, char *label);
227struct reserve_info *chain_reserve_entry(struct reserve_info *first,
228 struct reserve_info *list);
229struct reserve_info *add_reserve_entry(struct reserve_info *list,
230 struct reserve_info *new);
231
232
233struct boot_info {
234 struct reserve_info *reservelist;
235 struct node *dt; /* the device tree */
236};
237
238struct boot_info *build_boot_info(struct reserve_info *reservelist,
239 struct node *tree);
240
241/* Checks */
242
243void process_checks(int force, struct boot_info *bi,
244 int checkflag, int outversion, int boot_cpuid_phys);
245
246/* Flattened trees */
247
248void dt_to_blob(FILE *f, struct boot_info *bi, int version,
249 int boot_cpuid_phys);
250void dt_to_asm(FILE *f, struct boot_info *bi, int version,
251 int boot_cpuid_phys);
252
253struct boot_info *dt_from_blob(FILE *f);
254
255/* Tree source */
256
257void dt_to_source(FILE *f, struct boot_info *bi);
258struct boot_info *dt_from_source(const char *f);
259
260/* FS trees */
261
262struct boot_info *dt_from_fs(const char *dirname);
263
264/* misc */
265
266char *join_path(const char *path, const char *name);
267void fill_fullpaths(struct node *tree, const char *prefix);
268
269#endif /* _DTC_H */
diff --git a/arch/powerpc/boot/dtc-src/flattree.c b/arch/powerpc/boot/dtc-src/flattree.c
new file mode 100644
index 000000000000..a7cfb843d334
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/flattree.c
@@ -0,0 +1,968 @@
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#include "dtc.h"
22
23#define FTF_FULLPATH 0x1
24#define FTF_VARALIGN 0x2
25#define FTF_NAMEPROPS 0x4
26#define FTF_BOOTCPUID 0x8
27#define FTF_STRTABSIZE 0x10
28#define FTF_STRUCTSIZE 0x20
29#define FTF_NOPS 0x40
30
31static struct version_info {
32 int version;
33 int last_comp_version;
34 int hdr_size;
35 int flags;
36} version_table[] = {
37 {1, 1, FDT_V1_SIZE,
38 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS},
39 {2, 1, FDT_V2_SIZE,
40 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID},
41 {3, 1, FDT_V3_SIZE,
42 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE},
43 {16, 16, FDT_V3_SIZE,
44 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS},
45 {17, 16, FDT_V17_SIZE,
46 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS},
47};
48
49struct emitter {
50 void (*cell)(void *, cell_t);
51 void (*string)(void *, char *, int);
52 void (*align)(void *, int);
53 void (*data)(void *, struct data);
54 void (*beginnode)(void *, const char *);
55 void (*endnode)(void *, const char *);
56 void (*property)(void *, const char *);
57};
58
59static void bin_emit_cell(void *e, cell_t val)
60{
61 struct data *dtbuf = e;
62
63 *dtbuf = data_append_cell(*dtbuf, val);
64}
65
66static void bin_emit_string(void *e, char *str, int len)
67{
68 struct data *dtbuf = e;
69
70 if (len == 0)
71 len = strlen(str);
72
73 *dtbuf = data_append_data(*dtbuf, str, len);
74 *dtbuf = data_append_byte(*dtbuf, '\0');
75}
76
77static void bin_emit_align(void *e, int a)
78{
79 struct data *dtbuf = e;
80
81 *dtbuf = data_append_align(*dtbuf, a);
82}
83
84static void bin_emit_data(void *e, struct data d)
85{
86 struct data *dtbuf = e;
87
88 *dtbuf = data_append_data(*dtbuf, d.val, d.len);
89}
90
91static void bin_emit_beginnode(void *e, const char *label)
92{
93 bin_emit_cell(e, FDT_BEGIN_NODE);
94}
95
96static void bin_emit_endnode(void *e, const char *label)
97{
98 bin_emit_cell(e, FDT_END_NODE);
99}
100
101static void bin_emit_property(void *e, const char *label)
102{
103 bin_emit_cell(e, FDT_PROP);
104}
105
106static struct emitter bin_emitter = {
107 .cell = bin_emit_cell,
108 .string = bin_emit_string,
109 .align = bin_emit_align,
110 .data = bin_emit_data,
111 .beginnode = bin_emit_beginnode,
112 .endnode = bin_emit_endnode,
113 .property = bin_emit_property,
114};
115
116static void emit_label(FILE *f, const char *prefix, const char *label)
117{
118 fprintf(f, "\t.globl\t%s_%s\n", prefix, label);
119 fprintf(f, "%s_%s:\n", prefix, label);
120 fprintf(f, "_%s_%s:\n", prefix, label);
121}
122
123static void emit_offset_label(FILE *f, const char *label, int offset)
124{
125 fprintf(f, "\t.globl\t%s\n", label);
126 fprintf(f, "%s\t= . + %d\n", label, offset);
127}
128
129static void asm_emit_cell(void *e, cell_t val)
130{
131 FILE *f = e;
132
133 fprintf(f, "\t.long\t0x%x\n", val);
134}
135
136static void asm_emit_string(void *e, char *str, int len)
137{
138 FILE *f = e;
139 char c = 0;
140
141 if (len != 0) {
142 /* XXX: ewww */
143 c = str[len];
144 str[len] = '\0';
145 }
146
147 fprintf(f, "\t.string\t\"%s\"\n", str);
148
149 if (len != 0) {
150 str[len] = c;
151 }
152}
153
154static void asm_emit_align(void *e, int a)
155{
156 FILE *f = e;
157
158 fprintf(f, "\t.balign\t%d\n", a);
159}
160
161static void asm_emit_data(void *e, struct data d)
162{
163 FILE *f = e;
164 int off = 0;
165 struct marker *m;
166
167 m = d.markers;
168 while (m) {
169 if (m->type == LABEL)
170 emit_offset_label(f, m->ref, m->offset);
171 m = m->next;
172 }
173
174 while ((d.len - off) >= sizeof(u32)) {
175 fprintf(f, "\t.long\t0x%x\n",
176 be32_to_cpu(*((u32 *)(d.val+off))));
177 off += sizeof(u32);
178 }
179
180 if ((d.len - off) >= sizeof(u16)) {
181 fprintf(f, "\t.short\t0x%hx\n",
182 be16_to_cpu(*((u16 *)(d.val+off))));
183 off += sizeof(u16);
184 }
185
186 if ((d.len - off) >= 1) {
187 fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]);
188 off += 1;
189 }
190
191 assert(off == d.len);
192}
193
194static void asm_emit_beginnode(void *e, const char *label)
195{
196 FILE *f = e;
197
198 if (label) {
199 fprintf(f, "\t.globl\t%s\n", label);
200 fprintf(f, "%s:\n", label);
201 }
202 fprintf(f, "\t.long\tFDT_BEGIN_NODE\n");
203}
204
205static void asm_emit_endnode(void *e, const char *label)
206{
207 FILE *f = e;
208
209 fprintf(f, "\t.long\tFDT_END_NODE\n");
210 if (label) {
211 fprintf(f, "\t.globl\t%s_end\n", label);
212 fprintf(f, "%s_end:\n", label);
213 }
214}
215
216static void asm_emit_property(void *e, const char *label)
217{
218 FILE *f = e;
219
220 if (label) {
221 fprintf(f, "\t.globl\t%s\n", label);
222 fprintf(f, "%s:\n", label);
223 }
224 fprintf(f, "\t.long\tFDT_PROP\n");
225}
226
227static struct emitter asm_emitter = {
228 .cell = asm_emit_cell,
229 .string = asm_emit_string,
230 .align = asm_emit_align,
231 .data = asm_emit_data,
232 .beginnode = asm_emit_beginnode,
233 .endnode = asm_emit_endnode,
234 .property = asm_emit_property,
235};
236
237static int stringtable_insert(struct data *d, const char *str)
238{
239 int i;
240
241 /* FIXME: do this more efficiently? */
242
243 for (i = 0; i < d->len; i++) {
244 if (streq(str, d->val + i))
245 return i;
246 }
247
248 *d = data_append_data(*d, str, strlen(str)+1);
249 return i;
250}
251
252static void flatten_tree(struct node *tree, struct emitter *emit,
253 void *etarget, struct data *strbuf,
254 struct version_info *vi)
255{
256 struct property *prop;
257 struct node *child;
258 int seen_name_prop = 0;
259
260 emit->beginnode(etarget, tree->label);
261
262 if (vi->flags & FTF_FULLPATH)
263 emit->string(etarget, tree->fullpath, 0);
264 else
265 emit->string(etarget, tree->name, 0);
266
267 emit->align(etarget, sizeof(cell_t));
268
269 for_each_property(tree, prop) {
270 int nameoff;
271
272 if (streq(prop->name, "name"))
273 seen_name_prop = 1;
274
275 nameoff = stringtable_insert(strbuf, prop->name);
276
277 emit->property(etarget, prop->label);
278 emit->cell(etarget, prop->val.len);
279 emit->cell(etarget, nameoff);
280
281 if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8))
282 emit->align(etarget, 8);
283
284 emit->data(etarget, prop->val);
285 emit->align(etarget, sizeof(cell_t));
286 }
287
288 if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) {
289 emit->property(etarget, NULL);
290 emit->cell(etarget, tree->basenamelen+1);
291 emit->cell(etarget, stringtable_insert(strbuf, "name"));
292
293 if ((vi->flags & FTF_VARALIGN) && ((tree->basenamelen+1) >= 8))
294 emit->align(etarget, 8);
295
296 emit->string(etarget, tree->name, tree->basenamelen);
297 emit->align(etarget, sizeof(cell_t));
298 }
299
300 for_each_child(tree, child) {
301 flatten_tree(child, emit, etarget, strbuf, vi);
302 }
303
304 emit->endnode(etarget, tree->label);
305}
306
307static struct data flatten_reserve_list(struct reserve_info *reservelist,
308 struct version_info *vi)
309{
310 struct reserve_info *re;
311 struct data d = empty_data;
312 static struct fdt_reserve_entry null_re = {0,0};
313 int j;
314
315 for (re = reservelist; re; re = re->next) {
316 d = data_append_re(d, &re->re);
317 }
318 /*
319 * Add additional reserved slots if the user asked for them.
320 */
321 for (j = 0; j < reservenum; j++) {
322 d = data_append_re(d, &null_re);
323 }
324
325 return d;
326}
327
328static void make_fdt_header(struct fdt_header *fdt,
329 struct version_info *vi,
330 int reservesize, int dtsize, int strsize,
331 int boot_cpuid_phys)
332{
333 int reserve_off;
334
335 reservesize += sizeof(struct fdt_reserve_entry);
336
337 memset(fdt, 0xff, sizeof(*fdt));
338
339 fdt->magic = cpu_to_be32(FDT_MAGIC);
340 fdt->version = cpu_to_be32(vi->version);
341 fdt->last_comp_version = cpu_to_be32(vi->last_comp_version);
342
343 /* Reserve map should be doubleword aligned */
344 reserve_off = ALIGN(vi->hdr_size, 8);
345
346 fdt->off_mem_rsvmap = cpu_to_be32(reserve_off);
347 fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize);
348 fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize
349 + dtsize);
350 fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize);
351
352 if (vi->flags & FTF_BOOTCPUID)
353 fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys);
354 if (vi->flags & FTF_STRTABSIZE)
355 fdt->size_dt_strings = cpu_to_be32(strsize);
356 if (vi->flags & FTF_STRUCTSIZE)
357 fdt->size_dt_struct = cpu_to_be32(dtsize);
358}
359
360void dt_to_blob(FILE *f, struct boot_info *bi, int version,
361 int boot_cpuid_phys)
362{
363 struct version_info *vi = NULL;
364 int i;
365 struct data blob = empty_data;
366 struct data reservebuf = empty_data;
367 struct data dtbuf = empty_data;
368 struct data strbuf = empty_data;
369 struct fdt_header fdt;
370 int padlen = 0;
371
372 for (i = 0; i < ARRAY_SIZE(version_table); i++) {
373 if (version_table[i].version == version)
374 vi = &version_table[i];
375 }
376 if (!vi)
377 die("Unknown device tree blob version %d\n", version);
378
379 flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi);
380 bin_emit_cell(&dtbuf, FDT_END);
381
382 reservebuf = flatten_reserve_list(bi->reservelist, vi);
383
384 /* Make header */
385 make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
386 boot_cpuid_phys);
387
388 /*
389 * If the user asked for more space than is used, adjust the totalsize.
390 */
391 if (minsize > 0) {
392 padlen = minsize - be32_to_cpu(fdt.totalsize);
393 if ((padlen < 0) && (quiet < 1))
394 fprintf(stderr,
395 "Warning: blob size %d >= minimum size %d\n",
396 be32_to_cpu(fdt.totalsize), minsize);
397 }
398
399 if (padsize > 0)
400 padlen = padsize;
401
402 if (padlen > 0) {
403 int tsize = be32_to_cpu(fdt.totalsize);
404 tsize += padlen;
405 fdt.totalsize = cpu_to_be32(tsize);
406 }
407
408 /*
409 * Assemble the blob: start with the header, add with alignment
410 * the reserve buffer, add the reserve map terminating zeroes,
411 * the device tree itself, and finally the strings.
412 */
413 blob = data_append_data(blob, &fdt, sizeof(fdt));
414 blob = data_append_align(blob, 8);
415 blob = data_merge(blob, reservebuf);
416 blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
417 blob = data_merge(blob, dtbuf);
418 blob = data_merge(blob, strbuf);
419
420 /*
421 * If the user asked for more space than is used, pad out the blob.
422 */
423 if (padlen > 0)
424 blob = data_append_zeroes(blob, padlen);
425
426 fwrite(blob.val, blob.len, 1, f);
427
428 if (ferror(f))
429 die("Error writing device tree blob: %s\n", strerror(errno));
430
431 /*
432 * data_merge() frees the right-hand element so only the blob
433 * remains to be freed.
434 */
435 data_free(blob);
436}
437
438static void dump_stringtable_asm(FILE *f, struct data strbuf)
439{
440 const char *p;
441 int len;
442
443 p = strbuf.val;
444
445 while (p < (strbuf.val + strbuf.len)) {
446 len = strlen(p);
447 fprintf(f, "\t.string \"%s\"\n", p);
448 p += len+1;
449 }
450}
451
452void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys)
453{
454 struct version_info *vi = NULL;
455 int i;
456 struct data strbuf = empty_data;
457 struct reserve_info *re;
458 const char *symprefix = "dt";
459
460 for (i = 0; i < ARRAY_SIZE(version_table); i++) {
461 if (version_table[i].version == version)
462 vi = &version_table[i];
463 }
464 if (!vi)
465 die("Unknown device tree blob version %d\n", version);
466
467 fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
468 fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
469 fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
470 fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
471 fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
472 fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
473 fprintf(f, "\n");
474
475 emit_label(f, symprefix, "blob_start");
476 emit_label(f, symprefix, "header");
477 fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n");
478 fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n",
479 symprefix, symprefix);
480 fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n",
481 symprefix, symprefix);
482 fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n",
483 symprefix, symprefix);
484 fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n",
485 symprefix, symprefix);
486 fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version);
487 fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n",
488 vi->last_comp_version);
489
490 if (vi->flags & FTF_BOOTCPUID)
491 fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
492 boot_cpuid_phys);
493
494 if (vi->flags & FTF_STRTABSIZE)
495 fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
496 symprefix, symprefix);
497
498 if (vi->flags & FTF_STRUCTSIZE)
499 fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n",
500 symprefix, symprefix);
501
502 /*
503 * Reserve map entries.
504 * Align the reserve map to a doubleword boundary.
505 * Each entry is an (address, size) pair of u64 values.
506 * Always supply a zero-sized temination entry.
507 */
508 asm_emit_align(f, 8);
509 emit_label(f, symprefix, "reserve_map");
510
511 fprintf(f, "/* Memory reserve map from source file */\n");
512
513 /*
514 * Use .long on high and low halfs of u64s to avoid .quad
515 * as it appears .quad isn't available in some assemblers.
516 */
517 for (re = bi->reservelist; re; re = re->next) {
518 if (re->label) {
519 fprintf(f, "\t.globl\t%s\n", re->label);
520 fprintf(f, "%s:\n", re->label);
521 }
522 fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
523 (unsigned int)(re->re.address >> 32),
524 (unsigned int)(re->re.address & 0xffffffff));
525 fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
526 (unsigned int)(re->re.size >> 32),
527 (unsigned int)(re->re.size & 0xffffffff));
528 }
529 for (i = 0; i < reservenum; i++) {
530 fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
531 }
532
533 fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
534
535 emit_label(f, symprefix, "struct_start");
536 flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
537 fprintf(f, "\t.long\tFDT_END\n");
538 emit_label(f, symprefix, "struct_end");
539
540 emit_label(f, symprefix, "strings_start");
541 dump_stringtable_asm(f, strbuf);
542 emit_label(f, symprefix, "strings_end");
543
544 emit_label(f, symprefix, "blob_end");
545
546 /*
547 * If the user asked for more space than is used, pad it out.
548 */
549 if (minsize > 0) {
550 fprintf(f, "\t.space\t%d - (_%s_blob_end - _%s_blob_start), 0\n",
551 minsize, symprefix, symprefix);
552 }
553 if (padsize > 0) {
554 fprintf(f, "\t.space\t%d, 0\n", padsize);
555 }
556 emit_label(f, symprefix, "blob_abs_end");
557
558 data_free(strbuf);
559}
560
561struct inbuf {
562 char *base, *limit, *ptr;
563};
564
565static void inbuf_init(struct inbuf *inb, void *base, void *limit)
566{
567 inb->base = base;
568 inb->limit = limit;
569 inb->ptr = inb->base;
570}
571
572static void flat_read_chunk(struct inbuf *inb, void *p, int len)
573{
574 if ((inb->ptr + len) > inb->limit)
575 die("Premature end of data parsing flat device tree\n");
576
577 memcpy(p, inb->ptr, len);
578
579 inb->ptr += len;
580}
581
582static u32 flat_read_word(struct inbuf *inb)
583{
584 u32 val;
585
586 assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
587
588 flat_read_chunk(inb, &val, sizeof(val));
589
590 return be32_to_cpu(val);
591}
592
593static void flat_realign(struct inbuf *inb, int align)
594{
595 int off = inb->ptr - inb->base;
596
597 inb->ptr = inb->base + ALIGN(off, align);
598 if (inb->ptr > inb->limit)
599 die("Premature end of data parsing flat device tree\n");
600}
601
602static char *flat_read_string(struct inbuf *inb)
603{
604 int len = 0;
605 const char *p = inb->ptr;
606 char *str;
607
608 do {
609 if (p >= inb->limit)
610 die("Premature end of data parsing flat device tree\n");
611 len++;
612 } while ((*p++) != '\0');
613
614 str = strdup(inb->ptr);
615
616 inb->ptr += len;
617
618 flat_realign(inb, sizeof(u32));
619
620 return str;
621}
622
623static struct data flat_read_data(struct inbuf *inb, int len)
624{
625 struct data d = empty_data;
626
627 if (len == 0)
628 return empty_data;
629
630 d = data_grow_for(d, len);
631 d.len = len;
632
633 flat_read_chunk(inb, d.val, len);
634
635 flat_realign(inb, sizeof(u32));
636
637 return d;
638}
639
640static char *flat_read_stringtable(struct inbuf *inb, int offset)
641{
642 const char *p;
643
644 p = inb->base + offset;
645 while (1) {
646 if (p >= inb->limit || p < inb->base)
647 die("String offset %d overruns string table\n",
648 offset);
649
650 if (*p == '\0')
651 break;
652
653 p++;
654 }
655
656 return strdup(inb->base + offset);
657}
658
659static struct property *flat_read_property(struct inbuf *dtbuf,
660 struct inbuf *strbuf, int flags)
661{
662 u32 proplen, stroff;
663 char *name;
664 struct data val;
665
666 proplen = flat_read_word(dtbuf);
667 stroff = flat_read_word(dtbuf);
668
669 name = flat_read_stringtable(strbuf, stroff);
670
671 if ((flags & FTF_VARALIGN) && (proplen >= 8))
672 flat_realign(dtbuf, 8);
673
674 val = flat_read_data(dtbuf, proplen);
675
676 return build_property(name, val, NULL);
677}
678
679
680static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
681{
682 struct reserve_info *reservelist = NULL;
683 struct reserve_info *new;
684 const char *p;
685 struct fdt_reserve_entry re;
686
687 /*
688 * Each entry is a pair of u64 (addr, size) values for 4 cell_t's.
689 * List terminates at an entry with size equal to zero.
690 *
691 * First pass, count entries.
692 */
693 p = inb->ptr;
694 while (1) {
695 flat_read_chunk(inb, &re, sizeof(re));
696 re.address = be64_to_cpu(re.address);
697 re.size = be64_to_cpu(re.size);
698 if (re.size == 0)
699 break;
700
701 new = build_reserve_entry(re.address, re.size, NULL);
702 reservelist = add_reserve_entry(reservelist, new);
703 }
704
705 return reservelist;
706}
707
708
709static char *nodename_from_path(const char *ppath, const char *cpath)
710{
711 const char *lslash;
712 int plen;
713
714 lslash = strrchr(cpath, '/');
715 if (! lslash)
716 return NULL;
717
718 plen = lslash - cpath;
719
720 if (streq(cpath, "/") && streq(ppath, ""))
721 return "";
722
723 if ((plen == 0) && streq(ppath, "/"))
724 return strdup(lslash+1);
725
726 if (! strneq(ppath, cpath, plen))
727 return NULL;
728
729 return strdup(lslash+1);
730}
731
732static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-";
733static const char UNITCHAR[] = "0123456789abcdef,";
734
735static int check_node_name(const char *name)
736{
737 const char *atpos;
738 int basenamelen;
739
740 atpos = strrchr(name, '@');
741
742 if (atpos)
743 basenamelen = atpos - name;
744 else
745 basenamelen = strlen(name);
746
747 if (strspn(name, PROPCHAR) < basenamelen)
748 return -1;
749
750 if (atpos
751 && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name)))
752 return -1;
753
754 return basenamelen;
755}
756
757static struct node *unflatten_tree(struct inbuf *dtbuf,
758 struct inbuf *strbuf,
759 const char *parent_path, int flags)
760{
761 struct node *node;
762 u32 val;
763
764 node = build_node(NULL, NULL);
765
766 if (flags & FTF_FULLPATH) {
767 node->fullpath = flat_read_string(dtbuf);
768 node->name = nodename_from_path(parent_path, node->fullpath);
769
770 if (! node->name)
771 die("Path \"%s\" is not valid as a child of \"%s\"\n",
772 node->fullpath, parent_path);
773 } else {
774 node->name = flat_read_string(dtbuf);
775 node->fullpath = join_path(parent_path, node->name);
776 }
777
778 node->basenamelen = check_node_name(node->name);
779 if (node->basenamelen < 0) {
780 fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name);
781 }
782
783 do {
784 struct property *prop;
785 struct node *child;
786
787 val = flat_read_word(dtbuf);
788 switch (val) {
789 case FDT_PROP:
790 if (node->children)
791 fprintf(stderr, "Warning: Flat tree input has "
792 "subnodes preceding a property.\n");
793 prop = flat_read_property(dtbuf, strbuf, flags);
794 add_property(node, prop);
795 break;
796
797 case FDT_BEGIN_NODE:
798 child = unflatten_tree(dtbuf,strbuf, node->fullpath,
799 flags);
800 add_child(node, child);
801 break;
802
803 case FDT_END_NODE:
804 break;
805
806 case FDT_END:
807 die("Premature FDT_END in device tree blob\n");
808 break;
809
810 case FDT_NOP:
811 if (!(flags & FTF_NOPS))
812 fprintf(stderr, "Warning: NOP tag found in flat tree"
813 " version <16\n");
814
815 /* Ignore */
816 break;
817
818 default:
819 die("Invalid opcode word %08x in device tree blob\n",
820 val);
821 }
822 } while (val != FDT_END_NODE);
823
824 return node;
825}
826
827
828struct boot_info *dt_from_blob(FILE *f)
829{
830 u32 magic, totalsize, version, size_str, size_dt;
831 u32 off_dt, off_str, off_mem_rsvmap;
832 int rc;
833 char *blob;
834 struct fdt_header *fdt;
835 char *p;
836 struct inbuf dtbuf, strbuf;
837 struct inbuf memresvbuf;
838 int sizeleft;
839 struct reserve_info *reservelist;
840 struct node *tree;
841 u32 val;
842 int flags = 0;
843
844 rc = fread(&magic, sizeof(magic), 1, f);
845 if (ferror(f))
846 die("Error reading DT blob magic number: %s\n",
847 strerror(errno));
848 if (rc < 1) {
849 if (feof(f))
850 die("EOF reading DT blob magic number\n");
851 else
852 die("Mysterious short read reading magic number\n");
853 }
854
855 magic = be32_to_cpu(magic);
856 if (magic != FDT_MAGIC)
857 die("Blob has incorrect magic number\n");
858
859 rc = fread(&totalsize, sizeof(totalsize), 1, f);
860 if (ferror(f))
861 die("Error reading DT blob size: %s\n", strerror(errno));
862 if (rc < 1) {
863 if (feof(f))
864 die("EOF reading DT blob size\n");
865 else
866 die("Mysterious short read reading blob size\n");
867 }
868
869 totalsize = be32_to_cpu(totalsize);
870 if (totalsize < FDT_V1_SIZE)
871 die("DT blob size (%d) is too small\n", totalsize);
872
873 blob = xmalloc(totalsize);
874
875 fdt = (struct fdt_header *)blob;
876 fdt->magic = cpu_to_be32(magic);
877 fdt->totalsize = cpu_to_be32(totalsize);
878
879 sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
880 p = blob + sizeof(magic) + sizeof(totalsize);
881
882 while (sizeleft) {
883 if (feof(f))
884 die("EOF before reading %d bytes of DT blob\n",
885 totalsize);
886
887 rc = fread(p, 1, sizeleft, f);
888 if (ferror(f))
889 die("Error reading DT blob: %s\n",
890 strerror(errno));
891
892 sizeleft -= rc;
893 p += rc;
894 }
895
896 off_dt = be32_to_cpu(fdt->off_dt_struct);
897 off_str = be32_to_cpu(fdt->off_dt_strings);
898 off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap);
899 version = be32_to_cpu(fdt->version);
900
901 fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
902 fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
903 fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt);
904 fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str);
905 fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
906 fprintf(stderr, "\tversion:\t\t0x%x\n", version );
907 fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
908 be32_to_cpu(fdt->last_comp_version));
909
910 if (off_mem_rsvmap >= totalsize)
911 die("Mem Reserve structure offset exceeds total size\n");
912
913 if (off_dt >= totalsize)
914 die("DT structure offset exceeds total size\n");
915
916 if (off_str > totalsize)
917 die("String table offset exceeds total size\n");
918
919 if (version >= 2)
920 fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n",
921 be32_to_cpu(fdt->boot_cpuid_phys));
922
923 size_str = -1;
924 if (version >= 3) {
925 size_str = be32_to_cpu(fdt->size_dt_strings);
926 fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str);
927 if (off_str+size_str > totalsize)
928 die("String table extends past total size\n");
929 }
930
931 if (version >= 17) {
932 size_dt = be32_to_cpu(fdt->size_dt_struct);
933 fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt);
934 if (off_dt+size_dt > totalsize)
935 die("Structure block extends past total size\n");
936 }
937
938 if (version < 16) {
939 flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN;
940 } else {
941 flags |= FTF_NOPS;
942 }
943
944 inbuf_init(&memresvbuf,
945 blob + off_mem_rsvmap, blob + totalsize);
946 inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
947 if (size_str >= 0)
948 inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
949 else
950 inbuf_init(&strbuf, blob + off_str, blob + totalsize);
951
952 reservelist = flat_read_mem_reserve(&memresvbuf);
953
954 val = flat_read_word(&dtbuf);
955
956 if (val != FDT_BEGIN_NODE)
957 die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val);
958
959 tree = unflatten_tree(&dtbuf, &strbuf, "", flags);
960
961 val = flat_read_word(&dtbuf);
962 if (val != FDT_END)
963 die("Device tree blob doesn't end with FDT_END\n");
964
965 free(blob);
966
967 return build_boot_info(reservelist, tree);
968}
diff --git a/arch/powerpc/boot/dtc-src/fstree.c b/arch/powerpc/boot/dtc-src/fstree.c
new file mode 100644
index 000000000000..2a160a46998e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/fstree.c
@@ -0,0 +1,94 @@
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#include "dtc.h"
22
23#include <dirent.h>
24#include <sys/stat.h>
25
26static struct node *read_fstree(const char *dirname)
27{
28 DIR *d;
29 struct dirent *de;
30 struct stat st;
31 struct node *tree;
32
33 d = opendir(dirname);
34 if (! d)
35 die("opendir(): %s\n", strerror(errno));
36
37 tree = build_node(NULL, NULL);
38
39 while ((de = readdir(d)) != NULL) {
40 char *tmpnam;
41
42 if (streq(de->d_name, ".")
43 || streq(de->d_name, ".."))
44 continue;
45
46 tmpnam = join_path(dirname, de->d_name);
47
48 if (lstat(tmpnam, &st) < 0)
49 die("stat(%s): %s\n", tmpnam, strerror(errno));
50
51 if (S_ISREG(st.st_mode)) {
52 struct property *prop;
53 FILE *pfile;
54
55 pfile = fopen(tmpnam, "r");
56 if (! pfile) {
57 fprintf(stderr,
58 "WARNING: Cannot open %s: %s\n",
59 tmpnam, strerror(errno));
60 } else {
61 prop = build_property(strdup(de->d_name),
62 data_copy_file(pfile,
63 st.st_size),
64 NULL);
65 add_property(tree, prop);
66 fclose(pfile);
67 }
68 } else if (S_ISDIR(st.st_mode)) {
69 struct node *newchild;
70
71 newchild = read_fstree(tmpnam);
72 newchild = name_node(newchild, strdup(de->d_name),
73 NULL);
74 add_child(tree, newchild);
75 }
76
77 free(tmpnam);
78 }
79
80 return tree;
81}
82
83struct boot_info *dt_from_fs(const char *dirname)
84{
85 struct node *tree;
86
87 tree = read_fstree(dirname);
88 tree = name_node(tree, "", NULL);
89
90 fill_fullpaths(tree, "");
91
92 return build_boot_info(NULL, tree);
93}
94
diff --git a/arch/powerpc/boot/dtc-src/livetree.c b/arch/powerpc/boot/dtc-src/livetree.c
new file mode 100644
index 000000000000..6ba0846b4310
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/livetree.c
@@ -0,0 +1,305 @@
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#include "dtc.h"
22
23/*
24 * Tree building functions
25 */
26
27struct property *build_property(char *name, struct data val, char *label)
28{
29 struct property *new = xmalloc(sizeof(*new));
30
31 new->name = name;
32 new->val = val;
33
34 new->next = NULL;
35
36 new->label = label;
37
38 return new;
39}
40
41struct property *chain_property(struct property *first, struct property *list)
42{
43 assert(first->next == NULL);
44
45 first->next = list;
46 return first;
47}
48
49struct property *reverse_properties(struct property *first)
50{
51 struct property *p = first;
52 struct property *head = NULL;
53 struct property *next;
54
55 while (p) {
56 next = p->next;
57 p->next = head;
58 head = p;
59 p = next;
60 }
61 return head;
62}
63
64struct node *build_node(struct property *proplist, struct node *children)
65{
66 struct node *new = xmalloc(sizeof(*new));
67 struct node *child;
68
69 memset(new, 0, sizeof(*new));
70
71 new->proplist = reverse_properties(proplist);
72 new->children = children;
73
74 for_each_child(new, child) {
75 child->parent = new;
76 }
77
78 return new;
79}
80
81struct node *name_node(struct node *node, char *name, char * label)
82{
83 assert(node->name == NULL);
84
85 node->name = name;
86
87 node->label = label;
88
89 return node;
90}
91
92struct node *chain_node(struct node *first, struct node *list)
93{
94 assert(first->next_sibling == NULL);
95
96 first->next_sibling = list;
97 return first;
98}
99
100void add_property(struct node *node, struct property *prop)
101{
102 struct property **p;
103
104 prop->next = NULL;
105
106 p = &node->proplist;
107 while (*p)
108 p = &((*p)->next);
109
110 *p = prop;
111}
112
113void add_child(struct node *parent, struct node *child)
114{
115 struct node **p;
116
117 child->next_sibling = NULL;
118
119 p = &parent->children;
120 while (*p)
121 p = &((*p)->next_sibling);
122
123 *p = child;
124}
125
126struct reserve_info *build_reserve_entry(u64 address, u64 size, char *label)
127{
128 struct reserve_info *new = xmalloc(sizeof(*new));
129
130 new->re.address = address;
131 new->re.size = size;
132
133 new->next = NULL;
134
135 new->label = label;
136
137 return new;
138}
139
140struct reserve_info *chain_reserve_entry(struct reserve_info *first,
141 struct reserve_info *list)
142{
143 assert(first->next == NULL);
144
145 first->next = list;
146 return first;
147}
148
149struct reserve_info *add_reserve_entry(struct reserve_info *list,
150 struct reserve_info *new)
151{
152 struct reserve_info *last;
153
154 new->next = NULL;
155
156 if (! list)
157 return new;
158
159 for (last = list; last->next; last = last->next)
160 ;
161
162 last->next = new;
163
164 return list;
165}
166
167struct boot_info *build_boot_info(struct reserve_info *reservelist,
168 struct node *tree)
169{
170 struct boot_info *bi;
171
172 bi = xmalloc(sizeof(*bi));
173 bi->reservelist = reservelist;
174 bi->dt = tree;
175
176 return bi;
177}
178
179/*
180 * Tree accessor functions
181 */
182
183const char *get_unitname(struct node *node)
184{
185 if (node->name[node->basenamelen] == '\0')
186 return "";
187 else
188 return node->name + node->basenamelen + 1;
189}
190
191struct property *get_property(struct node *node, const char *propname)
192{
193 struct property *prop;
194
195 for_each_property(node, prop)
196 if (streq(prop->name, propname))
197 return prop;
198
199 return NULL;
200}
201
202cell_t propval_cell(struct property *prop)
203{
204 assert(prop->val.len == sizeof(cell_t));
205 return be32_to_cpu(*((cell_t *)prop->val.val));
206}
207
208struct node *get_subnode(struct node *node, const char *nodename)
209{
210 struct node *child;
211
212 for_each_child(node, child)
213 if (streq(child->name, nodename))
214 return child;
215
216 return NULL;
217}
218
219struct node *get_node_by_path(struct node *tree, const char *path)
220{
221 const char *p;
222 struct node *child;
223
224 if (!path || ! (*path))
225 return tree;
226
227 while (path[0] == '/')
228 path++;
229
230 p = strchr(path, '/');
231
232 for_each_child(tree, child) {
233 if (p && strneq(path, child->name, p-path))
234 return get_node_by_path(child, p+1);
235 else if (!p && streq(path, child->name))
236 return child;
237 }
238
239 return NULL;
240}
241
242struct node *get_node_by_label(struct node *tree, const char *label)
243{
244 struct node *child, *node;
245
246 assert(label && (strlen(label) > 0));
247
248 if (tree->label && streq(tree->label, label))
249 return tree;
250
251 for_each_child(tree, child) {
252 node = get_node_by_label(child, label);
253 if (node)
254 return node;
255 }
256
257 return NULL;
258}
259
260struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
261{
262 struct node *child, *node;
263
264 assert((phandle != 0) && (phandle != -1));
265
266 if (tree->phandle == phandle)
267 return tree;
268
269 for_each_child(tree, child) {
270 node = get_node_by_phandle(child, phandle);
271 if (node)
272 return node;
273 }
274
275 return NULL;
276}
277
278struct node *get_node_by_ref(struct node *tree, const char *ref)
279{
280 if (ref[0] == '/')
281 return get_node_by_path(tree, ref);
282 else
283 return get_node_by_label(tree, ref);
284}
285
286cell_t get_node_phandle(struct node *root, struct node *node)
287{
288 static cell_t phandle = 1; /* FIXME: ick, static local */
289
290 if ((node->phandle != 0) && (node->phandle != -1))
291 return node->phandle;
292
293 assert(! get_property(node, "linux,phandle"));
294
295 while (get_node_by_phandle(root, phandle))
296 phandle++;
297
298 node->phandle = phandle;
299 add_property(node,
300 build_property("linux,phandle",
301 data_append_cell(empty_data, phandle),
302 NULL));
303
304 return node->phandle;
305}
diff --git a/arch/powerpc/boot/dtc-src/srcpos.c b/arch/powerpc/boot/dtc-src/srcpos.c
new file mode 100644
index 000000000000..352b0fe06fde
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/srcpos.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA
18 */
19
20#include "dtc.h"
21#include "srcpos.h"
22
23
24/*
25 * Record the complete unique set of opened file names.
26 * Primarily used to cache source position file names.
27 */
28#define MAX_N_FILE_NAMES (100)
29
30const char *file_names[MAX_N_FILE_NAMES];
31static int n_file_names = 0;
32
33/*
34 * Like yylineno, this is the current open file pos.
35 */
36
37int srcpos_filenum = -1;
38
39
40
41FILE *dtc_open_file(const char *fname)
42{
43 FILE *f;
44
45 if (lookup_file_name(fname, 1) < 0)
46 die("Too many files opened\n");
47
48 if (streq(fname, "-"))
49 f = stdin;
50 else
51 f = fopen(fname, "r");
52
53 if (! f)
54 die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
55
56 return f;
57}
58
59
60
61/*
62 * Locate and optionally add filename fname in the file_names[] array.
63 *
64 * If the filename is currently not in the array and the boolean
65 * add_it is non-zero, an attempt to add the filename will be made.
66 *
67 * Returns;
68 * Index [0..MAX_N_FILE_NAMES) where the filename is kept
69 * -1 if the name can not be recorded
70 */
71
72int lookup_file_name(const char *fname, int add_it)
73{
74 int i;
75
76 for (i = 0; i < n_file_names; i++) {
77 if (strcmp(file_names[i], fname) == 0)
78 return i;
79 }
80
81 if (add_it) {
82 if (n_file_names < MAX_N_FILE_NAMES) {
83 file_names[n_file_names] = strdup(fname);
84 return n_file_names++;
85 }
86 }
87
88 return -1;
89}
90
91
92const char *srcpos_filename_for_num(int filenum)
93{
94 if (0 <= filenum && filenum < n_file_names) {
95 return file_names[filenum];
96 }
97
98 return 0;
99}
100
101
102const char *srcpos_get_filename(void)
103{
104 return srcpos_filename_for_num(srcpos_filenum);
105}
diff --git a/arch/powerpc/boot/dtc-src/srcpos.h b/arch/powerpc/boot/dtc-src/srcpos.h
new file mode 100644
index 000000000000..ce7ab5ba5b46
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/srcpos.h
@@ -0,0 +1,75 @@
1/*
2 * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA
18 */
19
20/*
21 * Augment the standard YYLTYPE with a filenum index into an
22 * array of all opened filenames.
23 */
24
25#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
26typedef struct YYLTYPE {
27 int first_line;
28 int first_column;
29 int last_line;
30 int last_column;
31 int filenum;
32} YYLTYPE;
33
34#define YYLTYPE_IS_DECLARED 1
35#define YYLTYPE_IS_TRIVIAL 1
36#endif
37
38/* Cater to old parser templates. */
39#ifndef YYID
40#define YYID(n) (n)
41#endif
42
43#define YYLLOC_DEFAULT(Current, Rhs, N) \
44 do \
45 if (YYID (N)) \
46 { \
47 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
48 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
49 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
50 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
51 (Current).filenum = YYRHSLOC (Rhs, N).filenum; \
52 } \
53 else \
54 { \
55 (Current).first_line = (Current).last_line = \
56 YYRHSLOC (Rhs, 0).last_line; \
57 (Current).first_column = (Current).last_column = \
58 YYRHSLOC (Rhs, 0).last_column; \
59 (Current).filenum = YYRHSLOC (Rhs, 0).filenum; \
60 } \
61 while (YYID (0))
62
63
64
65extern void yyerror(char const *);
66
67extern int srcpos_filenum;
68
69extern int push_input_file(const char *filename);
70extern int pop_input_file(void);
71
72extern FILE *dtc_open_file(const char *fname);
73extern int lookup_file_name(const char *fname, int add_it);
74extern const char *srcpos_filename_for_num(int filenum);
75const char *srcpos_get_filename(void);
diff --git a/arch/powerpc/boot/dtc-src/treesource.c b/arch/powerpc/boot/dtc-src/treesource.c
new file mode 100644
index 000000000000..a6a776797636
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/treesource.c
@@ -0,0 +1,275 @@
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#include "dtc.h"
22#include "srcpos.h"
23
24extern FILE *yyin;
25extern int yyparse(void);
26extern void yyerror(char const *);
27
28struct boot_info *the_boot_info;
29
30struct boot_info *dt_from_source(const char *fname)
31{
32 the_boot_info = NULL;
33
34 push_input_file(fname);
35
36 if (yyparse() != 0)
37 return NULL;
38
39 fill_fullpaths(the_boot_info->dt, "");
40
41 return the_boot_info;
42}
43
44static void write_prefix(FILE *f, int level)
45{
46 int i;
47
48 for (i = 0; i < level; i++)
49 fputc('\t', f);
50}
51
52int isstring(char c)
53{
54 return (isprint(c)
55 || (c == '\0')
56 || strchr("\a\b\t\n\v\f\r", c));
57}
58
59static void write_propval_string(FILE *f, struct data val)
60{
61 const char *str = val.val;
62 int i;
63 int newchunk = 1;
64 struct marker *m = val.markers;
65
66 assert(str[val.len-1] == '\0');
67
68 for (i = 0; i < (val.len-1); i++) {
69 char c = str[i];
70
71 if (newchunk) {
72 while (m && (m->offset <= i)) {
73 if (m->type == LABEL) {
74 assert(m->offset == i);
75 fprintf(f, "%s: ", m->ref);
76 }
77 m = m->next;
78 }
79 fprintf(f, "\"");
80 newchunk = 0;
81 }
82
83 switch (c) {
84 case '\a':
85 fprintf(f, "\\a");
86 break;
87 case '\b':
88 fprintf(f, "\\b");
89 break;
90 case '\t':
91 fprintf(f, "\\t");
92 break;
93 case '\n':
94 fprintf(f, "\\n");
95 break;
96 case '\v':
97 fprintf(f, "\\v");
98 break;
99 case '\f':
100 fprintf(f, "\\f");
101 break;
102 case '\r':
103 fprintf(f, "\\r");
104 break;
105 case '\\':
106 fprintf(f, "\\\\");
107 break;
108 case '\"':
109 fprintf(f, "\\\"");
110 break;
111 case '\0':
112 fprintf(f, "\", ");
113 newchunk = 1;
114 break;
115 default:
116 if (isprint(c))
117 fprintf(f, "%c", c);
118 else
119 fprintf(f, "\\x%02hhx", c);
120 }
121 }
122 fprintf(f, "\"");
123
124 /* Wrap up any labels at the end of the value */
125 for_each_marker_of_type(m, LABEL) {
126 assert (m->offset == val.len);
127 fprintf(f, " %s:", m->ref);
128 }
129}
130
131static void write_propval_cells(FILE *f, struct data val)
132{
133 void *propend = val.val + val.len;
134 cell_t *cp = (cell_t *)val.val;
135 struct marker *m = val.markers;
136
137 fprintf(f, "<");
138 for (;;) {
139 while (m && (m->offset <= ((char *)cp - val.val))) {
140 if (m->type == LABEL) {
141 assert(m->offset == ((char *)cp - val.val));
142 fprintf(f, "%s: ", m->ref);
143 }
144 m = m->next;
145 }
146
147 fprintf(f, "0x%x", be32_to_cpu(*cp++));
148 if ((void *)cp >= propend)
149 break;
150 fprintf(f, " ");
151 }
152
153 /* Wrap up any labels at the end of the value */
154 for_each_marker_of_type(m, LABEL) {
155 assert (m->offset == val.len);
156 fprintf(f, " %s:", m->ref);
157 }
158 fprintf(f, ">");
159}
160
161static void write_propval_bytes(FILE *f, struct data val)
162{
163 void *propend = val.val + val.len;
164 const char *bp = val.val;
165 struct marker *m = val.markers;
166
167 fprintf(f, "[");
168 for (;;) {
169 while (m && (m->offset == (bp-val.val))) {
170 if (m->type == LABEL)
171 fprintf(f, "%s: ", m->ref);
172 m = m->next;
173 }
174
175 fprintf(f, "%02hhx", *bp++);
176 if ((void *)bp >= propend)
177 break;
178 fprintf(f, " ");
179 }
180
181 /* Wrap up any labels at the end of the value */
182 for_each_marker_of_type(m, LABEL) {
183 assert (m->offset == val.len);
184 fprintf(f, " %s:", m->ref);
185 }
186 fprintf(f, "]");
187}
188
189static void write_propval(FILE *f, struct property *prop)
190{
191 int len = prop->val.len;
192 const char *p = prop->val.val;
193 struct marker *m = prop->val.markers;
194 int nnotstring = 0, nnul = 0;
195 int nnotstringlbl = 0, nnotcelllbl = 0;
196 int i;
197
198 if (len == 0) {
199 fprintf(f, ";\n");
200 return;
201 }
202
203 for (i = 0; i < len; i++) {
204 if (! isstring(p[i]))
205 nnotstring++;
206 if (p[i] == '\0')
207 nnul++;
208 }
209
210 for_each_marker_of_type(m, LABEL) {
211 if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
212 nnotstringlbl++;
213 if ((m->offset % sizeof(cell_t)) != 0)
214 nnotcelllbl++;
215 }
216
217 fprintf(f, " = ");
218 if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
219 && (nnotstringlbl == 0)) {
220 write_propval_string(f, prop->val);
221 } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
222 write_propval_cells(f, prop->val);
223 } else {
224 write_propval_bytes(f, prop->val);
225 }
226
227 fprintf(f, ";\n");
228}
229
230static void write_tree_source_node(FILE *f, struct node *tree, int level)
231{
232 struct property *prop;
233 struct node *child;
234
235 write_prefix(f, level);
236 if (tree->label)
237 fprintf(f, "%s: ", tree->label);
238 if (tree->name && (*tree->name))
239 fprintf(f, "%s {\n", tree->name);
240 else
241 fprintf(f, "/ {\n");
242
243 for_each_property(tree, prop) {
244 write_prefix(f, level+1);
245 if (prop->label)
246 fprintf(f, "%s: ", prop->label);
247 fprintf(f, "%s", prop->name);
248 write_propval(f, prop);
249 }
250 for_each_child(tree, child) {
251 fprintf(f, "\n");
252 write_tree_source_node(f, child, level+1);
253 }
254 write_prefix(f, level);
255 fprintf(f, "};\n");
256}
257
258
259void dt_to_source(FILE *f, struct boot_info *bi)
260{
261 struct reserve_info *re;
262
263 fprintf(f, "/dts-v1/;\n\n");
264
265 for (re = bi->reservelist; re; re = re->next) {
266 if (re->label)
267 fprintf(f, "%s: ", re->label);
268 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
269 (unsigned long long)re->re.address,
270 (unsigned long long)re->re.size);
271 }
272
273 write_tree_source_node(f, bi->dt, 0);
274}
275
diff --git a/arch/powerpc/boot/dtc-src/version_gen.h b/arch/powerpc/boot/dtc-src/version_gen.h
new file mode 100644
index 000000000000..6c343031538e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/version_gen.h
@@ -0,0 +1 @@
#define DTC_VERSION "DTC 1.0.0-gd6f9b62f"