📄 util.c
字号:
if(l->values[d]) { if(l->values[d]->t >= BLOCK) { check_types(l->values[d]->v.b); } } } } } } return 0;}void load_block(struct lp_block *b) { int n; lp_lookup_type(b->name, &n); lp_typetbl[n]->spec = b;}void load_topo(struct lp_topospec *t, int len) {/* unparse_topospec(t, outputfile); */ topoloader(t, len);}void printvars(void) { int c, d; for(c = 0; c < lp_max_mod; c++) { for(d = 0; d < lp_modules[c]->modvars_len; d++) { printf("%s::%s\n", lp_modules[c]->name, lp_modules[c]->modvars[d].name); } }}void dummy (struct lp_block *b) { fprintf(stderr, "*** error: %s cannot be declared at top-level.\n", b->name); exit(1);}struct lp_list *lp_list_add(struct lp_list *l, struct lp_value *v){ int c, newlen; for(c = 0; c < l->values_len; c++) { if(!l->values[c]) goto done; } newlen = 2 * c * sizeof(struct lp_value *); l->values = realloc(l->values, newlen); bzero(l->values + c, newlen / 2); l->values_len *= 2; done: l->values[c] = v; return l;}/* maps a modtype and parameter name to a nonnegative numeric * representation. -1 returned on error */int lp_param_name(int m, char *n){ int c = 0; if(!RANGE(m,0,lp_max_mod)) return -1; if(!n) return -1; while((c < lp_modules[m]->modvars_len) && strcmp(lp_modules[m]->modvars[c].name, n)) c++; if(c >= lp_modules[m]->modvars_len) { return -1; } else { return c; }}int lp_mod_name(char *n) { int c = 0; if(!n) return -1; while((c < lp_max_mod) && strcmp(lp_modules[c]->name, n)) c++; if(c >= lp_max_mod) { return -1; } else { return c; }}/* get the base type of name */char *lp_lookup_base_type(char *name, int *n) { int c; for(c = 0; c < lp_typetbl_len; c++) { if(lp_typetbl[c]) { if(!strcmp(name, lp_typetbl[c]->sub)) { if(lp_typetbl[c]->super) { return lp_lookup_base_type(lp_typetbl[c]->super, n); } else { break; } } } } if(n) *n = c; return name;}char *lp_lookup_type(char *name, int *n) { int c; for(c = 0; c < lp_typetbl_len; c++) { if(lp_typetbl[c]) { if(!strcmp(name, lp_typetbl[c]->sub)) { if(n) *n = c; return lp_typetbl[c]->super; } } } return 0;}/* find the specification for name or return 0 if it doesn't exist */struct lp_block *lp_lookup_spec(char *name) { int c; if(!name) return 0; for(c = 0; c < lp_typetbl_len; c++) if(lp_typetbl[c]) if(!strcmp(name, lp_typetbl[c]->sub)) return lp_typetbl[c]->spec; return 0;}struct lp_tlt *lp_new_tl_topo(struct lp_topospec *t, char *source_file){ struct lp_tlt *result = malloc(sizeof(struct lp_tlt)); result->source_file = source_file; result->what = TLT_TOPO; result->it.topo = t; lp_add_tlt(result); return result;}struct lp_tlt *lp_new_tl_inst(struct lp_inst *i, char *source_file){ struct lp_tlt *result = malloc(sizeof(struct lp_tlt)); result->source_file = source_file; result->what = TLT_INST; result->it.inst = i; lp_add_tlt(result); return result;}struct lp_tlt *lp_new_tl_block(struct lp_block *b, char *source_file){ struct lp_tlt *result = malloc(sizeof(struct lp_tlt)); result->source_file = source_file; result->what = TLT_BLOCK; result->it.block = b; lp_add_tlt(result); return result;}void lp_add_tlt(struct lp_tlt *tlt) { int c; int found = 0; for(c = 0; c < lp_tlts_len; c++) { if(!lp_tlts[c]) { found = c; break; } } if(!found) { int newlen = lp_tlts_len ? 2 * lp_tlts_len : 2; int zerocnt = lp_tlts_len ? lp_tlts_len : 2; int newsize = newlen * sizeof(struct lp_tlts *); zerocnt *= sizeof(struct lp_tlts *); lp_tlts = realloc(lp_tlts, newsize); memset(lp_tlts + lp_tlts_len, 0, zerocnt); found = lp_tlts_len; lp_tlts_len = newlen; } lp_tlts[c] = tlt;}int lp_add_type(char *newt, char *parent) { int c; struct lp_subtype *st = malloc(sizeof(struct lp_subtype)); st->super = strdup(parent); st->sub = strdup(newt); if(!lp_lookup_type(newt,0)) { for(c = 0; c < lp_typetbl_len; c++) if(!lp_typetbl[c]) { goto done; } lp_typetbl = realloc(lp_typetbl, 2 * lp_typetbl_len * sizeof(int *)); bzero(lp_typetbl + c, c * sizeof(int *)); lp_typetbl_len *= 2; } else return -1; done: lp_typetbl[c] = st; return 0;}int lp_add_param(struct lp_param ***b, int *plen, struct lp_param *p){ int c; /* look for dupe params */ for(c = 0; c < *plen; c++) { if(!(*b)[c]) continue; if(!strcmp((*b)[c]->name, p->name)) { fprintf(stderr, "*** error: redefined %s\n", p->name); return -1; } } for(c = 0; c < *plen; c++) { if(!(*b)[c]) { (*b)[c] = p; break; } } if(c == *plen) { /* didn't find a free slot -- double the array */ int newlen = 2 * (*plen) + 1; (*b) = realloc((*b), newlen * sizeof(int *)); bzero((int *)(*b) + *plen, ((*plen) + 1) * sizeof(int*)); (*b)[(*plen)] = p; *plen = newlen; } return 0;}/* copy all of the params in parent not defined in child into * child */int lp_setup_subtype(struct lp_block *parent, struct lp_block *child){ int c, d; for(c = 0; c < parent->params_len; c++) { for(d = 0; d < child->params_len; c++) { if(!strcmp(child->params[d]->name, parent->params[c]->name)) goto next; } lp_add_param(&child->params, &child->params_len, parent->params[c]); next: } return 0;}void lp_init_typetbl(void) { int c; lp_typetbl = malloc(lp_max_mod * sizeof(struct subtype *)); bzero(lp_typetbl, lp_max_mod * sizeof(struct subtype *)); for(c = 0; c < lp_max_mod; c++) { lp_typetbl[c] = malloc(sizeof(struct lp_subtype)); bzero(lp_typetbl[c], sizeof(struct lp_subtype)); lp_typetbl[c]->sub = strdup(lp_modules[c]->name); } lp_typetbl_len = lp_max_mod;}void lp_release_typetbl(void) { int c; for(c = 0; c < lp_typetbl_len; c++) { if(!lp_typetbl[c]) continue; if(lp_typetbl[c]->spec) destroy_block(lp_typetbl[c]->spec); if(lp_typetbl[c]->sub) free(lp_typetbl[c]->sub); if(lp_typetbl[c]->super) free(lp_typetbl[c]->super); free(lp_typetbl[c]); } free(lp_typetbl);}/* splits s into a trailing number (i) and the leading part */int dumb_split(char *s, char **t, int *i) { int c = strlen(s) - 1; while(c && isdigit(s[c])) c--; if(!c) return -1; c++; (*i) = atoi(&s[c]); *t = strdup(s); (*t)[c] = 0; return 0;}/* separate foo:bar into foo and bar */int dumb_split2(char *s, char **s1, char **s2) { int c = 0; (*s1) = strdup(s); while(s[c] && (s[c] != ':')) c++; (*s1)[c] = 0; if(s[c]) (*s2) = strdup(s + c + 1); else return -1; return 0;}static int param_override(struct lp_block *b, char *pname, char *pval) { int c; for(c = 0; c < b->params_len; c++) { if(!b->params[c]) continue; if(!strcmp(b->params[c]->name, pname)) { switch(b->params[c]->v->t) { case I: b->params[c]->v->v.i = atoi(pval); break; case D: b->params[c]->v->v.d = atof(pval); break; case S: free(b->params[c]->v->v.s); b->params[c]->v->v.s = strdup(pval); return 0; break; default: ddbg_assert(0); } return -1; } } return -1;} int range_match(char *range, char *name) { char *base1, *base2, *base3; char r1[128], r2[128]; int i1, i2, i3; if(!strcmp(range, name)) { return 1; } if(!strcmp(range, "*")) return 1; if(sscanf(range, "%s .. %s", r1, r2) != 2) { char *prefix; int junk; dumb_split(name, &prefix, &junk); /* i.e. driver* matches driver2 and driver and driver2344 but not * driverqux */ if((strlen(range) == ( strlen(prefix) + 1)) && !strncmp(range,prefix,strlen(prefix)) && (range[strlen(prefix)] == '*')) return 1; return 0; } dumb_split(r1, &base1, &i1); dumb_split(r2, &base2, &i2); if(strcmp(base1, base2) || (i1 < 0) || (i2 < i1)) { fprintf(stderr, "*** error: bad range \"%s .. %s\"\n", r1, r2); return 0; } dumb_split(name, &base3, &i3); if(!strcmp(base3, base2) && (i3 >= i1) && (i3 <= i2)) { return 1; } else { return 0; }}/* instantiate a component with overrides * tname type to instantiate, * cname name of instantiated component * loader is the module loader function for tname */int *lp_override_inst(struct lp_block *spec, char *cname, lp_modloader_t loader, char **overrides, int overrides_len){ int c, d; struct lp_block *spec_copy; char *p1, *p2; int *result; spec_copy = copy_block(spec); for(c = 0; c < overrides_len; c += 3) { if(range_match(overrides[c], cname)) { /* overrides[c+2] could be an int, a real, a string or a list or * a block. need parser to deal with lists and blocks * reasonably so we aren't going to deal with them here */ if(!dumb_split2(overrides[c+1], &p1, &p2)) { /* descend hierarchy */ for(d = 0; d < spec_copy->params_len; d++) { if(!spec_copy->params[d]) continue; if(!strcmp(p1, spec_copy->params[d]->name)) { if(spec_copy->params[d]->v->t != BLOCK) { fprintf(stderr, "*** error: tried to recurse through non-block parameter.\n"); return 0; } else { param_override(spec_copy->params[d]->v->v.b, p2, overrides[c+2]); } } } } else { param_override(spec_copy, overrides[c+1], overrides[c+2]); } } } if(!check_types(spec_copy)) { result = loader(spec_copy, 0); } destroy_block(spec_copy); return result; }extern void libparamparse(void);int lp_loadfile(FILE *in, struct lp_tlt ***tlts, int *tlts_len, char *infile, char **cli_overrides, int cli_overrides_len) { top_file = 0; lp_lineno = 1; lp_filename = infile; libparamin = in; overrides = cli_overrides; overrides_len = cli_overrides_len; // this creates a fresh array every time its run so caller // is responsible for freeing it lp_tlts = 0; lp_tlts_len = 0; libparamparse(); if(tlts) { *tlts = lp_tlts; } if(tlts_len) { *tlts_len = lp_tlts_len; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -