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 #include <libxml/xmlversion.h>
30 #include <libxml/parser.h>
31 #include <libxml/xpath.h>
32 #include <libxml/xmlreader.h>
42 static char *catstr (char *a
, char *b
) {
45 return aprintf("%s_%s", a
, b
);
48 static int strdiff (const char *a
, const char *b
) {
61 struct rnndb
*rnn_newdb(void) {
62 struct rnndb
*db
= calloc(sizeof *db
, 1);
66 static char *getcontent (xmlNode
*attr
) {
67 xmlNode
*chain
= attr
->children
;
71 if (chain
->type
== XML_TEXT_NODE
)
72 size
+= strlen(chain
->content
);
75 p
= content
= malloc(size
+ 1);
76 chain
= attr
->children
;
78 if (chain
->type
== XML_TEXT_NODE
) {
79 char* sp
= chain
->content
;
84 size_t len
= strlen(sp
);
90 while(p
!= content
&& isspace(p
[-1]))
96 static char *getattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
97 xmlNode
*chain
= attr
->children
;
99 if (chain
->type
!= XML_TEXT_NODE
) {
100 fprintf (stderr
, "%s:%d: unknown attribute child \"%s\" in attribute \"%s\"\n", file
, line
, chain
->name
, attr
->name
);
103 return chain
->content
;
110 static int getboolattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
111 char *c
= getattrib(db
, file
, line
, attr
);
112 if (!strcmp(c
, "yes") || !strcmp(c
, "1"))
114 if (!strcmp(c
, "no") || !strcmp(c
, "0"))
116 fprintf (stderr
, "%s:%d: invalid boolean value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
121 static uint64_t getnum(struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
, char *c
)
125 if (strchr(c
, 'x') || strchr(c
, 'X'))
126 res
= strtoull(c
, &cc
, 16);
128 res
= strtoull(c
, &cc
, 10);
130 fprintf (stderr
, "%s:%d: invalid numeric value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
136 static uint64_t getnumattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
137 char *c
= getattrib(db
, file
, line
, attr
);
138 return getnum(db
, file
, line
, attr
, c
);
141 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
);
143 static int trydoc (struct rnndb
*db
, char *file
, xmlNode
*node
) {
144 if (!strcmp(node
->name
, "brief")) {
146 } else if (!strcmp(node
->name
, "doc")) {
152 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
);
153 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
);
155 static int trytypetag (struct rnndb
*db
, char *file
, xmlNode
*node
, struct rnntypeinfo
*ti
) {
156 if (!strcmp(node
->name
, "value")) {
157 struct rnnvalue
*val
= parsevalue(db
, file
, node
);
159 ADDARRAY(ti
->vals
, val
);
161 } else if (!strcmp(node
->name
, "bitfield")) {
162 struct rnnbitfield
*bf
= parsebitfield(db
, file
, node
);
164 ADDARRAY(ti
->bitfields
, bf
);
169 static int trytypeattr (struct rnndb
*db
, char *file
, xmlNode
*node
, xmlAttr
*attr
, struct rnntypeinfo
*ti
) {
170 if (!strcmp(attr
->name
, "shr")) {
171 ti
->shr
= getnumattrib(db
, file
, node
->line
, attr
);
173 } else if (!strcmp(attr
->name
, "min")) {
174 ti
->min
= getnumattrib(db
, file
, node
->line
, attr
);
177 } else if (!strcmp(attr
->name
, "max")) {
178 ti
->max
= getnumattrib(db
, file
, node
->line
, attr
);
181 } else if (!strcmp(attr
->name
, "align")) {
182 ti
->align
= getnumattrib(db
, file
, node
->line
, attr
);
185 } else if (!strcmp(attr
->name
, "type")) {
186 ti
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));;
188 } else if (!strcmp(attr
->name
, "radix")) {
189 ti
->radix
= getnumattrib(db
, file
, node
->line
, attr
);
192 } else if (!strcmp(attr
->name
, "pos")) {
193 ti
->high
= ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
195 } else if (!strcmp(attr
->name
, "low")) {
196 ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
198 } else if (!strcmp(attr
->name
, "high")) {
199 ti
->high
= getnumattrib(db
, file
, node
->line
, attr
);
201 } else if (!strcmp(attr
->name
, "addvariant")) {
202 ti
->addvariant
= getboolattrib(db
, file
, node
->line
, attr
);
207 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
) {
208 struct rnnvalue
*val
= calloc(sizeof *val
, 1);
210 xmlAttr
*attr
= node
->properties
;
212 if (!strcmp(attr
->name
, "name")) {
213 val
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
214 } else if (!strcmp(attr
->name
, "value")) {
215 val
->value
= getnumattrib(db
, file
, node
->line
, attr
);
217 } else if (!strcmp(attr
->name
, "varset")) {
218 val
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
219 } else if (!strcmp(attr
->name
, "variants")) {
220 val
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
222 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for value\n", file
, node
->line
, attr
->name
);
227 xmlNode
*chain
= node
->children
;
229 if (chain
->type
!= XML_ELEMENT_NODE
) {
230 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
231 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
237 fprintf (stderr
, "%s:%d: nameless value\n", file
, node
->line
);
245 static void parsespectype(struct rnndb
*db
, char *file
, xmlNode
*node
) {
246 struct rnnspectype
*res
= calloc (sizeof *res
, 1);
248 xmlAttr
*attr
= node
->properties
;
251 if (!strcmp(attr
->name
, "name")) {
252 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
253 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
254 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for spectype\n", file
, node
->line
, attr
->name
);
260 fprintf (stderr
, "%s:%d: nameless spectype\n", file
, node
->line
);
264 for (i
= 0; i
< db
->spectypesnum
; i
++)
265 if (!strcmp(db
->spectypes
[i
]->name
, res
->name
)) {
266 fprintf (stderr
, "%s:%d: duplicated spectype name %s\n", file
, node
->line
, res
->name
);
270 ADDARRAY(db
->spectypes
, res
);
271 xmlNode
*chain
= node
->children
;
273 if (chain
->type
!= XML_ELEMENT_NODE
) {
274 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
275 fprintf (stderr
, "%s:%d: wrong tag in spectype: <%s>\n", file
, chain
->line
, chain
->name
);
282 static void parseenum(struct rnndb
*db
, char *file
, xmlNode
*node
) {
283 xmlAttr
*attr
= node
->properties
;
289 char *variantsstr
= 0;
292 if (!strcmp(attr
->name
, "name")) {
293 name
= getattrib(db
, file
, node
->line
, attr
);
294 } else if (!strcmp(attr
->name
, "bare")) {
295 bare
= getboolattrib(db
, file
, node
->line
, attr
);
296 } else if (!strcmp(attr
->name
, "inline")) {
297 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
298 } else if (!strcmp(attr
->name
, "prefix")) {
299 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
300 } else if (!strcmp(attr
->name
, "varset")) {
301 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
302 } else if (!strcmp(attr
->name
, "variants")) {
303 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
305 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for enum\n", file
, node
->line
, attr
->name
);
311 fprintf (stderr
, "%s:%d: nameless enum\n", file
, node
->line
);
315 struct rnnenum
*cur
= 0;
316 for (i
= 0; i
< db
->enumsnum
; i
++)
317 if (!strcmp(db
->enums
[i
]->name
, name
)) {
322 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
323 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
324 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
325 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
326 fprintf (stderr
, "%s:%d: merge fail for enum %s\n", file
, node
->line
, node
->name
);
330 cur
= calloc(sizeof *cur
, 1);
331 cur
->name
= strdup(name
);
332 cur
->isinline
= isinline
;
334 cur
->varinfo
.prefixstr
= prefixstr
;
335 cur
->varinfo
.varsetstr
= varsetstr
;
336 cur
->varinfo
.variantsstr
= variantsstr
;
338 ADDARRAY(db
->enums
, cur
);
340 xmlNode
*chain
= node
->children
;
342 if (chain
->type
!= XML_ELEMENT_NODE
) {
343 } else if (!strcmp(chain
->name
, "value")) {
344 struct rnnvalue
*val
= parsevalue(db
, file
, chain
);
346 ADDARRAY(cur
->vals
, val
);
347 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
348 fprintf (stderr
, "%s:%d: wrong tag in enum: <%s>\n", file
, chain
->line
, chain
->name
);
355 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
) {
356 struct rnnbitfield
*bf
= calloc(sizeof *bf
, 1);
358 xmlAttr
*attr
= node
->properties
;
359 bf
->typeinfo
.low
= bf
->typeinfo
.high
= -1;
361 if (!strcmp(attr
->name
, "name")) {
362 bf
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
363 } else if (!strcmp(attr
->name
, "varset")) {
364 bf
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
365 } else if (!strcmp(attr
->name
, "variants")) {
366 bf
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
367 } else if (!trytypeattr(db
, file
, node
, attr
, &bf
->typeinfo
)) {
368 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for bitfield\n", file
, node
->line
, attr
->name
);
373 xmlNode
*chain
= node
->children
;
375 if (chain
->type
!= XML_ELEMENT_NODE
) {
376 } else if (!trytypetag(db
, file
, chain
, &bf
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
377 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
383 fprintf (stderr
, "%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 fprintf (stderr
, "%s:%d: bitfield has wrong placement\n", file
, node
->line
);
395 static void parsebitset(struct rnndb
*db
, char *file
, xmlNode
*node
) {
396 xmlAttr
*attr
= node
->properties
;
402 char *variantsstr
= 0;
405 if (!strcmp(attr
->name
, "name")) {
406 name
= getattrib(db
, file
, node
->line
, attr
);
407 } else if (!strcmp(attr
->name
, "bare")) {
408 bare
= getboolattrib(db
, file
, node
->line
, attr
);
409 } else if (!strcmp(attr
->name
, "inline")) {
410 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
411 } else if (!strcmp(attr
->name
, "prefix")) {
412 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
413 } else if (!strcmp(attr
->name
, "varset")) {
414 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
415 } else if (!strcmp(attr
->name
, "variants")) {
416 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
418 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for bitset\n", file
, node
->line
, attr
->name
);
424 fprintf (stderr
, "%s:%d: nameless bitset\n", file
, node
->line
);
428 struct rnnbitset
*cur
= 0;
429 for (i
= 0; i
< db
->bitsetsnum
; i
++)
430 if (!strcmp(db
->bitsets
[i
]->name
, name
)) {
431 cur
= db
->bitsets
[i
];
435 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
436 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
437 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
438 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
439 fprintf (stderr
, "%s:%d: merge fail for bitset %s\n", file
, node
->line
, node
->name
);
443 cur
= calloc(sizeof *cur
, 1);
444 cur
->name
= strdup(name
);
445 cur
->isinline
= isinline
;
447 cur
->varinfo
.prefixstr
= prefixstr
;
448 cur
->varinfo
.varsetstr
= varsetstr
;
449 cur
->varinfo
.variantsstr
= variantsstr
;
451 ADDARRAY(db
->bitsets
, cur
);
453 xmlNode
*chain
= node
->children
;
455 if (chain
->type
!= XML_ELEMENT_NODE
) {
456 } else if (!strcmp(chain
->name
, "bitfield")) {
457 struct rnnbitfield
*bf
= parsebitfield(db
, file
, chain
);
459 ADDARRAY(cur
->bitfields
, bf
);
460 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
461 fprintf (stderr
, "%s:%d: wrong tag in bitset: <%s>\n", file
, chain
->line
, chain
->name
);
468 static struct rnndelem
*trydelem(struct rnndb
*db
, char *file
, xmlNode
*node
) {
469 if (!strcmp(node
->name
, "use-group")) {
470 struct rnndelem
*res
= calloc(sizeof *res
, 1);
472 res
->type
= RNN_ETYPE_USE_GROUP
;
473 xmlAttr
*attr
= node
->properties
;
475 if (!strcmp(attr
->name
, "name")) {
476 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
478 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
484 fprintf (stderr
, "%s:%d: nameless use-group\n", file
, node
->line
);
489 } else if (!strcmp(node
->name
, "stripe") || !strcmp(node
->name
, "array")) {
490 struct rnndelem
*res
= calloc(sizeof *res
, 1);
491 res
->type
= (strcmp(node
->name
, "stripe")?RNN_ETYPE_ARRAY
:RNN_ETYPE_STRIPE
);
494 xmlAttr
*attr
= node
->properties
;
496 if (!strcmp(attr
->name
, "name")) {
497 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
498 } else if (!strcmp(attr
->name
, "offset")) {
499 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
500 } else if (!strcmp(attr
->name
, "offsets")) {
501 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
502 char *tok
, *save
, *tmp
= str
;
503 while ((tok
= strtok_r(str
, ",", &save
))) {
504 uint64_t offset
= getnum(db
, file
, node
->line
, attr
, tok
);
505 ADDARRAY(res
->offsets
, offset
);
509 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
511 } else if (!strcmp(attr
->name
, "doffset")) {
512 /* dynamic runtime determined offset: */
513 res
->doffset
= strdup(getattrib(db
, file
, node
->line
, attr
));
514 } else if (!strcmp(attr
->name
, "doffsets")) {
515 /* dynamic runtime determined offsets: */
516 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
517 char *tok
, *save
, *tmp
= str
;
518 while ((tok
= strtok_r(str
, ",", &save
))) {
519 char *doffset
= strdup(tok
);
520 ADDARRAY(res
->doffsets
, doffset
);
524 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
526 } else if (!strcmp(attr
->name
, "length")) {
527 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
528 } else if (!strcmp(attr
->name
, "stride")) {
529 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
530 } else if (!strcmp(attr
->name
, "prefix")) {
531 res
->varinfo
.prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
532 } else if (!strcmp(attr
->name
, "varset")) {
533 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
534 } else if (!strcmp(attr
->name
, "variants")) {
535 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
536 } else if (!strcmp(attr
->name
, "index")) {
537 const char *enumname
= getattrib(db
, file
, node
->line
, attr
);
538 res
->index
= rnn_findenum(db
, enumname
);
540 fprintf(stderr
, "%s:%d: invalid enum name \"%s\"\n", file
, node
->line
, enumname
);
544 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
549 xmlNode
*chain
= node
->children
;
551 struct rnndelem
*delem
;
552 if (chain
->type
!= XML_ELEMENT_NODE
) {
553 } else if ((delem
= trydelem(db
, file
, chain
))) {
554 ADDARRAY(res
->subelems
, delem
);
555 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
556 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
562 /* Sanity checking */
563 if (res
->type
== RNN_ETYPE_ARRAY
&& res
->stride
== 0) {
564 fprintf(stderr
, "%s: Array %s's stride is undefined. Aborting.\n", file
, res
->name
);
571 if (!strcmp(node
->name
, "reg8"))
573 else if (!strcmp(node
->name
, "reg16"))
575 else if (!strcmp(node
->name
, "reg32"))
577 else if (!strcmp(node
->name
, "reg64"))
581 struct rnndelem
*res
= calloc(sizeof *res
, 1);
583 res
->type
= RNN_ETYPE_REG
;
586 res
->access
= RNN_ACCESS_RW
;
587 xmlAttr
*attr
= node
->properties
;
588 res
->typeinfo
.low
= 0;
589 res
->typeinfo
.high
= width
- 1;
591 if (!strcmp(attr
->name
, "name")) {
592 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
593 } else if (!strcmp(attr
->name
, "offset")) {
594 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
595 } else if (!strcmp(attr
->name
, "length")) {
596 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
597 } else if (!strcmp(attr
->name
, "stride")) {
598 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
599 } else if (!strcmp(attr
->name
, "varset")) {
600 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
601 } else if (!strcmp(attr
->name
, "variants")) {
602 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
603 } else if (!strcmp(attr
->name
, "access")) {
604 char *str
= getattrib(db
, file
, node
->line
, attr
);
605 if (!strcmp(str
, "r"))
606 res
->access
= RNN_ACCESS_R
;
607 else if (!strcmp(str
, "w"))
608 res
->access
= RNN_ACCESS_W
;
609 else if (!strcmp(str
, "rw"))
610 res
->access
= RNN_ACCESS_RW
;
612 fprintf (stderr
, "%s:%d: wrong access type \"%s\" for register\n", file
, node
->line
, str
);
613 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
614 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for register\n", file
, node
->line
, attr
->name
);
619 xmlNode
*chain
= node
->children
;
621 if (chain
->type
!= XML_ELEMENT_NODE
) {
622 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
623 fprintf (stderr
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
629 fprintf (stderr
, "%s:%d: nameless register\n", file
, node
->line
);
637 static void parsegroup(struct rnndb
*db
, char *file
, xmlNode
*node
) {
638 xmlAttr
*attr
= node
->properties
;
642 if (!strcmp(attr
->name
, "name")) {
643 name
= getattrib(db
, file
, node
->line
, attr
);
645 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for group\n", file
, node
->line
, attr
->name
);
651 fprintf (stderr
, "%s:%d: nameless group\n", file
, node
->line
);
655 struct rnngroup
*cur
= 0;
656 for (i
= 0; i
< db
->groupsnum
; i
++)
657 if (!strcmp(db
->groups
[i
]->name
, name
)) {
662 cur
= calloc(sizeof *cur
, 1);
663 cur
->name
= strdup(name
);
664 ADDARRAY(db
->groups
, cur
);
666 xmlNode
*chain
= node
->children
;
668 struct rnndelem
*delem
;
669 if (chain
->type
!= XML_ELEMENT_NODE
) {
670 } else if ((delem
= trydelem(db
, file
, chain
))) {
671 ADDARRAY(cur
->subelems
, delem
);
672 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
673 fprintf (stderr
, "%s:%d: wrong tag in group: <%s>\n", file
, chain
->line
, chain
->name
);
680 static void parsedomain(struct rnndb
*db
, char *file
, xmlNode
*node
) {
681 xmlAttr
*attr
= node
->properties
;
683 uint64_t size
= 0; int width
= 8;
687 char *variantsstr
= 0;
690 if (!strcmp(attr
->name
, "name")) {
691 name
= getattrib(db
, file
, node
->line
, attr
);
692 } else if (!strcmp(attr
->name
, "bare")) {
693 bare
= getboolattrib(db
, file
, node
->line
, attr
);
694 } else if (!strcmp(attr
->name
, "size")) {
695 size
= getnumattrib(db
, file
, node
->line
, attr
);
696 } else if (!strcmp(attr
->name
, "width")) {
697 width
= getnumattrib(db
, file
, node
->line
, attr
);
698 } else if (!strcmp(attr
->name
, "prefix")) {
699 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
700 } else if (!strcmp(attr
->name
, "varset")) {
701 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
702 } else if (!strcmp(attr
->name
, "variants")) {
703 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
705 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for domain\n", file
, node
->line
, attr
->name
);
711 fprintf (stderr
, "%s:%d: nameless domain\n", file
, node
->line
);
715 struct rnndomain
*cur
= 0;
716 for (i
= 0; i
< db
->domainsnum
; i
++)
717 if (!strcmp(db
->domains
[i
]->name
, name
)) {
718 cur
= db
->domains
[i
];
722 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
723 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
724 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
725 cur
->width
!= width
||
727 (size
&& cur
->size
&& size
!= cur
->size
)) {
728 fprintf (stderr
, "%s:%d: merge fail for domain %s\n", file
, node
->line
, node
->name
);
735 cur
= calloc(sizeof *cur
, 1);
736 cur
->name
= strdup(name
);
740 cur
->varinfo
.prefixstr
= prefixstr
;
741 cur
->varinfo
.varsetstr
= varsetstr
;
742 cur
->varinfo
.variantsstr
= variantsstr
;
744 ADDARRAY(db
->domains
, cur
);
746 xmlNode
*chain
= node
->children
;
748 struct rnndelem
*delem
;
749 if (chain
->type
!= XML_ELEMENT_NODE
) {
750 } else if ((delem
= trydelem(db
, file
, chain
))) {
751 ADDARRAY(cur
->subelems
, delem
);
752 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
753 fprintf (stderr
, "%s:%d: wrong tag in domain: <%s>\n", file
, chain
->line
, chain
->name
);
760 static void parsecopyright(struct rnndb
*db
, char *file
, xmlNode
*node
) {
761 struct rnncopyright
* copyright
= &db
->copyright
;
762 xmlAttr
*attr
= node
->properties
;
764 if (!strcmp(attr
->name
, "year")) {
765 unsigned firstyear
= getnumattrib(db
, file
, node
->line
, attr
);
766 if(!copyright
->firstyear
|| firstyear
< copyright
->firstyear
)
767 copyright
->firstyear
= firstyear
;
769 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for copyright\n", file
, node
->line
, attr
->name
);
774 xmlNode
*chain
= node
->children
;
776 if (chain
->type
!= XML_ELEMENT_NODE
) {
777 } else if (!strcmp(chain
->name
, "license"))
778 if(copyright
->license
) {
779 if(strcmp(copyright
->license
, node
->content
)) {
780 fprintf(stderr
, "fatal error: multiple different licenses specified!\n");
781 abort(); /* TODO: do something better here, but headergen, xml2html, etc. should not produce anything in this case */
784 copyright
->license
= getcontent(chain
);
785 else if (!strcmp(chain
->name
, "author")) {
786 struct rnnauthor
* author
= calloc(sizeof *author
, 1);
787 xmlAttr
* authorattr
= chain
->properties
;
788 xmlNode
*authorchild
= chain
->children
;
789 author
->contributions
= getcontent(chain
);
791 if (!strcmp(authorattr
->name
, "name"))
792 author
->name
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
793 else if (!strcmp(authorattr
->name
, "email"))
794 author
->email
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
796 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for author\n", file
, chain
->line
, authorattr
->name
);
799 authorattr
= authorattr
->next
;
802 if (authorchild
->type
!= XML_ELEMENT_NODE
) {
803 } else if (!strcmp(authorchild
->name
, "nick")) {
804 xmlAttr
* nickattr
= authorchild
->properties
;
807 if (!strcmp(nickattr
->name
, "name"))
808 nickname
= strdup(getattrib(db
, file
, authorchild
->line
, nickattr
));
810 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for nick\n", file
, authorchild
->line
, nickattr
->name
);
813 nickattr
= nickattr
->next
;
816 fprintf (stderr
, "%s:%d: missing \"name\" attribute for nick\n", file
, authorchild
->line
);
819 ADDARRAY(author
->nicknames
, nickname
);
821 fprintf (stderr
, "%s:%d: wrong tag in author: <%s>\n", file
, authorchild
->line
, authorchild
->name
);
824 authorchild
= authorchild
->next
;
826 ADDARRAY(copyright
->authors
, author
);
828 fprintf (stderr
, "%s:%d: wrong tag in copyright: <%s>\n", file
, chain
->line
, chain
->name
);
835 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
) {
836 if (!strcmp(node
->name
, "enum")) {
837 parseenum(db
, file
, node
);
839 } else if (!strcmp(node
->name
, "bitset")) {
840 parsebitset(db
, file
, node
);
842 } else if (!strcmp(node
->name
, "group")) {
843 parsegroup(db
, file
, node
);
845 } else if (!strcmp(node
->name
, "domain")) {
846 parsedomain(db
, file
, node
);
848 } else if (!strcmp(node
->name
, "spectype")) {
849 parsespectype(db
, file
, node
);
851 } else if (!strcmp(node
->name
, "import")) {
852 xmlAttr
*attr
= node
->properties
;
855 if (!strcmp(attr
->name
, "file")) {
856 subfile
= getattrib(db
, file
, node
->line
, attr
);
858 fprintf (stderr
, "%s:%d: wrong attribute \"%s\" for import\n", file
, node
->line
, attr
->name
);
864 fprintf (stderr
, "%s:%d: missing \"file\" attribute for import\n", file
, node
->line
);
867 rnn_parsefile(db
, subfile
);
870 } else if (!strcmp(node
->name
, "copyright")) {
871 parsecopyright(db
, file
, node
);
877 void rnn_parsefile (struct rnndb
*db
, char *file_orig
) {
880 const char *rnn_path
= getenv("RNN_PATH");
883 rnn_path
= RNN_DEF_PATH
;
885 FILE *file
= find_in_path(file_orig
, rnn_path
, &fname
);
887 fprintf (stderr
, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", file_orig
);
893 for (i
= 0; i
< db
->filesnum
; i
++)
894 if (!strcmp(db
->files
[i
], fname
))
897 ADDARRAY(db
->files
, fname
);
898 xmlDocPtr doc
= xmlParseFile(fname
);
900 fprintf (stderr
, "%s: couldn't open database file. Please set the env var RNN_PATH.\n", fname
);
904 xmlNode
*root
= doc
->children
;
906 if (root
->type
!= XML_ELEMENT_NODE
) {
907 } else if (strcmp(root
->name
, "database")) {
908 fprintf (stderr
, "%s:%d: wrong top-level tag <%s>\n", fname
, root
->line
, root
->name
);
911 xmlNode
*chain
= root
->children
;
913 if (chain
->type
!= XML_ELEMENT_NODE
) {
914 } else if (!trytop(db
, fname
, chain
) && !trydoc(db
, fname
, chain
)) {
915 fprintf (stderr
, "%s:%d: wrong tag in database: <%s>\n", fname
, chain
->line
, chain
->name
);
926 static struct rnnvalue
*copyvalue (struct rnnvalue
*val
, char *file
) {
927 struct rnnvalue
*res
= calloc (sizeof *res
, 1);
928 res
->name
= val
->name
;
929 res
->valvalid
= val
->valvalid
;
930 res
->value
= val
->value
;
931 res
->varinfo
= val
->varinfo
;
936 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
);
939 static void copytypeinfo (struct rnntypeinfo
*dst
, struct rnntypeinfo
*src
, char *file
) {
941 dst
->name
= src
->name
;
944 dst
->high
= src
->high
;
947 dst
->align
= src
->align
;
948 dst
->addvariant
= src
->addvariant
;
949 for (i
= 0; i
< src
->valsnum
; i
++)
950 ADDARRAY(dst
->vals
, copyvalue(src
->vals
[i
], file
));
951 for (i
= 0; i
< src
->bitfieldsnum
; i
++)
952 ADDARRAY(dst
->bitfields
, copybitfield(src
->bitfields
[i
], file
));
955 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
) {
956 struct rnnbitfield
*res
= calloc (sizeof *res
, 1);
957 res
->name
= bf
->name
;
958 res
->varinfo
= bf
->varinfo
;
960 copytypeinfo(&res
->typeinfo
, &bf
->typeinfo
, file
);
964 static struct rnndelem
*copydelem (struct rnndelem
*elem
, char *file
) {
965 struct rnndelem
*res
= calloc (sizeof *res
, 1);
966 res
->type
= elem
->type
;
967 res
->name
= elem
->name
;
968 res
->width
= elem
->width
;
969 res
->access
= elem
->access
;
970 res
->offset
= elem
->offset
;
971 res
->length
= elem
->length
;
972 res
->stride
= elem
->stride
;
973 res
->varinfo
= elem
->varinfo
;
975 copytypeinfo(&res
->typeinfo
, &elem
->typeinfo
, file
);
977 for (i
= 0; i
< elem
->subelemsnum
; i
++)
978 ADDARRAY(res
->subelems
, copydelem(elem
->subelems
[i
], file
));
979 for (i
= 0; i
< elem
->offsetsnum
; i
++)
980 ADDARRAY(res
->offsets
, elem
->offsets
[i
]);
984 static struct rnnvarset
*copyvarset (struct rnnvarset
*varset
) {
985 struct rnnvarset
*res
= calloc(sizeof *res
, 1);
986 res
->venum
= varset
->venum
;
987 res
->variants
= calloc(sizeof *res
->variants
, res
->venum
->valsnum
);
989 for (i
= 0; i
< res
->venum
->valsnum
; i
++)
990 res
->variants
[i
] = varset
->variants
[i
];
994 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
);
996 static int findvidx (struct rnndb
*db
, struct rnnenum
*en
, char *name
) {
998 for (i
= 0; i
< en
->valsnum
; i
++)
999 if (!strcmp(en
->vals
[i
]->name
, name
))
1001 fprintf (stderr
, "Cannot find variant %s in enum %s!\n", name
, en
->name
);
1006 static void prepvarinfo (struct rnndb
*db
, char *what
, struct rnnvarinfo
*vi
, struct rnnvarinfo
*parent
) {
1008 vi
->prefenum
= parent
->prefenum
;
1009 if (vi
->prefixstr
) {
1010 if (!strcmp(vi
->prefixstr
, "none"))
1013 vi
->prefenum
= rnn_findenum(db
, vi
->prefixstr
); // XXX
1017 for (i
= 0; i
< parent
->varsetsnum
; i
++)
1018 ADDARRAY(vi
->varsets
, copyvarset(parent
->varsets
[i
]));
1019 struct rnnenum
*varset
= vi
->prefenum
;
1020 if (!varset
&& !vi
->varsetstr
&& parent
)
1021 vi
->varsetstr
= parent
->varsetstr
;
1023 varset
= rnn_findenum(db
, vi
->varsetstr
);
1024 if (vi
->variantsstr
) {
1025 char *vars
= vi
->variantsstr
;
1027 fprintf (stderr
, "%s: tried to use variants without active varset!\n", what
);
1031 struct rnnvarset
*vs
= 0;
1032 int nvars
= varset
->valsnum
;
1033 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1034 if (vi
->varsets
[i
]->venum
== varset
) {
1035 vs
= vi
->varsets
[i
];
1039 vs
= calloc (sizeof *vs
, 1);
1041 vs
->variants
= calloc(sizeof *vs
->variants
, nvars
);
1042 for (i
= 0; i
< nvars
; i
++)
1043 vs
->variants
[i
] = 1;
1044 ADDARRAY(vi
->varsets
, vs
);
1047 while (*vars
== ' ') vars
++;
1051 while (*split
!= ':' && *split
!= '-' && *split
!= ' ' && *split
!= 0)
1055 first
= strndup(vars
, split
-vars
);
1056 if (*split
== ' ' || *split
== 0) {
1057 int idx
= findvidx(db
, varset
, first
);
1059 vs
->variants
[idx
] |= 2;
1062 char *end
= split
+1;
1063 while (*end
!= ' ' && *end
!= 0)
1067 second
= strndup(split
+1, end
-split
-1);
1070 idx1
= findvidx(db
, varset
, first
);
1073 idx2
= findvidx(db
, varset
, second
);
1077 if (idx1
!= -1 && idx2
!= -1)
1078 for (i
= idx1
; i
< idx2
; i
++)
1079 vs
->variants
[i
] |= 2;
1086 for (i
= 0; i
< nvars
; i
++) {
1087 vs
->variants
[i
] = (vs
->variants
[i
] == 3);
1088 if (vs
->variants
[i
])
1095 struct rnnvarset
*vs
= 0;
1096 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1097 if (vi
->varsets
[i
]->venum
== vi
->prefenum
) {
1098 vs
= vi
->varsets
[i
];
1102 for (i
= 0; i
< vi
->prefenum
->valsnum
; i
++)
1103 if (vs
->variants
[i
]) {
1104 vi
->prefix
= vi
->prefenum
->vals
[i
]->name
;
1108 vi
->prefix
= vi
->prefenum
->vals
[0]->name
;
1113 static void prepvalue(struct rnndb
*db
, struct rnnvalue
*val
, char *prefix
, struct rnnvarinfo
*parvi
) {
1114 val
->fullname
= catstr(prefix
, val
->name
);
1115 prepvarinfo (db
, val
->fullname
, &val
->varinfo
, parvi
);
1116 if (val
->varinfo
.dead
)
1118 if (val
->varinfo
.prefix
)
1119 val
->fullname
= catstr(val
->varinfo
.prefix
, val
->fullname
);
1122 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
);
1124 static void preptypeinfo(struct rnndb
*db
, struct rnntypeinfo
*ti
, char *prefix
, struct rnnvarinfo
*vi
, char *file
) {
1127 struct rnnenum
*en
= rnn_findenum (db
, ti
->name
);
1128 struct rnnbitset
*bs
= rnn_findbitset (db
, ti
->name
);
1129 struct rnnspectype
*st
= rnn_findspectype (db
, ti
->name
);
1132 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1134 for (j
= 0; j
< en
->valsnum
; j
++)
1135 ADDARRAY(ti
->vals
, copyvalue(en
->vals
[j
], file
));
1137 ti
->type
= RNN_TTYPE_ENUM
;
1142 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1144 for (j
= 0; j
< bs
->bitfieldsnum
; j
++)
1145 ADDARRAY(ti
->bitfields
, copybitfield(bs
->bitfields
[j
], file
));
1147 ti
->type
= RNN_TTYPE_BITSET
;
1151 ti
->type
= RNN_TTYPE_SPECTYPE
;
1153 } else if (!strcmp(ti
->name
, "hex")) {
1154 ti
->type
= RNN_TTYPE_HEX
;
1155 } else if (!strcmp(ti
->name
, "float")) {
1156 ti
->type
= RNN_TTYPE_FLOAT
;
1157 } else if (!strcmp(ti
->name
, "uint")) {
1158 ti
->type
= RNN_TTYPE_UINT
;
1159 } else if (!strcmp(ti
->name
, "int")) {
1160 ti
->type
= RNN_TTYPE_INT
;
1161 } else if (!strcmp(ti
->name
, "boolean")) {
1162 ti
->type
= RNN_TTYPE_BOOLEAN
;
1163 } else if (!strcmp(ti
->name
, "bitfield")) {
1164 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1165 } else if (!strcmp(ti
->name
, "enum")) {
1166 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1167 } else if (!strcmp(ti
->name
, "fixed")) {
1168 ti
->type
= RNN_TTYPE_FIXED
;
1169 } else if (!strcmp(ti
->name
, "ufixed")) {
1170 ti
->type
= RNN_TTYPE_UFIXED
;
1171 } else if (!strcmp(ti
->name
, "a3xx_regid")) {
1172 ti
->type
= RNN_TTYPE_A3XX_REGID
;
1173 } else if (!strcmp(ti
->name
, "waddress") || !strcmp(ti
->name
, "address")) {
1174 ti
->type
= RNN_TTYPE_HEX
;
1176 ti
->type
= RNN_TTYPE_HEX
;
1177 fprintf (stderr
, "%s: unknown type %s\n", prefix
, ti
->name
);
1180 } else if (ti
->bitfieldsnum
) {
1181 ti
->name
= "bitfield";
1182 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1183 } else if (ti
->valsnum
) {
1185 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1186 } else if (ti
->low
== 0 && ti
->high
== 0) {
1187 ti
->name
= "boolean";
1188 ti
->type
= RNN_TTYPE_BOOLEAN
;
1191 ti
->type
= RNN_TTYPE_HEX
;
1193 if (ti
->addvariant
&& ti
->type
!= RNN_TTYPE_ENUM
) {
1194 fprintf (stderr
, "%s: addvariant specified on non-enum type %s\n", prefix
, ti
->name
);
1197 for (i
= 0; i
< ti
->bitfieldsnum
; i
++)
1198 prepbitfield(db
, ti
->bitfields
[i
], prefix
, vi
);
1199 for (i
= 0; i
< ti
->valsnum
; i
++)
1200 prepvalue(db
, ti
->vals
[i
], prefix
, vi
);
1203 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
) {
1204 bf
->fullname
= catstr(prefix
, bf
->name
);
1205 prepvarinfo (db
, bf
->fullname
, &bf
->varinfo
, parvi
);
1206 if (bf
->varinfo
.dead
)
1208 preptypeinfo(db
, &bf
->typeinfo
, bf
->fullname
, &bf
->varinfo
, bf
->file
);
1209 if (bf
->varinfo
.prefix
)
1210 bf
->fullname
= catstr(bf
->varinfo
.prefix
, bf
->fullname
);
1213 static void prepdelem(struct rnndb
*db
, struct rnndelem
*elem
, char *prefix
, struct rnnvarinfo
*parvi
, int width
) {
1214 if (elem
->type
== RNN_ETYPE_USE_GROUP
) {
1216 struct rnngroup
*gr
= 0;
1217 for (i
= 0; i
< db
->groupsnum
; i
++)
1218 if (!strcmp(db
->groups
[i
]->name
, elem
->name
)) {
1223 for (i
= 0; i
< gr
->subelemsnum
; i
++)
1224 ADDARRAY(elem
->subelems
, copydelem(gr
->subelems
[i
], elem
->file
));
1226 fprintf (stderr
, "group %s not found!\n", elem
->name
);
1229 elem
->type
= RNN_ETYPE_STRIPE
;
1234 elem
->fullname
= catstr(prefix
, elem
->name
);
1235 prepvarinfo (db
, elem
->fullname
?elem
->fullname
:prefix
, &elem
->varinfo
, parvi
);
1236 if (elem
->varinfo
.dead
)
1238 if (elem
->length
!= 1 && !elem
->stride
) {
1239 if (elem
->type
!= RNN_ETYPE_REG
) {
1240 fprintf (stderr
, "%s has non-1 length, but no stride!\n", elem
->fullname
);
1243 elem
->stride
= elem
->width
/width
;
1246 preptypeinfo(db
, &elem
->typeinfo
, elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, elem
->file
);
1249 for (i
= 0; i
< elem
->subelemsnum
; i
++)
1250 prepdelem(db
, elem
->subelems
[i
], elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, width
);
1251 if (elem
->varinfo
.prefix
&& elem
->name
)
1252 elem
->fullname
= catstr(elem
->varinfo
.prefix
, elem
->fullname
);
1255 static void prepdomain(struct rnndb
*db
, struct rnndomain
*dom
) {
1256 prepvarinfo (db
, dom
->name
, &dom
->varinfo
, 0);
1258 for (i
= 0; i
< dom
->subelemsnum
; i
++)
1259 prepdelem(db
, dom
->subelems
[i
], dom
->bare
?0:dom
->name
, &dom
->varinfo
, dom
->width
);
1260 dom
->fullname
= catstr(dom
->varinfo
.prefix
, dom
->name
);
1263 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
) {
1266 prepvarinfo (db
, en
->name
, &en
->varinfo
, 0);
1270 for (i
= 0; i
< en
->valsnum
; i
++)
1271 prepvalue(db
, en
->vals
[i
], en
->bare
?0:en
->name
, &en
->varinfo
);
1272 en
->fullname
= catstr(en
->varinfo
.prefix
, en
->name
);
1276 static void prepbitset(struct rnndb
*db
, struct rnnbitset
*bs
) {
1277 prepvarinfo (db
, bs
->name
, &bs
->varinfo
, 0);
1281 for (i
= 0; i
< bs
->bitfieldsnum
; i
++)
1282 prepbitfield(db
, bs
->bitfields
[i
], bs
->bare
?0:bs
->name
, &bs
->varinfo
);
1283 bs
->fullname
= catstr(bs
->varinfo
.prefix
, bs
->name
);
1286 static void prepspectype(struct rnndb
*db
, struct rnnspectype
*st
) {
1287 preptypeinfo(db
, &st
->typeinfo
, st
->name
, 0, st
->file
); // XXX doesn't exactly make sense...
1290 void rnn_prepdb (struct rnndb
*db
) {
1292 for (i
= 0; i
< db
->enumsnum
; i
++)
1293 prepenum(db
, db
->enums
[i
]);
1294 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1295 prepbitset(db
, db
->bitsets
[i
]);
1296 for (i
= 0; i
< db
->domainsnum
; i
++)
1297 prepdomain(db
, db
->domains
[i
]);
1298 for (i
= 0; i
< db
->spectypesnum
; i
++)
1299 prepspectype(db
, db
->spectypes
[i
]);
1302 struct rnnenum
*rnn_findenum (struct rnndb
*db
, const char *name
) {
1304 for (i
= 0; i
< db
->enumsnum
; i
++)
1305 if (!strcmp(db
->enums
[i
]->name
, name
))
1306 return db
->enums
[i
];
1310 struct rnnbitset
*rnn_findbitset (struct rnndb
*db
, const char *name
) {
1312 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1313 if (!strcmp(db
->bitsets
[i
]->name
, name
))
1314 return db
->bitsets
[i
];
1318 struct rnndomain
*rnn_finddomain (struct rnndb
*db
, const char *name
) {
1320 for (i
= 0; i
< db
->domainsnum
; i
++)
1321 if (!strcmp(db
->domains
[i
]->name
, name
))
1322 return db
->domains
[i
];
1326 struct rnnspectype
*rnn_findspectype (struct rnndb
*db
, const char *name
) {
1328 for (i
= 0; i
< db
->spectypesnum
; i
++)
1329 if (!strcmp(db
->spectypes
[i
]->name
, name
))
1330 return db
->spectypes
[i
];