2 * Copyright (C) 2010-2011 Marcin KoĆcielnicki <koriakin@0x04.net>
3 * Copyright (C) 2010 Luca Barbieri <luca@luca-barbieri.com>
4 * Copyright (C) 2010 Francisco Jerez <currojerez@riseup.net>
5 * Copyright (C) 2010 Martin Peres <martin.peres@ensi-bourges.fr>
6 * Copyright (C) 2010 Marcin Slusarz <marcin.slusarz@gmail.com>
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE.
29 /* workaround libxml2 silliness: */
30 #pragma GCC diagnostic ignored "-Wpointer-sign"
32 #include <libxml/xmlversion.h>
33 #include <libxml/parser.h>
34 #include <libxml/xpath.h>
35 #include <libxml/xmlreader.h>
45 #include "util/u_debug.h"
47 static char *catstr (char *a
, char *b
) {
50 return aprintf("%s_%s", a
, b
);
53 static int strdiff (const char *a
, const char *b
) {
61 static void rnn_err(struct rnndb
*db
, const char *format
, ...) _util_printf_format(2, 3);
63 static void rnn_err(struct rnndb
*db
, const char *format
, ...)
67 vfprintf(stderr
, format
, ap
);
77 struct rnndb
*rnn_newdb(void) {
78 struct rnndb
*db
= calloc(sizeof *db
, 1);
82 static char *getcontent (xmlNode
*attr
) {
83 xmlNode
*chain
= attr
->children
;
87 if (chain
->type
== XML_TEXT_NODE
)
88 size
+= strlen(chain
->content
);
91 p
= content
= malloc(size
+ 1);
92 chain
= attr
->children
;
94 if (chain
->type
== XML_TEXT_NODE
) {
95 char* sp
= chain
->content
;
100 size_t len
= strlen(sp
);
106 while(p
!= content
&& isspace(p
[-1]))
112 static char *getattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
113 xmlNode
*chain
= attr
->children
;
115 if (chain
->type
!= XML_TEXT_NODE
) {
116 rnn_err(db
, "%s:%d: unknown attribute child \"%s\" in attribute \"%s\"\n", file
, line
, chain
->name
, attr
->name
);
118 return chain
->content
;
125 static int getboolattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
126 char *c
= getattrib(db
, file
, line
, attr
);
127 if (!strcmp(c
, "yes") || !strcmp(c
, "1") || !strcmp(c
, "true"))
129 if (!strcmp(c
, "no") || !strcmp(c
, "0") || !strcmp(c
, "false"))
131 rnn_err(db
, "%s:%d: invalid boolean value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
135 static uint64_t getnum(struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
, char *c
)
139 if (strchr(c
, 'x') || strchr(c
, 'X'))
140 res
= strtoull(c
, &cc
, 16);
142 res
= strtoull(c
, &cc
, 10);
144 rnn_err(db
, "%s:%d: invalid numeric value \"%s\" in attribute \"%s\"\n", file
, line
, c
, attr
->name
);
149 static uint64_t getnumattrib (struct rnndb
*db
, char *file
, int line
, xmlAttr
*attr
) {
150 char *c
= getattrib(db
, file
, line
, attr
);
151 return getnum(db
, file
, line
, attr
, c
);
154 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
);
156 static int trydoc (struct rnndb
*db
, char *file
, xmlNode
*node
) {
157 if (!strcmp(node
->name
, "brief")) {
159 } else if (!strcmp(node
->name
, "doc")) {
165 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
);
166 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
);
168 static int trytypetag (struct rnndb
*db
, char *file
, xmlNode
*node
, struct rnntypeinfo
*ti
) {
169 if (!strcmp(node
->name
, "value")) {
170 struct rnnvalue
*val
= parsevalue(db
, file
, node
);
172 ADDARRAY(ti
->vals
, val
);
174 } else if (!strcmp(node
->name
, "bitfield")) {
175 struct rnnbitfield
*bf
= parsebitfield(db
, file
, node
);
177 ADDARRAY(ti
->bitfields
, bf
);
182 static int trytypeattr (struct rnndb
*db
, char *file
, xmlNode
*node
, xmlAttr
*attr
, struct rnntypeinfo
*ti
) {
183 if (!strcmp(attr
->name
, "shr")) {
184 ti
->shr
= getnumattrib(db
, file
, node
->line
, attr
);
186 } else if (!strcmp(attr
->name
, "min")) {
187 ti
->min
= getnumattrib(db
, file
, node
->line
, attr
);
190 } else if (!strcmp(attr
->name
, "max")) {
191 ti
->max
= getnumattrib(db
, file
, node
->line
, attr
);
194 } else if (!strcmp(attr
->name
, "align")) {
195 ti
->align
= getnumattrib(db
, file
, node
->line
, attr
);
198 } else if (!strcmp(attr
->name
, "type")) {
199 ti
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));;
201 } else if (!strcmp(attr
->name
, "radix")) {
202 ti
->radix
= getnumattrib(db
, file
, node
->line
, attr
);
205 } else if (!strcmp(attr
->name
, "pos")) {
206 ti
->high
= ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
208 } else if (!strcmp(attr
->name
, "low")) {
209 ti
->low
= getnumattrib(db
, file
, node
->line
, attr
);
211 } else if (!strcmp(attr
->name
, "high")) {
212 ti
->high
= getnumattrib(db
, file
, node
->line
, attr
);
214 } else if (!strcmp(attr
->name
, "addvariant")) {
215 ti
->addvariant
= getboolattrib(db
, file
, node
->line
, attr
);
221 static struct rnnvalue
*parsevalue(struct rnndb
*db
, char *file
, xmlNode
*node
) {
222 struct rnnvalue
*val
= calloc(sizeof *val
, 1);
224 xmlAttr
*attr
= node
->properties
;
226 if (!strcmp(attr
->name
, "name")) {
227 val
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
228 } else if (!strcmp(attr
->name
, "value")) {
229 val
->value
= getnumattrib(db
, file
, node
->line
, attr
);
231 } else if (!strcmp(attr
->name
, "varset")) {
232 val
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
233 } else if (!strcmp(attr
->name
, "variants")) {
234 val
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
236 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for value\n", file
, node
->line
, attr
->name
);
240 xmlNode
*chain
= node
->children
;
242 if (chain
->type
!= XML_ELEMENT_NODE
) {
243 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
244 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
249 rnn_err(db
, "%s:%d: nameless value\n", file
, node
->line
);
256 static void parsespectype(struct rnndb
*db
, char *file
, xmlNode
*node
) {
257 struct rnnspectype
*res
= calloc (sizeof *res
, 1);
259 xmlAttr
*attr
= node
->properties
;
262 if (!strcmp(attr
->name
, "name")) {
263 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
264 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
265 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for spectype\n", file
, node
->line
, attr
->name
);
270 rnn_err(db
, "%s:%d: nameless spectype\n", file
, node
->line
);
273 for (i
= 0; i
< db
->spectypesnum
; i
++)
274 if (!strcmp(db
->spectypes
[i
]->name
, res
->name
)) {
275 rnn_err(db
, "%s:%d: duplicated spectype name %s\n", file
, node
->line
, res
->name
);
278 ADDARRAY(db
->spectypes
, res
);
279 xmlNode
*chain
= node
->children
;
281 if (chain
->type
!= XML_ELEMENT_NODE
) {
282 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
283 rnn_err(db
, "%s:%d: wrong tag in spectype: <%s>\n", file
, chain
->line
, chain
->name
);
289 static void parseenum(struct rnndb
*db
, char *file
, xmlNode
*node
) {
290 xmlAttr
*attr
= node
->properties
;
296 char *variantsstr
= 0;
299 if (!strcmp(attr
->name
, "name")) {
300 name
= getattrib(db
, file
, node
->line
, attr
);
301 } else if (!strcmp(attr
->name
, "bare")) {
302 bare
= getboolattrib(db
, file
, node
->line
, attr
);
303 } else if (!strcmp(attr
->name
, "inline")) {
304 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
305 } else if (!strcmp(attr
->name
, "prefix")) {
306 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
307 } else if (!strcmp(attr
->name
, "varset")) {
308 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
309 } else if (!strcmp(attr
->name
, "variants")) {
310 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
312 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for enum\n", file
, node
->line
, attr
->name
);
317 rnn_err(db
, "%s:%d: nameless enum\n", file
, node
->line
);
320 struct rnnenum
*cur
= 0;
321 for (i
= 0; i
< db
->enumsnum
; i
++)
322 if (!strcmp(db
->enums
[i
]->name
, name
)) {
327 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
328 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
329 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
330 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
331 rnn_err(db
, "%s:%d: merge fail for enum %s\n", file
, node
->line
, node
->name
);
334 cur
= calloc(sizeof *cur
, 1);
335 cur
->name
= strdup(name
);
336 cur
->isinline
= isinline
;
338 cur
->varinfo
.prefixstr
= prefixstr
;
339 cur
->varinfo
.varsetstr
= varsetstr
;
340 cur
->varinfo
.variantsstr
= variantsstr
;
342 ADDARRAY(db
->enums
, cur
);
344 xmlNode
*chain
= node
->children
;
346 if (chain
->type
!= XML_ELEMENT_NODE
) {
347 } else if (!strcmp(chain
->name
, "value")) {
348 struct rnnvalue
*val
= parsevalue(db
, file
, chain
);
350 ADDARRAY(cur
->vals
, val
);
351 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
352 rnn_err(db
, "%s:%d: wrong tag in enum: <%s>\n", file
, chain
->line
, chain
->name
);
358 static struct rnnbitfield
*parsebitfield(struct rnndb
*db
, char *file
, xmlNode
*node
) {
359 struct rnnbitfield
*bf
= calloc(sizeof *bf
, 1);
361 xmlAttr
*attr
= node
->properties
;
362 bf
->typeinfo
.low
= bf
->typeinfo
.high
= -1;
364 if (!strcmp(attr
->name
, "name")) {
365 bf
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
366 } else if (!strcmp(attr
->name
, "varset")) {
367 bf
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
368 } else if (!strcmp(attr
->name
, "variants")) {
369 bf
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
370 } else if (!trytypeattr(db
, file
, node
, attr
, &bf
->typeinfo
)) {
371 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for bitfield\n", file
, node
->line
, attr
->name
);
375 xmlNode
*chain
= node
->children
;
377 if (chain
->type
!= XML_ELEMENT_NODE
) {
378 } else if (!trytypetag(db
, file
, chain
, &bf
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
379 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
384 rnn_err(db
, "%s:%d: nameless bitfield\n", file
, node
->line
);
386 } else if (bf
->typeinfo
.low
< 0|| bf
->typeinfo
.high
< 0 || bf
->typeinfo
.high
< bf
->typeinfo
.low
) {
387 rnn_err(db
, "%s:%d: bitfield has wrong placement\n", file
, node
->line
);
394 static void parsebitset(struct rnndb
*db
, char *file
, xmlNode
*node
) {
395 xmlAttr
*attr
= node
->properties
;
401 char *variantsstr
= 0;
404 if (!strcmp(attr
->name
, "name")) {
405 name
= getattrib(db
, file
, node
->line
, attr
);
406 } else if (!strcmp(attr
->name
, "bare")) {
407 bare
= getboolattrib(db
, file
, node
->line
, attr
);
408 } else if (!strcmp(attr
->name
, "inline")) {
409 isinline
= getboolattrib(db
, file
, node
->line
, attr
);
410 } else if (!strcmp(attr
->name
, "prefix")) {
411 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
412 } else if (!strcmp(attr
->name
, "varset")) {
413 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
414 } else if (!strcmp(attr
->name
, "variants")) {
415 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
417 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for bitset\n", file
, node
->line
, attr
->name
);
422 rnn_err(db
, "%s:%d: nameless bitset\n", file
, node
->line
);
425 struct rnnbitset
*cur
= 0;
426 for (i
= 0; i
< db
->bitsetsnum
; i
++)
427 if (!strcmp(db
->bitsets
[i
]->name
, name
)) {
428 cur
= db
->bitsets
[i
];
432 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
433 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
434 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
435 cur
->isinline
!= isinline
|| cur
->bare
!= bare
) {
436 rnn_err(db
, "%s:%d: merge fail for bitset %s\n", file
, node
->line
, node
->name
);
439 cur
= calloc(sizeof *cur
, 1);
440 cur
->name
= strdup(name
);
441 cur
->isinline
= isinline
;
443 cur
->varinfo
.prefixstr
= prefixstr
;
444 cur
->varinfo
.varsetstr
= varsetstr
;
445 cur
->varinfo
.variantsstr
= variantsstr
;
447 ADDARRAY(db
->bitsets
, cur
);
449 xmlNode
*chain
= node
->children
;
451 if (chain
->type
!= XML_ELEMENT_NODE
) {
452 } else if (!strcmp(chain
->name
, "bitfield")) {
453 struct rnnbitfield
*bf
= parsebitfield(db
, file
, chain
);
455 ADDARRAY(cur
->bitfields
, bf
);
456 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
457 rnn_err(db
, "%s:%d: wrong tag in bitset: <%s>\n", file
, chain
->line
, chain
->name
);
463 static struct rnndelem
*trydelem(struct rnndb
*db
, char *file
, xmlNode
*node
) {
464 if (!strcmp(node
->name
, "use-group")) {
465 struct rnndelem
*res
= calloc(sizeof *res
, 1);
467 res
->type
= RNN_ETYPE_USE_GROUP
;
468 xmlAttr
*attr
= node
->properties
;
470 if (!strcmp(attr
->name
, "name")) {
471 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
473 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
478 rnn_err(db
, "%s:%d: nameless use-group\n", file
, node
->line
);
482 } else if (!strcmp(node
->name
, "stripe") || !strcmp(node
->name
, "array")) {
483 struct rnndelem
*res
= calloc(sizeof *res
, 1);
484 res
->type
= (strcmp(node
->name
, "stripe")?RNN_ETYPE_ARRAY
:RNN_ETYPE_STRIPE
);
487 xmlAttr
*attr
= node
->properties
;
489 if (!strcmp(attr
->name
, "name")) {
490 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
491 } else if (!strcmp(attr
->name
, "offset")) {
492 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
493 } else if (!strcmp(attr
->name
, "offsets")) {
494 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
495 char *tok
, *save
, *tmp
= str
;
496 while ((tok
= strtok_r(str
, ",", &save
))) {
497 uint64_t offset
= getnum(db
, file
, node
->line
, attr
, tok
);
498 ADDARRAY(res
->offsets
, offset
);
502 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
504 } else if (!strcmp(attr
->name
, "doffset")) {
505 /* dynamic runtime determined offset: */
506 res
->doffset
= strdup(getattrib(db
, file
, node
->line
, attr
));
507 } else if (!strcmp(attr
->name
, "doffsets")) {
508 /* dynamic runtime determined offsets: */
509 char *str
= strdup(getattrib(db
, file
, node
->line
, attr
));
510 char *tok
, *save
, *tmp
= str
;
511 while ((tok
= strtok_r(str
, ",", &save
))) {
512 char *doffset
= strdup(tok
);
513 ADDARRAY(res
->doffsets
, doffset
);
517 fprintf(stderr
, "%s:%d: invalid offsets: %s\n", file
, node
->line
, str
);
519 } else if (!strcmp(attr
->name
, "length")) {
520 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
521 } else if (!strcmp(attr
->name
, "stride")) {
522 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
523 } else if (!strcmp(attr
->name
, "prefix")) {
524 res
->varinfo
.prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
525 } else if (!strcmp(attr
->name
, "varset")) {
526 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
527 } else if (!strcmp(attr
->name
, "variants")) {
528 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
529 } else if (!strcmp(attr
->name
, "index")) {
530 const char *enumname
= getattrib(db
, file
, node
->line
, attr
);
531 res
->index
= rnn_findenum(db
, enumname
);
533 rnn_err(db
, "%s:%d: invalid enum name \"%s\"\n", file
, node
->line
, enumname
);
536 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for %s\n", file
, node
->line
, attr
->name
, node
->name
);
540 xmlNode
*chain
= node
->children
;
542 struct rnndelem
*delem
;
543 if (chain
->type
!= XML_ELEMENT_NODE
) {
544 } else if ((delem
= trydelem(db
, file
, chain
))) {
545 ADDARRAY(res
->subelems
, delem
);
546 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
547 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
552 /* Sanity checking */
553 if (res
->type
== RNN_ETYPE_ARRAY
&& res
->stride
== 0) {
554 fprintf(stderr
, "%s: Array %s's stride is undefined. Aborting.\n", file
, res
->name
);
561 if (!strcmp(node
->name
, "reg8"))
563 else if (!strcmp(node
->name
, "reg16"))
565 else if (!strcmp(node
->name
, "reg32"))
567 else if (!strcmp(node
->name
, "reg64"))
571 struct rnndelem
*res
= calloc(sizeof *res
, 1);
573 res
->type
= RNN_ETYPE_REG
;
576 res
->access
= RNN_ACCESS_RW
;
577 xmlAttr
*attr
= node
->properties
;
578 res
->typeinfo
.low
= 0;
579 res
->typeinfo
.high
= width
- 1;
581 if (!strcmp(attr
->name
, "name")) {
582 res
->name
= strdup(getattrib(db
, file
, node
->line
, attr
));
583 } else if (!strcmp(attr
->name
, "offset")) {
584 res
->offset
= getnumattrib(db
, file
, node
->line
, attr
);
585 } else if (!strcmp(attr
->name
, "length")) {
586 res
->length
= getnumattrib(db
, file
, node
->line
, attr
);
587 } else if (!strcmp(attr
->name
, "stride")) {
588 res
->stride
= getnumattrib(db
, file
, node
->line
, attr
);
589 } else if (!strcmp(attr
->name
, "varset")) {
590 res
->varinfo
.varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
591 } else if (!strcmp(attr
->name
, "variants")) {
592 res
->varinfo
.variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
593 } else if (!strcmp(attr
->name
, "access")) {
594 char *str
= getattrib(db
, file
, node
->line
, attr
);
595 if (!strcmp(str
, "r"))
596 res
->access
= RNN_ACCESS_R
;
597 else if (!strcmp(str
, "w"))
598 res
->access
= RNN_ACCESS_W
;
599 else if (!strcmp(str
, "rw"))
600 res
->access
= RNN_ACCESS_RW
;
602 fprintf (stderr
, "%s:%d: wrong access type \"%s\" for register\n", file
, node
->line
, str
);
603 } else if (!trytypeattr(db
, file
, node
, attr
, &res
->typeinfo
)) {
604 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for register\n", file
, node
->line
, attr
->name
);
608 xmlNode
*chain
= node
->children
;
610 if (chain
->type
!= XML_ELEMENT_NODE
) {
611 } else if (!trytypetag(db
, file
, chain
, &res
->typeinfo
) && !trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
612 rnn_err(db
, "%s:%d: wrong tag in %s: <%s>\n", file
, chain
->line
, node
->name
, chain
->name
);
617 rnn_err(db
, "%s:%d: nameless register\n", file
, node
->line
);
624 static void parsegroup(struct rnndb
*db
, char *file
, xmlNode
*node
) {
625 xmlAttr
*attr
= node
->properties
;
629 if (!strcmp(attr
->name
, "name")) {
630 name
= getattrib(db
, file
, node
->line
, attr
);
632 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for group\n", file
, node
->line
, attr
->name
);
637 rnn_err(db
, "%s:%d: nameless group\n", file
, node
->line
);
640 struct rnngroup
*cur
= 0;
641 for (i
= 0; i
< db
->groupsnum
; i
++)
642 if (!strcmp(db
->groups
[i
]->name
, name
)) {
647 cur
= calloc(sizeof *cur
, 1);
648 cur
->name
= strdup(name
);
649 ADDARRAY(db
->groups
, cur
);
651 xmlNode
*chain
= node
->children
;
653 struct rnndelem
*delem
;
654 if (chain
->type
!= XML_ELEMENT_NODE
) {
655 } else if ((delem
= trydelem(db
, file
, chain
))) {
656 ADDARRAY(cur
->subelems
, delem
);
657 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
658 rnn_err(db
, "%s:%d: wrong tag in group: <%s>\n", file
, chain
->line
, chain
->name
);
664 static void parsedomain(struct rnndb
*db
, char *file
, xmlNode
*node
) {
665 xmlAttr
*attr
= node
->properties
;
667 uint64_t size
= 0; int width
= 8;
671 char *variantsstr
= 0;
674 if (!strcmp(attr
->name
, "name")) {
675 name
= getattrib(db
, file
, node
->line
, attr
);
676 } else if (!strcmp(attr
->name
, "bare")) {
677 bare
= getboolattrib(db
, file
, node
->line
, attr
);
678 } else if (!strcmp(attr
->name
, "size")) {
679 size
= getnumattrib(db
, file
, node
->line
, attr
);
680 } else if (!strcmp(attr
->name
, "width")) {
681 width
= getnumattrib(db
, file
, node
->line
, attr
);
682 } else if (!strcmp(attr
->name
, "prefix")) {
683 prefixstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
684 } else if (!strcmp(attr
->name
, "varset")) {
685 varsetstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
686 } else if (!strcmp(attr
->name
, "variants")) {
687 variantsstr
= strdup(getattrib(db
, file
, node
->line
, attr
));
689 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for domain\n", file
, node
->line
, attr
->name
);
694 rnn_err(db
, "%s:%d: nameless domain\n", file
, node
->line
);
697 struct rnndomain
*cur
= 0;
698 for (i
= 0; i
< db
->domainsnum
; i
++)
699 if (!strcmp(db
->domains
[i
]->name
, name
)) {
700 cur
= db
->domains
[i
];
704 if (strdiff(cur
->varinfo
.prefixstr
, prefixstr
) ||
705 strdiff(cur
->varinfo
.varsetstr
, varsetstr
) ||
706 strdiff(cur
->varinfo
.variantsstr
, variantsstr
) ||
707 cur
->width
!= width
||
709 (size
&& cur
->size
&& size
!= cur
->size
)) {
710 rnn_err(db
, "%s:%d: merge fail for domain %s\n", file
, node
->line
, node
->name
);
716 cur
= calloc(sizeof *cur
, 1);
717 cur
->name
= strdup(name
);
721 cur
->varinfo
.prefixstr
= prefixstr
;
722 cur
->varinfo
.varsetstr
= varsetstr
;
723 cur
->varinfo
.variantsstr
= variantsstr
;
725 ADDARRAY(db
->domains
, cur
);
727 xmlNode
*chain
= node
->children
;
729 struct rnndelem
*delem
;
730 if (chain
->type
!= XML_ELEMENT_NODE
) {
731 } else if ((delem
= trydelem(db
, file
, chain
))) {
732 ADDARRAY(cur
->subelems
, delem
);
733 } else if (!trytop(db
, file
, chain
) && !trydoc(db
, file
, chain
)) {
734 rnn_err(db
, "%s:%d: wrong tag in domain: <%s>\n", file
, chain
->line
, chain
->name
);
740 static void parsecopyright(struct rnndb
*db
, char *file
, xmlNode
*node
) {
741 struct rnncopyright
* copyright
= &db
->copyright
;
742 xmlAttr
*attr
= node
->properties
;
744 if (!strcmp(attr
->name
, "year")) {
745 unsigned firstyear
= getnumattrib(db
, file
, node
->line
, attr
);
746 if(!copyright
->firstyear
|| firstyear
< copyright
->firstyear
)
747 copyright
->firstyear
= firstyear
;
749 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for copyright\n", file
, node
->line
, attr
->name
);
753 xmlNode
*chain
= node
->children
;
755 if (chain
->type
!= XML_ELEMENT_NODE
) {
756 } else if (!strcmp(chain
->name
, "license"))
757 if(copyright
->license
) {
758 if(strcmp(copyright
->license
, node
->content
)) {
759 fprintf(stderr
, "fatal error: multiple different licenses specified!\n");
760 abort(); /* TODO: do something better here, but headergen, xml2html, etc. should not produce anything in this case */
763 copyright
->license
= getcontent(chain
);
764 else if (!strcmp(chain
->name
, "author")) {
765 struct rnnauthor
* author
= calloc(sizeof *author
, 1);
766 xmlAttr
* authorattr
= chain
->properties
;
767 xmlNode
*authorchild
= chain
->children
;
768 author
->contributions
= getcontent(chain
);
770 if (!strcmp(authorattr
->name
, "name"))
771 author
->name
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
772 else if (!strcmp(authorattr
->name
, "email"))
773 author
->email
= strdup(getattrib(db
, file
, chain
->line
, authorattr
));
775 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for author\n", file
, chain
->line
, authorattr
->name
);
777 authorattr
= authorattr
->next
;
780 if (authorchild
->type
!= XML_ELEMENT_NODE
) {
781 } else if (!strcmp(authorchild
->name
, "nick")) {
782 xmlAttr
* nickattr
= authorchild
->properties
;
785 if (!strcmp(nickattr
->name
, "name"))
786 nickname
= strdup(getattrib(db
, file
, authorchild
->line
, nickattr
));
788 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for nick\n", file
, authorchild
->line
, nickattr
->name
);
790 nickattr
= nickattr
->next
;
793 rnn_err(db
, "%s:%d: missing \"name\" attribute for nick\n", file
, authorchild
->line
);
795 ADDARRAY(author
->nicknames
, nickname
);
797 rnn_err(db
, "%s:%d: wrong tag in author: <%s>\n", file
, authorchild
->line
, authorchild
->name
);
799 authorchild
= authorchild
->next
;
801 ADDARRAY(copyright
->authors
, author
);
803 rnn_err(db
, "%s:%d: wrong tag in copyright: <%s>\n", file
, chain
->line
, chain
->name
);
809 static int trytop (struct rnndb
*db
, char *file
, xmlNode
*node
) {
810 if (!strcmp(node
->name
, "enum")) {
811 parseenum(db
, file
, node
);
813 } else if (!strcmp(node
->name
, "bitset")) {
814 parsebitset(db
, file
, node
);
816 } else if (!strcmp(node
->name
, "group")) {
817 parsegroup(db
, file
, node
);
819 } else if (!strcmp(node
->name
, "domain")) {
820 parsedomain(db
, file
, node
);
822 } else if (!strcmp(node
->name
, "spectype")) {
823 parsespectype(db
, file
, node
);
825 } else if (!strcmp(node
->name
, "import")) {
826 xmlAttr
*attr
= node
->properties
;
829 if (!strcmp(attr
->name
, "file")) {
830 subfile
= getattrib(db
, file
, node
->line
, attr
);
832 rnn_err(db
, "%s:%d: wrong attribute \"%s\" for import\n", file
, node
->line
, attr
->name
);
837 rnn_err(db
, "%s:%d: missing \"file\" attribute for import\n", file
, node
->line
);
839 rnn_parsefile(db
, subfile
);
842 } else if (!strcmp(node
->name
, "copyright")) {
843 parsecopyright(db
, file
, node
);
849 static char * find_file(const char *file_orig
)
851 const char *rnn_path
= getenv("RNN_PATH");
855 rnn_path
= RNN_DEF_PATH
;
857 FILE *file
= find_in_path(file_orig
, rnn_path
, &fname
);
859 fprintf (stderr
, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", file_orig
);
867 void rnn_parsefile (struct rnndb
*db
, char *file_orig
) {
871 fname
= find_file(file_orig
);
877 for (i
= 0; i
< db
->filesnum
; i
++)
878 if (!strcmp(db
->files
[i
], fname
))
881 ADDARRAY(db
->files
, fname
);
882 xmlDocPtr doc
= xmlParseFile(fname
);
884 rnn_err(db
, "%s: couldn't open database file. Please set the env var RNN_PATH.\n", fname
);
887 xmlNode
*root
= doc
->children
;
889 if (root
->type
!= XML_ELEMENT_NODE
) {
890 } else if (strcmp(root
->name
, "database")) {
891 rnn_err(db
, "%s:%d: wrong top-level tag <%s>\n", fname
, root
->line
, root
->name
);
893 xmlNode
*chain
= root
->children
;
895 if (chain
->type
!= XML_ELEMENT_NODE
) {
896 } else if (!trytop(db
, fname
, chain
) && !trydoc(db
, fname
, chain
)) {
897 rnn_err(db
, "%s:%d: wrong tag in database: <%s>\n", fname
, chain
->line
, chain
->name
);
907 static struct rnnvalue
*copyvalue (struct rnnvalue
*val
, char *file
) {
908 struct rnnvalue
*res
= calloc (sizeof *res
, 1);
909 res
->name
= val
->name
;
910 res
->valvalid
= val
->valvalid
;
911 res
->value
= val
->value
;
912 res
->varinfo
= val
->varinfo
;
917 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
);
920 static void copytypeinfo (struct rnntypeinfo
*dst
, struct rnntypeinfo
*src
, char *file
) {
922 dst
->name
= src
->name
;
925 dst
->high
= src
->high
;
928 dst
->align
= src
->align
;
929 dst
->addvariant
= src
->addvariant
;
930 for (i
= 0; i
< src
->valsnum
; i
++)
931 ADDARRAY(dst
->vals
, copyvalue(src
->vals
[i
], file
));
932 for (i
= 0; i
< src
->bitfieldsnum
; i
++)
933 ADDARRAY(dst
->bitfields
, copybitfield(src
->bitfields
[i
], file
));
936 static struct rnnbitfield
*copybitfield (struct rnnbitfield
*bf
, char *file
) {
937 struct rnnbitfield
*res
= calloc (sizeof *res
, 1);
938 res
->name
= bf
->name
;
939 res
->varinfo
= bf
->varinfo
;
941 copytypeinfo(&res
->typeinfo
, &bf
->typeinfo
, file
);
945 static struct rnndelem
*copydelem (struct rnndelem
*elem
, char *file
) {
946 struct rnndelem
*res
= calloc (sizeof *res
, 1);
947 res
->type
= elem
->type
;
948 res
->name
= elem
->name
;
949 res
->width
= elem
->width
;
950 res
->access
= elem
->access
;
951 res
->offset
= elem
->offset
;
952 res
->length
= elem
->length
;
953 res
->stride
= elem
->stride
;
954 res
->varinfo
= elem
->varinfo
;
956 copytypeinfo(&res
->typeinfo
, &elem
->typeinfo
, file
);
958 for (i
= 0; i
< elem
->subelemsnum
; i
++)
959 ADDARRAY(res
->subelems
, copydelem(elem
->subelems
[i
], file
));
960 for (i
= 0; i
< elem
->offsetsnum
; i
++)
961 ADDARRAY(res
->offsets
, elem
->offsets
[i
]);
965 static struct rnnvarset
*copyvarset (struct rnnvarset
*varset
) {
966 struct rnnvarset
*res
= calloc(sizeof *res
, 1);
967 res
->venum
= varset
->venum
;
968 res
->variants
= calloc(sizeof *res
->variants
, res
->venum
->valsnum
);
970 for (i
= 0; i
< res
->venum
->valsnum
; i
++)
971 res
->variants
[i
] = varset
->variants
[i
];
975 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
);
977 static int findvidx (struct rnndb
*db
, struct rnnenum
*en
, char *name
) {
979 for (i
= 0; i
< en
->valsnum
; i
++)
980 if (!strcmp(en
->vals
[i
]->name
, name
))
982 rnn_err(db
, "Cannot find variant %s in enum %s!\n", name
, en
->name
);
986 static void prepvarinfo (struct rnndb
*db
, char *what
, struct rnnvarinfo
*vi
, struct rnnvarinfo
*parent
) {
988 vi
->prefenum
= parent
->prefenum
;
990 if (!strcmp(vi
->prefixstr
, "none"))
993 vi
->prefenum
= rnn_findenum(db
, vi
->prefixstr
); // XXX
997 for (i
= 0; i
< parent
->varsetsnum
; i
++)
998 ADDARRAY(vi
->varsets
, copyvarset(parent
->varsets
[i
]));
999 struct rnnenum
*varset
= vi
->prefenum
;
1000 if (!varset
&& !vi
->varsetstr
&& parent
)
1001 vi
->varsetstr
= parent
->varsetstr
;
1003 varset
= rnn_findenum(db
, vi
->varsetstr
);
1004 if (vi
->variantsstr
) {
1005 char *vars
= vi
->variantsstr
;
1007 rnn_err(db
, "%s: tried to use variants without active varset!\n", what
);
1010 struct rnnvarset
*vs
= 0;
1011 int nvars
= varset
->valsnum
;
1012 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1013 if (vi
->varsets
[i
]->venum
== varset
) {
1014 vs
= vi
->varsets
[i
];
1018 vs
= calloc (sizeof *vs
, 1);
1020 vs
->variants
= calloc(sizeof *vs
->variants
, nvars
);
1021 for (i
= 0; i
< nvars
; i
++)
1022 vs
->variants
[i
] = 1;
1023 ADDARRAY(vi
->varsets
, vs
);
1026 while (*vars
== ' ') vars
++;
1030 while (*split
!= ':' && *split
!= '-' && *split
!= ' ' && *split
!= 0)
1034 first
= strndup(vars
, split
-vars
);
1035 if (*split
== ' ' || *split
== 0) {
1036 int idx
= findvidx(db
, varset
, first
);
1038 vs
->variants
[idx
] |= 2;
1041 char *end
= split
+1;
1042 while (*end
!= ' ' && *end
!= 0)
1046 second
= strndup(split
+1, end
-split
-1);
1049 idx1
= findvidx(db
, varset
, first
);
1052 idx2
= findvidx(db
, varset
, second
);
1056 if (idx1
!= -1 && idx2
!= -1)
1057 for (i
= idx1
; i
< idx2
; i
++)
1058 vs
->variants
[i
] |= 2;
1065 for (i
= 0; i
< nvars
; i
++) {
1066 vs
->variants
[i
] = (vs
->variants
[i
] == 3);
1067 if (vs
->variants
[i
])
1074 struct rnnvarset
*vs
= 0;
1075 for (i
= 0; i
< vi
->varsetsnum
; i
++)
1076 if (vi
->varsets
[i
]->venum
== vi
->prefenum
) {
1077 vs
= vi
->varsets
[i
];
1081 for (i
= 0; i
< vi
->prefenum
->valsnum
; i
++)
1082 if (vs
->variants
[i
]) {
1083 vi
->prefix
= vi
->prefenum
->vals
[i
]->name
;
1087 vi
->prefix
= vi
->prefenum
->vals
[0]->name
;
1092 static void prepvalue(struct rnndb
*db
, struct rnnvalue
*val
, char *prefix
, struct rnnvarinfo
*parvi
) {
1093 val
->fullname
= catstr(prefix
, val
->name
);
1094 prepvarinfo (db
, val
->fullname
, &val
->varinfo
, parvi
);
1095 if (val
->varinfo
.dead
)
1097 if (val
->varinfo
.prefix
)
1098 val
->fullname
= catstr(val
->varinfo
.prefix
, val
->fullname
);
1101 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
);
1103 static void preptypeinfo(struct rnndb
*db
, struct rnntypeinfo
*ti
, char *prefix
, struct rnnvarinfo
*vi
, char *file
) {
1106 struct rnnenum
*en
= rnn_findenum (db
, ti
->name
);
1107 struct rnnbitset
*bs
= rnn_findbitset (db
, ti
->name
);
1108 struct rnnspectype
*st
= rnn_findspectype (db
, ti
->name
);
1111 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1113 for (j
= 0; j
< en
->valsnum
; j
++)
1114 ADDARRAY(ti
->vals
, copyvalue(en
->vals
[j
], file
));
1116 ti
->type
= RNN_TTYPE_ENUM
;
1121 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1123 for (j
= 0; j
< bs
->bitfieldsnum
; j
++)
1124 ADDARRAY(ti
->bitfields
, copybitfield(bs
->bitfields
[j
], file
));
1126 ti
->type
= RNN_TTYPE_BITSET
;
1130 ti
->type
= RNN_TTYPE_SPECTYPE
;
1132 } else if (!strcmp(ti
->name
, "hex")) {
1133 ti
->type
= RNN_TTYPE_HEX
;
1134 } else if (!strcmp(ti
->name
, "float")) {
1135 ti
->type
= RNN_TTYPE_FLOAT
;
1136 } else if (!strcmp(ti
->name
, "uint")) {
1137 ti
->type
= RNN_TTYPE_UINT
;
1138 } else if (!strcmp(ti
->name
, "int")) {
1139 ti
->type
= RNN_TTYPE_INT
;
1140 } else if (!strcmp(ti
->name
, "boolean")) {
1141 ti
->type
= RNN_TTYPE_BOOLEAN
;
1142 } else if (!strcmp(ti
->name
, "bitfield")) {
1143 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1144 } else if (!strcmp(ti
->name
, "enum")) {
1145 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1146 } else if (!strcmp(ti
->name
, "fixed")) {
1147 ti
->type
= RNN_TTYPE_FIXED
;
1148 } else if (!strcmp(ti
->name
, "ufixed")) {
1149 ti
->type
= RNN_TTYPE_UFIXED
;
1150 } else if (!strcmp(ti
->name
, "a3xx_regid")) {
1151 ti
->type
= RNN_TTYPE_A3XX_REGID
;
1152 } else if (!strcmp(ti
->name
, "waddress") || !strcmp(ti
->name
, "address")) {
1153 ti
->type
= RNN_TTYPE_HEX
;
1155 ti
->type
= RNN_TTYPE_HEX
;
1156 rnn_err(db
, "%s: unknown type %s\n", prefix
, ti
->name
);
1158 } else if (ti
->bitfieldsnum
) {
1159 ti
->name
= "bitfield";
1160 ti
->type
= RNN_TTYPE_INLINE_BITSET
;
1161 } else if (ti
->valsnum
) {
1163 ti
->type
= RNN_TTYPE_INLINE_ENUM
;
1164 } else if (ti
->low
== 0 && ti
->high
== 0) {
1165 ti
->name
= "boolean";
1166 ti
->type
= RNN_TTYPE_BOOLEAN
;
1169 ti
->type
= RNN_TTYPE_HEX
;
1171 if (ti
->addvariant
&& ti
->type
!= RNN_TTYPE_ENUM
) {
1172 rnn_err(db
, "%s: addvariant specified on non-enum type %s\n", prefix
, ti
->name
);
1174 for (i
= 0; i
< ti
->bitfieldsnum
; i
++)
1175 prepbitfield(db
, ti
->bitfields
[i
], prefix
, vi
);
1176 for (i
= 0; i
< ti
->valsnum
; i
++)
1177 prepvalue(db
, ti
->vals
[i
], prefix
, vi
);
1180 static void prepbitfield(struct rnndb
*db
, struct rnnbitfield
*bf
, char *prefix
, struct rnnvarinfo
*parvi
) {
1181 bf
->fullname
= catstr(prefix
, bf
->name
);
1182 prepvarinfo (db
, bf
->fullname
, &bf
->varinfo
, parvi
);
1183 if (bf
->varinfo
.dead
)
1185 preptypeinfo(db
, &bf
->typeinfo
, bf
->fullname
, &bf
->varinfo
, bf
->file
);
1186 if (bf
->varinfo
.prefix
)
1187 bf
->fullname
= catstr(bf
->varinfo
.prefix
, bf
->fullname
);
1190 static void prepdelem(struct rnndb
*db
, struct rnndelem
*elem
, char *prefix
, struct rnnvarinfo
*parvi
, int width
) {
1191 if (elem
->type
== RNN_ETYPE_USE_GROUP
) {
1193 struct rnngroup
*gr
= 0;
1194 for (i
= 0; i
< db
->groupsnum
; i
++)
1195 if (!strcmp(db
->groups
[i
]->name
, elem
->name
)) {
1200 for (i
= 0; i
< gr
->subelemsnum
; i
++)
1201 ADDARRAY(elem
->subelems
, copydelem(gr
->subelems
[i
], elem
->file
));
1203 rnn_err(db
, "group %s not found!\n", elem
->name
);
1205 elem
->type
= RNN_ETYPE_STRIPE
;
1210 elem
->fullname
= catstr(prefix
, elem
->name
);
1211 prepvarinfo (db
, elem
->fullname
?elem
->fullname
:prefix
, &elem
->varinfo
, parvi
);
1212 if (elem
->varinfo
.dead
)
1214 if (elem
->length
!= 1 && !elem
->stride
) {
1215 if (elem
->type
!= RNN_ETYPE_REG
) {
1216 rnn_err(db
, "%s has non-1 length, but no stride!\n", elem
->fullname
);
1218 elem
->stride
= elem
->width
/width
;
1221 preptypeinfo(db
, &elem
->typeinfo
, elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, elem
->file
);
1224 for (i
= 0; i
< elem
->subelemsnum
; i
++)
1225 prepdelem(db
, elem
->subelems
[i
], elem
->name
?elem
->fullname
:prefix
, &elem
->varinfo
, width
);
1226 if (elem
->varinfo
.prefix
&& elem
->name
)
1227 elem
->fullname
= catstr(elem
->varinfo
.prefix
, elem
->fullname
);
1230 static void prepdomain(struct rnndb
*db
, struct rnndomain
*dom
) {
1231 prepvarinfo (db
, dom
->name
, &dom
->varinfo
, 0);
1233 for (i
= 0; i
< dom
->subelemsnum
; i
++)
1234 prepdelem(db
, dom
->subelems
[i
], dom
->bare
?0:dom
->name
, &dom
->varinfo
, dom
->width
);
1235 dom
->fullname
= catstr(dom
->varinfo
.prefix
, dom
->name
);
1238 static void prepenum(struct rnndb
*db
, struct rnnenum
*en
) {
1241 prepvarinfo (db
, en
->name
, &en
->varinfo
, 0);
1245 for (i
= 0; i
< en
->valsnum
; i
++)
1246 prepvalue(db
, en
->vals
[i
], en
->bare
?0:en
->name
, &en
->varinfo
);
1247 en
->fullname
= catstr(en
->varinfo
.prefix
, en
->name
);
1251 static void prepbitset(struct rnndb
*db
, struct rnnbitset
*bs
) {
1252 prepvarinfo (db
, bs
->name
, &bs
->varinfo
, 0);
1256 for (i
= 0; i
< bs
->bitfieldsnum
; i
++)
1257 prepbitfield(db
, bs
->bitfields
[i
], bs
->bare
?0:bs
->name
, &bs
->varinfo
);
1258 bs
->fullname
= catstr(bs
->varinfo
.prefix
, bs
->name
);
1261 static void prepspectype(struct rnndb
*db
, struct rnnspectype
*st
) {
1262 preptypeinfo(db
, &st
->typeinfo
, st
->name
, 0, st
->file
); // XXX doesn't exactly make sense...
1265 void rnn_prepdb (struct rnndb
*db
) {
1267 for (i
= 0; i
< db
->enumsnum
; i
++)
1268 prepenum(db
, db
->enums
[i
]);
1269 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1270 prepbitset(db
, db
->bitsets
[i
]);
1271 for (i
= 0; i
< db
->domainsnum
; i
++)
1272 prepdomain(db
, db
->domains
[i
]);
1273 for (i
= 0; i
< db
->spectypesnum
; i
++)
1274 prepspectype(db
, db
->spectypes
[i
]);
1277 struct rnnenum
*rnn_findenum (struct rnndb
*db
, const char *name
) {
1279 for (i
= 0; i
< db
->enumsnum
; i
++)
1280 if (!strcmp(db
->enums
[i
]->name
, name
))
1281 return db
->enums
[i
];
1285 struct rnnbitset
*rnn_findbitset (struct rnndb
*db
, const char *name
) {
1287 for (i
= 0; i
< db
->bitsetsnum
; i
++)
1288 if (!strcmp(db
->bitsets
[i
]->name
, name
))
1289 return db
->bitsets
[i
];
1293 struct rnndomain
*rnn_finddomain (struct rnndb
*db
, const char *name
) {
1295 for (i
= 0; i
< db
->domainsnum
; i
++)
1296 if (!strcmp(db
->domains
[i
]->name
, name
))
1297 return db
->domains
[i
];
1301 struct rnnspectype
*rnn_findspectype (struct rnndb
*db
, const char *name
) {
1303 for (i
= 0; i
< db
->spectypesnum
; i
++)
1304 if (!strcmp(db
->spectypes
[i
]->name
, name
))
1305 return db
->spectypes
[i
];