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
);
210 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
) {
211 struct rnnvalue
*val
= calloc(sizeof *val
, 1);
213 xmlAttr
*attr
= node
->properties
;
215 if (!strcmp(attr
->name
, "name")) {
216 val
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
217 } else if (!strcmp(attr
->name
, "value")) {
218 val
->value
= getnumattrib(db
, file
, node
->line
, attr
);
220 } else if (!strcmp(attr
->name
, "varset")) {
221 val
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
222 } else if (!strcmp(attr
->name
, "variants")) {
223 val
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
225 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for value\n", file
, node
->line
, attr
->name
);
230 xmlNode
*chain
= node
->children
;
232 if (chain
->type
!= XML_ELEMENT_NODE
) {
233 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
234 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
240 fprintf (stderr
, "%s:%d: nameless value\n", file
, node
->line
);
248 static void parsespectype(struct rnndb
*db
, char *file
, xmlNode
*node
) {
249 struct rnnspectype
*res
= calloc (sizeof *res
, 1);
251 xmlAttr
*attr
= node
->properties
;
254 if (!strcmp(attr
->name
, "name")) {
255 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
256 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
257 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for spectype\n", file
, node
->line
, attr
->name
);
263 fprintf (stderr
, "%s:%d: nameless spectype\n", file
, node
->line
);
267 for (i
= 0; i
< db
->spectypesnum
; i
++)
268 if (!strcmp(db
->spectypes
[i
]->name
, res
->name
)) {
269 fprintf (stderr
, "%s:%d: duplicated spectype name %s\n", file
, node
->line
, res
->name
);
273 ADDARRAY(db
->spectypes
, res
);
274 xmlNode
*chain
= node
->children
;
276 if (chain
->type
!= XML_ELEMENT_NODE
) {
277 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
278 fprintf (stderr
, "%s:%d: wrong tag in spectype: <%s>\n", file
, chain
->line
, chain
->name
);
285 static void parseenum(struct rnndb
*db
, char *file
, xmlNode
*node
) {
286 xmlAttr
*attr
= node
->properties
;
292 char *variantsstr
= 0;
295 if (!strcmp(attr
->name
, "name")) {
296 name
= getattrib(db
, file
, node
->line
, attr
);
297 } else if (!strcmp(attr
->name
, "bare")) {
298 bare
= getboolattrib(db
, file
, node
->line
, attr
);
299 } else if (!strcmp(attr
->name
, "inline")) {
300 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
301 } else if (!strcmp(attr
->name
, "prefix")) {
302 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
303 } else if (!strcmp(attr
->name
, "varset")) {
304 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
305 } else if (!strcmp(attr
->name
, "variants")) {
306 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
308 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for enum\n", file
, node
->line
, attr
->name
);
314 fprintf (stderr
, "%s:%d: nameless enum\n", file
, node
->line
);
318 struct rnnenum
*cur
= 0;
319 for (i
= 0; i
< db
->enumsnum
; i
++)
320 if (!strcmp(db
->enums
[i
]->name
, name
)) {
325 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
326 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
327 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
328 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
329 fprintf (stderr
, "%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 fprintf (stderr
, "%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 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for bitfield\n", file
, node
->line
, attr
->name
);
376 xmlNode
*chain
= node
->children
;
378 if (chain
->type
!= XML_ELEMENT_NODE
) {
379 } else if (!trytypetag(db
, file
, chain
, &bf
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
380 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
386 fprintf (stderr
, "%s:%d: nameless bitfield\n", file
, node
->line
);
389 } else if (bf
->typeinfo
.low
< 0|| bf
->typeinfo
.high
< 0 || bf
->typeinfo
.high
< bf
->typeinfo
.low
) {
390 fprintf (stderr
, "%s:%d: bitfield has wrong placement\n", file
, node
->line
);
398 static void parsebitset(struct rnndb
*db
, char *file
, xmlNode
*node
) {
399 xmlAttr
*attr
= node
->properties
;
405 char *variantsstr
= 0;
408 if (!strcmp(attr
->name
, "name")) {
409 name
= getattrib(db
, file
, node
->line
, attr
);
410 } else if (!strcmp(attr
->name
, "bare")) {
411 bare
= getboolattrib(db
, file
, node
->line
, attr
);
412 } else if (!strcmp(attr
->name
, "inline")) {
413 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
414 } else if (!strcmp(attr
->name
, "prefix")) {
415 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
416 } else if (!strcmp(attr
->name
, "varset")) {
417 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
418 } else if (!strcmp(attr
->name
, "variants")) {
419 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
421 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for bitset\n", file
, node
->line
, attr
->name
);
427 fprintf (stderr
, "%s:%d: nameless bitset\n", file
, node
->line
);
431 struct rnnbitset
*cur
= 0;
432 for (i
= 0; i
< db
->bitsetsnum
; i
++)
433 if (!strcmp(db
->bitsets
[i
]->name
, name
)) {
434 cur
= db
->bitsets
[i
];
438 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
439 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
440 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
441 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
442 fprintf (stderr
, "%s:%d: merge fail for bitset %s\n", file
, node
->line
, node
->name
);
446 cur
= calloc(sizeof *cur
, 1);
447 cur
->name
= strdup(name
);
448 cur
->isinline
= isinline
;
450 cur
->varinfo
.prefixstr
= prefixstr
;
451 cur
->varinfo
.varsetstr
= varsetstr
;
452 cur
->varinfo
.variantsstr
= variantsstr
;
454 ADDARRAY(db
->bitsets
, cur
);
456 xmlNode
*chain
= node
->children
;
458 if (chain
->type
!= XML_ELEMENT_NODE
) {
459 } else if (!strcmp(chain
->name
, "bitfield")) {
460 struct rnnbitfield
*bf
= parsebitfield(db
, file
, chain
);
462 ADDARRAY(cur
->bitfields
, bf
);
463 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
464 fprintf (stderr
, "%s:%d: wrong tag in bitset: <%s>\n", file
, chain
->line
, chain
->name
);
471 static struct rnndelem
*trydelem(struct rnndb
*db
, char *file
, xmlNode
*node
) {
472 if (!strcmp(node
->name
, "use-group")) {
473 struct rnndelem
*res
= calloc(sizeof *res
, 1);
475 res
->type
= RNN_ETYPE_USE_GROUP
;
476 xmlAttr
*attr
= node
->properties
;
478 if (!strcmp(attr
->name
, "name")) {
479 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
481 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
487 fprintf (stderr
, "%s:%d: nameless use-group\n", file
, node
->line
);
492 } else if (!strcmp(node
->name
, "stripe") || !strcmp(node
->name
, "array")) {
493 struct rnndelem
*res
= calloc(sizeof *res
, 1);
494 res
->type
= (strcmp(node
->name
, "stripe")?RNN_ETYPE_ARRAY
:RNN_ETYPE_STRIPE
);
497 xmlAttr
*attr
= node
->properties
;
499 if (!strcmp(attr
->name
, "name")) {
500 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
501 } else if (!strcmp(attr
->name
, "offset")) {
502 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
503 } else if (!strcmp(attr
->name
, "offsets")) {
504 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
505 char *tok
, *save
, *tmp
= str
;
506 while ((tok
= strtok_r(str
, ",", &save
))) {
507 uint64_t offset
= getnum(db
, file
, node
->line
, attr
, tok
);
508 ADDARRAY(res
->offsets
, offset
);
512 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
514 } else if (!strcmp(attr
->name
, "doffset")) {
515 /* dynamic runtime determined offset: */
516 res
->doffset
= strdup(getattrib(db
, file
, node
->line
, attr
));
517 } else if (!strcmp(attr
->name
, "doffsets")) {
518 /* dynamic runtime determined offsets: */
519 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
520 char *tok
, *save
, *tmp
= str
;
521 while ((tok
= strtok_r(str
, ",", &save
))) {
522 char *doffset
= strdup(tok
);
523 ADDARRAY(res
->doffsets
, doffset
);
527 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
529 } else if (!strcmp(attr
->name
, "length")) {
530 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
531 } else if (!strcmp(attr
->name
, "stride")) {
532 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
533 } else if (!strcmp(attr
->name
, "prefix")) {
534 res
->varinfo
.prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
535 } else if (!strcmp(attr
->name
, "varset")) {
536 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
537 } else if (!strcmp(attr
->name
, "variants")) {
538 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
539 } else if (!strcmp(attr
->name
, "index")) {
540 const char *enumname
= getattrib(db
, file
, node
->line
, attr
);
541 res
->index
= rnn_findenum(db
, enumname
);
543 fprintf(stderr
, "%s:%d: invalid enum name \"%s\"\n", file
, node
->line
, enumname
);
547 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
552 xmlNode
*chain
= node
->children
;
554 struct rnndelem
*delem
;
555 if (chain
->type
!= XML_ELEMENT_NODE
) {
556 } else if ((delem
= trydelem(db
, file
, chain
))) {
557 ADDARRAY(res
->subelems
, delem
);
558 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
559 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
565 /* Sanity checking */
566 if (res
->type
== RNN_ETYPE_ARRAY
&& res
->stride
== 0) {
567 fprintf(stderr
, "%s: Array %s's stride is undefined. Aborting.\n", file
, res
->name
);
574 if (!strcmp(node
->name
, "reg8"))
576 else if (!strcmp(node
->name
, "reg16"))
578 else if (!strcmp(node
->name
, "reg32"))
580 else if (!strcmp(node
->name
, "reg64"))
584 struct rnndelem
*res
= calloc(sizeof *res
, 1);
586 res
->type
= RNN_ETYPE_REG
;
589 res
->access
= RNN_ACCESS_RW
;
590 xmlAttr
*attr
= node
->properties
;
591 res
->typeinfo
.low
= 0;
592 res
->typeinfo
.high
= width
- 1;
594 if (!strcmp(attr
->name
, "name")) {
595 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
596 } else if (!strcmp(attr
->name
, "offset")) {
597 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
598 } else if (!strcmp(attr
->name
, "length")) {
599 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
600 } else if (!strcmp(attr
->name
, "stride")) {
601 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
602 } else if (!strcmp(attr
->name
, "varset")) {
603 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
604 } else if (!strcmp(attr
->name
, "variants")) {
605 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
606 } else if (!strcmp(attr
->name
, "access")) {
607 char *str
= getattrib(db
, file
, node
->line
, attr
);
608 if (!strcmp(str
, "r"))
609 res
->access
= RNN_ACCESS_R
;
610 else if (!strcmp(str
, "w"))
611 res
->access
= RNN_ACCESS_W
;
612 else if (!strcmp(str
, "rw"))
613 res
->access
= RNN_ACCESS_RW
;
615 fprintf (stderr
, "%s:%d: wrong access type \"%s\" for register\n", file
, node
->line
, str
);
616 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
617 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for register\n", file
, node
->line
, attr
->name
);
622 xmlNode
*chain
= node
->children
;
624 if (chain
->type
!= XML_ELEMENT_NODE
) {
625 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
626 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
632 fprintf (stderr
, "%s:%d: nameless register\n", file
, node
->line
);
640 static void parsegroup(struct rnndb
*db
, char *file
, xmlNode
*node
) {
641 xmlAttr
*attr
= node
->properties
;
645 if (!strcmp(attr
->name
, "name")) {
646 name
= getattrib(db
, file
, node
->line
, attr
);
648 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for group\n", file
, node
->line
, attr
->name
);
654 fprintf (stderr
, "%s:%d: nameless group\n", file
, node
->line
);
658 struct rnngroup
*cur
= 0;
659 for (i
= 0; i
< db
->groupsnum
; i
++)
660 if (!strcmp(db
->groups
[i
]->name
, name
)) {
665 cur
= calloc(sizeof *cur
, 1);
666 cur
->name
= strdup(name
);
667 ADDARRAY(db
->groups
, cur
);
669 xmlNode
*chain
= node
->children
;
671 struct rnndelem
*delem
;
672 if (chain
->type
!= XML_ELEMENT_NODE
) {
673 } else if ((delem
= trydelem(db
, file
, chain
))) {
674 ADDARRAY(cur
->subelems
, delem
);
675 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
676 fprintf (stderr
, "%s:%d: wrong tag in group: <%s>\n", file
, chain
->line
, chain
->name
);
683 static void parsedomain(struct rnndb
*db
, char *file
, xmlNode
*node
) {
684 xmlAttr
*attr
= node
->properties
;
686 uint64_t size
= 0; int width
= 8;
690 char *variantsstr
= 0;
693 if (!strcmp(attr
->name
, "name")) {
694 name
= getattrib(db
, file
, node
->line
, attr
);
695 } else if (!strcmp(attr
->name
, "bare")) {
696 bare
= getboolattrib(db
, file
, node
->line
, attr
);
697 } else if (!strcmp(attr
->name
, "size")) {
698 size
= getnumattrib(db
, file
, node
->line
, attr
);
699 } else if (!strcmp(attr
->name
, "width")) {
700 width
= getnumattrib(db
, file
, node
->line
, attr
);
701 } else if (!strcmp(attr
->name
, "prefix")) {
702 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
703 } else if (!strcmp(attr
->name
, "varset")) {
704 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
705 } else if (!strcmp(attr
->name
, "variants")) {
706 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
708 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for domain\n", file
, node
->line
, attr
->name
);
714 fprintf (stderr
, "%s:%d: nameless domain\n", file
, node
->line
);
718 struct rnndomain
*cur
= 0;
719 for (i
= 0; i
< db
->domainsnum
; i
++)
720 if (!strcmp(db
->domains
[i
]->name
, name
)) {
721 cur
= db
->domains
[i
];
725 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
726 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
727 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
728 cur
->width
!= width
||
730 (size
&& cur
->size
&& size
!= cur
->size
)) {
731 fprintf (stderr
, "%s:%d: merge fail for domain %s\n", file
, node
->line
, node
->name
);
738 cur
= calloc(sizeof *cur
, 1);
739 cur
->name
= strdup(name
);
743 cur
->varinfo
.prefixstr
= prefixstr
;
744 cur
->varinfo
.varsetstr
= varsetstr
;
745 cur
->varinfo
.variantsstr
= variantsstr
;
747 ADDARRAY(db
->domains
, cur
);
749 xmlNode
*chain
= node
->children
;
751 struct rnndelem
*delem
;
752 if (chain
->type
!= XML_ELEMENT_NODE
) {
753 } else if ((delem
= trydelem(db
, file
, chain
))) {
754 ADDARRAY(cur
->subelems
, delem
);
755 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
756 fprintf (stderr
, "%s:%d: wrong tag in domain: <%s>\n", file
, chain
->line
, chain
->name
);
763 static void parsecopyright(struct rnndb
*db
, char *file
, xmlNode
*node
) {
764 struct rnncopyright
* copyright
= &db
->copyright
;
765 xmlAttr
*attr
= node
->properties
;
767 if (!strcmp(attr
->name
, "year")) {
768 unsigned firstyear
= getnumattrib(db
, file
, node
->line
, attr
);
769 if(!copyright
->firstyear
|| firstyear
< copyright
->firstyear
)
770 copyright
->firstyear
= firstyear
;
772 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for copyright\n", file
, node
->line
, attr
->name
);
777 xmlNode
*chain
= node
->children
;
779 if (chain
->type
!= XML_ELEMENT_NODE
) {
780 } else if (!strcmp(chain
->name
, "license"))
781 if(copyright
->license
) {
782 if(strcmp(copyright
->license
, node
->content
)) {
783 fprintf(stderr
, "fatal error: multiple different licenses specified!\n");
784 abort(); /* TODO: do something better here, but headergen, xml2html, etc. should not produce anything in this case */
787 copyright
->license
= getcontent(chain
);
788 else if (!strcmp(chain
->name
, "author")) {
789 struct rnnauthor
* author
= calloc(sizeof *author
, 1);
790 xmlAttr
* authorattr
= chain
->properties
;
791 xmlNode
*authorchild
= chain
->children
;
792 author
->contributions
= getcontent(chain
);
794 if (!strcmp(authorattr
->name
, "name"))
795 author
->name
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
796 else if (!strcmp(authorattr
->name
, "email"))
797 author
->email
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
799 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for author\n", file
, chain
->line
, authorattr
->name
);
802 authorattr
= authorattr
->next
;
805 if (authorchild
->type
!= XML_ELEMENT_NODE
) {
806 } else if (!strcmp(authorchild
->name
, "nick")) {
807 xmlAttr
* nickattr
= authorchild
->properties
;
810 if (!strcmp(nickattr
->name
, "name"))
811 nickname
= strdup(getattrib(db
, file
, authorchild
->line
, nickattr
));
813 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for nick\n", file
, authorchild
->line
, nickattr
->name
);
816 nickattr
= nickattr
->next
;
819 fprintf (stderr
, "%s:%d: missing \"name\" attribute for nick\n", file
, authorchild
->line
);
822 ADDARRAY(author
->nicknames
, nickname
);
824 fprintf (stderr
, "%s:%d: wrong tag in author: <%s>\n", file
, authorchild
->line
, authorchild
->name
);
827 authorchild
= authorchild
->next
;
829 ADDARRAY(copyright
->authors
, author
);
831 fprintf (stderr
, "%s:%d: wrong tag in copyright: <%s>\n", file
, chain
->line
, chain
->name
);
838 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
) {
839 if (!strcmp(node
->name
, "enum")) {
840 parseenum(db
, file
, node
);
842 } else if (!strcmp(node
->name
, "bitset")) {
843 parsebitset(db
, file
, node
);
845 } else if (!strcmp(node
->name
, "group")) {
846 parsegroup(db
, file
, node
);
848 } else if (!strcmp(node
->name
, "domain")) {
849 parsedomain(db
, file
, node
);
851 } else if (!strcmp(node
->name
, "spectype")) {
852 parsespectype(db
, file
, node
);
854 } else if (!strcmp(node
->name
, "import")) {
855 xmlAttr
*attr
= node
->properties
;
858 if (!strcmp(attr
->name
, "file")) {
859 subfile
= getattrib(db
, file
, node
->line
, attr
);
861 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for import\n", file
, node
->line
, attr
->name
);
867 fprintf (stderr
, "%s:%d: missing \"file\" attribute for import\n", file
, node
->line
);
870 rnn_parsefile(db
, subfile
);
873 } else if (!strcmp(node
->name
, "copyright")) {
874 parsecopyright(db
, file
, node
);
880 void rnn_parsefile (struct rnndb
*db
, char *file_orig
) {
883 const char *rnn_path
= getenv("RNN_PATH");
886 rnn_path
= RNN_DEF_PATH
;
888 FILE *file
= find_in_path(file_orig
, rnn_path
, &fname
);
890 fprintf (stderr
, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", file_orig
);
896 for (i
= 0; i
< db
->filesnum
; i
++)
897 if (!strcmp(db
->files
[i
], fname
))
900 ADDARRAY(db
->files
, fname
);
901 xmlDocPtr doc
= xmlParseFile(fname
);
903 fprintf (stderr
, "%s: couldn't open database file. Please set the env var RNN_PATH.\n", fname
);
907 xmlNode
*root
= doc
->children
;
909 if (root
->type
!= XML_ELEMENT_NODE
) {
910 } else if (strcmp(root
->name
, "database")) {
911 fprintf (stderr
, "%s:%d: wrong top-level tag <%s>\n", fname
, root
->line
, root
->name
);
914 xmlNode
*chain
= root
->children
;
916 if (chain
->type
!= XML_ELEMENT_NODE
) {
917 } else if (!trytop(db
, fname
, chain
) && !trydoc(db
, fname
, chain
)) {
918 fprintf (stderr
, "%s:%d: wrong tag in database: <%s>\n", fname
, chain
->line
, chain
->name
);
929 static struct rnnvalue
*copyvalue (struct rnnvalue
*val
, char *file
) {
930 struct rnnvalue
*res
= calloc (sizeof *res
, 1);
931 res
->name
= val
->name
;
932 res
->valvalid
= val
->valvalid
;
933 res
->value
= val
->value
;
934 res
->varinfo
= val
->varinfo
;
939 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
);
942 static void copytypeinfo (struct rnntypeinfo
*dst
, struct rnntypeinfo
*src
, char *file
) {
944 dst
->name
= src
->name
;
947 dst
->high
= src
->high
;
950 dst
->align
= src
->align
;
951 dst
->addvariant
= src
->addvariant
;
952 for (i
= 0; i
< src
->valsnum
; i
++)
953 ADDARRAY(dst
->vals
, copyvalue(src
->vals
[i
], file
));
954 for (i
= 0; i
< src
->bitfieldsnum
; i
++)
955 ADDARRAY(dst
->bitfields
, copybitfield(src
->bitfields
[i
], file
));
958 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
) {
959 struct rnnbitfield
*res
= calloc (sizeof *res
, 1);
960 res
->name
= bf
->name
;
961 res
->varinfo
= bf
->varinfo
;
963 copytypeinfo(&res
->typeinfo
, &bf
->typeinfo
, file
);
967 static struct rnndelem
*copydelem (struct rnndelem
*elem
, char *file
) {
968 struct rnndelem
*res
= calloc (sizeof *res
, 1);
969 res
->type
= elem
->type
;
970 res
->name
= elem
->name
;
971 res
->width
= elem
->width
;
972 res
->access
= elem
->access
;
973 res
->offset
= elem
->offset
;
974 res
->length
= elem
->length
;
975 res
->stride
= elem
->stride
;
976 res
->varinfo
= elem
->varinfo
;
978 copytypeinfo(&res
->typeinfo
, &elem
->typeinfo
, file
);
980 for (i
= 0; i
< elem
->subelemsnum
; i
++)
981 ADDARRAY(res
->subelems
, copydelem(elem
->subelems
[i
], file
));
982 for (i
= 0; i
< elem
->offsetsnum
; i
++)
983 ADDARRAY(res
->offsets
, elem
->offsets
[i
]);
987 static struct rnnvarset
*copyvarset (struct rnnvarset
*varset
) {
988 struct rnnvarset
*res
= calloc(sizeof *res
, 1);
989 res
->venum
= varset
->venum
;
990 res
->variants
= calloc(sizeof *res
->variants
, res
->venum
->valsnum
);
992 for (i
= 0; i
< res
->venum
->valsnum
; i
++)
993 res
->variants
[i
] = varset
->variants
[i
];
997 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
);
999 static int findvidx (struct rnndb
*db
, struct rnnenum
*en
, char *name
) {
1001 for (i
= 0; i
< en
->valsnum
; i
++)
1002 if (!strcmp(en
->vals
[i
]->name
, name
))
1004 fprintf (stderr
, "Cannot find variant %s in enum %s!\n", name
, en
->name
);
1009 static void prepvarinfo (struct rnndb
*db
, char *what
, struct rnnvarinfo
*vi
, struct rnnvarinfo
*parent
) {
1011 vi
->prefenum
= parent
->prefenum
;
1012 if (vi
->prefixstr
) {
1013 if (!strcmp(vi
->prefixstr
, "none"))
1016 vi
->prefenum
= rnn_findenum(db
, vi
->prefixstr
); // XXX
1020 for (i
= 0; i
< parent
->varsetsnum
; i
++)
1021 ADDARRAY(vi
->varsets
, copyvarset(parent
->varsets
[i
]));
1022 struct rnnenum
*varset
= vi
->prefenum
;
1023 if (!varset
&& !vi
->varsetstr
&& parent
)
1024 vi
->varsetstr
= parent
->varsetstr
;
1026 varset
= rnn_findenum(db
, vi
->varsetstr
);
1027 if (vi
->variantsstr
) {
1028 char *vars
= vi
->variantsstr
;
1030 fprintf (stderr
, "%s: tried to use variants without active varset!\n", what
);
1034 struct rnnvarset
*vs
= 0;
1035 int nvars
= varset
->valsnum
;
1036 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1037 if (vi
->varsets
[i
]->venum
== varset
) {
1038 vs
= vi
->varsets
[i
];
1042 vs
= calloc (sizeof *vs
, 1);
1044 vs
->variants
= calloc(sizeof *vs
->variants
, nvars
);
1045 for (i
= 0; i
< nvars
; i
++)
1046 vs
->variants
[i
] = 1;
1047 ADDARRAY(vi
->varsets
, vs
);
1050 while (*vars
== ' ') vars
++;
1054 while (*split
!= ':' && *split
!= '-' && *split
!= ' ' && *split
!= 0)
1058 first
= strndup(vars
, split
-vars
);
1059 if (*split
== ' ' || *split
== 0) {
1060 int idx
= findvidx(db
, varset
, first
);
1062 vs
->variants
[idx
] |= 2;
1065 char *end
= split
+1;
1066 while (*end
!= ' ' && *end
!= 0)
1070 second
= strndup(split
+1, end
-split
-1);
1073 idx1
= findvidx(db
, varset
, first
);
1076 idx2
= findvidx(db
, varset
, second
);
1080 if (idx1
!= -1 && idx2
!= -1)
1081 for (i
= idx1
; i
< idx2
; i
++)
1082 vs
->variants
[i
] |= 2;
1089 for (i
= 0; i
< nvars
; i
++) {
1090 vs
->variants
[i
] = (vs
->variants
[i
] == 3);
1091 if (vs
->variants
[i
])
1098 struct rnnvarset
*vs
= 0;
1099 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1100 if (vi
->varsets
[i
]->venum
== vi
->prefenum
) {
1101 vs
= vi
->varsets
[i
];
1105 for (i
= 0; i
< vi
->prefenum
->valsnum
; i
++)
1106 if (vs
->variants
[i
]) {
1107 vi
->prefix
= vi
->prefenum
->vals
[i
]->name
;
1111 vi
->prefix
= vi
->prefenum
->vals
[0]->name
;
1116 static void prepvalue(struct rnndb
*db
, struct rnnvalue
*val
, char *prefix
, struct rnnvarinfo
*parvi
) {
1117 val
->fullname
= catstr(prefix
, val
->name
);
1118 prepvarinfo (db
, val
->fullname
, &val
->varinfo
, parvi
);
1119 if (val
->varinfo
.dead
)
1121 if (val
->varinfo
.prefix
)
1122 val
->fullname
= catstr(val
->varinfo
.prefix
, val
->fullname
);
1125 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
);
1127 static void preptypeinfo(struct rnndb
*db
, struct rnntypeinfo
*ti
, char *prefix
, struct rnnvarinfo
*vi
, char *file
) {
1130 struct rnnenum
*en
= rnn_findenum (db
, ti
->name
);
1131 struct rnnbitset
*bs
= rnn_findbitset (db
, ti
->name
);
1132 struct rnnspectype
*st
= rnn_findspectype (db
, ti
->name
);
1135 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1137 for (j
= 0; j
< en
->valsnum
; j
++)
1138 ADDARRAY(ti
->vals
, copyvalue(en
->vals
[j
], file
));
1140 ti
->type
= RNN_TTYPE_ENUM
;
1145 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1147 for (j
= 0; j
< bs
->bitfieldsnum
; j
++)
1148 ADDARRAY(ti
->bitfields
, copybitfield(bs
->bitfields
[j
], file
));
1150 ti
->type
= RNN_TTYPE_BITSET
;
1154 ti
->type
= RNN_TTYPE_SPECTYPE
;
1156 } else if (!strcmp(ti
->name
, "hex")) {
1157 ti
->type
= RNN_TTYPE_HEX
;
1158 } else if (!strcmp(ti
->name
, "float")) {
1159 ti
->type
= RNN_TTYPE_FLOAT
;
1160 } else if (!strcmp(ti
->name
, "uint")) {
1161 ti
->type
= RNN_TTYPE_UINT
;
1162 } else if (!strcmp(ti
->name
, "int")) {
1163 ti
->type
= RNN_TTYPE_INT
;
1164 } else if (!strcmp(ti
->name
, "boolean")) {
1165 ti
->type
= RNN_TTYPE_BOOLEAN
;
1166 } else if (!strcmp(ti
->name
, "bitfield")) {
1167 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1168 } else if (!strcmp(ti
->name
, "enum")) {
1169 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1170 } else if (!strcmp(ti
->name
, "fixed")) {
1171 ti
->type
= RNN_TTYPE_FIXED
;
1172 } else if (!strcmp(ti
->name
, "ufixed")) {
1173 ti
->type
= RNN_TTYPE_UFIXED
;
1174 } else if (!strcmp(ti
->name
, "a3xx_regid")) {
1175 ti
->type
= RNN_TTYPE_A3XX_REGID
;
1176 } else if (!strcmp(ti
->name
, "waddress") || !strcmp(ti
->name
, "address")) {
1177 ti
->type
= RNN_TTYPE_HEX
;
1179 ti
->type
= RNN_TTYPE_HEX
;
1180 fprintf (stderr
, "%s: unknown type %s\n", prefix
, ti
->name
);
1183 } else if (ti
->bitfieldsnum
) {
1184 ti
->name
= "bitfield";
1185 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1186 } else if (ti
->valsnum
) {
1188 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1189 } else if (ti
->low
== 0 && ti
->high
== 0) {
1190 ti
->name
= "boolean";
1191 ti
->type
= RNN_TTYPE_BOOLEAN
;
1194 ti
->type
= RNN_TTYPE_HEX
;
1196 if (ti
->addvariant
&& ti
->type
!= RNN_TTYPE_ENUM
) {
1197 fprintf (stderr
, "%s: addvariant specified on non-enum type %s\n", prefix
, ti
->name
);
1200 for (i
= 0; i
< ti
->bitfieldsnum
; i
++)
1201 prepbitfield(db
, ti
->bitfields
[i
], prefix
, vi
);
1202 for (i
= 0; i
< ti
->valsnum
; i
++)
1203 prepvalue(db
, ti
->vals
[i
], prefix
, vi
);
1206 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
) {
1207 bf
->fullname
= catstr(prefix
, bf
->name
);
1208 prepvarinfo (db
, bf
->fullname
, &bf
->varinfo
, parvi
);
1209 if (bf
->varinfo
.dead
)
1211 preptypeinfo(db
, &bf
->typeinfo
, bf
->fullname
, &bf
->varinfo
, bf
->file
);
1212 if (bf
->varinfo
.prefix
)
1213 bf
->fullname
= catstr(bf
->varinfo
.prefix
, bf
->fullname
);
1216 static void prepdelem(struct rnndb
*db
, struct rnndelem
*elem
, char *prefix
, struct rnnvarinfo
*parvi
, int width
) {
1217 if (elem
->type
== RNN_ETYPE_USE_GROUP
) {
1219 struct rnngroup
*gr
= 0;
1220 for (i
= 0; i
< db
->groupsnum
; i
++)
1221 if (!strcmp(db
->groups
[i
]->name
, elem
->name
)) {
1226 for (i
= 0; i
< gr
->subelemsnum
; i
++)
1227 ADDARRAY(elem
->subelems
, copydelem(gr
->subelems
[i
], elem
->file
));
1229 fprintf (stderr
, "group %s not found!\n", elem
->name
);
1232 elem
->type
= RNN_ETYPE_STRIPE
;
1237 elem
->fullname
= catstr(prefix
, elem
->name
);
1238 prepvarinfo (db
, elem
->fullname
?elem
->fullname
:prefix
, &elem
->varinfo
, parvi
);
1239 if (elem
->varinfo
.dead
)
1241 if (elem
->length
!= 1 && !elem
->stride
) {
1242 if (elem
->type
!= RNN_ETYPE_REG
) {
1243 fprintf (stderr
, "%s has non-1 length, but no stride!\n", elem
->fullname
);
1246 elem
->stride
= elem
->width
/width
;
1249 preptypeinfo(db
, &elem
->typeinfo
, elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, elem
->file
);
1252 for (i
= 0; i
< elem
->subelemsnum
; i
++)
1253 prepdelem(db
, elem
->subelems
[i
], elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, width
);
1254 if (elem
->varinfo
.prefix
&& elem
->name
)
1255 elem
->fullname
= catstr(elem
->varinfo
.prefix
, elem
->fullname
);
1258 static void prepdomain(struct rnndb
*db
, struct rnndomain
*dom
) {
1259 prepvarinfo (db
, dom
->name
, &dom
->varinfo
, 0);
1261 for (i
= 0; i
< dom
->subelemsnum
; i
++)
1262 prepdelem(db
, dom
->subelems
[i
], dom
->bare
?0:dom
->name
, &dom
->varinfo
, dom
->width
);
1263 dom
->fullname
= catstr(dom
->varinfo
.prefix
, dom
->name
);
1266 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
) {
1269 prepvarinfo (db
, en
->name
, &en
->varinfo
, 0);
1273 for (i
= 0; i
< en
->valsnum
; i
++)
1274 prepvalue(db
, en
->vals
[i
], en
->bare
?0:en
->name
, &en
->varinfo
);
1275 en
->fullname
= catstr(en
->varinfo
.prefix
, en
->name
);
1279 static void prepbitset(struct rnndb
*db
, struct rnnbitset
*bs
) {
1280 prepvarinfo (db
, bs
->name
, &bs
->varinfo
, 0);
1284 for (i
= 0; i
< bs
->bitfieldsnum
; i
++)
1285 prepbitfield(db
, bs
->bitfields
[i
], bs
->bare
?0:bs
->name
, &bs
->varinfo
);
1286 bs
->fullname
= catstr(bs
->varinfo
.prefix
, bs
->name
);
1289 static void prepspectype(struct rnndb
*db
, struct rnnspectype
*st
) {
1290 preptypeinfo(db
, &st
->typeinfo
, st
->name
, 0, st
->file
); // XXX doesn't exactly make sense...
1293 void rnn_prepdb (struct rnndb
*db
) {
1295 for (i
= 0; i
< db
->enumsnum
; i
++)
1296 prepenum(db
, db
->enums
[i
]);
1297 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1298 prepbitset(db
, db
->bitsets
[i
]);
1299 for (i
= 0; i
< db
->domainsnum
; i
++)
1300 prepdomain(db
, db
->domains
[i
]);
1301 for (i
= 0; i
< db
->spectypesnum
; i
++)
1302 prepspectype(db
, db
->spectypes
[i
]);
1305 struct rnnenum
*rnn_findenum (struct rnndb
*db
, const char *name
) {
1307 for (i
= 0; i
< db
->enumsnum
; i
++)
1308 if (!strcmp(db
->enums
[i
]->name
, name
))
1309 return db
->enums
[i
];
1313 struct rnnbitset
*rnn_findbitset (struct rnndb
*db
, const char *name
) {
1315 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1316 if (!strcmp(db
->bitsets
[i
]->name
, name
))
1317 return db
->bitsets
[i
];
1321 struct rnndomain
*rnn_finddomain (struct rnndb
*db
, const char *name
) {
1323 for (i
= 0; i
< db
->domainsnum
; i
++)
1324 if (!strcmp(db
->domains
[i
]->name
, name
))
1325 return db
->domains
[i
];
1329 struct rnnspectype
*rnn_findspectype (struct rnndb
*db
, const char *name
) {
1331 for (i
= 0; i
< db
->spectypesnum
; i
++)
1332 if (!strcmp(db
->spectypes
[i
]->name
, name
))
1333 return db
->spectypes
[i
];