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>
45 #include "util/u_debug.h"
47 static char *catstr (char *a
, char *b
) {
50 return aprintf("%s_%s", a
, b
);
53 static int strdiff (const char *a
, const char *b
) {
61 static void rnn_err(struct rnndb
*db
, const char *format
, ...) _util_printf_format(2, 3);
63 static void rnn_err(struct rnndb
*db
, const char *format
, ...)
67 vfprintf(stderr
, format
, ap
);
77 struct rnndb
*rnn_newdb(void) {
78 struct rnndb
*db
= calloc(sizeof *db
, 1);
82 static char *getcontent (xmlNode
*attr
) {
83 xmlNode
*chain
= attr
->children
;
87 if (chain
->type
== XML_TEXT_NODE
)
88 size
+= strlen(chain
->content
);
91 p
= content
= malloc(size
+ 1);
92 chain
= attr
->children
;
94 if (chain
->type
== XML_TEXT_NODE
) {
95 char* sp
= chain
->content
;
100 size_t len
= strlen(sp
);
106 while(p
!= content
&& isspace(p
[-1]))
112 static char *getattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
113 xmlNode
*chain
= attr
->children
;
115 if (chain
->type
!= XML_TEXT_NODE
) {
116 rnn_err(db
, "%s:%d: unknown attribute child \"%s\" in attribute \"%s\"\n", file
, line
, chain
->name
, attr
->name
);
118 return chain
->content
;
125 static int getboolattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
126 char *c
= getattrib(db
, file
, line
, attr
);
127 if (!strcmp(c
, "yes") || !strcmp(c
, "1") || !strcmp(c
, "true"))
129 if (!strcmp(c
, "no") || !strcmp(c
, "0") || !strcmp(c
, "false"))
131 rnn_err(db
, "%s:%d: invalid boolean value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
135 static uint64_t getnum(struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
, char *c
)
139 if (strchr(c
, 'x') || strchr(c
, 'X'))
140 res
= strtoull(c
, &cc
, 16);
142 res
= strtoull(c
, &cc
, 10);
144 rnn_err(db
, "%s:%d: invalid numeric value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
149 static uint64_t getnumattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
150 char *c
= getattrib(db
, file
, line
, attr
);
151 return getnum(db
, file
, line
, attr
, c
);
154 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
);
156 static int trydoc (struct rnndb
*db
, char *file
, xmlNode
*node
) {
157 if (!strcmp(node
->name
, "brief")) {
159 } else if (!strcmp(node
->name
, "doc")) {
165 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
);
166 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
);
168 static int trytypetag (struct rnndb
*db
, char *file
, xmlNode
*node
, struct rnntypeinfo
*ti
) {
169 if (!strcmp(node
->name
, "value")) {
170 struct rnnvalue
*val
= parsevalue(db
, file
, node
);
172 ADDARRAY(ti
->vals
, val
);
174 } else if (!strcmp(node
->name
, "bitfield")) {
175 struct rnnbitfield
*bf
= parsebitfield(db
, file
, node
);
177 ADDARRAY(ti
->bitfields
, bf
);
182 static int trytypeattr (struct rnndb
*db
, char *file
, xmlNode
*node
, xmlAttr
*attr
, struct rnntypeinfo
*ti
) {
183 if (!strcmp(attr
->name
, "shr")) {
184 ti
->shr
= getnumattrib(db
, file
, node
->line
, attr
);
186 } else if (!strcmp(attr
->name
, "min")) {
187 ti
->min
= getnumattrib(db
, file
, node
->line
, attr
);
190 } else if (!strcmp(attr
->name
, "max")) {
191 ti
->max
= getnumattrib(db
, file
, node
->line
, attr
);
194 } else if (!strcmp(attr
->name
, "align")) {
195 ti
->align
= getnumattrib(db
, file
, node
->line
, attr
);
198 } else if (!strcmp(attr
->name
, "type")) {
199 ti
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));;
201 } else if (!strcmp(attr
->name
, "radix")) {
202 ti
->radix
= getnumattrib(db
, file
, node
->line
, attr
);
205 } else if (!strcmp(attr
->name
, "pos")) {
206 ti
->high
= ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
208 } else if (!strcmp(attr
->name
, "low")) {
209 ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
211 } else if (!strcmp(attr
->name
, "high")) {
212 ti
->high
= getnumattrib(db
, file
, node
->line
, attr
);
214 } else if (!strcmp(attr
->name
, "addvariant")) {
215 ti
->addvariant
= getboolattrib(db
, file
, node
->line
, attr
);
221 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
) {
222 struct rnnvalue
*val
= calloc(sizeof *val
, 1);
224 xmlAttr
*attr
= node
->properties
;
226 if (!strcmp(attr
->name
, "name")) {
227 val
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
228 } else if (!strcmp(attr
->name
, "value")) {
229 val
->value
= getnumattrib(db
, file
, node
->line
, attr
);
231 } else if (!strcmp(attr
->name
, "varset")) {
232 val
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
233 } else if (!strcmp(attr
->name
, "variants")) {
234 val
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
236 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for value\n", file
, node
->line
, attr
->name
);
240 xmlNode
*chain
= node
->children
;
242 if (chain
->type
!= XML_ELEMENT_NODE
) {
243 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
244 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
249 rnn_err(db
, "%s:%d: nameless value\n", file
, node
->line
);
256 static void parsespectype(struct rnndb
*db
, char *file
, xmlNode
*node
) {
257 struct rnnspectype
*res
= calloc (sizeof *res
, 1);
259 xmlAttr
*attr
= node
->properties
;
262 if (!strcmp(attr
->name
, "name")) {
263 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
264 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
265 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for spectype\n", file
, node
->line
, attr
->name
);
270 rnn_err(db
, "%s:%d: nameless spectype\n", file
, node
->line
);
273 for (i
= 0; i
< db
->spectypesnum
; i
++)
274 if (!strcmp(db
->spectypes
[i
]->name
, res
->name
)) {
275 rnn_err(db
, "%s:%d: duplicated spectype name %s\n", file
, node
->line
, res
->name
);
278 ADDARRAY(db
->spectypes
, res
);
279 xmlNode
*chain
= node
->children
;
281 if (chain
->type
!= XML_ELEMENT_NODE
) {
282 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
283 rnn_err(db
, "%s:%d: wrong tag in spectype: <%s>\n", file
, chain
->line
, chain
->name
);
289 static void parseenum(struct rnndb
*db
, char *file
, xmlNode
*node
) {
290 xmlAttr
*attr
= node
->properties
;
296 char *variantsstr
= 0;
299 if (!strcmp(attr
->name
, "name")) {
300 name
= getattrib(db
, file
, node
->line
, attr
);
301 } else if (!strcmp(attr
->name
, "bare")) {
302 bare
= getboolattrib(db
, file
, node
->line
, attr
);
303 } else if (!strcmp(attr
->name
, "inline")) {
304 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
305 } else if (!strcmp(attr
->name
, "prefix")) {
306 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
307 } else if (!strcmp(attr
->name
, "varset")) {
308 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
309 } else if (!strcmp(attr
->name
, "variants")) {
310 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
312 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for enum\n", file
, node
->line
, attr
->name
);
317 rnn_err(db
, "%s:%d: nameless enum\n", file
, node
->line
);
320 struct rnnenum
*cur
= 0;
321 for (i
= 0; i
< db
->enumsnum
; i
++)
322 if (!strcmp(db
->enums
[i
]->name
, name
)) {
327 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
328 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
329 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
330 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
331 rnn_err(db
, "%s:%d: merge fail for enum %s\n", file
, node
->line
, node
->name
);
334 cur
= calloc(sizeof *cur
, 1);
335 cur
->name
= strdup(name
);
336 cur
->isinline
= isinline
;
338 cur
->varinfo
.prefixstr
= prefixstr
;
339 cur
->varinfo
.varsetstr
= varsetstr
;
340 cur
->varinfo
.variantsstr
= variantsstr
;
342 ADDARRAY(db
->enums
, cur
);
344 xmlNode
*chain
= node
->children
;
346 if (chain
->type
!= XML_ELEMENT_NODE
) {
347 } else if (!strcmp(chain
->name
, "value")) {
348 struct rnnvalue
*val
= parsevalue(db
, file
, chain
);
350 ADDARRAY(cur
->vals
, val
);
351 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
352 rnn_err(db
, "%s:%d: wrong tag in enum: <%s>\n", file
, chain
->line
, chain
->name
);
358 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
) {
359 struct rnnbitfield
*bf
= calloc(sizeof *bf
, 1);
361 xmlAttr
*attr
= node
->properties
;
362 bf
->typeinfo
.low
= bf
->typeinfo
.high
= -1;
364 if (!strcmp(attr
->name
, "name")) {
365 bf
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
366 } else if (!strcmp(attr
->name
, "varset")) {
367 bf
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
368 } else if (!strcmp(attr
->name
, "variants")) {
369 bf
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
370 } else if (!trytypeattr(db
, file
, node
, attr
, &bf
->typeinfo
)) {
371 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for bitfield\n", file
, node
->line
, attr
->name
);
375 xmlNode
*chain
= node
->children
;
377 if (chain
->type
!= XML_ELEMENT_NODE
) {
378 } else if (!trytypetag(db
, file
, chain
, &bf
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
379 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
384 rnn_err(db
, "%s:%d: nameless bitfield\n", file
, node
->line
);
386 } else if (bf
->typeinfo
.low
< 0|| bf
->typeinfo
.high
< 0 || bf
->typeinfo
.high
< bf
->typeinfo
.low
) {
387 rnn_err(db
, "%s:%d: bitfield has wrong placement\n", file
, node
->line
);
394 static void parsebitset(struct rnndb
*db
, char *file
, xmlNode
*node
) {
395 xmlAttr
*attr
= node
->properties
;
401 char *variantsstr
= 0;
404 if (!strcmp(attr
->name
, "name")) {
405 name
= getattrib(db
, file
, node
->line
, attr
);
406 } else if (!strcmp(attr
->name
, "bare")) {
407 bare
= getboolattrib(db
, file
, node
->line
, attr
);
408 } else if (!strcmp(attr
->name
, "inline")) {
409 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
410 } else if (!strcmp(attr
->name
, "prefix")) {
411 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
412 } else if (!strcmp(attr
->name
, "varset")) {
413 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
414 } else if (!strcmp(attr
->name
, "variants")) {
415 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
417 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for bitset\n", file
, node
->line
, attr
->name
);
422 rnn_err(db
, "%s:%d: nameless bitset\n", file
, node
->line
);
425 struct rnnbitset
*cur
= 0;
426 for (i
= 0; i
< db
->bitsetsnum
; i
++)
427 if (!strcmp(db
->bitsets
[i
]->name
, name
)) {
428 cur
= db
->bitsets
[i
];
432 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
433 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
434 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
435 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
436 rnn_err(db
, "%s:%d: merge fail for bitset %s\n", file
, node
->line
, node
->name
);
439 cur
= calloc(sizeof *cur
, 1);
440 cur
->name
= strdup(name
);
441 cur
->isinline
= isinline
;
443 cur
->varinfo
.prefixstr
= prefixstr
;
444 cur
->varinfo
.varsetstr
= varsetstr
;
445 cur
->varinfo
.variantsstr
= variantsstr
;
447 ADDARRAY(db
->bitsets
, cur
);
449 xmlNode
*chain
= node
->children
;
451 if (chain
->type
!= XML_ELEMENT_NODE
) {
452 } else if (!strcmp(chain
->name
, "bitfield")) {
453 struct rnnbitfield
*bf
= parsebitfield(db
, file
, chain
);
455 ADDARRAY(cur
->bitfields
, bf
);
456 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
457 rnn_err(db
, "%s:%d: wrong tag in bitset: <%s>\n", file
, chain
->line
, chain
->name
);
463 static struct rnndelem
*trydelem(struct rnndb
*db
, char *file
, xmlNode
*node
) {
464 if (!strcmp(node
->name
, "use-group")) {
465 struct rnndelem
*res
= calloc(sizeof *res
, 1);
467 res
->type
= RNN_ETYPE_USE_GROUP
;
468 xmlAttr
*attr
= node
->properties
;
470 if (!strcmp(attr
->name
, "ref")) {
471 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
473 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
478 rnn_err(db
, "%s:%d: nameless use-group\n", file
, node
->line
);
482 } else if (!strcmp(node
->name
, "stripe") || !strcmp(node
->name
, "array")) {
483 struct rnndelem
*res
= calloc(sizeof *res
, 1);
484 if (!strcmp(node
->name
, "array"))
486 res
->type
= (strcmp(node
->name
, "stripe")?RNN_ETYPE_ARRAY
:RNN_ETYPE_STRIPE
);
489 xmlAttr
*attr
= node
->properties
;
491 if (!strcmp(attr
->name
, "name")) {
492 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
493 } else if (!strcmp(attr
->name
, "offset")) {
494 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
495 } else if (!strcmp(attr
->name
, "offsets")) {
496 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
497 char *tok
, *save
, *tmp
= str
;
498 while ((tok
= strtok_r(str
, ",", &save
))) {
499 uint64_t offset
= getnum(db
, file
, node
->line
, attr
, tok
);
500 ADDARRAY(res
->offsets
, offset
);
504 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
506 } else if (!strcmp(attr
->name
, "doffset")) {
507 /* dynamic runtime determined offset: */
508 res
->doffset
= strdup(getattrib(db
, file
, node
->line
, attr
));
509 } else if (!strcmp(attr
->name
, "doffsets")) {
510 /* dynamic runtime determined offsets: */
511 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
512 char *tok
, *save
, *tmp
= str
;
513 while ((tok
= strtok_r(str
, ",", &save
))) {
514 char *doffset
= strdup(tok
);
515 ADDARRAY(res
->doffsets
, doffset
);
519 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
521 } else if (!strcmp(attr
->name
, "length")) {
522 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
523 } else if (!strcmp(attr
->name
, "stride")) {
524 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
525 } else if (!strcmp(attr
->name
, "prefix")) {
526 res
->varinfo
.prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
527 } else if (!strcmp(attr
->name
, "varset")) {
528 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
529 } else if (!strcmp(attr
->name
, "variants")) {
530 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
531 } else if (!strcmp(attr
->name
, "index")) {
532 const char *enumname
= getattrib(db
, file
, node
->line
, attr
);
533 res
->index
= rnn_findenum(db
, enumname
);
535 rnn_err(db
, "%s:%d: invalid enum name \"%s\"\n", file
, node
->line
, enumname
);
538 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
542 xmlNode
*chain
= node
->children
;
544 struct rnndelem
*delem
;
545 if (chain
->type
!= XML_ELEMENT_NODE
) {
546 } else if ((delem
= trydelem(db
, file
, chain
))) {
547 ADDARRAY(res
->subelems
, delem
);
548 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
549 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
554 /* Sanity checking */
555 if (res
->type
== RNN_ETYPE_ARRAY
&& res
->stride
== 0) {
556 fprintf(stderr
, "%s: Array %s's stride is undefined. Aborting.\n", file
, res
->name
);
563 if (!strcmp(node
->name
, "reg8"))
565 else if (!strcmp(node
->name
, "reg16"))
567 else if (!strcmp(node
->name
, "reg32"))
569 else if (!strcmp(node
->name
, "reg64"))
573 struct rnndelem
*res
= calloc(sizeof *res
, 1);
575 res
->type
= RNN_ETYPE_REG
;
578 res
->access
= RNN_ACCESS_RW
;
579 xmlAttr
*attr
= node
->properties
;
580 res
->typeinfo
.low
= 0;
581 res
->typeinfo
.high
= width
- 1;
583 if (!strcmp(attr
->name
, "name")) {
584 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
585 } else if (!strcmp(attr
->name
, "offset")) {
586 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
587 } else if (!strcmp(attr
->name
, "length")) {
588 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
589 } else if (!strcmp(attr
->name
, "stride")) {
590 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
591 } else if (!strcmp(attr
->name
, "varset")) {
592 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
593 } else if (!strcmp(attr
->name
, "variants")) {
594 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
595 } else if (!strcmp(attr
->name
, "access")) {
596 char *str
= getattrib(db
, file
, node
->line
, attr
);
597 if (!strcmp(str
, "r"))
598 res
->access
= RNN_ACCESS_R
;
599 else if (!strcmp(str
, "w"))
600 res
->access
= RNN_ACCESS_W
;
601 else if (!strcmp(str
, "rw"))
602 res
->access
= RNN_ACCESS_RW
;
604 fprintf (stderr
, "%s:%d: wrong access type \"%s\" for register\n", file
, node
->line
, str
);
605 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
606 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for register\n", file
, node
->line
, attr
->name
);
610 xmlNode
*chain
= node
->children
;
612 if (chain
->type
!= XML_ELEMENT_NODE
) {
613 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
614 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
619 rnn_err(db
, "%s:%d: nameless register\n", file
, node
->line
);
626 static void parsegroup(struct rnndb
*db
, char *file
, xmlNode
*node
) {
627 xmlAttr
*attr
= node
->properties
;
631 if (!strcmp(attr
->name
, "name")) {
632 name
= getattrib(db
, file
, node
->line
, attr
);
634 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for group\n", file
, node
->line
, attr
->name
);
639 rnn_err(db
, "%s:%d: nameless group\n", file
, node
->line
);
642 struct rnngroup
*cur
= 0;
643 for (i
= 0; i
< db
->groupsnum
; i
++)
644 if (!strcmp(db
->groups
[i
]->name
, name
)) {
649 cur
= calloc(sizeof *cur
, 1);
650 cur
->name
= strdup(name
);
651 ADDARRAY(db
->groups
, cur
);
653 xmlNode
*chain
= node
->children
;
655 struct rnndelem
*delem
;
656 if (chain
->type
!= XML_ELEMENT_NODE
) {
657 } else if ((delem
= trydelem(db
, file
, chain
))) {
658 ADDARRAY(cur
->subelems
, delem
);
659 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
660 rnn_err(db
, "%s:%d: wrong tag in group: <%s>\n", file
, chain
->line
, chain
->name
);
666 static void parsedomain(struct rnndb
*db
, char *file
, xmlNode
*node
) {
667 xmlAttr
*attr
= node
->properties
;
669 uint64_t size
= 0; int width
= 8;
673 char *variantsstr
= 0;
676 if (!strcmp(attr
->name
, "name")) {
677 name
= getattrib(db
, file
, node
->line
, attr
);
678 } else if (!strcmp(attr
->name
, "bare")) {
679 bare
= getboolattrib(db
, file
, node
->line
, attr
);
680 } else if (!strcmp(attr
->name
, "size")) {
681 size
= getnumattrib(db
, file
, node
->line
, attr
);
682 } else if (!strcmp(attr
->name
, "width")) {
683 width
= getnumattrib(db
, file
, node
->line
, attr
);
684 } else if (!strcmp(attr
->name
, "prefix")) {
685 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
686 } else if (!strcmp(attr
->name
, "varset")) {
687 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
688 } else if (!strcmp(attr
->name
, "variants")) {
689 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
691 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for domain\n", file
, node
->line
, attr
->name
);
696 rnn_err(db
, "%s:%d: nameless domain\n", file
, node
->line
);
699 struct rnndomain
*cur
= 0;
700 for (i
= 0; i
< db
->domainsnum
; i
++)
701 if (!strcmp(db
->domains
[i
]->name
, name
)) {
702 cur
= db
->domains
[i
];
706 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
707 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
708 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
709 cur
->width
!= width
||
711 (size
&& cur
->size
&& size
!= cur
->size
)) {
712 rnn_err(db
, "%s:%d: merge fail for domain %s\n", file
, node
->line
, node
->name
);
718 cur
= calloc(sizeof *cur
, 1);
719 cur
->name
= strdup(name
);
723 cur
->varinfo
.prefixstr
= prefixstr
;
724 cur
->varinfo
.varsetstr
= varsetstr
;
725 cur
->varinfo
.variantsstr
= variantsstr
;
727 ADDARRAY(db
->domains
, cur
);
729 xmlNode
*chain
= node
->children
;
731 struct rnndelem
*delem
;
732 if (chain
->type
!= XML_ELEMENT_NODE
) {
733 } else if ((delem
= trydelem(db
, file
, chain
))) {
734 ADDARRAY(cur
->subelems
, delem
);
735 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
736 rnn_err(db
, "%s:%d: wrong tag in domain: <%s>\n", file
, chain
->line
, chain
->name
);
742 static void parsecopyright(struct rnndb
*db
, char *file
, xmlNode
*node
) {
743 struct rnncopyright
* copyright
= &db
->copyright
;
744 xmlAttr
*attr
= node
->properties
;
746 if (!strcmp(attr
->name
, "year")) {
747 unsigned firstyear
= getnumattrib(db
, file
, node
->line
, attr
);
748 if(!copyright
->firstyear
|| firstyear
< copyright
->firstyear
)
749 copyright
->firstyear
= firstyear
;
751 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for copyright\n", file
, node
->line
, attr
->name
);
755 xmlNode
*chain
= node
->children
;
757 if (chain
->type
!= XML_ELEMENT_NODE
) {
758 } else if (!strcmp(chain
->name
, "license"))
759 if(copyright
->license
) {
760 if(strcmp(copyright
->license
, node
->content
)) {
761 fprintf(stderr
, "fatal error: multiple different licenses specified!\n");
762 abort(); /* TODO: do something better here, but headergen, xml2html, etc. should not produce anything in this case */
765 copyright
->license
= getcontent(chain
);
766 else if (!strcmp(chain
->name
, "author")) {
767 struct rnnauthor
* author
= calloc(sizeof *author
, 1);
768 xmlAttr
* authorattr
= chain
->properties
;
769 xmlNode
*authorchild
= chain
->children
;
770 author
->contributions
= getcontent(chain
);
772 if (!strcmp(authorattr
->name
, "name"))
773 author
->name
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
774 else if (!strcmp(authorattr
->name
, "email"))
775 author
->email
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
777 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for author\n", file
, chain
->line
, authorattr
->name
);
779 authorattr
= authorattr
->next
;
782 if (authorchild
->type
!= XML_ELEMENT_NODE
) {
783 } else if (!strcmp(authorchild
->name
, "nick")) {
784 xmlAttr
* nickattr
= authorchild
->properties
;
787 if (!strcmp(nickattr
->name
, "name"))
788 nickname
= strdup(getattrib(db
, file
, authorchild
->line
, nickattr
));
790 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for nick\n", file
, authorchild
->line
, nickattr
->name
);
792 nickattr
= nickattr
->next
;
795 rnn_err(db
, "%s:%d: missing \"name\" attribute for nick\n", file
, authorchild
->line
);
797 ADDARRAY(author
->nicknames
, nickname
);
799 rnn_err(db
, "%s:%d: wrong tag in author: <%s>\n", file
, authorchild
->line
, authorchild
->name
);
801 authorchild
= authorchild
->next
;
803 ADDARRAY(copyright
->authors
, author
);
805 rnn_err(db
, "%s:%d: wrong tag in copyright: <%s>\n", file
, chain
->line
, chain
->name
);
811 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
) {
812 if (!strcmp(node
->name
, "enum")) {
813 parseenum(db
, file
, node
);
815 } else if (!strcmp(node
->name
, "bitset")) {
816 parsebitset(db
, file
, node
);
818 } else if (!strcmp(node
->name
, "group")) {
819 parsegroup(db
, file
, node
);
821 } else if (!strcmp(node
->name
, "domain")) {
822 parsedomain(db
, file
, node
);
824 } else if (!strcmp(node
->name
, "spectype")) {
825 parsespectype(db
, file
, node
);
827 } else if (!strcmp(node
->name
, "import")) {
828 xmlAttr
*attr
= node
->properties
;
831 if (!strcmp(attr
->name
, "file")) {
832 subfile
= getattrib(db
, file
, node
->line
, attr
);
834 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for import\n", file
, node
->line
, attr
->name
);
839 rnn_err(db
, "%s:%d: missing \"file\" attribute for import\n", file
, node
->line
);
841 rnn_parsefile(db
, subfile
);
844 } else if (!strcmp(node
->name
, "copyright")) {
845 parsecopyright(db
, file
, node
);
851 static char * find_file(const char *file_orig
)
853 const char *rnn_path
= getenv("RNN_PATH");
857 rnn_path
= RNN_DEF_PATH
;
859 FILE *file
= find_in_path(file_orig
, rnn_path
, &fname
);
861 fprintf (stderr
, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", file_orig
);
869 static int validate_doc(struct rnndb
*db
, xmlDocPtr doc
, xmlNodePtr database
)
871 /* find the schemaLocation property: */
872 xmlAttrPtr attr
= database
->properties
;
873 const char *schema_name
= NULL
;
877 if (!strcmp(attr
->name
, "schemaLocation")) {
878 xmlNodePtr data
= attr
->children
;
879 schema_name
= data
->content
;
880 /* we expect this to look like <namespace url> schema.xsd.. I think
881 * technically it is supposed to be just a URL, but that doesn't
882 * quite match up to what we do.. Just skip over everything up to
883 * and including the first whitespace character:
885 while (schema_name
&& (schema_name
[0] != ' '))
893 rnn_err(db
, "could not find schema. Missing schemaLocation?");
897 schema_path
= find_file(schema_name
);
899 rnn_err(db
, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", schema_name
);
903 xmlSchemaParserCtxtPtr parser
= xmlSchemaNewParserCtxt(schema_path
);
904 xmlSchemaPtr schema
= xmlSchemaParse(parser
);
905 xmlSchemaValidCtxtPtr validCtxt
= xmlSchemaNewValidCtxt(schema
);
906 int ret
= xmlSchemaValidateDoc(validCtxt
, doc
);
908 xmlSchemaFreeValidCtxt(validCtxt
);
909 xmlSchemaFree(schema
);
910 xmlSchemaFreeParserCtxt(parser
);
917 void rnn_parsefile (struct rnndb
*db
, char *file_orig
) {
921 fname
= find_file(file_orig
);
927 for (i
= 0; i
< db
->filesnum
; i
++)
928 if (!strcmp(db
->files
[i
], fname
))
931 ADDARRAY(db
->files
, fname
);
932 xmlDocPtr doc
= xmlParseFile(fname
);
934 rnn_err(db
, "%s: couldn't open database file. Please set the env var RNN_PATH.\n", fname
);
937 xmlNode
*root
= doc
->children
;
939 if (root
->type
!= XML_ELEMENT_NODE
) {
940 } else if (strcmp(root
->name
, "database")) {
941 rnn_err(db
, "%s:%d: wrong top-level tag <%s>\n", fname
, root
->line
, root
->name
);
943 xmlNode
*chain
= root
->children
;
944 if (validate_doc(db
, doc
, root
)) {
945 rnn_err(db
, "%s: database file has errors\n", fname
);
949 if (chain
->type
!= XML_ELEMENT_NODE
) {
950 } else if (!trytop(db
, fname
, chain
) && !trydoc(db
, fname
, chain
)) {
951 rnn_err(db
, "%s:%d: wrong tag in database: <%s>\n", fname
, chain
->line
, chain
->name
);
961 static struct rnnvalue
*copyvalue (struct rnnvalue
*val
, char *file
) {
962 struct rnnvalue
*res
= calloc (sizeof *res
, 1);
963 res
->name
= val
->name
;
964 res
->valvalid
= val
->valvalid
;
965 res
->value
= val
->value
;
966 res
->varinfo
= val
->varinfo
;
971 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
);
974 static void copytypeinfo (struct rnntypeinfo
*dst
, struct rnntypeinfo
*src
, char *file
) {
976 dst
->name
= src
->name
;
979 dst
->high
= src
->high
;
982 dst
->align
= src
->align
;
983 dst
->addvariant
= src
->addvariant
;
984 for (i
= 0; i
< src
->valsnum
; i
++)
985 ADDARRAY(dst
->vals
, copyvalue(src
->vals
[i
], file
));
986 for (i
= 0; i
< src
->bitfieldsnum
; i
++)
987 ADDARRAY(dst
->bitfields
, copybitfield(src
->bitfields
[i
], file
));
990 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
) {
991 struct rnnbitfield
*res
= calloc (sizeof *res
, 1);
992 res
->name
= bf
->name
;
993 res
->varinfo
= bf
->varinfo
;
995 copytypeinfo(&res
->typeinfo
, &bf
->typeinfo
, file
);
999 static struct rnndelem
*copydelem (struct rnndelem
*elem
, char *file
) {
1000 struct rnndelem
*res
= calloc (sizeof *res
, 1);
1001 res
->type
= elem
->type
;
1002 res
->name
= elem
->name
;
1003 res
->width
= elem
->width
;
1004 res
->access
= elem
->access
;
1005 res
->offset
= elem
->offset
;
1006 res
->length
= elem
->length
;
1007 res
->stride
= elem
->stride
;
1008 res
->varinfo
= elem
->varinfo
;
1010 copytypeinfo(&res
->typeinfo
, &elem
->typeinfo
, file
);
1012 for (i
= 0; i
< elem
->subelemsnum
; i
++)
1013 ADDARRAY(res
->subelems
, copydelem(elem
->subelems
[i
], file
));
1014 for (i
= 0; i
< elem
->offsetsnum
; i
++)
1015 ADDARRAY(res
->offsets
, elem
->offsets
[i
]);
1019 static struct rnnvarset
*copyvarset (struct rnnvarset
*varset
) {
1020 struct rnnvarset
*res
= calloc(sizeof *res
, 1);
1021 res
->venum
= varset
->venum
;
1022 res
->variants
= calloc(sizeof *res
->variants
, res
->venum
->valsnum
);
1024 for (i
= 0; i
< res
->venum
->valsnum
; i
++)
1025 res
->variants
[i
] = varset
->variants
[i
];
1029 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
);
1031 static int findvidx (struct rnndb
*db
, struct rnnenum
*en
, char *name
) {
1033 for (i
= 0; i
< en
->valsnum
; i
++)
1034 if (!strcmp(en
->vals
[i
]->name
, name
))
1036 rnn_err(db
, "Cannot find variant %s in enum %s!\n", name
, en
->name
);
1040 static void prepvarinfo (struct rnndb
*db
, char *what
, struct rnnvarinfo
*vi
, struct rnnvarinfo
*parent
) {
1042 vi
->prefenum
= parent
->prefenum
;
1043 if (vi
->prefixstr
) {
1044 if (!strcmp(vi
->prefixstr
, "none"))
1047 vi
->prefenum
= rnn_findenum(db
, vi
->prefixstr
); // XXX
1051 for (i
= 0; i
< parent
->varsetsnum
; i
++)
1052 ADDARRAY(vi
->varsets
, copyvarset(parent
->varsets
[i
]));
1053 struct rnnenum
*varset
= vi
->prefenum
;
1054 if (!varset
&& !vi
->varsetstr
&& parent
)
1055 vi
->varsetstr
= parent
->varsetstr
;
1057 varset
= rnn_findenum(db
, vi
->varsetstr
);
1058 if (vi
->variantsstr
) {
1059 char *vars
= vi
->variantsstr
;
1061 rnn_err(db
, "%s: tried to use variants without active varset!\n", what
);
1064 struct rnnvarset
*vs
= 0;
1065 int nvars
= varset
->valsnum
;
1066 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1067 if (vi
->varsets
[i
]->venum
== varset
) {
1068 vs
= vi
->varsets
[i
];
1072 vs
= calloc (sizeof *vs
, 1);
1074 vs
->variants
= calloc(sizeof *vs
->variants
, nvars
);
1075 for (i
= 0; i
< nvars
; i
++)
1076 vs
->variants
[i
] = 1;
1077 ADDARRAY(vi
->varsets
, vs
);
1080 while (*vars
== ' ') vars
++;
1084 while (*split
!= ':' && *split
!= '-' && *split
!= ' ' && *split
!= 0)
1088 first
= strndup(vars
, split
-vars
);
1089 if (*split
== ' ' || *split
== 0) {
1090 int idx
= findvidx(db
, varset
, first
);
1092 vs
->variants
[idx
] |= 2;
1095 char *end
= split
+1;
1096 while (*end
!= ' ' && *end
!= 0)
1100 second
= strndup(split
+1, end
-split
-1);
1103 idx1
= findvidx(db
, varset
, first
);
1106 idx2
= findvidx(db
, varset
, second
);
1110 if (idx1
!= -1 && idx2
!= -1)
1111 for (i
= idx1
; i
< idx2
; i
++)
1112 vs
->variants
[i
] |= 2;
1119 for (i
= 0; i
< nvars
; i
++) {
1120 vs
->variants
[i
] = (vs
->variants
[i
] == 3);
1121 if (vs
->variants
[i
])
1128 struct rnnvarset
*vs
= 0;
1129 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1130 if (vi
->varsets
[i
]->venum
== vi
->prefenum
) {
1131 vs
= vi
->varsets
[i
];
1135 for (i
= 0; i
< vi
->prefenum
->valsnum
; i
++)
1136 if (vs
->variants
[i
]) {
1137 vi
->prefix
= vi
->prefenum
->vals
[i
]->name
;
1141 vi
->prefix
= vi
->prefenum
->vals
[0]->name
;
1146 static void prepvalue(struct rnndb
*db
, struct rnnvalue
*val
, char *prefix
, struct rnnvarinfo
*parvi
) {
1147 val
->fullname
= catstr(prefix
, val
->name
);
1148 prepvarinfo (db
, val
->fullname
, &val
->varinfo
, parvi
);
1149 if (val
->varinfo
.dead
)
1151 if (val
->varinfo
.prefix
)
1152 val
->fullname
= catstr(val
->varinfo
.prefix
, val
->fullname
);
1155 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
);
1157 static void preptypeinfo(struct rnndb
*db
, struct rnntypeinfo
*ti
, char *prefix
, struct rnnvarinfo
*vi
, char *file
) {
1160 struct rnnenum
*en
= rnn_findenum (db
, ti
->name
);
1161 struct rnnbitset
*bs
= rnn_findbitset (db
, ti
->name
);
1162 struct rnnspectype
*st
= rnn_findspectype (db
, ti
->name
);
1165 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1167 for (j
= 0; j
< en
->valsnum
; j
++)
1168 ADDARRAY(ti
->vals
, copyvalue(en
->vals
[j
], file
));
1170 ti
->type
= RNN_TTYPE_ENUM
;
1175 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1177 for (j
= 0; j
< bs
->bitfieldsnum
; j
++)
1178 ADDARRAY(ti
->bitfields
, copybitfield(bs
->bitfields
[j
], file
));
1180 ti
->type
= RNN_TTYPE_BITSET
;
1184 ti
->type
= RNN_TTYPE_SPECTYPE
;
1186 } else if (!strcmp(ti
->name
, "hex")) {
1187 ti
->type
= RNN_TTYPE_HEX
;
1188 } else if (!strcmp(ti
->name
, "float")) {
1189 ti
->type
= RNN_TTYPE_FLOAT
;
1190 } else if (!strcmp(ti
->name
, "uint")) {
1191 ti
->type
= RNN_TTYPE_UINT
;
1192 } else if (!strcmp(ti
->name
, "int")) {
1193 ti
->type
= RNN_TTYPE_INT
;
1194 } else if (!strcmp(ti
->name
, "boolean")) {
1195 ti
->type
= RNN_TTYPE_BOOLEAN
;
1196 } else if (!strcmp(ti
->name
, "bitfield")) {
1197 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1198 } else if (!strcmp(ti
->name
, "enum")) {
1199 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1200 } else if (!strcmp(ti
->name
, "fixed")) {
1201 ti
->type
= RNN_TTYPE_FIXED
;
1202 } else if (!strcmp(ti
->name
, "ufixed")) {
1203 ti
->type
= RNN_TTYPE_UFIXED
;
1204 } else if (!strcmp(ti
->name
, "a3xx_regid")) {
1205 ti
->type
= RNN_TTYPE_A3XX_REGID
;
1206 } else if (!strcmp(ti
->name
, "waddress") || !strcmp(ti
->name
, "address")) {
1207 ti
->type
= RNN_TTYPE_HEX
;
1209 ti
->type
= RNN_TTYPE_HEX
;
1210 rnn_err(db
, "%s: unknown type %s\n", prefix
, ti
->name
);
1212 } else if (ti
->bitfieldsnum
) {
1213 ti
->name
= "bitfield";
1214 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1215 } else if (ti
->valsnum
) {
1217 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1218 } else if (ti
->low
== 0 && ti
->high
== 0) {
1219 ti
->name
= "boolean";
1220 ti
->type
= RNN_TTYPE_BOOLEAN
;
1223 ti
->type
= RNN_TTYPE_HEX
;
1225 if (ti
->addvariant
&& ti
->type
!= RNN_TTYPE_ENUM
) {
1226 rnn_err(db
, "%s: addvariant specified on non-enum type %s\n", prefix
, ti
->name
);
1228 for (i
= 0; i
< ti
->bitfieldsnum
; i
++)
1229 prepbitfield(db
, ti
->bitfields
[i
], prefix
, vi
);
1230 for (i
= 0; i
< ti
->valsnum
; i
++)
1231 prepvalue(db
, ti
->vals
[i
], prefix
, vi
);
1234 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
) {
1235 bf
->fullname
= catstr(prefix
, bf
->name
);
1236 prepvarinfo (db
, bf
->fullname
, &bf
->varinfo
, parvi
);
1237 if (bf
->varinfo
.dead
)
1239 preptypeinfo(db
, &bf
->typeinfo
, bf
->fullname
, &bf
->varinfo
, bf
->file
);
1240 if (bf
->varinfo
.prefix
)
1241 bf
->fullname
= catstr(bf
->varinfo
.prefix
, bf
->fullname
);
1244 static void prepdelem(struct rnndb
*db
, struct rnndelem
*elem
, char *prefix
, struct rnnvarinfo
*parvi
, int width
) {
1245 if (elem
->type
== RNN_ETYPE_USE_GROUP
) {
1247 struct rnngroup
*gr
= 0;
1248 for (i
= 0; i
< db
->groupsnum
; i
++)
1249 if (!strcmp(db
->groups
[i
]->name
, elem
->name
)) {
1254 for (i
= 0; i
< gr
->subelemsnum
; i
++)
1255 ADDARRAY(elem
->subelems
, copydelem(gr
->subelems
[i
], elem
->file
));
1257 rnn_err(db
, "group %s not found!\n", elem
->name
);
1259 elem
->type
= RNN_ETYPE_STRIPE
;
1264 elem
->fullname
= catstr(prefix
, elem
->name
);
1265 prepvarinfo (db
, elem
->fullname
?elem
->fullname
:prefix
, &elem
->varinfo
, parvi
);
1266 if (elem
->varinfo
.dead
)
1268 if (elem
->length
!= 1 && !elem
->stride
) {
1269 if (elem
->type
!= RNN_ETYPE_REG
) {
1270 rnn_err(db
, "%s has non-1 length, but no stride!\n", elem
->fullname
);
1272 elem
->stride
= elem
->width
/width
;
1275 preptypeinfo(db
, &elem
->typeinfo
, elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, elem
->file
);
1278 for (i
= 0; i
< elem
->subelemsnum
; i
++)
1279 prepdelem(db
, elem
->subelems
[i
], elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, width
);
1280 if (elem
->varinfo
.prefix
&& elem
->name
)
1281 elem
->fullname
= catstr(elem
->varinfo
.prefix
, elem
->fullname
);
1284 static void prepdomain(struct rnndb
*db
, struct rnndomain
*dom
) {
1285 prepvarinfo (db
, dom
->name
, &dom
->varinfo
, 0);
1287 for (i
= 0; i
< dom
->subelemsnum
; i
++)
1288 prepdelem(db
, dom
->subelems
[i
], dom
->bare
?0:dom
->name
, &dom
->varinfo
, dom
->width
);
1289 dom
->fullname
= catstr(dom
->varinfo
.prefix
, dom
->name
);
1292 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
) {
1295 prepvarinfo (db
, en
->name
, &en
->varinfo
, 0);
1299 for (i
= 0; i
< en
->valsnum
; i
++)
1300 prepvalue(db
, en
->vals
[i
], en
->bare
?0:en
->name
, &en
->varinfo
);
1301 en
->fullname
= catstr(en
->varinfo
.prefix
, en
->name
);
1305 static void prepbitset(struct rnndb
*db
, struct rnnbitset
*bs
) {
1306 prepvarinfo (db
, bs
->name
, &bs
->varinfo
, 0);
1310 for (i
= 0; i
< bs
->bitfieldsnum
; i
++)
1311 prepbitfield(db
, bs
->bitfields
[i
], bs
->bare
?0:bs
->name
, &bs
->varinfo
);
1312 bs
->fullname
= catstr(bs
->varinfo
.prefix
, bs
->name
);
1315 static void prepspectype(struct rnndb
*db
, struct rnnspectype
*st
) {
1316 preptypeinfo(db
, &st
->typeinfo
, st
->name
, 0, st
->file
); // XXX doesn't exactly make sense...
1319 void rnn_prepdb (struct rnndb
*db
) {
1321 for (i
= 0; i
< db
->enumsnum
; i
++)
1322 prepenum(db
, db
->enums
[i
]);
1323 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1324 prepbitset(db
, db
->bitsets
[i
]);
1325 for (i
= 0; i
< db
->domainsnum
; i
++)
1326 prepdomain(db
, db
->domains
[i
]);
1327 for (i
= 0; i
< db
->spectypesnum
; i
++)
1328 prepspectype(db
, db
->spectypes
[i
]);
1331 struct rnnenum
*rnn_findenum (struct rnndb
*db
, const char *name
) {
1333 for (i
= 0; i
< db
->enumsnum
; i
++)
1334 if (!strcmp(db
->enums
[i
]->name
, name
))
1335 return db
->enums
[i
];
1339 struct rnnbitset
*rnn_findbitset (struct rnndb
*db
, const char *name
) {
1341 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1342 if (!strcmp(db
->bitsets
[i
]->name
, name
))
1343 return db
->bitsets
[i
];
1347 struct rnndomain
*rnn_finddomain (struct rnndb
*db
, const char *name
) {
1349 for (i
= 0; i
< db
->domainsnum
; i
++)
1350 if (!strcmp(db
->domains
[i
]->name
, name
))
1351 return db
->domains
[i
];
1355 struct rnnspectype
*rnn_findspectype (struct rnndb
*db
, const char *name
) {
1357 for (i
= 0; i
< db
->spectypesnum
; i
++)
1358 if (!strcmp(db
->spectypes
[i
]->name
, name
))
1359 return db
->spectypes
[i
];