static void copytypeinfo (struct rnntypeinfo *dst, struct rnntypeinfo *src, char *file) { int i; dst->name = src->name; dst->shr = src->shr; dst->min = src->min; dst->max = src->max; dst->align = src->align; for (i = 0; i < src->valsnum; i++) ADDARRAY(dst->vals, copyvalue(src->vals[i], file)); for (i = 0; i < src->bitfieldsnum; i++) ADDARRAY(dst->bitfields, copybitfield(src->bitfields[i], file)); }
static int trytypetag (struct rnndb *db, char *file, xmlNode *node, struct rnntypeinfo *ti) { if (!strcmp(node->name, "value")) { struct rnnvalue *val = parsevalue(db, file, node); if (val) ADDARRAY(ti->vals, val); return 1; } else if (!strcmp(node->name, "bitfield")) { struct rnnbitfield *bf = parsebitfield(db, file, node); if (bf) ADDARRAY(ti->bitfields, bf); return 1; } return 0; }
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; } }
uint32_t *findmem (struct cctx *ctx, uint64_t addr) { int i; uint64_t tag = addr & ~0xfffull; for (i = 0; i < ctx->pagesnum; i++) { if (tag == ctx->pages[i]->tag) return &ctx->pages[i]->contents[(addr&0xfff)/4]; } struct mpage *pg = calloc (sizeof *pg, 1); pg->tag = tag; ADDARRAY(ctx->pages, pg); return &pg->contents[(addr&0xfff)/4]; }
void rnn_parsefile (struct rnndb *db, char *file_orig) { int i; char *fname; const char *rnn_path = getenv("RNN_PATH"); if (!rnn_path) rnn_path = RNN_DEF_PATH; FILE *file = find_in_path(file_orig, rnn_path, &fname); if (!file) { fprintf (stderr, "%s: couldn't find database file. Please set the env var RNN_PATH.\n", file_orig); db->estatus = 1; return; } fclose(file); for (i = 0; i < db->filesnum; i++) if (!strcmp(db->files[i], fname)) return; ADDARRAY(db->files, fname); xmlDocPtr doc = xmlParseFile(fname); if (!doc) { fprintf (stderr, "%s: couldn't open database file. Please set the env var RNN_PATH.\n", fname); db->estatus = 1; return; } xmlNode *root = doc->children; while (root) { if (root->type != XML_ELEMENT_NODE) { } else if (strcmp(root->name, "database")) { fprintf (stderr, "%s:%d: wrong top-level tag <%s>\n", fname, root->line, root->name); db->estatus = 1; } else { xmlNode *chain = root->children; while (chain) { if (chain->type != XML_ELEMENT_NODE) { } else if (!trytop(db, fname, chain) && !trydoc(db, fname, chain)) { fprintf (stderr, "%s:%d: wrong tag in database: <%s>\n", fname, chain->line, chain->name); db->estatus = 1; } chain = chain->next; } } root = root->next; } xmlFreeDoc(doc); }
static struct rnndelem *copydelem (struct rnndelem *elem, char *file) { struct rnndelem *res = calloc (sizeof *res, 1); res->type = elem->type; res->name = elem->name; res->width = elem->width; res->access = elem->access; res->offset = elem->offset; res->length = elem->length; res->stride = elem->stride; res->varinfo = elem->varinfo; res->file = file; copytypeinfo(&res->typeinfo, &elem->typeinfo, file); int i; for (i = 0; i < elem->subelemsnum; i++) ADDARRAY(res->subelems, copydelem(elem->subelems[i], file)); return res; }
int rnndec_varadd(struct rnndeccontext *ctx, char *varset, char *variant) { struct rnnenum *en = rnn_findenum(ctx->db, varset); if (!en) { fprintf (stderr, "Enum %s doesn't exist in database!\n", varset); return 0; } int i; for (i = 0; i < en->valsnum; i++) if (!strcasecmp(en->vals[i]->name, variant)) { struct rnndecvariant *ci = calloc (sizeof *ci, 1); ci->en = en; ci->variant = i; ADDARRAY(ctx->vars, ci); return 1; } fprintf (stderr, "Variant %s doesn't exist in enum %s!\n", variant, varset); return 0; }
static void prepdelem(struct rnndb *db, struct rnndelem *elem, char *prefix, struct rnnvarinfo *parvi, int width) { if (elem->type == RNN_ETYPE_USE_GROUP) { int i; struct rnngroup *gr = 0; for (i = 0; i < db->groupsnum; i++) if (!strcmp(db->groups[i]->name, elem->name)) { gr = db->groups[i]; break; } if (gr) { for (i = 0; i < gr->subelemsnum; i++) ADDARRAY(elem->subelems, copydelem(gr->subelems[i], elem->file)); } else { fprintf (stderr, "group %s not found!\n", elem->name); db->estatus = 1; } elem->type = RNN_ETYPE_STRIPE; elem->length = 1; elem->name = 0; } if (elem->name) elem->fullname = catstr(prefix, elem->name); prepvarinfo (db, elem->fullname?elem->fullname:prefix, &elem->varinfo, parvi); if (elem->varinfo.dead) return; if (elem->length != 1 && !elem->stride) { if (elem->type != RNN_ETYPE_REG) { fprintf (stderr, "%s has non-1 length, but no stride!\n", elem->fullname); db->estatus = 1; } else { elem->stride = elem->width/width; } } preptypeinfo(db, &elem->typeinfo, elem->name?elem->fullname:prefix, &elem->varinfo, elem->width, elem->file); int i; for (i = 0; i < elem->subelemsnum; i++) prepdelem(db, elem->subelems[i], elem->name?elem->fullname:prefix, &elem->varinfo, width); if (elem->varinfo.prefix && elem->name) elem->fullname = catstr(elem->varinfo.prefix, elem->fullname); }
void printdelem (struct rnndelem *elem, uint64_t offset) { if (elem->varinfo.dead) return; if (elem->length != 1) ADDARRAY(strides, elem->stride); if (elem->name) { if (stridesnum) { int len, total; FILE *dst = findfout(elem->file); fprintf (dst, "#define %s(%n", elem->fullname, &total); int i; for (i = 0; i < stridesnum; i++) { if (i) { fprintf(dst, ", "); total += 2; } fprintf (dst, "i%d%n", i, &len); total += len; } fprintf (dst, ")"); total++; seekcol (dst, total, startcol-1); fprintf (dst, "(0x%08"PRIx64"", offset + elem->offset); for (i = 0; i < stridesnum; i++) fprintf (dst, " + %#" PRIx64 "*(i%d)", strides[i], i); fprintf (dst, ")\n"); } else printdef (elem->fullname, 0, 0, offset + elem->offset, elem->file); if (elem->stride) printdef (elem->fullname, "ESIZE", 0, elem->stride, elem->file); if (elem->length != 1) printdef (elem->fullname, "LEN", 0, elem->length, elem->file); printtypeinfo (&elem->typeinfo, elem->fullname, 0, elem->file); } fprintf (findfout(elem->file), "\n"); int j; for (j = 0; j < elem->subelemsnum; j++) { printdelem(elem->subelems[j], offset + elem->offset); } if (elem->length != 1) stridesnum--; }
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; } }
int main(int argc, char **argv) { FILE *infile = stdin; const struct disisa *isa = 0; struct label *labels = 0; int labelsnum = 0; int labelsmax = 0; int w = 0, bin = 0, quiet = 0; const char *varname = 0; argv[0] = basename(argv[0]); int len = strlen(argv[0]); if (len > 3 && !strcmp(argv[0] + len - 3, "dis")) { argv[0][len-3] = 0; isa = ed_getisa(argv[0]); if (isa && isa->opunit == 4) w = 1; } int ptype = -1; int vartype = -1; int c; unsigned base = 0, skip = 0, limit = 0; while ((c = getopt (argc, argv, "vgfpcsb:d:l:m:V:wWinqu:M:")) != -1) switch (c) { case 'v': ptype = VP; break; case 'g': ptype = GP; break; case 'f': case 'p': ptype = FP; break; case 'c': ptype = CP; break; case 's': ptype = VP|GP|FP; break; case 'b': sscanf(optarg, "%x", &base); break; case 'd': sscanf(optarg, "%x", &skip); break; case 'l': sscanf(optarg, "%x", &limit); break; case 'w': w = 1; break; case 'W': w = 2; break; case 'i': bin = 1; break; case 'q': quiet = 1; break; case 'n': cnorm = ""; cname = ""; creg0 = ""; creg1 = ""; cmem = ""; cnum = ""; cunk = ""; cbtarg = ""; cctarg = ""; cbctarg = ""; break; case 'm': isa = ed_getisa(optarg); if (!isa) { fprintf (stderr, "Unknown architecure \"%s\"!\n", optarg); return 1; } break; case 'V': varname = optarg; break; case 'M': { FILE *mapfile = fopen(optarg, "r"); if (!mapfile) { perror(optarg); return 1; } struct label nl; char type; char buf[1000] = ""; while(fgets(buf, sizeof(buf), mapfile)) { if (buf[0] == '#' || buf[0] == '\n') continue; char* tmp = strchr(buf, '#'); if (tmp) tmp = '\0'; char name[200]; int comps = sscanf(buf, "%c%llx%s%x", &type, &nl.val, name, &nl.size);; if (comps < 2) { fprintf(stderr, "Malformated input: %s\n", buf); continue; } switch (type) { case 'B': nl.type = 1; break; case 'C': nl.type = 2; break; case 'E': nl.type = 4; break; case 'S': nl.type = 0x20; break; case 'N': nl.type = 0x42; break; case 'D': nl.type = 0x10; break; default: fprintf (stderr, "Unknown label type %c\n", type); return 1; } if (comps < 4) nl.size = 0; if (comps >= 3) nl.name = strdup(name); else nl.name = 0; ADDARRAY(labels, nl); } break; } case 'u': { struct label nl; sscanf(optarg, "%llx", &nl.val); nl.type = 1; nl.name = 0; ADDARRAY(labels, nl); break; } } if (optind < argc) { if (!(infile = fopen(argv[optind], "r"))) { perror(argv[optind]); return 1; } optind++; if (optind < argc) { fprintf (stderr, "Too many parameters!\n"); return 1; } } if (!isa) { fprintf (stderr, "No architecture specified!\n"); return 1; } if (varname) { vartype = ed_getvariant(isa, varname); if (!vartype) { fprintf (stderr, "Unknown variant \"%s\"!\n", varname); return 1; } } int num = 0; int maxnum = 16; uint8_t *code = malloc (maxnum); ull t; if (bin) { int c; while ((c = getc(infile)) != EOF) { if (num + 3 >= maxnum) maxnum *= 2, code = realloc (code, maxnum); code[num++] = c; } } else { while (!feof(infile) && fscanf (infile, "%llx", &t) == 1) { if (num + 3 >= maxnum) maxnum *= 2, code = realloc (code, maxnum); if (w == 2) { code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; } else if (w) { code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; } else
int main(int argc, char **argv) { FILE *infile = stdin; const struct disisa *isa = 0; struct label *labels = 0; int labelsnum = 0; int labelsmax = 0; int w = 0, bin = 0, quiet = 0; const char **varnames = 0; int varnamesnum = 0; int varnamesmax = 0; const char **modenames = 0; int modenamesnum = 0; int modenamesmax = 0; const char **featnames = 0; int featnamesnum = 0; int featnamesmax = 0; const struct envy_colors *cols = &envy_def_colors; argv[0] = basename(argv[0]); int len = strlen(argv[0]); if (len > 3 && !strcmp(argv[0] + len - 3, "dis")) { argv[0][len-3] = 0; isa = ed_getisa(argv[0]); if (isa && isa->opunit == 4) w = 1; } int c; unsigned base = 0, skip = 0, limit = 0; while ((c = getopt (argc, argv, "b:d:l:m:V:O:F:wWinqu:M:")) != -1) switch (c) { case 'b': sscanf(optarg, "%x", &base); break; case 'd': sscanf(optarg, "%x", &skip); break; case 'l': sscanf(optarg, "%x", &limit); break; case 'w': w = 1; break; case 'W': w = 2; break; case 'i': bin = 1; break; case 'q': quiet = 1; break; case 'n': cols = &envy_null_colors; break; case 'm': isa = ed_getisa(optarg); if (!isa) { fprintf (stderr, "Unknown architecture \"%s\"!\n", optarg); return 1; } break; case 'V': ADDARRAY(varnames, optarg); break; case 'O': ADDARRAY(modenames, optarg); break; case 'F': ADDARRAY(featnames, optarg); break; case 'M': { FILE *mapfile = fopen(optarg, "r"); if (!mapfile) { perror(optarg); return 1; } struct label nl; char type; char buf[1000] = ""; while(fgets(buf, sizeof(buf), mapfile)) { if (buf[0] == '#' || buf[0] == '\n') continue; char* tmp = strchr(buf, '#'); if (tmp) tmp = '\0'; char name[200]; int comps = sscanf(buf, "%c%llx%s%x", &type, &nl.val, name, &nl.size);; if (comps < 2) { fprintf(stderr, "Malformated input: %s\n", buf); continue; } switch (type) { case 'B': nl.type = 1; break; case 'C': nl.type = 2; break; case 'E': nl.type = 4; break; case 'S': nl.type = 0x20; break; case 'N': nl.type = 0x42; break; case 'D': nl.type = 0x10; break; default: fprintf (stderr, "Unknown label type %c\n", type); return 1; } if (comps < 4) nl.size = 0; if (comps >= 3) nl.name = strdup(name); else nl.name = 0; ADDARRAY(labels, nl); } break; } case 'u': { struct label nl; sscanf(optarg, "%llx", &nl.val); nl.type = 1; nl.name = 0; ADDARRAY(labels, nl); break; } } if (optind < argc) { if (!(infile = fopen(argv[optind], "r"))) { perror(argv[optind]); return 1; } optind++; if (optind < argc) { fprintf (stderr, "Too many parameters!\n"); return 1; } } if (!isa) { fprintf (stderr, "No architecture specified!\n"); return 1; } struct varinfo *var = varinfo_new(isa->vardata); if (!var) return 1; int i; for (i = 0; i < varnamesnum; i++) if (varinfo_set_variant(var, varnames[i])) return 1; for (i = 0; i < featnamesnum; i++) if (varinfo_set_feature(var, featnames[i])) return 1; for (i = 0; i < modenamesnum; i++) if (varinfo_set_mode(var, modenames[i])) return 1; int num = 0; int maxnum = 16; uint8_t *code = malloc (maxnum); unsigned long long t; if (bin) { int c; while ((c = getc(infile)) != EOF) { if (num + 3 >= maxnum) maxnum *= 2, code = realloc (code, maxnum); code[num++] = c; } } else { while (!feof(infile) && fscanf (infile, "%llx", &t) == 1) { if (num + 3 >= maxnum) maxnum *= 2, code = realloc (code, maxnum); if (w == 2) { code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; } else if (w) { code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; t >>= 8; code[num++] = t & 0xff; } else
int nva_init() { int ret; ret = pci_system_init(); if (ret) return -1; int i; for (i = 0; i < ARRAY_SIZE(nv_match); i++) { struct pci_device_iterator* it = pci_id_match_iterator_create(&nv_match[i]); if (!it) { pci_system_cleanup(); return -1; } struct pci_device *dev; while ((dev = pci_device_next(it))) { struct nva_card c = { 0 }; ret = pci_device_probe(dev); if (ret) { fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func); continue; } c.pci = dev; ADDARRAY(nva_cards, c); } pci_iterator_destroy(it); } for (i = 0; i < nva_cardsnum; i++) { struct pci_device *dev; dev = nva_cards[i].pci; ret = pci_device_map_range(dev, dev->regions[0].base_addr, dev->regions[0].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar0); if (ret) { fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func); int j; for (j = i + 1; j < nva_cardsnum; j++) { nva_cards[j-1] = nva_cards[j]; } nva_cardsnum--; i--; continue; } nva_cards[i].bar0len = dev->regions[0].size; if (dev->regions[1].size) { nva_cards[i].hasbar1 = 1; nva_cards[i].bar1len = dev->regions[1].size; ret = pci_device_map_range(dev, dev->regions[1].base_addr, dev->regions[1].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar1); if (ret) { nva_cards[i].bar1 = 0; } } if (dev->regions[2].size) { nva_cards[i].hasbar2 = 1; nva_cards[i].bar2len = dev->regions[2].size; ret = pci_device_map_range(dev, dev->regions[2].base_addr, dev->regions[2].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar2); if (ret) { nva_cards[i].bar2 = 0; } } else if (dev->regions[3].size) { nva_cards[i].hasbar2 = 1; nva_cards[i].bar2len = dev->regions[3].size; ret = pci_device_map_range(dev, dev->regions[3].base_addr, dev->regions[3].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar2); if (ret) { nva_cards[i].bar2 = 0; } } uint32_t pmc_id = nva_rd32(i, 0); parse_pmc_id(pmc_id, &nva_cards[i].chipset); } return (nva_cardsnum == 0); }
int nva_init() { int ret; ret = pci_system_init(); if (ret) return -1; struct pci_id_match nv_match = {0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0x30000, 0xffff0000}; struct pci_device_iterator* it = pci_id_match_iterator_create(&nv_match); if (!it) { pci_system_cleanup(); return -1; } struct pci_device *dev; while (dev = pci_device_next(it)) { struct nva_card c = { 0 }; ret = pci_device_probe(dev); if (ret) { fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func); continue; } c.pci = dev; ADDARRAY(nva_cards, c); } pci_iterator_destroy(it); struct pci_id_match nv_sgs_match = {0x12d2, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0x30000, 0xffff0000}; it = pci_id_match_iterator_create(&nv_sgs_match); if (!it) { pci_system_cleanup(); return -1; } while (dev = pci_device_next(it)) { struct nva_card c = { 0 }; ret = pci_device_probe(dev); if (ret) { fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func); continue; } c.pci = dev; ADDARRAY(nva_cards, c); } pci_iterator_destroy(it); int i; for (i = 0; i < nva_cardsnum; i++) { dev = nva_cards[i].pci; ret = pci_device_map_range(dev, dev->regions[0].base_addr, dev->regions[0].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar0); if (ret) return -1; nva_cards[i].boot0 = nva_rd32(i, 0); nva_cards[i].chipset = nva_cards[i].boot0 >> 20 & 0xff; if (nva_cards[i].chipset < 0x10) { if (nva_cards[i].boot0 & 0xf000) { if (nva_cards[i].boot0 & 0xf00000) nva_cards[i].chipset = 5; else nva_cards[i].chipset = 4; } else { nva_cards[i].chipset = nva_cards[i].boot0 >> 16 & 0xf; if ((nva_cards[i].boot0 & 0xff) >= 0x20) nva_cards[i].is_nv03p = 1; } } if (nva_cards[i].chipset < 0x04) nva_cards[i].card_type = nva_cards[i].chipset; else if (nva_cards[i].chipset < 0x10) nva_cards[i].card_type = 0x04; else if (nva_cards[i].chipset < 0x20) nva_cards[i].card_type = 0x10; else if (nva_cards[i].chipset < 0x30) nva_cards[i].card_type = 0x20; else if (nva_cards[i].chipset < 0x40) nva_cards[i].card_type = 0x30; else if (nva_cards[i].chipset < 0x50 || nva_cards[i].chipset & 0xf0 == 0x60) nva_cards[i].card_type = 0x40; else if (nva_cards[i].chipset < 0xc0) nva_cards[i].card_type = 0x50; else nva_cards[i].card_type = 0xc0; } return 0; }
int vs_byte(struct bitstream *str) { if (str->dir == VS_ENCODE) { switch (str->type) { case VS_H262: if (str->curbyte < 2 && str->zero_bytes >= 2) { fprintf(stderr, "00 00 0%d emitted!\n", str->curbyte); return 1; } break; case VS_H264: if (str->curbyte < 4 && str->zero_bytes == 2) { /* escape */ ADDARRAY(str->bytes, 3); str->zero_bytes = 0; } break; case VS_H261: case VS_H263: /* start codes not byte-oriented in these */ break; default: abort(); } ADDARRAY(str->bytes, str->curbyte); if (!str->curbyte) str->zero_bytes++; else str->zero_bytes = 0; str->curbyte = 0; } else { if (str->bytepos >= str->bytesnum) { fprintf(stderr, "End of bitstream in a NAL!\n"); return 1; } str->curbyte = str->bytes[str->bytepos++]; switch (str->type) { case VS_H262: if (str->curbyte < 2 && str->zero_bytes >= 2) { fprintf(stderr, "00 00 0%d read in a NAL!\n", str->curbyte); return 1; } break; case VS_H264: if (str->zero_bytes == 2) { switch (str->curbyte) { case 0: case 1: case 2: fprintf(stderr, "00 00 0%d read in a NAL!\n", str->curbyte); return 1; case 3: if (str->bytepos >= str->bytesnum) { fprintf(stderr, "End of bitstream in a NAL!\n"); return 1; } str->zero_bytes = 0; str->curbyte = str->bytes[str->bytepos++]; if (str->curbyte > 3) { fprintf(stderr, "Invalid escape sequence: 00 00 03 %02x!\n", str->curbyte); return 1; } break; } } break; case VS_H261: case VS_H263: /* start codes not byte-oriented in these */ break; default: abort(); } if (!str->curbyte) str->zero_bytes++; else str->zero_bytes = 0; str->hasbyte = 1; } str->bitpos = 7; return 0; }
static void prepvarinfo (struct rnndb *db, char *what, struct rnnvarinfo *vi, struct rnnvarinfo *parent) { if (parent) vi->prefenum = parent->prefenum; if (vi->prefixstr) { if (!strcmp(vi->prefixstr, "none")) vi->prefenum = 0; else vi->prefenum = rnn_findenum(db, vi->prefixstr); // XXX } int i; if (parent) for (i = 0; i < parent->varsetsnum; i++) ADDARRAY(vi->varsets, copyvarset(parent->varsets[i])); struct rnnenum *varset = vi->prefenum; if (!varset && !vi->varsetstr && parent) vi->varsetstr = parent->varsetstr; if (vi->varsetstr) varset = rnn_findenum(db, vi->varsetstr); if (vi->variantsstr) { char *vars = vi->variantsstr; if (!varset) { fprintf (stderr, "%s: tried to use variants without active varset!\n", what); db->estatus = 1; return; } struct rnnvarset *vs = 0; int nvars = varset->valsnum; for (i = 0; i < vi->varsetsnum; i++) if (vi->varsets[i]->venum == varset) { vs = vi->varsets[i]; break; } if (!vs) { vs = calloc (sizeof *vs, 1); vs->venum = varset; vs->variants = calloc(sizeof *vs->variants, nvars); for (i = 0; i < nvars; i++) vs->variants[i] = 1; ADDARRAY(vi->varsets, vs); } while (1) { while (*vars == ' ') vars++; if (*vars == 0) break; char *split = vars; while (*split != ':' && *split != '-' && *split != ' ' && *split != 0) split++; char *first = 0; if (split != vars) first = strndup(vars, split-vars); if (*split == ' ' || *split == 0) { int idx = findvidx(db, varset, first); if (idx != -1) vs->variants[idx] |= 2; vars = split; } else { char *end = split+1; while (*end != ' ' && *end != 0) end++; char *second = 0; if (end != split+1) second = strndup(split+1, end-split-1); int idx1 = 0; if (first) idx1 = findvidx(db, varset, first); int idx2 = nvars; if (second) { idx2 = findvidx(db, varset, second); if (*split == '-') idx2++; } if (idx1 != -1 && idx2 != -1) for (i = idx1; i < idx2; i++) vs->variants[i] |= 2; vars = end; free(second); } free(first); } vi->dead = 1; for (i = 0; i < nvars; i++) { vs->variants[i] = (vs->variants[i] == 3); if (vs->variants[i]) vi->dead = 0; } } if (vi->dead) return; if (vi->prefenum) { struct rnnvarset *vs = 0; for (i = 0; i < vi->varsetsnum; i++) if (vi->varsets[i]->venum == vi->prefenum) { vs = vi->varsets[i]; break; } if (vs) { for (i = 0; i < vi->prefenum->valsnum; i++) if (vs->variants[i]) { vi->prefix = vi->prefenum->vals[i]->name; return; } } else { vi->prefix = vi->prefenum->vals[0]->name; } } }
int main() { uint8_t *bytes = 0; int bytesnum = 0; int bytesmax = 0; int c; int res; while ((c = getchar()) != EOF) { ADDARRAY(bytes, c); } struct bitstream *str = vs_new_decode(VS_H262, bytes, bytesnum); struct h262_seqparm *seqparm = calloc(sizeof *seqparm, 1); struct h262_picparm *picparm = calloc(sizeof *picparm, 1); struct h262_gop *gop = calloc(sizeof *gop, 1); struct h262_slice *slice; while (1) { uint32_t start_code; uint32_t ext_start_code; if (vs_start(str, &start_code)) goto err; printf("Start code: %02x\n", start_code); switch (start_code) { case H262_START_CODE_SEQPARM: if (h262_seqparm(str, seqparm)) goto err; if (vs_end(str)) goto err; h262_print_seqparm(seqparm); break; case H262_START_CODE_PICPARM: if (h262_picparm(str, seqparm, picparm)) goto err; if (vs_end(str)) goto err; h262_print_picparm(picparm); break; case H262_START_CODE_GOP: if (h262_gop(str, gop)) goto err; if (vs_end(str)) goto err; h262_print_gop(gop); break; case H262_START_CODE_EXTENSION: if (vs_u(str, &ext_start_code, 4)) goto err; printf("Extension start code: %d\n", ext_start_code); switch (ext_start_code) { case H262_EXT_SEQUENCE: if (h262_seqparm_ext(str, seqparm)) goto err; if (vs_end(str)) goto err; h262_print_seqparm(seqparm); break; case H262_EXT_PIC_CODING: if (h262_picparm_ext(str, seqparm, picparm)) goto err; if (vs_end(str)) goto err; h262_print_picparm(picparm); break; default: fprintf(stderr, "Unknown extension start code\n"); goto err; } break; case H262_START_CODE_END: printf ("End of sequence.\n"); break; default: if (start_code >= H262_START_CODE_SLICE_BASE && start_code <= H262_START_CODE_SLICE_LAST) { slice = calloc (sizeof *slice, 1); slice->mbs = calloc (sizeof *slice->mbs, picparm->pic_size_in_mbs); slice->slice_vertical_position = start_code - H262_START_CODE_SLICE_BASE; if (seqparm->vertical_size > 2800) { uint32_t svp_ext; if (vs_u(str, &svp_ext, 3)) { h262_del_slice(slice); goto err; } if (slice->slice_vertical_position >= 0x80) { fprintf(stderr, "Invalid slice start code for large picture\n"); goto err; } slice->slice_vertical_position += svp_ext * 0x80; } if (slice->slice_vertical_position >= picparm->pic_height_in_mbs) { fprintf(stderr, "slice_vertical_position too large\n"); goto err; } if (h262_slice(str, seqparm, picparm, slice)) { h262_print_slice(seqparm, picparm, slice); h262_del_slice(slice); goto err; } h262_print_slice(seqparm, picparm, slice); if (vs_end(str)) { h262_del_slice(slice); goto err; } h262_del_slice(slice); break; } else { fprintf(stderr, "Unknown start code\n"); goto err; } } printf("NAL decoded successfully\n\n"); continue; err: res = vs_search_start(str); if (res == -1) return 1; if (!res) break; printf("\n"); } return 0; }
static void preptypeinfo(struct rnndb *db, struct rnntypeinfo *ti, char *prefix, struct rnnvarinfo *vi, int width, char *file) { int i; if (ti->name) { struct rnnenum *en = rnn_findenum (db, ti->name); struct rnnbitset *bs = rnn_findbitset (db, ti->name); struct rnnspectype *st = rnn_findspectype (db, ti->name); if (en) { if (en->isinline) { ti->type = RNN_TTYPE_INLINE_ENUM; int j; for (j = 0; j < en->valsnum; j++) ADDARRAY(ti->vals, copyvalue(en->vals[j], file)); } else { ti->type = RNN_TTYPE_ENUM; ti->eenum = en; } } else if (bs) { if (bs->isinline) { ti->type = RNN_TTYPE_INLINE_BITSET; int j; for (j = 0; j < bs->bitfieldsnum; j++) ADDARRAY(ti->bitfields, copybitfield(bs->bitfields[j], file)); } else { ti->type = RNN_TTYPE_BITSET; ti->ebitset = bs; } } else if (st) { ti->type = RNN_TTYPE_SPECTYPE; ti->spectype = st; } else if (!strcmp(ti->name, "hex")) { ti->type = RNN_TTYPE_HEX; } else if (!strcmp(ti->name, "float")) { ti->type = RNN_TTYPE_FLOAT; } else if (!strcmp(ti->name, "uint")) { ti->type = RNN_TTYPE_UINT; } else if (!strcmp(ti->name, "int")) { ti->type = RNN_TTYPE_INT; } else if (!strcmp(ti->name, "boolean")) { ti->type = RNN_TTYPE_BOOLEAN; } else if (!strcmp(ti->name, "bitfield")) { ti->type = RNN_TTYPE_INLINE_BITSET; } else if (!strcmp(ti->name, "enum")) { ti->type = RNN_TTYPE_INLINE_ENUM; } else if (!strcmp(ti->name, "fixed")) { ti->type = RNN_TTYPE_FIXED; } else if (!strcmp(ti->name, "ufixed")) { ti->type = RNN_TTYPE_UFIXED; } else { ti->type = RNN_TTYPE_HEX; fprintf (stderr, "%s: unknown type %s\n", prefix, ti->name); db->estatus = 1; } } else if (ti->bitfieldsnum) { ti->name = "bitfield"; ti->type = RNN_TTYPE_INLINE_BITSET; } else if (ti->valsnum) { ti->name = "enum"; ti->type = RNN_TTYPE_INLINE_ENUM; } else if (width == 1) { ti->name = "boolean"; ti->type = RNN_TTYPE_BOOLEAN; } else { ti->name = "hex"; ti->type = RNN_TTYPE_HEX; } for (i = 0; i < ti->bitfieldsnum; i++) prepbitfield(db, ti->bitfields[i], prefix, vi); for (i = 0; i < ti->valsnum; i++) prepvalue(db, ti->vals[i], prefix, vi); }
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; } }
int main(int argc, char **argv) { struct rnndb *db; int i, j; if (argc < 2) { fprintf(stderr, "Usage:\n\theadergen database-file\n"); exit(1); } rnn_init(); db = rnn_newdb(); rnn_parsefile (db, argv[1]); rnn_prepdb (db); for(i = 0; i < db->filesnum; ++i) { char *dstname = malloc(strlen(db->files[i]) + 3); char *pretty; strcpy(dstname, db->files[i]); strcat(dstname, ".h"); struct fout f = { db->files[i], fopen(dstname, "w") }; if (!f.file) { perror(dstname); exit(1); } free(dstname); pretty = strrchr(f.name, '/'); if (pretty) pretty += 1; else pretty = f.name; f.guard = strdup(pretty); for (j = 0; j < strlen(f.guard); j++) if (isalnum(f.guard[j])) f.guard[j] = toupper(f.guard[j]); else f.guard[j] = '_'; ADDARRAY(fouts, f); printhead(f, db); } for (i = 0; i < db->enumsnum; i++) { if (db->enums[i]->isinline) continue; int j; for (j = 0; j < db->enums[i]->valsnum; j++) printvalue (db->enums[i]->vals[j], 0); } for (i = 0; i < db->bitsetsnum; i++) { if (db->bitsets[i]->isinline) continue; int j; for (j = 0; j < db->bitsets[i]->bitfieldsnum; j++) printbitfield (db->bitsets[i]->bitfields[j], 0); } for (i = 0; i < db->domainsnum; i++) { if (db->domains[i]->size) printdef (db->domains[i]->fullname, "SIZE", 0, db->domains[i]->size, db->domains[i]->file); int j; for (j = 0; j < db->domains[i]->subelemsnum; j++) { printdelem(db->domains[i]->subelems[j], 0); } } for(i = 0; i < foutsnum; ++i) { fprintf (fouts[i].file, "\n#endif /* %s */\n", fouts[i].guard); } return db->estatus; }
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; } }