2 * Copyright (C) 2010-2011 Marcin KoĆcielnicki <koriakin@0x04.net>
3 * Copyright (C) 2010 Luca Barbieri <luca@luca-barbieri.com>
4 * Copyright (C) 2010 Francisco Jerez <currojerez@riseup.net>
5 * Copyright (C) 2010 Martin Peres <martin.peres@ensi-bourges.fr>
6 * Copyright (C) 2010 Marcin Slusarz <marcin.slusarz@gmail.com>
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE.
29 /* workaround libxml2 silliness: */
30 #pragma GCC diagnostic ignored "-Wpointer-sign"
32 #include <libxml/xmlversion.h>
33 #include <libxml/parser.h>
34 #include <libxml/xpath.h>
35 #include <libxml/xmlreader.h>
44 #include "util/u_debug.h"
46 static char *catstr (char *a
, char *b
) {
49 return aprintf("%s_%s", a
, b
);
52 static int strdiff (const char *a
, const char *b
) {
60 static void rnn_err(struct rnndb
*db
, const char *format
, ...) _util_printf_format(2, 3);
62 static void rnn_err(struct rnndb
*db
, const char *format
, ...)
66 vfprintf(stderr
, format
, ap
);
76 struct rnndb
*rnn_newdb(void) {
77 struct rnndb
*db
= calloc(sizeof *db
, 1);
81 static char *getcontent (xmlNode
*attr
) {
82 xmlNode
*chain
= attr
->children
;
86 if (chain
->type
== XML_TEXT_NODE
)
87 size
+= strlen(chain
->content
);
90 p
= content
= malloc(size
+ 1);
91 chain
= attr
->children
;
93 if (chain
->type
== XML_TEXT_NODE
) {
94 char* sp
= chain
->content
;
99 size_t len
= strlen(sp
);
105 while(p
!= content
&& isspace(p
[-1]))
111 static char *getattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
112 xmlNode
*chain
= attr
->children
;
114 if (chain
->type
!= XML_TEXT_NODE
) {
115 rnn_err(db
, "%s:%d: unknown attribute child \"%s\" in attribute \"%s\"\n", file
, line
, chain
->name
, attr
->name
);
117 return chain
->content
;
124 static int getboolattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
125 char *c
= getattrib(db
, file
, line
, attr
);
126 if (!strcmp(c
, "yes") || !strcmp(c
, "1") || !strcmp(c
, "true"))
128 if (!strcmp(c
, "no") || !strcmp(c
, "0") || !strcmp(c
, "false"))
130 rnn_err(db
, "%s:%d: invalid boolean value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
134 static uint64_t getnum(struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
, char *c
)
138 if (strchr(c
, 'x') || strchr(c
, 'X'))
139 res
= strtoull(c
, &cc
, 16);
141 res
= strtoull(c
, &cc
, 10);
143 rnn_err(db
, "%s:%d: invalid numeric value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
148 static uint64_t getnumattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
149 char *c
= getattrib(db
, file
, line
, attr
);
150 return getnum(db
, file
, line
, attr
, c
);
153 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
);
155 static int trydoc (struct rnndb
*db
, char *file
, xmlNode
*node
) {
156 if (!strcmp(node
->name
, "brief")) {
158 } else if (!strcmp(node
->name
, "doc")) {
164 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
);
165 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
);
167 static int trytypetag (struct rnndb
*db
, char *file
, xmlNode
*node
, struct rnntypeinfo
*ti
) {
168 if (!strcmp(node
->name
, "value")) {
169 struct rnnvalue
*val
= parsevalue(db
, file
, node
);
171 ADDARRAY(ti
->vals
, val
);
173 } else if (!strcmp(node
->name
, "bitfield")) {
174 struct rnnbitfield
*bf
= parsebitfield(db
, file
, node
);
176 ADDARRAY(ti
->bitfields
, bf
);
181 static int trytypeattr (struct rnndb
*db
, char *file
, xmlNode
*node
, xmlAttr
*attr
, struct rnntypeinfo
*ti
) {
182 if (!strcmp(attr
->name
, "shr")) {
183 ti
->shr
= getnumattrib(db
, file
, node
->line
, attr
);
185 } else if (!strcmp(attr
->name
, "min")) {
186 ti
->min
= getnumattrib(db
, file
, node
->line
, attr
);
189 } else if (!strcmp(attr
->name
, "max")) {
190 ti
->max
= getnumattrib(db
, file
, node
->line
, attr
);
193 } else if (!strcmp(attr
->name
, "align")) {
194 ti
->align
= getnumattrib(db
, file
, node
->line
, attr
);
197 } else if (!strcmp(attr
->name
, "type")) {
198 ti
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));;
200 } else if (!strcmp(attr
->name
, "radix")) {
201 ti
->radix
= getnumattrib(db
, file
, node
->line
, attr
);
204 } else if (!strcmp(attr
->name
, "pos")) {
205 ti
->high
= ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
207 } else if (!strcmp(attr
->name
, "low")) {
208 ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
210 } else if (!strcmp(attr
->name
, "high")) {
211 ti
->high
= getnumattrib(db
, file
, node
->line
, attr
);
213 } else if (!strcmp(attr
->name
, "addvariant")) {
214 ti
->addvariant
= getboolattrib(db
, file
, node
->line
, attr
);
220 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
) {
221 struct rnnvalue
*val
= calloc(sizeof *val
, 1);
223 xmlAttr
*attr
= node
->properties
;
225 if (!strcmp(attr
->name
, "name")) {
226 val
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
227 } else if (!strcmp(attr
->name
, "value")) {
228 val
->value
= getnumattrib(db
, file
, node
->line
, attr
);
230 } else if (!strcmp(attr
->name
, "varset")) {
231 val
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
232 } else if (!strcmp(attr
->name
, "variants")) {
233 val
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
235 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for value\n", file
, node
->line
, attr
->name
);
239 xmlNode
*chain
= node
->children
;
241 if (chain
->type
!= XML_ELEMENT_NODE
) {
242 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
243 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
248 rnn_err(db
, "%s:%d: nameless value\n", file
, node
->line
);
255 static void parsespectype(struct rnndb
*db
, char *file
, xmlNode
*node
) {
256 struct rnnspectype
*res
= calloc (sizeof *res
, 1);
258 xmlAttr
*attr
= node
->properties
;
261 if (!strcmp(attr
->name
, "name")) {
262 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
263 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
264 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for spectype\n", file
, node
->line
, attr
->name
);
269 rnn_err(db
, "%s:%d: nameless spectype\n", file
, node
->line
);
272 for (i
= 0; i
< db
->spectypesnum
; i
++)
273 if (!strcmp(db
->spectypes
[i
]->name
, res
->name
)) {
274 rnn_err(db
, "%s:%d: duplicated spectype name %s\n", file
, node
->line
, res
->name
);
277 ADDARRAY(db
->spectypes
, res
);
278 xmlNode
*chain
= node
->children
;
280 if (chain
->type
!= XML_ELEMENT_NODE
) {
281 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
282 rnn_err(db
, "%s:%d: wrong tag in spectype: <%s>\n", file
, chain
->line
, chain
->name
);
288 static void parseenum(struct rnndb
*db
, char *file
, xmlNode
*node
) {
289 xmlAttr
*attr
= node
->properties
;
295 char *variantsstr
= 0;
298 if (!strcmp(attr
->name
, "name")) {
299 name
= getattrib(db
, file
, node
->line
, attr
);
300 } else if (!strcmp(attr
->name
, "bare")) {
301 bare
= getboolattrib(db
, file
, node
->line
, attr
);
302 } else if (!strcmp(attr
->name
, "inline")) {
303 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
304 } else if (!strcmp(attr
->name
, "prefix")) {
305 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
306 } else if (!strcmp(attr
->name
, "varset")) {
307 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
308 } else if (!strcmp(attr
->name
, "variants")) {
309 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
311 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for enum\n", file
, node
->line
, attr
->name
);
316 rnn_err(db
, "%s:%d: nameless enum\n", file
, node
->line
);
319 struct rnnenum
*cur
= 0;
320 for (i
= 0; i
< db
->enumsnum
; i
++)
321 if (!strcmp(db
->enums
[i
]->name
, name
)) {
326 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
327 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
328 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
329 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
330 rnn_err(db
, "%s:%d: merge fail for enum %s\n", file
, node
->line
, node
->name
);
333 cur
= calloc(sizeof *cur
, 1);
334 cur
->name
= strdup(name
);
335 cur
->isinline
= isinline
;
337 cur
->varinfo
.prefixstr
= prefixstr
;
338 cur
->varinfo
.varsetstr
= varsetstr
;
339 cur
->varinfo
.variantsstr
= variantsstr
;
341 ADDARRAY(db
->enums
, cur
);
343 xmlNode
*chain
= node
->children
;
345 if (chain
->type
!= XML_ELEMENT_NODE
) {
346 } else if (!strcmp(chain
->name
, "value")) {
347 struct rnnvalue
*val
= parsevalue(db
, file
, chain
);
349 ADDARRAY(cur
->vals
, val
);
350 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
351 rnn_err(db
, "%s:%d: wrong tag in enum: <%s>\n", file
, chain
->line
, chain
->name
);
357 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
) {
358 struct rnnbitfield
*bf
= calloc(sizeof *bf
, 1);
360 xmlAttr
*attr
= node
->properties
;
361 bf
->typeinfo
.low
= bf
->typeinfo
.high
= -1;
363 if (!strcmp(attr
->name
, "name")) {
364 bf
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
365 } else if (!strcmp(attr
->name
, "varset")) {
366 bf
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
367 } else if (!strcmp(attr
->name
, "variants")) {
368 bf
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
369 } else if (!trytypeattr(db
, file
, node
, attr
, &bf
->typeinfo
)) {
370 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for bitfield\n", file
, node
->line
, attr
->name
);
374 xmlNode
*chain
= node
->children
;
376 if (chain
->type
!= XML_ELEMENT_NODE
) {
377 } else if (!trytypetag(db
, file
, chain
, &bf
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
378 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
383 rnn_err(db
, "%s:%d: nameless bitfield\n", file
, node
->line
);
385 } else if (bf
->typeinfo
.low
< 0|| bf
->typeinfo
.high
< 0 || bf
->typeinfo
.high
< bf
->typeinfo
.low
) {
386 rnn_err(db
, "%s:%d: bitfield has wrong placement\n", file
, node
->line
);
393 static void parsebitset(struct rnndb
*db
, char *file
, xmlNode
*node
) {
394 xmlAttr
*attr
= node
->properties
;
400 char *variantsstr
= 0;
403 if (!strcmp(attr
->name
, "name")) {
404 name
= getattrib(db
, file
, node
->line
, attr
);
405 } else if (!strcmp(attr
->name
, "bare")) {
406 bare
= getboolattrib(db
, file
, node
->line
, attr
);
407 } else if (!strcmp(attr
->name
, "inline")) {
408 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
409 } else if (!strcmp(attr
->name
, "prefix")) {
410 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
411 } else if (!strcmp(attr
->name
, "varset")) {
412 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
413 } else if (!strcmp(attr
->name
, "variants")) {
414 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
416 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for bitset\n", file
, node
->line
, attr
->name
);
421 rnn_err(db
, "%s:%d: nameless bitset\n", file
, node
->line
);
424 struct rnnbitset
*cur
= 0;
425 for (i
= 0; i
< db
->bitsetsnum
; i
++)
426 if (!strcmp(db
->bitsets
[i
]->name
, name
)) {
427 cur
= db
->bitsets
[i
];
431 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
432 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
433 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
434 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
435 rnn_err(db
, "%s:%d: merge fail for bitset %s\n", file
, node
->line
, node
->name
);
438 cur
= calloc(sizeof *cur
, 1);
439 cur
->name
= strdup(name
);
440 cur
->isinline
= isinline
;
442 cur
->varinfo
.prefixstr
= prefixstr
;
443 cur
->varinfo
.varsetstr
= varsetstr
;
444 cur
->varinfo
.variantsstr
= variantsstr
;
446 ADDARRAY(db
->bitsets
, cur
);
448 xmlNode
*chain
= node
->children
;
450 if (chain
->type
!= XML_ELEMENT_NODE
) {
451 } else if (!strcmp(chain
->name
, "bitfield")) {
452 struct rnnbitfield
*bf
= parsebitfield(db
, file
, chain
);
454 ADDARRAY(cur
->bitfields
, bf
);
455 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
456 rnn_err(db
, "%s:%d: wrong tag in bitset: <%s>\n", file
, chain
->line
, chain
->name
);
462 static struct rnndelem
*trydelem(struct rnndb
*db
, char *file
, xmlNode
*node
) {
463 if (!strcmp(node
->name
, "use-group")) {
464 struct rnndelem
*res
= calloc(sizeof *res
, 1);
466 res
->type
= RNN_ETYPE_USE_GROUP
;
467 xmlAttr
*attr
= node
->properties
;
469 if (!strcmp(attr
->name
, "ref")) {
470 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
472 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
477 rnn_err(db
, "%s:%d: nameless use-group\n", file
, node
->line
);
481 } else if (!strcmp(node
->name
, "stripe") || !strcmp(node
->name
, "array")) {
482 struct rnndelem
*res
= calloc(sizeof *res
, 1);
483 if (!strcmp(node
->name
, "array"))
485 res
->type
= (strcmp(node
->name
, "stripe")?RNN_ETYPE_ARRAY
:RNN_ETYPE_STRIPE
);
488 xmlAttr
*attr
= node
->properties
;
490 if (!strcmp(attr
->name
, "name")) {
491 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
492 } else if (!strcmp(attr
->name
, "offset")) {
493 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
494 } else if (!strcmp(attr
->name
, "offsets")) {
495 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
496 char *tok
, *save
, *tmp
= str
;
497 while ((tok
= strtok_r(str
, ",", &save
))) {
498 uint64_t offset
= getnum(db
, file
, node
->line
, attr
, tok
);
499 ADDARRAY(res
->offsets
, offset
);
503 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
505 } else if (!strcmp(attr
->name
, "doffset")) {
506 /* dynamic runtime determined offset: */
507 res
->doffset
= strdup(getattrib(db
, file
, node
->line
, attr
));
508 } else if (!strcmp(attr
->name
, "doffsets")) {
509 /* dynamic runtime determined offsets: */
510 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
511 char *tok
, *save
, *tmp
= str
;
512 while ((tok
= strtok_r(str
, ",", &save
))) {
513 char *doffset
= strdup(tok
);
514 ADDARRAY(res
->doffsets
, doffset
);
518 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
520 } else if (!strcmp(attr
->name
, "length")) {
521 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
522 } else if (!strcmp(attr
->name
, "stride")) {
523 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
524 } else if (!strcmp(attr
->name
, "prefix")) {
525 res
->varinfo
.prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
526 } else if (!strcmp(attr
->name
, "varset")) {
527 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
528 } else if (!strcmp(attr
->name
, "variants")) {
529 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
530 } else if (!strcmp(attr
->name
, "index")) {
531 const char *enumname
= getattrib(db
, file
, node
->line
, attr
);
532 res
->index
= rnn_findenum(db
, enumname
);
534 rnn_err(db
, "%s:%d: invalid enum name \"%s\"\n", file
, node
->line
, enumname
);
537 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
541 xmlNode
*chain
= node
->children
;
543 struct rnndelem
*delem
;
544 if (chain
->type
!= XML_ELEMENT_NODE
) {
545 } else if ((delem
= trydelem(db
, file
, chain
))) {
546 ADDARRAY(res
->subelems
, delem
);
547 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
548 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
553 /* Sanity checking */
554 if (res
->type
== RNN_ETYPE_ARRAY
&& res
->stride
== 0) {
555 fprintf(stderr
, "%s: Array %s's stride is undefined. Aborting.\n", file
, res
->name
);
562 if (!strcmp(node
->name
, "reg8"))
564 else if (!strcmp(node
->name
, "reg16"))
566 else if (!strcmp(node
->name
, "reg32"))
568 else if (!strcmp(node
->name
, "reg64"))
572 struct rnndelem
*res
= calloc(sizeof *res
, 1);
574 res
->type
= RNN_ETYPE_REG
;
577 res
->access
= RNN_ACCESS_RW
;
578 xmlAttr
*attr
= node
->properties
;
579 res
->typeinfo
.low
= 0;
580 res
->typeinfo
.high
= width
- 1;
582 if (!strcmp(attr
->name
, "name")) {
583 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
584 } else if (!strcmp(attr
->name
, "offset")) {
585 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
586 } else if (!strcmp(attr
->name
, "length")) {
587 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
588 } else if (!strcmp(attr
->name
, "stride")) {
589 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
590 } else if (!strcmp(attr
->name
, "varset")) {
591 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
592 } else if (!strcmp(attr
->name
, "variants")) {
593 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
594 } else if (!strcmp(attr
->name
, "access")) {
595 char *str
= getattrib(db
, file
, node
->line
, attr
);
596 if (!strcmp(str
, "r"))
597 res
->access
= RNN_ACCESS_R
;
598 else if (!strcmp(str
, "w"))
599 res
->access
= RNN_ACCESS_W
;
600 else if (!strcmp(str
, "rw"))
601 res
->access
= RNN_ACCESS_RW
;
603 fprintf (stderr
, "%s:%d: wrong access type \"%s\" for register\n", file
, node
->line
, str
);
604 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
605 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for register\n", file
, node
->line
, attr
->name
);
609 xmlNode
*chain
= node
->children
;
611 if (chain
->type
!= XML_ELEMENT_NODE
) {
612 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
613 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
618 rnn_err(db
, "%s:%d: nameless register\n", file
, node
->line
);
625 static void parsegroup(struct rnndb
*db
, char *file
, xmlNode
*node
) {
626 xmlAttr
*attr
= node
->properties
;
630 if (!strcmp(attr
->name
, "name")) {
631 name
= getattrib(db
, file
, node
->line
, attr
);
633 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for group\n", file
, node
->line
, attr
->name
);
638 rnn_err(db
, "%s:%d: nameless group\n", file
, node
->line
);
641 struct rnngroup
*cur
= 0;
642 for (i
= 0; i
< db
->groupsnum
; i
++)
643 if (!strcmp(db
->groups
[i
]->name
, name
)) {
648 cur
= calloc(sizeof *cur
, 1);
649 cur
->name
= strdup(name
);
650 ADDARRAY(db
->groups
, cur
);
652 xmlNode
*chain
= node
->children
;
654 struct rnndelem
*delem
;
655 if (chain
->type
!= XML_ELEMENT_NODE
) {
656 } else if ((delem
= trydelem(db
, file
, chain
))) {
657 ADDARRAY(cur
->subelems
, delem
);
658 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
659 rnn_err(db
, "%s:%d: wrong tag in group: <%s>\n", file
, chain
->line
, chain
->name
);
665 static void parsedomain(struct rnndb
*db
, char *file
, xmlNode
*node
) {
666 xmlAttr
*attr
= node
->properties
;
668 uint64_t size
= 0; int width
= 8;
672 char *variantsstr
= 0;
675 if (!strcmp(attr
->name
, "name")) {
676 name
= getattrib(db
, file
, node
->line
, attr
);
677 } else if (!strcmp(attr
->name
, "bare")) {
678 bare
= getboolattrib(db
, file
, node
->line
, attr
);
679 } else if (!strcmp(attr
->name
, "size")) {
680 size
= getnumattrib(db
, file
, node
->line
, attr
);
681 } else if (!strcmp(attr
->name
, "width")) {
682 width
= getnumattrib(db
, file
, node
->line
, attr
);
683 } else if (!strcmp(attr
->name
, "prefix")) {
684 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
685 } else if (!strcmp(attr
->name
, "varset")) {
686 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
687 } else if (!strcmp(attr
->name
, "variants")) {
688 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
690 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for domain\n", file
, node
->line
, attr
->name
);
695 rnn_err(db
, "%s:%d: nameless domain\n", file
, node
->line
);
698 struct rnndomain
*cur
= 0;
699 for (i
= 0; i
< db
->domainsnum
; i
++)
700 if (!strcmp(db
->domains
[i
]->name
, name
)) {
701 cur
= db
->domains
[i
];
705 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
706 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
707 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
708 cur
->width
!= width
||
710 (size
&& cur
->size
&& size
!= cur
->size
)) {
711 rnn_err(db
, "%s:%d: merge fail for domain %s\n", file
, node
->line
, node
->name
);
717 cur
= calloc(sizeof *cur
, 1);
718 cur
->name
= strdup(name
);
722 cur
->varinfo
.prefixstr
= prefixstr
;
723 cur
->varinfo
.varsetstr
= varsetstr
;
724 cur
->varinfo
.variantsstr
= variantsstr
;
726 ADDARRAY(db
->domains
, cur
);
728 xmlNode
*chain
= node
->children
;
730 struct rnndelem
*delem
;
731 if (chain
->type
!= XML_ELEMENT_NODE
) {
732 } else if ((delem
= trydelem(db
, file
, chain
))) {
733 ADDARRAY(cur
->subelems
, delem
);
734 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
735 rnn_err(db
, "%s:%d: wrong tag in domain: <%s>\n", file
, chain
->line
, chain
->name
);
741 static void parsecopyright(struct rnndb
*db
, char *file
, xmlNode
*node
) {
742 struct rnncopyright
* copyright
= &db
->copyright
;
743 xmlAttr
*attr
= node
->properties
;
745 if (!strcmp(attr
->name
, "year")) {
746 unsigned firstyear
= getnumattrib(db
, file
, node
->line
, attr
);
747 if(!copyright
->firstyear
|| firstyear
< copyright
->firstyear
)
748 copyright
->firstyear
= firstyear
;
750 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for copyright\n", file
, node
->line
, attr
->name
);
754 xmlNode
*chain
= node
->children
;
756 if (chain
->type
!= XML_ELEMENT_NODE
) {
757 } else if (!strcmp(chain
->name
, "license"))
758 if(copyright
->license
) {
759 if(strcmp(copyright
->license
, node
->content
)) {
760 fprintf(stderr
, "fatal error: multiple different licenses specified!\n");
761 abort(); /* TODO: do something better here, but headergen, xml2html, etc. should not produce anything in this case */
764 copyright
->license
= getcontent(chain
);
765 else if (!strcmp(chain
->name
, "author")) {
766 struct rnnauthor
* author
= calloc(sizeof *author
, 1);
767 xmlAttr
* authorattr
= chain
->properties
;
768 xmlNode
*authorchild
= chain
->children
;
769 author
->contributions
= getcontent(chain
);
771 if (!strcmp(authorattr
->name
, "name"))
772 author
->name
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
773 else if (!strcmp(authorattr
->name
, "email"))
774 author
->email
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
776 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for author\n", file
, chain
->line
, authorattr
->name
);
778 authorattr
= authorattr
->next
;
781 if (authorchild
->type
!= XML_ELEMENT_NODE
) {
782 } else if (!strcmp(authorchild
->name
, "nick")) {
783 xmlAttr
* nickattr
= authorchild
->properties
;
786 if (!strcmp(nickattr
->name
, "name"))
787 nickname
= strdup(getattrib(db
, file
, authorchild
->line
, nickattr
));
789 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for nick\n", file
, authorchild
->line
, nickattr
->name
);
791 nickattr
= nickattr
->next
;
794 rnn_err(db
, "%s:%d: missing \"name\" attribute for nick\n", file
, authorchild
->line
);
796 ADDARRAY(author
->nicknames
, nickname
);
798 rnn_err(db
, "%s:%d: wrong tag in author: <%s>\n", file
, authorchild
->line
, authorchild
->name
);
800 authorchild
= authorchild
->next
;
802 ADDARRAY(copyright
->authors
, author
);
804 rnn_err(db
, "%s:%d: wrong tag in copyright: <%s>\n", file
, chain
->line
, chain
->name
);
810 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
) {
811 if (!strcmp(node
->name
, "enum")) {
812 parseenum(db
, file
, node
);
814 } else if (!strcmp(node
->name
, "bitset")) {
815 parsebitset(db
, file
, node
);
817 } else if (!strcmp(node
->name
, "group")) {
818 parsegroup(db
, file
, node
);
820 } else if (!strcmp(node
->name
, "domain")) {
821 parsedomain(db
, file
, node
);
823 } else if (!strcmp(node
->name
, "spectype")) {
824 parsespectype(db
, file
, node
);
826 } else if (!strcmp(node
->name
, "import")) {
827 xmlAttr
*attr
= node
->properties
;
830 if (!strcmp(attr
->name
, "file")) {
831 subfile
= getattrib(db
, file
, node
->line
, attr
);
833 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for import\n", file
, node
->line
, attr
->name
);
838 rnn_err(db
, "%s:%d: missing \"file\" attribute for import\n", file
, node
->line
);
840 rnn_parsefile(db
, subfile
);
843 } else if (!strcmp(node
->name
, "copyright")) {
844 parsecopyright(db
, file
, node
);
850 static char * find_file(const char *file_orig
)
852 const char *rnn_path
= getenv("RNN_PATH");
856 rnn_path
= RNN_DEF_PATH
;
858 FILE *file
= find_in_path(file_orig
, rnn_path
, &fname
);
860 fprintf (stderr
, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", file_orig
);
868 static int validate_doc(struct rnndb
*db
, xmlDocPtr doc
, xmlNodePtr database
)
870 /* find the schemaLocation property: */
871 xmlAttrPtr attr
= database
->properties
;
872 const char *schema_name
= NULL
;
876 if (!strcmp(attr
->name
, "schemaLocation")) {
877 xmlNodePtr data
= attr
->children
;
878 schema_name
= data
->content
;
879 /* we expect this to look like <namespace url> schema.xsd.. I think
880 * technically it is supposed to be just a URL, but that doesn't
881 * quite match up to what we do.. Just skip over everything up to
882 * and including the first whitespace character:
884 while (schema_name
&& (schema_name
[0] != ' '))
892 rnn_err(db
, "could not find schema. Missing schemaLocation?");
896 schema_path
= find_file(schema_name
);
898 rnn_err(db
, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", schema_name
);
902 xmlSchemaParserCtxtPtr parser
= xmlSchemaNewParserCtxt(schema_path
);
903 xmlSchemaPtr schema
= xmlSchemaParse(parser
);
904 xmlSchemaValidCtxtPtr validCtxt
= xmlSchemaNewValidCtxt(schema
);
905 int ret
= xmlSchemaValidateDoc(validCtxt
, doc
);
907 xmlSchemaFreeValidCtxt(validCtxt
);
908 xmlSchemaFree(schema
);
909 xmlSchemaFreeParserCtxt(parser
);
916 void rnn_parsefile (struct rnndb
*db
, char *file_orig
) {
920 fname
= find_file(file_orig
);
926 for (i
= 0; i
< db
->filesnum
; i
++)
927 if (!strcmp(db
->files
[i
], fname
))
930 ADDARRAY(db
->files
, fname
);
931 xmlDocPtr doc
= xmlParseFile(fname
);
933 rnn_err(db
, "%s: couldn't open database file. Please set the env var RNN_PATH.\n", fname
);
936 xmlNode
*root
= doc
->children
;
938 if (root
->type
!= XML_ELEMENT_NODE
) {
939 } else if (strcmp(root
->name
, "database")) {
940 rnn_err(db
, "%s:%d: wrong top-level tag <%s>\n", fname
, root
->line
, root
->name
);
942 xmlNode
*chain
= root
->children
;
943 if (validate_doc(db
, doc
, root
)) {
944 rnn_err(db
, "%s: database file has errors\n", fname
);
948 if (chain
->type
!= XML_ELEMENT_NODE
) {
949 } else if (!trytop(db
, fname
, chain
) && !trydoc(db
, fname
, chain
)) {
950 rnn_err(db
, "%s:%d: wrong tag in database: <%s>\n", fname
, chain
->line
, chain
->name
);
960 static struct rnnvalue
*copyvalue (struct rnnvalue
*val
, char *file
) {
961 struct rnnvalue
*res
= calloc (sizeof *res
, 1);
962 res
->name
= val
->name
;
963 res
->valvalid
= val
->valvalid
;
964 res
->value
= val
->value
;
965 res
->varinfo
= val
->varinfo
;
970 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
);
973 static void copytypeinfo (struct rnntypeinfo
*dst
, struct rnntypeinfo
*src
, char *file
) {
975 dst
->name
= src
->name
;
978 dst
->high
= src
->high
;
981 dst
->align
= src
->align
;
982 dst
->addvariant
= src
->addvariant
;
983 for (i
= 0; i
< src
->valsnum
; i
++)
984 ADDARRAY(dst
->vals
, copyvalue(src
->vals
[i
], file
));
985 for (i
= 0; i
< src
->bitfieldsnum
; i
++)
986 ADDARRAY(dst
->bitfields
, copybitfield(src
->bitfields
[i
], file
));
989 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
) {
990 struct rnnbitfield
*res
= calloc (sizeof *res
, 1);
991 res
->name
= bf
->name
;
992 res
->varinfo
= bf
->varinfo
;
994 copytypeinfo(&res
->typeinfo
, &bf
->typeinfo
, file
);
998 static struct rnndelem
*copydelem (struct rnndelem
*elem
, char *file
) {
999 struct rnndelem
*res
= calloc (sizeof *res
, 1);
1000 res
->type
= elem
->type
;
1001 res
->name
= elem
->name
;
1002 res
->width
= elem
->width
;
1003 res
->access
= elem
->access
;
1004 res
->offset
= elem
->offset
;
1005 res
->length
= elem
->length
;
1006 res
->stride
= elem
->stride
;
1007 res
->varinfo
= elem
->varinfo
;
1009 copytypeinfo(&res
->typeinfo
, &elem
->typeinfo
, file
);
1011 for (i
= 0; i
< elem
->subelemsnum
; i
++)
1012 ADDARRAY(res
->subelems
, copydelem(elem
->subelems
[i
], file
));
1013 for (i
= 0; i
< elem
->offsetsnum
; i
++)
1014 ADDARRAY(res
->offsets
, elem
->offsets
[i
]);
1018 static struct rnnvarset
*copyvarset (struct rnnvarset
*varset
) {
1019 struct rnnvarset
*res
= calloc(sizeof *res
, 1);
1020 res
->venum
= varset
->venum
;
1021 res
->variants
= calloc(sizeof *res
->variants
, res
->venum
->valsnum
);
1023 for (i
= 0; i
< res
->venum
->valsnum
; i
++)
1024 res
->variants
[i
] = varset
->variants
[i
];
1028 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
);
1030 static int findvidx (struct rnndb
*db
, struct rnnenum
*en
, char *name
) {
1032 for (i
= 0; i
< en
->valsnum
; i
++)
1033 if (!strcmp(en
->vals
[i
]->name
, name
))
1035 rnn_err(db
, "Cannot find variant %s in enum %s!\n", name
, en
->name
);
1039 static void prepvarinfo (struct rnndb
*db
, char *what
, struct rnnvarinfo
*vi
, struct rnnvarinfo
*parent
) {
1041 vi
->prefenum
= parent
->prefenum
;
1042 if (vi
->prefixstr
) {
1043 if (!strcmp(vi
->prefixstr
, "none"))
1046 vi
->prefenum
= rnn_findenum(db
, vi
->prefixstr
); // XXX
1050 for (i
= 0; i
< parent
->varsetsnum
; i
++)
1051 ADDARRAY(vi
->varsets
, copyvarset(parent
->varsets
[i
]));
1052 struct rnnenum
*varset
= vi
->prefenum
;
1053 if (!varset
&& !vi
->varsetstr
&& parent
)
1054 vi
->varsetstr
= parent
->varsetstr
;
1056 varset
= rnn_findenum(db
, vi
->varsetstr
);
1057 if (vi
->variantsstr
) {
1058 char *vars
= vi
->variantsstr
;
1060 rnn_err(db
, "%s: tried to use variants without active varset!\n", what
);
1063 struct rnnvarset
*vs
= 0;
1064 int nvars
= varset
->valsnum
;
1065 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1066 if (vi
->varsets
[i
]->venum
== varset
) {
1067 vs
= vi
->varsets
[i
];
1071 vs
= calloc (sizeof *vs
, 1);
1073 vs
->variants
= calloc(sizeof *vs
->variants
, nvars
);
1074 for (i
= 0; i
< nvars
; i
++)
1075 vs
->variants
[i
] = 1;
1076 ADDARRAY(vi
->varsets
, vs
);
1079 while (*vars
== ' ') vars
++;
1083 while (*split
!= ':' && *split
!= '-' && *split
!= ' ' && *split
!= 0)
1087 first
= strndup(vars
, split
-vars
);
1088 if (*split
== ' ' || *split
== 0) {
1089 int idx
= findvidx(db
, varset
, first
);
1091 vs
->variants
[idx
] |= 2;
1094 char *end
= split
+1;
1095 while (*end
!= ' ' && *end
!= 0)
1099 second
= strndup(split
+1, end
-split
-1);
1102 idx1
= findvidx(db
, varset
, first
);
1105 idx2
= findvidx(db
, varset
, second
);
1109 if (idx1
!= -1 && idx2
!= -1)
1110 for (i
= idx1
; i
< idx2
; i
++)
1111 vs
->variants
[i
] |= 2;
1118 for (i
= 0; i
< nvars
; i
++) {
1119 vs
->variants
[i
] = (vs
->variants
[i
] == 3);
1120 if (vs
->variants
[i
])
1127 struct rnnvarset
*vs
= 0;
1128 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1129 if (vi
->varsets
[i
]->venum
== vi
->prefenum
) {
1130 vs
= vi
->varsets
[i
];
1134 for (i
= 0; i
< vi
->prefenum
->valsnum
; i
++)
1135 if (vs
->variants
[i
]) {
1136 vi
->prefix
= vi
->prefenum
->vals
[i
]->name
;
1140 vi
->prefix
= vi
->prefenum
->vals
[0]->name
;
1145 static void prepvalue(struct rnndb
*db
, struct rnnvalue
*val
, char *prefix
, struct rnnvarinfo
*parvi
) {
1146 val
->fullname
= catstr(prefix
, val
->name
);
1147 prepvarinfo (db
, val
->fullname
, &val
->varinfo
, parvi
);
1148 if (val
->varinfo
.dead
)
1150 if (val
->varinfo
.prefix
)
1151 val
->fullname
= catstr(val
->varinfo
.prefix
, val
->fullname
);
1154 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
);
1156 static void preptypeinfo(struct rnndb
*db
, struct rnntypeinfo
*ti
, char *prefix
, struct rnnvarinfo
*vi
, char *file
) {
1159 struct rnnenum
*en
= rnn_findenum (db
, ti
->name
);
1160 struct rnnbitset
*bs
= rnn_findbitset (db
, ti
->name
);
1161 struct rnnspectype
*st
= rnn_findspectype (db
, ti
->name
);
1164 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1166 for (j
= 0; j
< en
->valsnum
; j
++)
1167 ADDARRAY(ti
->vals
, copyvalue(en
->vals
[j
], file
));
1169 ti
->type
= RNN_TTYPE_ENUM
;
1174 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1176 for (j
= 0; j
< bs
->bitfieldsnum
; j
++)
1177 ADDARRAY(ti
->bitfields
, copybitfield(bs
->bitfields
[j
], file
));
1179 ti
->type
= RNN_TTYPE_BITSET
;
1183 ti
->type
= RNN_TTYPE_SPECTYPE
;
1185 } else if (!strcmp(ti
->name
, "hex")) {
1186 ti
->type
= RNN_TTYPE_HEX
;
1187 } else if (!strcmp(ti
->name
, "float")) {
1188 ti
->type
= RNN_TTYPE_FLOAT
;
1189 } else if (!strcmp(ti
->name
, "uint")) {
1190 ti
->type
= RNN_TTYPE_UINT
;
1191 } else if (!strcmp(ti
->name
, "int")) {
1192 ti
->type
= RNN_TTYPE_INT
;
1193 } else if (!strcmp(ti
->name
, "boolean")) {
1194 ti
->type
= RNN_TTYPE_BOOLEAN
;
1195 } else if (!strcmp(ti
->name
, "bitfield")) {
1196 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1197 } else if (!strcmp(ti
->name
, "enum")) {
1198 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1199 } else if (!strcmp(ti
->name
, "fixed")) {
1200 ti
->type
= RNN_TTYPE_FIXED
;
1201 } else if (!strcmp(ti
->name
, "ufixed")) {
1202 ti
->type
= RNN_TTYPE_UFIXED
;
1203 } else if (!strcmp(ti
->name
, "a3xx_regid")) {
1204 ti
->type
= RNN_TTYPE_A3XX_REGID
;
1205 } else if (!strcmp(ti
->name
, "waddress") || !strcmp(ti
->name
, "address")) {
1206 ti
->type
= RNN_TTYPE_HEX
;
1208 ti
->type
= RNN_TTYPE_HEX
;
1209 rnn_err(db
, "%s: unknown type %s\n", prefix
, ti
->name
);
1211 } else if (ti
->bitfieldsnum
) {
1212 ti
->name
= "bitfield";
1213 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1214 } else if (ti
->valsnum
) {
1216 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1217 } else if (ti
->low
== 0 && ti
->high
== 0) {
1218 ti
->name
= "boolean";
1219 ti
->type
= RNN_TTYPE_BOOLEAN
;
1222 ti
->type
= RNN_TTYPE_HEX
;
1224 if (ti
->addvariant
&& ti
->type
!= RNN_TTYPE_ENUM
) {
1225 rnn_err(db
, "%s: addvariant specified on non-enum type %s\n", prefix
, ti
->name
);
1227 for (i
= 0; i
< ti
->bitfieldsnum
; i
++)
1228 prepbitfield(db
, ti
->bitfields
[i
], prefix
, vi
);
1229 for (i
= 0; i
< ti
->valsnum
; i
++)
1230 prepvalue(db
, ti
->vals
[i
], prefix
, vi
);
1233 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
) {
1234 bf
->fullname
= catstr(prefix
, bf
->name
);
1235 prepvarinfo (db
, bf
->fullname
, &bf
->varinfo
, parvi
);
1236 if (bf
->varinfo
.dead
)
1238 preptypeinfo(db
, &bf
->typeinfo
, bf
->fullname
, &bf
->varinfo
, bf
->file
);
1239 if (bf
->varinfo
.prefix
)
1240 bf
->fullname
= catstr(bf
->varinfo
.prefix
, bf
->fullname
);
1243 static void prepdelem(struct rnndb
*db
, struct rnndelem
*elem
, char *prefix
, struct rnnvarinfo
*parvi
, int width
) {
1244 if (elem
->type
== RNN_ETYPE_USE_GROUP
) {
1246 struct rnngroup
*gr
= 0;
1247 for (i
= 0; i
< db
->groupsnum
; i
++)
1248 if (!strcmp(db
->groups
[i
]->name
, elem
->name
)) {
1253 for (i
= 0; i
< gr
->subelemsnum
; i
++)
1254 ADDARRAY(elem
->subelems
, copydelem(gr
->subelems
[i
], elem
->file
));
1256 rnn_err(db
, "group %s not found!\n", elem
->name
);
1258 elem
->type
= RNN_ETYPE_STRIPE
;
1263 elem
->fullname
= catstr(prefix
, elem
->name
);
1264 prepvarinfo (db
, elem
->fullname
?elem
->fullname
:prefix
, &elem
->varinfo
, parvi
);
1265 if (elem
->varinfo
.dead
)
1267 if (elem
->length
!= 1 && !elem
->stride
) {
1268 if (elem
->type
!= RNN_ETYPE_REG
) {
1269 rnn_err(db
, "%s has non-1 length, but no stride!\n", elem
->fullname
);
1271 elem
->stride
= elem
->width
/width
;
1274 preptypeinfo(db
, &elem
->typeinfo
, elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, elem
->file
);
1277 for (i
= 0; i
< elem
->subelemsnum
; i
++)
1278 prepdelem(db
, elem
->subelems
[i
], elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, width
);
1279 if (elem
->varinfo
.prefix
&& elem
->name
)
1280 elem
->fullname
= catstr(elem
->varinfo
.prefix
, elem
->fullname
);
1283 static void prepdomain(struct rnndb
*db
, struct rnndomain
*dom
) {
1284 prepvarinfo (db
, dom
->name
, &dom
->varinfo
, 0);
1286 for (i
= 0; i
< dom
->subelemsnum
; i
++)
1287 prepdelem(db
, dom
->subelems
[i
], dom
->bare
?0:dom
->name
, &dom
->varinfo
, dom
->width
);
1288 dom
->fullname
= catstr(dom
->varinfo
.prefix
, dom
->name
);
1291 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
) {
1294 prepvarinfo (db
, en
->name
, &en
->varinfo
, 0);
1298 for (i
= 0; i
< en
->valsnum
; i
++)
1299 prepvalue(db
, en
->vals
[i
], en
->bare
?0:en
->name
, &en
->varinfo
);
1300 en
->fullname
= catstr(en
->varinfo
.prefix
, en
->name
);
1304 static void prepbitset(struct rnndb
*db
, struct rnnbitset
*bs
) {
1305 prepvarinfo (db
, bs
->name
, &bs
->varinfo
, 0);
1309 for (i
= 0; i
< bs
->bitfieldsnum
; i
++)
1310 prepbitfield(db
, bs
->bitfields
[i
], bs
->bare
?0:bs
->name
, &bs
->varinfo
);
1311 bs
->fullname
= catstr(bs
->varinfo
.prefix
, bs
->name
);
1314 static void prepspectype(struct rnndb
*db
, struct rnnspectype
*st
) {
1315 preptypeinfo(db
, &st
->typeinfo
, st
->name
, 0, st
->file
); // XXX doesn't exactly make sense...
1318 void rnn_prepdb (struct rnndb
*db
) {
1320 for (i
= 0; i
< db
->enumsnum
; i
++)
1321 prepenum(db
, db
->enums
[i
]);
1322 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1323 prepbitset(db
, db
->bitsets
[i
]);
1324 for (i
= 0; i
< db
->domainsnum
; i
++)
1325 prepdomain(db
, db
->domains
[i
]);
1326 for (i
= 0; i
< db
->spectypesnum
; i
++)
1327 prepspectype(db
, db
->spectypes
[i
]);
1330 struct rnnenum
*rnn_findenum (struct rnndb
*db
, const char *name
) {
1332 for (i
= 0; i
< db
->enumsnum
; i
++)
1333 if (!strcmp(db
->enums
[i
]->name
, name
))
1334 return db
->enums
[i
];
1338 struct rnnbitset
*rnn_findbitset (struct rnndb
*db
, const char *name
) {
1340 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1341 if (!strcmp(db
->bitsets
[i
]->name
, name
))
1342 return db
->bitsets
[i
];
1346 struct rnndomain
*rnn_finddomain (struct rnndb
*db
, const char *name
) {
1348 for (i
= 0; i
< db
->domainsnum
; i
++)
1349 if (!strcmp(db
->domains
[i
]->name
, name
))
1350 return db
->domains
[i
];
1354 struct rnnspectype
*rnn_findspectype (struct rnndb
*db
, const char *name
) {
1356 for (i
= 0; i
< db
->spectypesnum
; i
++)
1357 if (!strcmp(db
->spectypes
[i
]->name
, name
))
1358 return db
->spectypes
[i
];