⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 2 页
字号:
	  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 + -