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

📄 util.c

📁 disksim是一个非常优秀的磁盘仿真工具
💻 C
📖 第 1 页 / 共 2 页
字号:
  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_pop++;  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. * New "wildcard" behavior: if name is null, return the first * spec in the typetbl with non-zero parent -- i.e. only  * match a user-provided spec, not a builtin type! */struct lp_block *lp_lookup_spec(char *name) {  int c;  for(c = 0; c < lp_typetbl_len; c++)     if(lp_typetbl[c]) {      if(!name) {	if(lp_typetbl[c]->super) {	  return lp_typetbl[c]->spec;	}      }      else 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 = calloc(1, sizeof(*result));  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 = calloc(1, sizeof(*result));  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 = calloc(1, sizeof(*result));  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;  int newlen;  struct lp_subtype *st = calloc(1, sizeof(*st));  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;      }    newlen = lp_typetbl_len ? 2 * lp_typetbl_len : 2;    lp_typetbl = realloc(lp_typetbl, newlen * sizeof(int *));    bzero(lp_typetbl + c, c * sizeof(int *));    lp_typetbl_len = newlen;  }  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++) {    int found = 0;    for(d = 0; d < child->params_len; d++) {      if(!strcmp(child->params[d]->name, parent->params[c]->name)) {	found = 1;      }    }    if(!found) {      lp_add_param(&child->params, &child->params_len, parent->params[c]);    }  }  return 0;}void lp_init_typetbl(void) {  int c;  lp_typetbl = calloc(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);  }  // XXX don't leak (segfaults)  //  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) {  char *lp_sp;  char *dirc;  char *dir;    int stdout_save;  int devnull;  top_file = 0;  lp_lineno = 1;  dirc = strdup(infile);  dir = dirname(dirc);  lp_filename = infile;  lp_cwd = dir;  libparamin = in;  overrides = cli_overrides;  overrides_len = cli_overrides_len;  // do the searchpath  lp_sp = getenv("LP_PATH");  if(lp_sp) {    char *p = lp_sp;    char *colon;        lp_searchpath = calloc(LP_MAX_SP, sizeof(char*));    while(*p) {      colon = strchr(p, ':');      if(colon) {	char *next;  	*colon = 0;	next = colon+1;	lp_searchpath[lp_searchpath_len++] = strdup(p);  	p = next;      }      else {	lp_searchpath[lp_searchpath_len++] = strdup(p);	break;      }    }  }  // this creates a fresh array every time its run so caller   // is responsible for freeing it  lp_tlts = 0;  lp_tlts_len = 0;    fflush(stdout);  stdout_save = dup(1);  devnull = open("/dev/null", O_RDONLY);  dup2(devnull, 1);  libparamparse();  fflush(stdout);  dup2(stdout_save, 1);  close(devnull);  close(stdout_save);  if(tlts) {    *tlts = lp_tlts;  }  if(tlts_len) {    *tlts_len = lp_tlts_len;  }  return 0;}#define LP_STACK_MAX 32intlp_loadparams(void *it, struct lp_block *b, struct lp_mod *m) {  int c;  int needed = 0;  int param_stack[LP_STACK_MAX];  int stack_ptr = 0;  // index of first free slot  // XXX not static size  char *paramvec = calloc(m->modvars_len, sizeof(char));  // This is pretty gross; there should be a better solution.  // dirname() munges its operand.  Its result may also be a static  // buffer somewhere, hence the 2 copies.  char *tmp = strdup(b->source_file);  lp_cwd = strdup(dirname(tmp));  //  free(tmp);   for(c = 0; c < b->params_len; c++) {    int pnum, deps;        if(!b->params[c]) continue;      TOP:    pnum = lp_param_name(lp_mod_name(m->name), b->params[c]->name);        // Don't initialize things more than once.    // Should warn here, probably.    if(BIT_TEST(paramvec, pnum)) continue;            if(stack_ptr > 0) {      for(c = 0; c < b->params_len; c++) {	if(lp_param_name(lp_mod_name(m->name), b->params[c]->name) == needed)	  goto FOUND;      }      break;    }  FOUND:      deps = m->param_deps[pnum](paramvec);    if(deps > -1) {      ddbg_assert(stack_ptr < LP_STACK_MAX);      param_stack[stack_ptr++] = c;      needed = deps;      continue;    }    else {      switch(PTYPE(b->params[c])) {      case I:     	((lp_paramloader_int)m->param_loaders[pnum])(it, IVAL(b->params[c])); 	break;       case D:     	((lp_paramloader_double)m->param_loaders[pnum])(it, DVAL(b->params[c])); 	break;       case S:     	((lp_paramloader_string)m->param_loaders[pnum])(it, SVAL(b->params[c])); 	break;       case LIST:  	((lp_paramloader_list)m->param_loaders[pnum])(it, LVAL(b->params[c])); 	 break; 	       case BLOCK:      default:    	((lp_paramloader_block)m->param_loaders[pnum])(it, BVAL(b->params[c])); 	break;       }    }    BIT_SET(paramvec, pnum);    if(stack_ptr > 0) {       c = param_stack[--stack_ptr];       goto TOP;      }  }  for(c = 0; c < m->modvars_len; c++) {    if(m->modvars[c].req && !BIT_TEST(paramvec,c)) {      fprintf(stderr, "*** error: in %s spec -- missing required parameter %s\n", m->name, m->modvars[c].name);      break;    }  }  free(paramvec);  return 0; // ???}char *lp_search_path(char *cwd, char *name){  char *cand = calloc(LP_PATH_MAX, sizeof(char));  struct stat s;  int i;    if(name[0] == '/')    if(stat(name, &s))      goto fail;  snprintf(cand, LP_PATH_MAX, "%s/%s", cwd, name);  if(!stat(cand, &s))    goto succ;      for(i = 0; i < lp_searchpath_len; i++) {    snprintf(cand, LP_PATH_MAX, 	     "%s/%s", lp_searchpath[i], name);    if(!stat(cand, &s)) {      goto succ;    }  } fail:  free(cand);  return 0; succ:  return cand;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -