static struct rnnbitfield *parsebitfield(struct rnndb *db, char *file, xmlNode *node) { struct rnnbitfield *bf = calloc(sizeof *bf, 1); bf->file = file; xmlAttr *attr = node->properties; int highok = 0, lowok = 0; while (attr) { if (!strcmp(attr->name, "name")) { bf->name = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "high")) { bf->high = getnumattrib(db, file, node->line, attr); highok = 1; } else if (!strcmp(attr->name, "low")) { bf->low = getnumattrib(db, file, node->line, attr); lowok = 1; } else if (!strcmp(attr->name, "pos")) { bf->high = bf->low = getnumattrib(db, file, node->line, attr); lowok = highok = 1; } else if (!strcmp(attr->name, "varset")) { bf->varinfo.varsetstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "variants")) { bf->varinfo.variantsstr = strdup(getattrib(db, file, node->line, attr)); } else if (!trytypeattr(db, file, node, attr, &bf->typeinfo)) { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for bitfield\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } xmlNode *chain = node->children; while (chain) { if (chain->type != XML_ELEMENT_NODE) { } else if (!trytypetag(db, file, chain, &bf->typeinfo) && !trytop(db, file, chain) && !trydoc(db, file, chain)) { fprintf (stderr, "%s:%d: wrong tag in %s: <%s>\n", file, chain->line, node->name, chain->name); db->estatus = 1; } chain = chain->next; } if (!bf->name) { fprintf (stderr, "%s:%d: nameless bitfield\n", file, node->line); db->estatus = 1; return 0; } else if (!highok || !lowok || bf->high < bf->low) { fprintf (stderr, "%s:%d: bitfield has wrong placement\n", file, node->line); db->estatus = 1; return 0; } else { return bf; } }
static int trytypeattr (struct rnndb *db, char *file, xmlNode *node, xmlAttr *attr, struct rnntypeinfo *ti) { if (!strcmp(attr->name, "shr")) { ti->shr = getnumattrib(db, file, node->line, attr); return 1; } else if (!strcmp(attr->name, "min")) { ti->min = getnumattrib(db, file, node->line, attr); ti->minvalid = 1; return 1; } else if (!strcmp(attr->name, "max")) { ti->max = getnumattrib(db, file, node->line, attr); ti->maxvalid = 1; return 1; } else if (!strcmp(attr->name, "align")) { ti->align = getnumattrib(db, file, node->line, attr); ti->alignvalid = 1; return 1; } else if (!strcmp(attr->name, "type")) { ti->name = strdup(getattrib(db, file, node->line, attr));; return 1; } else if (!strcmp(attr->name, "radix")) { ti->radix = getnumattrib(db, file, node->line, attr); ti->radixvalid = 1; } return 0; }
static int getboolattrib (struct rnndb *db, char *file, int line, xmlAttr *attr) { char *c = getattrib(db, file, line, attr); if (!strcmp(c, "yes") || !strcmp(c, "1")) return 1; if (!strcmp(c, "no") || !strcmp(c, "0")) return 0; fprintf (stderr, "%s:%d: invalid boolean value \"%s\" in attribute \"%s\"\n", file, line, c, attr->name); db->estatus = 1; return 0; }
static uint64_t getnumattrib (struct rnndb *db, char *file, int line, xmlAttr *attr) { char *c = getattrib(db, file, line, attr); char *cc; uint64_t res; if (strchr(c, 'x') || strchr(c, 'X')) res = strtoull(c, &cc, 16); else res = strtoull(c, &cc, 10); if (*cc) { fprintf (stderr, "%s:%d: invalid numeric value \"%s\" in attribute \"%s\"\n", file, line, c, attr->name); db->estatus = 1; } return res; }
static struct rnnvalue *parsevalue(struct rnndb *db, char *file, xmlNode *node) { struct rnnvalue *val = calloc(sizeof *val, 1); val->file = file; xmlAttr *attr = node->properties; while (attr) { if (!strcmp(attr->name, "name")) { val->name = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "value")) { val->value = getnumattrib(db, file, node->line, attr); val->valvalid = 1; } else if (!strcmp(attr->name, "varset")) { val->varinfo.varsetstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "variants")) { val->varinfo.variantsstr = strdup(getattrib(db, file, node->line, attr)); } else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for value\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } xmlNode *chain = node->children; while (chain) { if (chain->type != XML_ELEMENT_NODE) { } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) { fprintf (stderr, "%s:%d: wrong tag in %s: <%s>\n", file, chain->line, node->name, chain->name); db->estatus = 1; } chain = chain->next; } if (!val->name) { fprintf (stderr, "%s:%d: nameless value\n", file, node->line); db->estatus = 1; return 0; } else { return val; } }
void main(int argc, char * argv[]) { int channel, rcvid, returncode; if(open("/sys/addressbook", O_PROC) != -1) { fprintf(stderr, "The addressbook service is already running.\n"); exit(EXIT_FAILURE); } xmlfile = XMLloadFile(fpathname("data/addressbook.xml", getappdir(), 1)); xmlelem = XMLgetNode(xmlfile, "xml"); channel = makeChanP("/sys/addressbook"); retexit(1); while(1) { rcvid = recvMsg(channel,(void *)&msg); switch(msg->code) { case GET_ATTRIB: returncode = getattrib(); break; case GET_ALL_LIST: returncode = getalllist(); break; case MAKE_ENTRY: returncode = makeentry(); break; case PUT_ATTRIB: returncode = putattrib(); break; case DEL_ENTRY: returncode = deleteentry(); break; case DEL_ATTRIB: returncode = deleteattrib(); break; case IO_OPEN: if(*(int *)( ((char*)msg) +6) & (O_PROC|O_STAT)) returncode = makeCon(rcvid, 1); else returncode = -1; break; } replyMsg(rcvid, returncode); } }
static void parsegroup(struct rnndb *db, char *file, xmlNode *node) { xmlAttr *attr = node->properties; char *name = 0; int i; while (attr) { if (!strcmp(attr->name, "name")) { name = getattrib(db, file, node->line, attr); } else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for group\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } if (!name) { fprintf (stderr, "%s:%d: nameless group\n", file, node->line); db->estatus = 1; return; } struct rnngroup *cur = 0; for (i = 0; i < db->groupsnum; i++) if (!strcmp(db->groups[i]->name, name)) { cur = db->groups[i]; break; } if (!cur) { cur = calloc(sizeof *cur, 1); cur->name = strdup(name); ADDARRAY(db->groups, cur); } xmlNode *chain = node->children; while (chain) { struct rnndelem *delem; if (chain->type != XML_ELEMENT_NODE) { } else if ((delem = trydelem(db, file, chain))) { ADDARRAY(cur->subelems, delem); } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) { fprintf (stderr, "%s:%d: wrong tag in group: <%s>\n", file, chain->line, chain->name); db->estatus = 1; } chain = chain->next; } }
static int trytop (struct rnndb *db, char *file, xmlNode *node) { if (!strcmp(node->name, "enum")) { parseenum(db, file, node); return 1; } else if (!strcmp(node->name, "bitset")) { parsebitset(db, file, node); return 1; } else if (!strcmp(node->name, "group")) { parsegroup(db, file, node); return 1; } else if (!strcmp(node->name, "domain")) { parsedomain(db, file, node); return 1; } else if (!strcmp(node->name, "spectype")) { parsespectype(db, file, node); return 1; } else if (!strcmp(node->name, "import")) { xmlAttr *attr = node->properties; char *subfile = 0; while (attr) { if (!strcmp(attr->name, "file")) { subfile = getattrib(db, file, node->line, attr); } else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for import\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } if (!subfile) { fprintf (stderr, "%s:%d: missing \"file\" attribute for import\n", file, node->line); db->estatus = 1; } else { rnn_parsefile(db, subfile); } return 1; } else if (!strcmp(node->name, "copyright")) { parsecopyright(db, file, node); return 1; } return 0; }
static void parsespectype(struct rnndb *db, char *file, xmlNode *node) { struct rnnspectype *res = calloc (sizeof *res, 1); res->file = file; xmlAttr *attr = node->properties; int i; while (attr) { if (!strcmp(attr->name, "name")) { res->name = strdup(getattrib(db, file, node->line, attr)); } else if (!trytypeattr(db, file, node, attr, &res->typeinfo)) { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for spectype\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } if (!res->name) { fprintf (stderr, "%s:%d: nameless spectype\n", file, node->line); db->estatus = 1; return; } for (i = 0; i < db->spectypesnum; i++) if (!strcmp(db->spectypes[i]->name, res->name)) { fprintf (stderr, "%s:%d: duplicated spectype name %s\n", file, node->line, res->name); db->estatus = 1; return; } ADDARRAY(db->spectypes, res); xmlNode *chain = node->children; while (chain) { if (chain->type != XML_ELEMENT_NODE) { } else if (!trytypetag(db, file, chain, &res->typeinfo) && !trytop(db, file, chain) && !trydoc(db, file, chain)) { fprintf (stderr, "%s:%d: wrong tag in spectype: <%s>\n", file, chain->line, chain->name); db->estatus = 1; } chain = chain->next; } }
static void parsecopyright(struct rnndb *db, char *file, xmlNode *node) { struct rnncopyright* copyright = &db->copyright; xmlAttr *attr = node->properties; while (attr) { if (!strcmp(attr->name, "year")) { unsigned firstyear = getnumattrib(db, file, node->line, attr); if(!copyright->firstyear || firstyear < copyright->firstyear) copyright->firstyear = firstyear; } else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for copyright\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } xmlNode *chain = node->children; while (chain) { if (chain->type != XML_ELEMENT_NODE) { } else if (!strcmp(chain->name, "license")) if(copyright->license) { if(strcmp(copyright->license, node->content)) { fprintf(stderr, "fatal error: multiple different licenses specified!\n"); abort(); /* TODO: do something better here, but headergen, xml2html, etc. should not produce anything in this case */ } } else copyright->license = getcontent(chain); else if (!strcmp(chain->name, "author")) { struct rnnauthor* author = calloc(sizeof *author, 1); xmlAttr* authorattr = chain->properties; xmlNode *authorchild = chain->children; author->contributions = getcontent(chain); while (authorattr) { if (!strcmp(authorattr->name, "name")) author->name = strdup(getattrib(db, file, chain->line, authorattr)); else if (!strcmp(authorattr->name, "email")) author->email = strdup(getattrib(db, file, chain->line, authorattr)); else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for author\n", file, chain->line, authorattr->name); db->estatus = 1; } authorattr = authorattr->next; } while(authorchild) { if (authorchild->type != XML_ELEMENT_NODE) { } else if (!strcmp(authorchild->name, "nick")) { xmlAttr* nickattr = authorchild->properties; char* nickname = 0; while(nickattr) { if (!strcmp(nickattr->name, "name")) nickname = strdup(getattrib(db, file, authorchild->line, nickattr)); else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for nick\n", file, authorchild->line, nickattr->name); db->estatus = 1; } nickattr = nickattr->next; } if(!nickname) { fprintf (stderr, "%s:%d: missing \"name\" attribute for nick\n", file, authorchild->line); db->estatus = 1; } else ADDARRAY(author->nicknames, nickname); } else { fprintf (stderr, "%s:%d: wrong tag in author: <%s>\n", file, authorchild->line, authorchild->name); db->estatus = 1; } authorchild = authorchild->next; } ADDARRAY(copyright->authors, author); } else { fprintf (stderr, "%s:%d: wrong tag in copyright: <%s>\n", file, chain->line, chain->name); db->estatus = 1; } chain = chain->next; } }
static void parsedomain(struct rnndb *db, char *file, xmlNode *node) { xmlAttr *attr = node->properties; char *name = 0; uint64_t size = 0; int width = 8; int bare = 0; char *prefixstr = 0; char *varsetstr = 0; char *variantsstr = 0; int i; while (attr) { if (!strcmp(attr->name, "name")) { name = getattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "bare")) { bare = getboolattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "size")) { size = getnumattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "width")) { width = getnumattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "prefix")) { prefixstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "varset")) { varsetstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "variants")) { variantsstr = strdup(getattrib(db, file, node->line, attr)); } else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for domain\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } if (!name) { fprintf (stderr, "%s:%d: nameless domain\n", file, node->line); db->estatus = 1; return; } struct rnndomain *cur = 0; for (i = 0; i < db->domainsnum; i++) if (!strcmp(db->domains[i]->name, name)) { cur = db->domains[i]; break; } if (cur) { if (strdiff(cur->varinfo.prefixstr, prefixstr) || strdiff(cur->varinfo.varsetstr, varsetstr) || strdiff(cur->varinfo.variantsstr, variantsstr) || cur->width != width || cur->bare != bare || (size && cur->size && size != cur->size)) { fprintf (stderr, "%s:%d: merge fail for domain %s\n", file, node->line, node->name); db->estatus = 1; } else { if (size) cur->size = size; } } else { cur = calloc(sizeof *cur, 1); cur->name = strdup(name); cur->bare = bare; cur->width = width; cur->size = size; cur->varinfo.prefixstr = prefixstr; cur->varinfo.varsetstr = varsetstr; cur->varinfo.variantsstr = variantsstr; cur->file = file; ADDARRAY(db->domains, cur); } xmlNode *chain = node->children; while (chain) { struct rnndelem *delem; if (chain->type != XML_ELEMENT_NODE) { } else if ((delem = trydelem(db, file, chain))) { ADDARRAY(cur->subelems, delem); } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) { fprintf (stderr, "%s:%d: wrong tag in domain: <%s>\n", file, chain->line, chain->name); db->estatus = 1; } chain = chain->next; } }
static struct rnndelem *trydelem(struct rnndb *db, char *file, xmlNode *node) { if (!strcmp(node->name, "use-group")) { struct rnndelem *res = calloc(sizeof *res, 1); res->file = file; res->type = RNN_ETYPE_USE_GROUP; xmlAttr *attr = node->properties; while (attr) { if (!strcmp(attr->name, "name")) { res->name = strdup(getattrib(db, file, node->line, attr)); } else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for %s\n", file, node->line, attr->name, node->name); db->estatus = 1; } attr = attr->next; } if (!res->name) { fprintf (stderr, "%s:%d: nameless use-group\n", file, node->line); db->estatus = 1; return 0; } return res; } else if (!strcmp(node->name, "stripe") || !strcmp(node->name, "array")) { struct rnndelem *res = calloc(sizeof *res, 1); res->type = (strcmp(node->name, "stripe")?RNN_ETYPE_ARRAY:RNN_ETYPE_STRIPE); res->length = 1; res->file = file; xmlAttr *attr = node->properties; while (attr) { if (!strcmp(attr->name, "name")) { res->name = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "offset")) { res->offset = getnumattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "length")) { res->length = getnumattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "stride")) { res->stride = getnumattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "prefix")) { res->varinfo.prefixstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "varset")) { res->varinfo.varsetstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "variants")) { res->varinfo.variantsstr = strdup(getattrib(db, file, node->line, attr)); } else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for %s\n", file, node->line, attr->name, node->name); db->estatus = 1; } attr = attr->next; } xmlNode *chain = node->children; while (chain) { struct rnndelem *delem; if (chain->type != XML_ELEMENT_NODE) { } else if ((delem = trydelem(db, file, chain))) { ADDARRAY(res->subelems, delem); } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) { fprintf (stderr, "%s:%d: wrong tag in %s: <%s>\n", file, chain->line, node->name, chain->name); db->estatus = 1; } chain = chain->next; } /* Sanity checking */ if (res->type == RNN_ETYPE_ARRAY && res->stride == 0) { fprintf(stderr, "%s: Array %s's stride is undefined. Aborting.\n", file, res->name); exit(-1); } return res; } int width; if (!strcmp(node->name, "reg8")) width = 8; else if (!strcmp(node->name, "reg16")) width = 16; else if (!strcmp(node->name, "reg32")) width = 32; else if (!strcmp(node->name, "reg64")) width = 64; else return 0; struct rnndelem *res = calloc(sizeof *res, 1); res->file = file; res->type = RNN_ETYPE_REG; res->width = width; res->length = 1; res->access = RNN_ACCESS_RW; xmlAttr *attr = node->properties; while (attr) { if (!strcmp(attr->name, "name")) { res->name = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "offset")) { res->offset = getnumattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "length")) { res->length = getnumattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "stride")) { res->stride = getnumattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "varset")) { res->varinfo.varsetstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "variants")) { res->varinfo.variantsstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "access")) { char *str = getattrib(db, file, node->line, attr); if (!strcmp(str, "r")) res->access = RNN_ACCESS_R; else if (!strcmp(str, "w")) res->access = RNN_ACCESS_W; else if (!strcmp(str, "rw")) res->access = RNN_ACCESS_RW; else fprintf (stderr, "%s:%d: wrong access type \"%s\" for register\n", file, node->line, str); } else if (!trytypeattr(db, file, node, attr, &res->typeinfo)) { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for register\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } xmlNode *chain = node->children; while (chain) { if (chain->type != XML_ELEMENT_NODE) { } else if (!trytypetag(db, file, chain, &res->typeinfo) && !trytop(db, file, chain) && !trydoc(db, file, chain)) { fprintf (stderr, "%s:%d: wrong tag in %s: <%s>\n", file, chain->line, node->name, chain->name); db->estatus = 1; } chain = chain->next; } if (!res->name) { fprintf (stderr, "%s:%d: nameless register\n", file, node->line); db->estatus = 1; return 0; } else { } return res; }
static void parsebitset(struct rnndb *db, char *file, xmlNode *node) { xmlAttr *attr = node->properties; char *name = 0; int isinline = 0; int bare = 0; char *prefixstr = 0; char *varsetstr = 0; char *variantsstr = 0; int i; while (attr) { if (!strcmp(attr->name, "name")) { name = getattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "bare")) { bare = getboolattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "inline")) { isinline = getboolattrib(db, file, node->line, attr); } else if (!strcmp(attr->name, "prefix")) { prefixstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "varset")) { varsetstr = strdup(getattrib(db, file, node->line, attr)); } else if (!strcmp(attr->name, "variants")) { variantsstr = strdup(getattrib(db, file, node->line, attr)); } else { fprintf (stderr, "%s:%d: wrong attribute \"%s\" for bitset\n", file, node->line, attr->name); db->estatus = 1; } attr = attr->next; } if (!name) { fprintf (stderr, "%s:%d: nameless bitset\n", file, node->line); db->estatus = 1; return; } struct rnnbitset *cur = 0; for (i = 0; i < db->bitsetsnum; i++) if (!strcmp(db->bitsets[i]->name, name)) { cur = db->bitsets[i]; break; } if (cur) { if (strdiff(cur->varinfo.prefixstr, prefixstr) || strdiff(cur->varinfo.varsetstr, varsetstr) || strdiff(cur->varinfo.variantsstr, variantsstr) || cur->isinline != isinline || cur->bare != bare) { fprintf (stderr, "%s:%d: merge fail for bitset %s\n", file, node->line, node->name); db->estatus = 1; } } else { cur = calloc(sizeof *cur, 1); cur->name = strdup(name); cur->isinline = isinline; cur->bare = bare; cur->varinfo.prefixstr = prefixstr; cur->varinfo.varsetstr = varsetstr; cur->varinfo.variantsstr = variantsstr; cur->file = file; ADDARRAY(db->bitsets, cur); } xmlNode *chain = node->children; while (chain) { if (chain->type != XML_ELEMENT_NODE) { } else if (!strcmp(chain->name, "bitfield")) { struct rnnbitfield *bf = parsebitfield(db, file, chain); if (bf) ADDARRAY(cur->bitfields, bf); } else if (!trytop(db, file, chain) && !trydoc(db, file, chain)) { fprintf (stderr, "%s:%d: wrong tag in bitset: <%s>\n", file, chain->line, chain->name); db->estatus = 1; } chain = chain->next; } }