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

📄 util.c

📁 目前最精确的磁盘模拟器的第3版
💻 C
📖 第 1 页 / 共 2 页
字号:
/* libparam (version 1.0) * Authors: John Bucy, Greg Ganger * Contributors: John Griffin, Jiri Schindler, Steve Schlosser * * Copyright (c) of Carnegie Mellon University, 2001, 2002, 2003. * * This software is being provided by the copyright holders under the * following license. By obtaining, using and/or copying this * software, you agree that you have read, understood, and will comply * with the following terms and conditions: * * Permission to reproduce, use, and prepare derivative works of this * software is granted provided the copyright and "No Warranty" * statements are included with all reproductions and derivative works * and associated documentation. This software may also be * redistributed without charge provided that the copyright and "No * Warranty" statements are included in all redistributions. * * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS. * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH * RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT * INFRINGEMENT.  COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY USE * OF THIS SOFTWARE OR DOCUMENTATION.   */#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <libddbg/libddbg.h>#include "libparam.h"#include "bitvector.h"static lp_topoloader_t topoloader = 0;void lp_register_topoloader(lp_topoloader_t l) {  topoloader = l;}int *lp_instantiate(char *targ, char *name);char *lp_builtin_names[] = {  0,  "Block",  "String",  "Int",  "Double",  "List",   "Topospec"};// FILE *libparamin = 0;char *lp_filename = 0;extern int lp_lineno;static void destroy_block(struct lp_block *b);static void destroy_value(struct lp_value *v);static void destroy_param(struct lp_param *p);static void destroy_list(struct lp_list *l);static void destroy_topospec(struct lp_topospec *t);int dumb_split(char *s, char **t, int *i);int dumb_split2(char *s, char **s1, char **s2);static int lp_max_mod = 0;static int lp_mod_size = 0;struct lp_mod **lp_modules = 0;static char **overrides = 0;static int overrides_len = 0;#define outputfile stdoutint lp_register_module(struct lp_mod *m) {  int c;  for(c = 0; c < lp_max_mod; c++) {    if(!strcmp(m->name, lp_modules[c]->name)) {      return -1;    }  }  if(c >= lp_mod_size) {    lp_mod_size *= 2; lp_mod_size++;    lp_modules = realloc(lp_modules, lp_mod_size * sizeof(int *));  }  if(c > 0)     lp_modules[c] = m;  else     lp_modules[0] = m;  lp_max_mod++;  return c;}static void die(char *msg) {  fprintf(stderr, "*** error: FATAL: %s\n", msg);  exit(1);}static void destroy_param(struct lp_param *p){  free(p->name);  destroy_value(p->v);  free(p);}static void destroy_list(struct lp_list *l) {  int c;  for(c = 0; c < l->values_len; c++)    if(l->values[c])      destroy_value(l->values[c]);  free(l->values);  free(l);}static void destroy_value(struct lp_value *v) {  int d;  switch(v->t) {  case S:    free(v->v.s);     break;      case LIST:    destroy_list(v->v.l);    break;      case I:   case D: break;  case TOPOSPEC:    for(d = 0; d < v->v.t.len; d++)      destroy_topospec(&v->v.t.l[d]);    free(v->v.t.l);    break;        default:    destroy_block(v->v.b);  }  free(v);}static void destroy_block(struct lp_block *b) {  int c;  for(c = 0; c < b->params_len; c++) {    if(b->params[c]) {      destroy_param(b->params[c]);    }   }  free(b->name);  free(b->params);  free(b);}static void destroy_topospec(struct lp_topospec *t){  free(t->type);  free(t->name);  destroy_list(t->l);}static struct lp_block *copy_block(struct lp_block *);static struct lp_list *copy_list(struct lp_list *);static struct lp_value *copy_value(struct lp_value *);static struct lp_param *copy_param(struct lp_param *);static struct lp_block *copy_block(struct lp_block *b){  int c;  struct lp_block *result = malloc(sizeof(struct lp_block));  memcpy(result, b, sizeof(struct lp_block));  result->params = malloc(b->params_len * sizeof(int *));  bzero(result->params, b->params_len * sizeof(int *));  if(b->name)    result->name = strdup(b->name);  for(c = 0; c < b->params_len; c++) {    if(b->params[c])      result->params[c] = copy_param(b->params[c]);  }  return result;}static struct lp_list *copy_list(struct lp_list *l) {  int c;  struct lp_list *result = malloc(sizeof(struct lp_list));  memcpy(result, l, sizeof(struct lp_list));  result->values = malloc(l->values_len * sizeof(int *));  memcpy(result->values, l->values, l->values_len * sizeof(int *));  for(c = 0; c < l->values_len; c++) {    if(l->values[c]) {      result->values[c] = copy_value(l->values[c]);    }  }  return result;}static struct lp_value *copy_value(struct lp_value *v) {  struct lp_value *result = malloc(sizeof(struct lp_value));  memcpy(result, v, sizeof(struct lp_value));  switch(v->t) {  case S:    result->v.s = strdup(v->v.s);    break;  case LIST:    result->v.l = copy_list(v->v.l);    break;  case BLOCK:    result->v.b = copy_block(v->v.b);    break;  default:  }    return result;}static struct lp_param *copy_param(struct lp_param *p) {  struct lp_param *result = malloc(sizeof(struct lp_param));  result->name = strdup(p->name);  result->v = copy_value(p->v);  return result;}static int indent_level = 0;static void indent(FILE *f) {  char *space = malloc(3*indent_level+1);  memset(space, (int)' ', 3*indent_level);  space[3*indent_level] = 0;  fprintf(f, "%s", space);  free(space);}void unparse_source(char *source, FILE *outfile) {  fprintf(outfile, "source %s\n\n", source);}void unparse_type(int t, FILE *outfile) {  indent(outfile);  if(t < 0) {    fprintf(outfile, "%s", lp_builtin_names[abs(t)]);  }  else {    if(t > lp_max_mod) {      fprintf(outfile, "<UNKNOWN TYPE>");    }    else {      fprintf(outfile, "%s", lp_modules[t]->name);    }  }}void unparse_param(struct lp_param *p, FILE *outfile) {  indent(outfile);  fprintf(outfile, "%s = ", p->name);  if(p->source_file && p->v->source_file) {    if(strcmp(p->source_file, p->v->source_file)) {      unparse_source(p->v->source_file, outfile);      return;    }  }  unparse_value(p->v, outfile);}void unparse_value(struct lp_value *v, FILE *outfile) {  int c;  switch(v->t) {  case I:    fprintf(outfile, "%d", v->v.i);    break;  case D:    fprintf(outfile, "%f", v->v.d);    break;  case S:    fprintf(outfile, "%s", v->v.s);    break;  case LIST:    unparse_list(v->v.l, outfile);    break;  case TOPOSPEC:    for(c = 0; c < v->v.t.len; c++)      unparse_topospec(&v->v.t.l[c], outfile);    break;  default:  case BLOCK:    unparse_block(v->v.b, outfile);    break;  }}void unparse_list(struct lp_list *l, FILE *outfile) {  int printed = 0;  int c;/*    indent(outfile); */  fprintf(outfile, "[");  indent_level++;  for(c = 0; c < l->values_len; c++) {     if(!l->values[c])       continue;    if(c) fprintf(outfile, ",\n"); else fprintf(outfile, "\n");    indent(outfile);    printed++;    unparse_value(l->values[c], outfile);  }  indent_level--;  if((c > 0) && printed) {    fprintf(outfile, "\n");    indent(outfile);  }  fprintf(outfile, "]");}void unparse_block(struct lp_block *b, FILE *outfile) {  int c;/*    indent(outfile); */  if(b->name) {    /* a block definition */    fprintf(outfile, "%s %s {\n", lp_modules[b->type]->name, b->name);  }  else {    /* a block value */    fprintf(outfile, "%s {\n", lp_modules[b->type]->name);  }  indent_level++;  for(c = 0; c < b->params_len; c++) {    if(!b->params[c]) continue;    if(c) fprintf(outfile, ",\n");    unparse_param(b->params[c], outfile);  }  indent_level--;  fprintf(outfile, "\n");  indent(outfile);  fprintf(outfile, "}");  if(b->name) {    fprintf(outfile, " # end of %s spec", b->name);    fprintf(outfile, "\n\n");  }}void unparse_topospec(struct lp_topospec *t, FILE *outfile) {  fprintf(outfile, "%s %s ", t->type, t->name);  unparse_list(t->l, outfile);  // unparse_list() prints a trailing newline...  //  fprintf(outputfile, "\n"); }// somewhat of a hackvoid unparse_tl_topospec(struct lp_topospec *t, FILE *outfile) {  fprintf(outfile, "topospec ");  unparse_topospec(t, outfile);  fprintf(outfile, "\n\n");}void unparse_inst(struct lp_inst *i, FILE *outfile) {  fprintf(outfile, "instantiate ");  unparse_list(i->l, outfile);  fprintf(outfile, " as %s\n\n", i->name);}void unparse_tlt(struct lp_tlt *tlt, FILE *outfile, char *infile) {  if(tlt->source_file && infile) {    if(strcmp(tlt->source_file, infile)) {      unparse_source(tlt->source_file, outfile);      return;    }  }    switch(tlt->what) {  case TLT_BLOCK: unparse_block(tlt->it.block, outfile); break;  case TLT_TOPO:  unparse_tl_topospec(tlt->it.topo, outfile); break;  case TLT_INST:  unparse_inst(tlt->it.inst, outfile); break;  default:        ddbg_assert(0); break;  };  }void lp_unparse_tlts(struct lp_tlt **tlts, 		     int tlts_len, 		     FILE *outfile, 		     char *infile) {  int c;  for(c = 0; c < tlts_len; c++) {    if(tlts[c] != 0) {      unparse_tlt(tlts[c], outfile, infile);    }  }}/* instantiate all the elements of <l> as <name> */int lp_inst_list(struct lp_inst *i){  int c;    /*      unparse_block(spec, outputfile); */  for(c = 0; c < i->l->values_len; c++) {    if(!i->l->values[c]) continue;        ddbg_assert3(i->l->values[c]->t == S, 	       ("bad type for component %s", i->l->values[c]->v.s));        lp_instantiate(i->l->values[c]->v.s, i->name);  }    return 0;}/* instantiate <targ> as <name> */int *lp_instantiate(char *targ, char *name) {  char *nametmp;  struct lp_block *spec;  int *obj;    /*    unparse_block(b, outputfile); */  spec = lp_lookup_spec(name);  ddbg_assert3(spec != 0, ("no such type %s.\n", name));  // this is a bit of a hack; we swap the name of the component  // being instantiated with the name of the module that's being  // instantiated so that the loader function sees the target  // name  nametmp = spec->name;  spec->name = targ;    //  fprintf(stderr, "*** Instantiating %s as %s\n", targ, name);  obj = lp_override_inst(spec, 			 targ,			 lp_modules[spec->type]->fn,			 overrides, 			 overrides_len);  // swap the name back  spec->name = nametmp;  if(!obj) {    return 0;  }    if(lp_modules[spec->type]->callback) {    lp_modules[spec->type]->callback(lp_modules[spec->type]->ctx, obj);  }  return obj;}/* 0 on success, nonzero on error */int check_types(struct lp_block *b) {  int c = 0;  /* we'll do all of the type checking here so that    * the per-mod loaders only have to sanitize values */  for(c = 0; c < b->params_len; c++) {    if(b->params[c]) {      if(lp_param_name(b->type, b->params[c]->name) == -1) {	fprintf(stderr, "*** warning: parameter %s not valid in context %s\n",		b->params[c]->name, lp_modules[b->type]->name);	      }      else if(lp_modules[b->type]->modvars[lp_param_name(b->type, b->params[c]->name)].type	 != PTYPE(b->params[c])) {	/* implicitly convert ints to doubles */	if((lp_modules[b->type]->modvars[lp_param_name(b->type, b->params[c]->name)].type	    == D)	   && (PTYPE(b->params[c]) == I)) {	  b->params[c]->v->t = D;	  DVAL(b->params[c]) = (double) IVAL(b->params[c]);	}	  	else { 	  fprintf(stderr, "*** error: type error: %s::\"%s\" cannot take type ",		  lp_modules[b->type]->name,		  b->params[c]->name);	  /*  	  unparse_type(PTYPE(b->params[c]), stderr); */	  fprintf(stderr, "\n");	  die("check_types() failed");	}      }            if(PTYPE(b->params[c]) >= BLOCK) {	check_types(BVAL(b->params[c]));      }      else if(PTYPE(b->params[c]) == LIST) {	int d;	struct lp_list *l = LVAL(b->params[c]);	for(d = 0; d < l->values_len; d++) {

⌨️ 快捷键说明

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