8893827170e0c6dd9879d9f417e58530b183f69f
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 static char *catstr (char *a
, char *b
) {
48 return aprintf("%s_%s", a
, b
);
51 static int strdiff (const char *a
, const char *b
) {
64 struct rnndb
*rnn_newdb(void) {
65 struct rnndb
*db
= calloc(sizeof *db
, 1);
69 static char *getcontent (xmlNode
*attr
) {
70 xmlNode
*chain
= attr
->children
;
74 if (chain
->type
== XML_TEXT_NODE
)
75 size
+= strlen(chain
->content
);
78 p
= content
= malloc(size
+ 1);
79 chain
= attr
->children
;
81 if (chain
->type
== XML_TEXT_NODE
) {
82 char* sp
= chain
->content
;
87 size_t len
= strlen(sp
);
93 while(p
!= content
&& isspace(p
[-1]))
99 static char *getattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
100 xmlNode
*chain
= attr
->children
;
102 if (chain
->type
!= XML_TEXT_NODE
) {
103 fprintf (stderr
, "%s:%d: unknown attribute child \"%s\" in attribute \"%s\"\n", file
, line
, chain
->name
, attr
->name
);
106 return chain
->content
;
113 static int getboolattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
114 char *c
= getattrib(db
, file
, line
, attr
);
115 if (!strcmp(c
, "yes") || !strcmp(c
, "1"))
117 if (!strcmp(c
, "no") || !strcmp(c
, "0"))
119 fprintf (stderr
, "%s:%d: invalid boolean value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
124 static uint64_t getnum(struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
, char *c
)
128 if (strchr(c
, 'x') || strchr(c
, 'X'))
129 res
= strtoull(c
, &cc
, 16);
131 res
= strtoull(c
, &cc
, 10);
133 fprintf (stderr
, "%s:%d: invalid numeric value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
139 static uint64_t getnumattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
140 char *c
= getattrib(db
, file
, line
, attr
);
141 return getnum(db
, file
, line
, attr
, c
);
144 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
);
146 static int trydoc (struct rnndb
*db
, char *file
, xmlNode
*node
) {
147 if (!strcmp(node
->name
, "brief")) {
149 } else if (!strcmp(node
->name
, "doc")) {
155 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
);
156 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
);
158 static int trytypetag (struct rnndb
*db
, char *file
, xmlNode
*node
, struct rnntypeinfo
*ti
) {
159 if (!strcmp(node
->name
, "value")) {
160 struct rnnvalue
*val
= parsevalue(db
, file
, node
);
162 ADDARRAY(ti
->vals
, val
);
164 } else if (!strcmp(node
->name
, "bitfield")) {
165 struct rnnbitfield
*bf
= parsebitfield(db
, file
, node
);
167 ADDARRAY(ti
->bitfields
, bf
);
172 static int trytypeattr (struct rnndb
*db
, char *file
, xmlNode
*node
, xmlAttr
*attr
, struct rnntypeinfo
*ti
) {
173 if (!strcmp(attr
->name
, "shr")) {
174 ti
->shr
= getnumattrib(db
, file
, node
->line
, attr
);
176 } else if (!strcmp(attr
->name
, "min")) {
177 ti
->min
= getnumattrib(db
, file
, node
->line
, attr
);
180 } else if (!strcmp(attr
->name
, "max")) {
181 ti
->max
= getnumattrib(db
, file
, node
->line
, attr
);
184 } else if (!strcmp(attr
->name
, "align")) {
185 ti
->align
= getnumattrib(db
, file
, node
->line
, attr
);
188 } else if (!strcmp(attr
->name
, "type")) {
189 ti
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));;
191 } else if (!strcmp(attr
->name
, "radix")) {
192 ti
->radix
= getnumattrib(db
, file
, node
->line
, attr
);
195 } else if (!strcmp(attr
->name
, "pos")) {
196 ti
->high
= ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
198 } else if (!strcmp(attr
->name
, "low")) {
199 ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
201 } else if (!strcmp(attr
->name
, "high")) {
202 ti
->high
= getnumattrib(db
, file
, node
->line
, attr
);
204 } else if (!strcmp(attr
->name
, "addvariant")) {
205 ti
->addvariant
= getboolattrib(db
, file
, node
->line
, attr
);
211 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
) {
212 struct rnnvalue
*val
= calloc(sizeof *val
, 1);
214 xmlAttr
*attr
= node
->properties
;
216 if (!strcmp(attr
->name
, "name")) {
217 val
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
218 } else if (!strcmp(attr
->name
, "value")) {
219 val
->value
= getnumattrib(db
, file
, node
->line
, attr
);
221 } else if (!strcmp(attr
->name
, "varset")) {
222 val
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
223 } else if (!strcmp(attr
->name
, "variants")) {
224 val
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
226 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for value\n", file
, node
->line
, attr
->name
);
231 xmlNode
*chain
= node
->children
;
233 if (chain
->type
!= XML_ELEMENT_NODE
) {
234 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
235 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
241 fprintf (stderr
, "%s:%d: nameless value\n", file
, node
->line
);
249 static void parsespectype(struct rnndb
*db
, char *file
, xmlNode
*node
) {
250 struct rnnspectype
*res
= calloc (sizeof *res
, 1);
252 xmlAttr
*attr
= node
->properties
;
255 if (!strcmp(attr
->name
, "name")) {
256 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
257 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
258 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for spectype\n", file
, node
->line
, attr
->name
);
264 fprintf (stderr
, "%s:%d: nameless spectype\n", file
, node
->line
);
268 for (i
= 0; i
< db
->spectypesnum
; i
++)
269 if (!strcmp(db
->spectypes
[i
]->name
, res
->name
)) {
270 fprintf (stderr
, "%s:%d: duplicated spectype name %s\n", file
, node
->line
, res
->name
);
274 ADDARRAY(db
->spectypes
, res
);
275 xmlNode
*chain
= node
->children
;
277 if (chain
->type
!= XML_ELEMENT_NODE
) {
278 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
279 fprintf (stderr
, "%s:%d: wrong tag in spectype: <%s>\n", file
, chain
->line
, chain
->name
);
286 static void parseenum(struct rnndb
*db
, char *file
, xmlNode
*node
) {
287 xmlAttr
*attr
= node
->properties
;
293 char *variantsstr
= 0;
296 if (!strcmp(attr
->name
, "name")) {
297 name
= getattrib(db
, file
, node
->line
, attr
);
298 } else if (!strcmp(attr
->name
, "bare")) {
299 bare
= getboolattrib(db
, file
, node
->line
, attr
);
300 } else if (!strcmp(attr
->name
, "inline")) {
301 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
302 } else if (!strcmp(attr
->name
, "prefix")) {
303 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
304 } else if (!strcmp(attr
->name
, "varset")) {
305 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
306 } else if (!strcmp(attr
->name
, "variants")) {
307 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
309 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for enum\n", file
, node
->line
, attr
->name
);
315 fprintf (stderr
, "%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 fprintf (stderr
, "%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 fprintf (stderr
, "%s:%d: wrong tag in enum: <%s>\n", file
, chain
->line
, chain
->name
);
359 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
) {
360 struct rnnbitfield
*bf
= calloc(sizeof *bf
, 1);
362 xmlAttr
*attr
= node
->properties
;
363 bf
->typeinfo
.low
= bf
->typeinfo
.high
= -1;
365 if (!strcmp(attr
->name
, "name")) {
366 bf
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
367 } else if (!strcmp(attr
->name
, "varset")) {
368 bf
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
369 } else if (!strcmp(attr
->name
, "variants")) {
370 bf
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
371 } else if (!trytypeattr(db
, file
, node
, attr
, &bf
->typeinfo
)) {
372 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for bitfield\n", file
, node
->line
, attr
->name
);
377 xmlNode
*chain
= node
->children
;
379 if (chain
->type
!= XML_ELEMENT_NODE
) {
380 } else if (!trytypetag(db
, file
, chain
, &bf
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
381 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
387 fprintf (stderr
, "%s:%d: nameless bitfield\n", file
, node
->line
);
390 } else if (bf
->typeinfo
.low
< 0|| bf
->typeinfo
.high
< 0 || bf
->typeinfo
.high
< bf
->typeinfo
.low
) {
391 fprintf (stderr
, "%s:%d: bitfield has wrong placement\n", file
, node
->line
);
399 static void parsebitset(struct rnndb
*db
, char *file
, xmlNode
*node
) {
400 xmlAttr
*attr
= node
->properties
;
406 char *variantsstr
= 0;
409 if (!strcmp(attr
->name
, "name")) {
410 name
= getattrib(db
, file
, node
->line
, attr
);
411 } else if (!strcmp(attr
->name
, "bare")) {
412 bare
= getboolattrib(db
, file
, node
->line
, attr
);
413 } else if (!strcmp(attr
->name
, "inline")) {
414 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
415 } else if (!strcmp(attr
->name
, "prefix")) {
416 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
417 } else if (!strcmp(attr
->name
, "varset")) {
418 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
419 } else if (!strcmp(attr
->name
, "variants")) {
420 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
422 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for bitset\n", file
, node
->line
, attr
->name
);
428 fprintf (stderr
, "%s:%d: nameless bitset\n", file
, node
->line
);
432 struct rnnbitset
*cur
= 0;
433 for (i
= 0; i
< db
->bitsetsnum
; i
++)
434 if (!strcmp(db
->bitsets
[i
]->name
, name
)) {
435 cur
= db
->bitsets
[i
];
439 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
440 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
441 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
442 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
443 fprintf (stderr
, "%s:%d: merge fail for bitset %s\n", file
, node
->line
, node
->name
);
447 cur
= calloc(sizeof *cur
, 1);
448 cur
->name
= strdup(name
);
449 cur
->isinline
= isinline
;
451 cur
->varinfo
.prefixstr
= prefixstr
;
452 cur
->varinfo
.varsetstr
= varsetstr
;
453 cur
->varinfo
.variantsstr
= variantsstr
;
455 ADDARRAY(db
->bitsets
, cur
);
457 xmlNode
*chain
= node
->children
;
459 if (chain
->type
!= XML_ELEMENT_NODE
) {
460 } else if (!strcmp(chain
->name
, "bitfield")) {
461 struct rnnbitfield
*bf
= parsebitfield(db
, file
, chain
);
463 ADDARRAY(cur
->bitfields
, bf
);
464 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
465 fprintf (stderr
, "%s:%d: wrong tag in bitset: <%s>\n", file
, chain
->line
, chain
->name
);
472 static struct rnndelem
*trydelem(struct rnndb
*db
, char *file
, xmlNode
*node
) {
473 if (!strcmp(node
->name
, "use-group")) {
474 struct rnndelem
*res
= calloc(sizeof *res
, 1);
476 res
->type
= RNN_ETYPE_USE_GROUP
;
477 xmlAttr
*attr
= node
->properties
;
479 if (!strcmp(attr
->name
, "name")) {
480 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
482 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
488 fprintf (stderr
, "%s:%d: nameless use-group\n", file
, node
->line
);
493 } else if (!strcmp(node
->name
, "stripe") || !strcmp(node
->name
, "array")) {
494 struct rnndelem
*res
= calloc(sizeof *res
, 1);
495 res
->type
= (strcmp(node
->name
, "stripe")?RNN_ETYPE_ARRAY
:RNN_ETYPE_STRIPE
);
498 xmlAttr
*attr
= node
->properties
;
500 if (!strcmp(attr
->name
, "name")) {
501 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
502 } else if (!strcmp(attr
->name
, "offset")) {
503 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
504 } else if (!strcmp(attr
->name
, "offsets")) {
505 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
506 char *tok
, *save
, *tmp
= str
;
507 while ((tok
= strtok_r(str
, ",", &save
))) {
508 uint64_t offset
= getnum(db
, file
, node
->line
, attr
, tok
);
509 ADDARRAY(res
->offsets
, offset
);
513 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
515 } else if (!strcmp(attr
->name
, "doffset")) {
516 /* dynamic runtime determined offset: */
517 res
->doffset
= strdup(getattrib(db
, file
, node
->line
, attr
));
518 } else if (!strcmp(attr
->name
, "doffsets")) {
519 /* dynamic runtime determined offsets: */
520 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
521 char *tok
, *save
, *tmp
= str
;
522 while ((tok
= strtok_r(str
, ",", &save
))) {
523 char *doffset
= strdup(tok
);
524 ADDARRAY(res
->doffsets
, doffset
);
528 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
530 } else if (!strcmp(attr
->name
, "length")) {
531 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
532 } else if (!strcmp(attr
->name
, "stride")) {
533 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
534 } else if (!strcmp(attr
->name
, "prefix")) {
535 res
->varinfo
.prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
536 } else if (!strcmp(attr
->name
, "varset")) {
537 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
538 } else if (!strcmp(attr
->name
, "variants")) {
539 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
540 } else if (!strcmp(attr
->name
, "index")) {
541 const char *enumname
= getattrib(db
, file
, node
->line
, attr
);
542 res
->index
= rnn_findenum(db
, enumname
);
544 fprintf(stderr
, "%s:%d: invalid enum name \"%s\"\n", file
, node
->line
, enumname
);
548 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
553 xmlNode
*chain
= node
->children
;
555 struct rnndelem
*delem
;
556 if (chain
->type
!= XML_ELEMENT_NODE
) {
557 } else if ((delem
= trydelem(db
, file
, chain
))) {
558 ADDARRAY(res
->subelems
, delem
);
559 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
560 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
566 /* Sanity checking */
567 if (res
->type
== RNN_ETYPE_ARRAY
&& res
->stride
== 0) {
568 fprintf(stderr
, "%s: Array %s's stride is undefined. Aborting.\n", file
, res
->name
);
575 if (!strcmp(node
->name
, "reg8"))
577 else if (!strcmp(node
->name
, "reg16"))
579 else if (!strcmp(node
->name
, "reg32"))
581 else if (!strcmp(node
->name
, "reg64"))
585 struct rnndelem
*res
= calloc(sizeof *res
, 1);
587 res
->type
= RNN_ETYPE_REG
;
590 res
->access
= RNN_ACCESS_RW
;
591 xmlAttr
*attr
= node
->properties
;
592 res
->typeinfo
.low
= 0;
593 res
->typeinfo
.high
= width
- 1;
595 if (!strcmp(attr
->name
, "name")) {
596 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
597 } else if (!strcmp(attr
->name
, "offset")) {
598 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
599 } else if (!strcmp(attr
->name
, "length")) {
600 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
601 } else if (!strcmp(attr
->name
, "stride")) {
602 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
603 } else if (!strcmp(attr
->name
, "varset")) {
604 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
605 } else if (!strcmp(attr
->name
, "variants")) {
606 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
607 } else if (!strcmp(attr
->name
, "access")) {
608 char *str
= getattrib(db
, file
, node
->line
, attr
);
609 if (!strcmp(str
, "r"))
610 res
->access
= RNN_ACCESS_R
;
611 else if (!strcmp(str
, "w"))
612 res
->access
= RNN_ACCESS_W
;
613 else if (!strcmp(str
, "rw"))
614 res
->access
= RNN_ACCESS_RW
;
616 fprintf (stderr
, "%s:%d: wrong access type \"%s\" for register\n", file
, node
->line
, str
);
617 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
618 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for register\n", file
, node
->line
, attr
->name
);
623 xmlNode
*chain
= node
->children
;
625 if (chain
->type
!= XML_ELEMENT_NODE
) {
626 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
627 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
633 fprintf (stderr
, "%s:%d: nameless register\n", file
, node
->line
);
641 static void parsegroup(struct rnndb
*db
, char *file
, xmlNode
*node
) {
642 xmlAttr
*attr
= node
->properties
;
646 if (!strcmp(attr
->name
, "name")) {
647 name
= getattrib(db
, file
, node
->line
, attr
);
649 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for group\n", file
, node
->line
, attr
->name
);
655 fprintf (stderr
, "%s:%d: nameless group\n", file
, node
->line
);
659 struct rnngroup
*cur
= 0;
660 for (i
= 0; i
< db
->groupsnum
; i
++)
661 if (!strcmp(db
->groups
[i
]->name
, name
)) {
666 cur
= calloc(sizeof *cur
, 1);
667 cur
->name
= strdup(name
);
668 ADDARRAY(db
->groups
, cur
);
670 xmlNode
*chain
= node
->children
;
672 struct rnndelem
*delem
;
673 if (chain
->type
!= XML_ELEMENT_NODE
) {
674 } else if ((delem
= trydelem(db
, file
, chain
))) {
675 ADDARRAY(cur
->subelems
, delem
);
676 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
677 fprintf (stderr
, "%s:%d: wrong tag in group: <%s>\n", file
, chain
->line
, chain
->name
);
684 static void parsedomain(struct rnndb
*db
, char *file
, xmlNode
*node
) {
685 xmlAttr
*attr
= node
->properties
;
687 uint64_t size
= 0; int width
= 8;
691 char *variantsstr
= 0;
694 if (!strcmp(attr
->name
, "name")) {
695 name
= getattrib(db
, file
, node
->line
, attr
);
696 } else if (!strcmp(attr
->name
, "bare")) {
697 bare
= getboolattrib(db
, file
, node
->line
, attr
);
698 } else if (!strcmp(attr
->name
, "size")) {
699 size
= getnumattrib(db
, file
, node
->line
, attr
);
700 } else if (!strcmp(attr
->name
, "width")) {
701 width
= getnumattrib(db
, file
, node
->line
, attr
);
702 } else if (!strcmp(attr
->name
, "prefix")) {
703 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
704 } else if (!strcmp(attr
->name
, "varset")) {
705 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
706 } else if (!strcmp(attr
->name
, "variants")) {
707 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
709 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for domain\n", file
, node
->line
, attr
->name
);
715 fprintf (stderr
, "%s:%d: nameless domain\n", file
, node
->line
);
719 struct rnndomain
*cur
= 0;
720 for (i
= 0; i
< db
->domainsnum
; i
++)
721 if (!strcmp(db
->domains
[i
]->name
, name
)) {
722 cur
= db
->domains
[i
];
726 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
727 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
728 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
729 cur
->width
!= width
||
731 (size
&& cur
->size
&& size
!= cur
->size
)) {
732 fprintf (stderr
, "%s:%d: merge fail for domain %s\n", file
, node
->line
, node
->name
);
739 cur
= calloc(sizeof *cur
, 1);
740 cur
->name
= strdup(name
);
744 cur
->varinfo
.prefixstr
= prefixstr
;
745 cur
->varinfo
.varsetstr
= varsetstr
;
746 cur
->varinfo
.variantsstr
= variantsstr
;
748 ADDARRAY(db
->domains
, cur
);
750 xmlNode
*chain
= node
->children
;
752 struct rnndelem
*delem
;
753 if (chain
->type
!= XML_ELEMENT_NODE
) {
754 } else if ((delem
= trydelem(db
, file
, chain
))) {
755 ADDARRAY(cur
->subelems
, delem
);
756 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
757 fprintf (stderr
, "%s:%d: wrong tag in domain: <%s>\n", file
, chain
->line
, chain
->name
);
764 static void parsecopyright(struct rnndb
*db
, char *file
, xmlNode
*node
) {
765 struct rnncopyright
* copyright
= &db
->copyright
;
766 xmlAttr
*attr
= node
->properties
;
768 if (!strcmp(attr
->name
, "year")) {
769 unsigned firstyear
= getnumattrib(db
, file
, node
->line
, attr
);
770 if(!copyright
->firstyear
|| firstyear
< copyright
->firstyear
)
771 copyright
->firstyear
= firstyear
;
773 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for copyright\n", file
, node
->line
, attr
->name
);
778 xmlNode
*chain
= node
->children
;
780 if (chain
->type
!= XML_ELEMENT_NODE
) {
781 } else if (!strcmp(chain
->name
, "license"))
782 if(copyright
->license
) {
783 if(strcmp(copyright
->license
, node
->content
)) {
784 fprintf(stderr
, "fatal error: multiple different licenses specified!\n");
785 abort(); /* TODO: do something better here, but headergen, xml2html, etc. should not produce anything in this case */
788 copyright
->license
= getcontent(chain
);
789 else if (!strcmp(chain
->name
, "author")) {
790 struct rnnauthor
* author
= calloc(sizeof *author
, 1);
791 xmlAttr
* authorattr
= chain
->properties
;
792 xmlNode
*authorchild
= chain
->children
;
793 author
->contributions
= getcontent(chain
);
795 if (!strcmp(authorattr
->name
, "name"))
796 author
->name
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
797 else if (!strcmp(authorattr
->name
, "email"))
798 author
->email
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
800 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for author\n", file
, chain
->line
, authorattr
->name
);
803 authorattr
= authorattr
->next
;
806 if (authorchild
->type
!= XML_ELEMENT_NODE
) {
807 } else if (!strcmp(authorchild
->name
, "nick")) {
808 xmlAttr
* nickattr
= authorchild
->properties
;
811 if (!strcmp(nickattr
->name
, "name"))
812 nickname
= strdup(getattrib(db
, file
, authorchild
->line
, nickattr
));
814 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for nick\n", file
, authorchild
->line
, nickattr
->name
);
817 nickattr
= nickattr
->next
;
820 fprintf (stderr
, "%s:%d: missing \"name\" attribute for nick\n", file
, authorchild
->line
);
823 ADDARRAY(author
->nicknames
, nickname
);
825 fprintf (stderr
, "%s:%d: wrong tag in author: <%s>\n", file
, authorchild
->line
, authorchild
->name
);
828 authorchild
= authorchild
->next
;
830 ADDARRAY(copyright
->authors
, author
);
832 fprintf (stderr
, "%s:%d: wrong tag in copyright: <%s>\n", file
, chain
->line
, chain
->name
);
839 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
) {
840 if (!strcmp(node
->name
, "enum")) {
841 parseenum(db
, file
, node
);
843 } else if (!strcmp(node
->name
, "bitset")) {
844 parsebitset(db
, file
, node
);
846 } else if (!strcmp(node
->name
, "group")) {
847 parsegroup(db
, file
, node
);
849 } else if (!strcmp(node
->name
, "domain")) {
850 parsedomain(db
, file
, node
);
852 } else if (!strcmp(node
->name
, "spectype")) {
853 parsespectype(db
, file
, node
);
855 } else if (!strcmp(node
->name
, "import")) {
856 xmlAttr
*attr
= node
->properties
;
859 if (!strcmp(attr
->name
, "file")) {
860 subfile
= getattrib(db
, file
, node
->line
, attr
);
862 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for import\n", file
, node
->line
, attr
->name
);
868 fprintf (stderr
, "%s:%d: missing \"file\" attribute for import\n", file
, node
->line
);
871 rnn_parsefile(db
, subfile
);
874 } else if (!strcmp(node
->name
, "copyright")) {
875 parsecopyright(db
, file
, node
);
881 static char * find_file(const char *file_orig
)
883 const char *rnn_path
= getenv("RNN_PATH");
887 rnn_path
= RNN_DEF_PATH
;
889 FILE *file
= find_in_path(file_orig
, rnn_path
, &fname
);
891 fprintf (stderr
, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", file_orig
);
899 void rnn_parsefile (struct rnndb
*db
, char *file_orig
) {
903 fname
= find_file(file_orig
);
909 for (i
= 0; i
< db
->filesnum
; i
++)
910 if (!strcmp(db
->files
[i
], fname
))
913 ADDARRAY(db
->files
, fname
);
914 xmlDocPtr doc
= xmlParseFile(fname
);
916 fprintf (stderr
, "%s: couldn't open database file. Please set the env var RNN_PATH.\n", fname
);
920 xmlNode
*root
= doc
->children
;
922 if (root
->type
!= XML_ELEMENT_NODE
) {
923 } else if (strcmp(root
->name
, "database")) {
924 fprintf (stderr
, "%s:%d: wrong top-level tag <%s>\n", fname
, root
->line
, root
->name
);
927 xmlNode
*chain
= root
->children
;
929 if (chain
->type
!= XML_ELEMENT_NODE
) {
930 } else if (!trytop(db
, fname
, chain
) && !trydoc(db
, fname
, chain
)) {
931 fprintf (stderr
, "%s:%d: wrong tag in database: <%s>\n", fname
, chain
->line
, chain
->name
);
942 static struct rnnvalue
*copyvalue (struct rnnvalue
*val
, char *file
) {
943 struct rnnvalue
*res
= calloc (sizeof *res
, 1);
944 res
->name
= val
->name
;
945 res
->valvalid
= val
->valvalid
;
946 res
->value
= val
->value
;
947 res
->varinfo
= val
->varinfo
;
952 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
);
955 static void copytypeinfo (struct rnntypeinfo
*dst
, struct rnntypeinfo
*src
, char *file
) {
957 dst
->name
= src
->name
;
960 dst
->high
= src
->high
;
963 dst
->align
= src
->align
;
964 dst
->addvariant
= src
->addvariant
;
965 for (i
= 0; i
< src
->valsnum
; i
++)
966 ADDARRAY(dst
->vals
, copyvalue(src
->vals
[i
], file
));
967 for (i
= 0; i
< src
->bitfieldsnum
; i
++)
968 ADDARRAY(dst
->bitfields
, copybitfield(src
->bitfields
[i
], file
));
971 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
) {
972 struct rnnbitfield
*res
= calloc (sizeof *res
, 1);
973 res
->name
= bf
->name
;
974 res
->varinfo
= bf
->varinfo
;
976 copytypeinfo(&res
->typeinfo
, &bf
->typeinfo
, file
);
980 static struct rnndelem
*copydelem (struct rnndelem
*elem
, char *file
) {
981 struct rnndelem
*res
= calloc (sizeof *res
, 1);
982 res
->type
= elem
->type
;
983 res
->name
= elem
->name
;
984 res
->width
= elem
->width
;
985 res
->access
= elem
->access
;
986 res
->offset
= elem
->offset
;
987 res
->length
= elem
->length
;
988 res
->stride
= elem
->stride
;
989 res
->varinfo
= elem
->varinfo
;
991 copytypeinfo(&res
->typeinfo
, &elem
->typeinfo
, file
);
993 for (i
= 0; i
< elem
->subelemsnum
; i
++)
994 ADDARRAY(res
->subelems
, copydelem(elem
->subelems
[i
], file
));
995 for (i
= 0; i
< elem
->offsetsnum
; i
++)
996 ADDARRAY(res
->offsets
, elem
->offsets
[i
]);
1000 static struct rnnvarset
*copyvarset (struct rnnvarset
*varset
) {
1001 struct rnnvarset
*res
= calloc(sizeof *res
, 1);
1002 res
->venum
= varset
->venum
;
1003 res
->variants
= calloc(sizeof *res
->variants
, res
->venum
->valsnum
);
1005 for (i
= 0; i
< res
->venum
->valsnum
; i
++)
1006 res
->variants
[i
] = varset
->variants
[i
];
1010 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
);
1012 static int findvidx (struct rnndb
*db
, struct rnnenum
*en
, char *name
) {
1014 for (i
= 0; i
< en
->valsnum
; i
++)
1015 if (!strcmp(en
->vals
[i
]->name
, name
))
1017 fprintf (stderr
, "Cannot find variant %s in enum %s!\n", name
, en
->name
);
1022 static void prepvarinfo (struct rnndb
*db
, char *what
, struct rnnvarinfo
*vi
, struct rnnvarinfo
*parent
) {
1024 vi
->prefenum
= parent
->prefenum
;
1025 if (vi
->prefixstr
) {
1026 if (!strcmp(vi
->prefixstr
, "none"))
1029 vi
->prefenum
= rnn_findenum(db
, vi
->prefixstr
); // XXX
1033 for (i
= 0; i
< parent
->varsetsnum
; i
++)
1034 ADDARRAY(vi
->varsets
, copyvarset(parent
->varsets
[i
]));
1035 struct rnnenum
*varset
= vi
->prefenum
;
1036 if (!varset
&& !vi
->varsetstr
&& parent
)
1037 vi
->varsetstr
= parent
->varsetstr
;
1039 varset
= rnn_findenum(db
, vi
->varsetstr
);
1040 if (vi
->variantsstr
) {
1041 char *vars
= vi
->variantsstr
;
1043 fprintf (stderr
, "%s: tried to use variants without active varset!\n", what
);
1047 struct rnnvarset
*vs
= 0;
1048 int nvars
= varset
->valsnum
;
1049 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1050 if (vi
->varsets
[i
]->venum
== varset
) {
1051 vs
= vi
->varsets
[i
];
1055 vs
= calloc (sizeof *vs
, 1);
1057 vs
->variants
= calloc(sizeof *vs
->variants
, nvars
);
1058 for (i
= 0; i
< nvars
; i
++)
1059 vs
->variants
[i
] = 1;
1060 ADDARRAY(vi
->varsets
, vs
);
1063 while (*vars
== ' ') vars
++;
1067 while (*split
!= ':' && *split
!= '-' && *split
!= ' ' && *split
!= 0)
1071 first
= strndup(vars
, split
-vars
);
1072 if (*split
== ' ' || *split
== 0) {
1073 int idx
= findvidx(db
, varset
, first
);
1075 vs
->variants
[idx
] |= 2;
1078 char *end
= split
+1;
1079 while (*end
!= ' ' && *end
!= 0)
1083 second
= strndup(split
+1, end
-split
-1);
1086 idx1
= findvidx(db
, varset
, first
);
1089 idx2
= findvidx(db
, varset
, second
);
1093 if (idx1
!= -1 && idx2
!= -1)
1094 for (i
= idx1
; i
< idx2
; i
++)
1095 vs
->variants
[i
] |= 2;
1102 for (i
= 0; i
< nvars
; i
++) {
1103 vs
->variants
[i
] = (vs
->variants
[i
] == 3);
1104 if (vs
->variants
[i
])
1111 struct rnnvarset
*vs
= 0;
1112 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1113 if (vi
->varsets
[i
]->venum
== vi
->prefenum
) {
1114 vs
= vi
->varsets
[i
];
1118 for (i
= 0; i
< vi
->prefenum
->valsnum
; i
++)
1119 if (vs
->variants
[i
]) {
1120 vi
->prefix
= vi
->prefenum
->vals
[i
]->name
;
1124 vi
->prefix
= vi
->prefenum
->vals
[0]->name
;
1129 static void prepvalue(struct rnndb
*db
, struct rnnvalue
*val
, char *prefix
, struct rnnvarinfo
*parvi
) {
1130 val
->fullname
= catstr(prefix
, val
->name
);
1131 prepvarinfo (db
, val
->fullname
, &val
->varinfo
, parvi
);
1132 if (val
->varinfo
.dead
)
1134 if (val
->varinfo
.prefix
)
1135 val
->fullname
= catstr(val
->varinfo
.prefix
, val
->fullname
);
1138 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
);
1140 static void preptypeinfo(struct rnndb
*db
, struct rnntypeinfo
*ti
, char *prefix
, struct rnnvarinfo
*vi
, char *file
) {
1143 struct rnnenum
*en
= rnn_findenum (db
, ti
->name
);
1144 struct rnnbitset
*bs
= rnn_findbitset (db
, ti
->name
);
1145 struct rnnspectype
*st
= rnn_findspectype (db
, ti
->name
);
1148 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1150 for (j
= 0; j
< en
->valsnum
; j
++)
1151 ADDARRAY(ti
->vals
, copyvalue(en
->vals
[j
], file
));
1153 ti
->type
= RNN_TTYPE_ENUM
;
1158 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1160 for (j
= 0; j
< bs
->bitfieldsnum
; j
++)
1161 ADDARRAY(ti
->bitfields
, copybitfield(bs
->bitfields
[j
], file
));
1163 ti
->type
= RNN_TTYPE_BITSET
;
1167 ti
->type
= RNN_TTYPE_SPECTYPE
;
1169 } else if (!strcmp(ti
->name
, "hex")) {
1170 ti
->type
= RNN_TTYPE_HEX
;
1171 } else if (!strcmp(ti
->name
, "float")) {
1172 ti
->type
= RNN_TTYPE_FLOAT
;
1173 } else if (!strcmp(ti
->name
, "uint")) {
1174 ti
->type
= RNN_TTYPE_UINT
;
1175 } else if (!strcmp(ti
->name
, "int")) {
1176 ti
->type
= RNN_TTYPE_INT
;
1177 } else if (!strcmp(ti
->name
, "boolean")) {
1178 ti
->type
= RNN_TTYPE_BOOLEAN
;
1179 } else if (!strcmp(ti
->name
, "bitfield")) {
1180 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1181 } else if (!strcmp(ti
->name
, "enum")) {
1182 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1183 } else if (!strcmp(ti
->name
, "fixed")) {
1184 ti
->type
= RNN_TTYPE_FIXED
;
1185 } else if (!strcmp(ti
->name
, "ufixed")) {
1186 ti
->type
= RNN_TTYPE_UFIXED
;
1187 } else if (!strcmp(ti
->name
, "a3xx_regid")) {
1188 ti
->type
= RNN_TTYPE_A3XX_REGID
;
1189 } else if (!strcmp(ti
->name
, "waddress") || !strcmp(ti
->name
, "address")) {
1190 ti
->type
= RNN_TTYPE_HEX
;
1192 ti
->type
= RNN_TTYPE_HEX
;
1193 fprintf (stderr
, "%s: unknown type %s\n", prefix
, ti
->name
);
1196 } else if (ti
->bitfieldsnum
) {
1197 ti
->name
= "bitfield";
1198 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1199 } else if (ti
->valsnum
) {
1201 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1202 } else if (ti
->low
== 0 && ti
->high
== 0) {
1203 ti
->name
= "boolean";
1204 ti
->type
= RNN_TTYPE_BOOLEAN
;
1207 ti
->type
= RNN_TTYPE_HEX
;
1209 if (ti
->addvariant
&& ti
->type
!= RNN_TTYPE_ENUM
) {
1210 fprintf (stderr
, "%s: addvariant specified on non-enum type %s\n", prefix
, ti
->name
);
1213 for (i
= 0; i
< ti
->bitfieldsnum
; i
++)
1214 prepbitfield(db
, ti
->bitfields
[i
], prefix
, vi
);
1215 for (i
= 0; i
< ti
->valsnum
; i
++)
1216 prepvalue(db
, ti
->vals
[i
], prefix
, vi
);
1219 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
) {
1220 bf
->fullname
= catstr(prefix
, bf
->name
);
1221 prepvarinfo (db
, bf
->fullname
, &bf
->varinfo
, parvi
);
1222 if (bf
->varinfo
.dead
)
1224 preptypeinfo(db
, &bf
->typeinfo
, bf
->fullname
, &bf
->varinfo
, bf
->file
);
1225 if (bf
->varinfo
.prefix
)
1226 bf
->fullname
= catstr(bf
->varinfo
.prefix
, bf
->fullname
);
1229 static void prepdelem(struct rnndb
*db
, struct rnndelem
*elem
, char *prefix
, struct rnnvarinfo
*parvi
, int width
) {
1230 if (elem
->type
== RNN_ETYPE_USE_GROUP
) {
1232 struct rnngroup
*gr
= 0;
1233 for (i
= 0; i
< db
->groupsnum
; i
++)
1234 if (!strcmp(db
->groups
[i
]->name
, elem
->name
)) {
1239 for (i
= 0; i
< gr
->subelemsnum
; i
++)
1240 ADDARRAY(elem
->subelems
, copydelem(gr
->subelems
[i
], elem
->file
));
1242 fprintf (stderr
, "group %s not found!\n", elem
->name
);
1245 elem
->type
= RNN_ETYPE_STRIPE
;
1250 elem
->fullname
= catstr(prefix
, elem
->name
);
1251 prepvarinfo (db
, elem
->fullname
?elem
->fullname
:prefix
, &elem
->varinfo
, parvi
);
1252 if (elem
->varinfo
.dead
)
1254 if (elem
->length
!= 1 && !elem
->stride
) {
1255 if (elem
->type
!= RNN_ETYPE_REG
) {
1256 fprintf (stderr
, "%s has non-1 length, but no stride!\n", elem
->fullname
);
1259 elem
->stride
= elem
->width
/width
;
1262 preptypeinfo(db
, &elem
->typeinfo
, elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, elem
->file
);
1265 for (i
= 0; i
< elem
->subelemsnum
; i
++)
1266 prepdelem(db
, elem
->subelems
[i
], elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, width
);
1267 if (elem
->varinfo
.prefix
&& elem
->name
)
1268 elem
->fullname
= catstr(elem
->varinfo
.prefix
, elem
->fullname
);
1271 static void prepdomain(struct rnndb
*db
, struct rnndomain
*dom
) {
1272 prepvarinfo (db
, dom
->name
, &dom
->varinfo
, 0);
1274 for (i
= 0; i
< dom
->subelemsnum
; i
++)
1275 prepdelem(db
, dom
->subelems
[i
], dom
->bare
?0:dom
->name
, &dom
->varinfo
, dom
->width
);
1276 dom
->fullname
= catstr(dom
->varinfo
.prefix
, dom
->name
);
1279 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
) {
1282 prepvarinfo (db
, en
->name
, &en
->varinfo
, 0);
1286 for (i
= 0; i
< en
->valsnum
; i
++)
1287 prepvalue(db
, en
->vals
[i
], en
->bare
?0:en
->name
, &en
->varinfo
);
1288 en
->fullname
= catstr(en
->varinfo
.prefix
, en
->name
);
1292 static void prepbitset(struct rnndb
*db
, struct rnnbitset
*bs
) {
1293 prepvarinfo (db
, bs
->name
, &bs
->varinfo
, 0);
1297 for (i
= 0; i
< bs
->bitfieldsnum
; i
++)
1298 prepbitfield(db
, bs
->bitfields
[i
], bs
->bare
?0:bs
->name
, &bs
->varinfo
);
1299 bs
->fullname
= catstr(bs
->varinfo
.prefix
, bs
->name
);
1302 static void prepspectype(struct rnndb
*db
, struct rnnspectype
*st
) {
1303 preptypeinfo(db
, &st
->typeinfo
, st
->name
, 0, st
->file
); // XXX doesn't exactly make sense...
1306 void rnn_prepdb (struct rnndb
*db
) {
1308 for (i
= 0; i
< db
->enumsnum
; i
++)
1309 prepenum(db
, db
->enums
[i
]);
1310 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1311 prepbitset(db
, db
->bitsets
[i
]);
1312 for (i
= 0; i
< db
->domainsnum
; i
++)
1313 prepdomain(db
, db
->domains
[i
]);
1314 for (i
= 0; i
< db
->spectypesnum
; i
++)
1315 prepspectype(db
, db
->spectypes
[i
]);
1318 struct rnnenum
*rnn_findenum (struct rnndb
*db
, const char *name
) {
1320 for (i
= 0; i
< db
->enumsnum
; i
++)
1321 if (!strcmp(db
->enums
[i
]->name
, name
))
1322 return db
->enums
[i
];
1326 struct rnnbitset
*rnn_findbitset (struct rnndb
*db
, const char *name
) {
1328 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1329 if (!strcmp(db
->bitsets
[i
]->name
, name
))
1330 return db
->bitsets
[i
];
1334 struct rnndomain
*rnn_finddomain (struct rnndb
*db
, const char *name
) {
1336 for (i
= 0; i
< db
->domainsnum
; i
++)
1337 if (!strcmp(db
->domains
[i
]->name
, name
))
1338 return db
->domains
[i
];
1342 struct rnnspectype
*rnn_findspectype (struct rnndb
*db
, const char *name
) {
1344 for (i
= 0; i
< db
->spectypesnum
; i
++)
1345 if (!strcmp(db
->spectypes
[i
]->name
, name
))
1346 return db
->spectypes
[i
];