?? myutil.c
字號(hào):
/* libparam (version 1.0) * Authors: John Bucy, Greg Ganger * Contributors: John Griffin, Jiri Schindler, Steve Schlosser * * Copyright (c) of Carnegie Mellon University, 2001-2008. * * 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 <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <unistd.h>#include <fcntl.h>#include <libgen.h>#include "libparam.h"#include "bitvector.h"static lp_topoloader_t topoloader = 0;void lp_register_topoloader(lp_topoloader_t l) { topoloader = l;}char *lp_builtin_names[] = { 0, "Block", "String", "Int", "Double", "List", "Topospec"};// FILE *libparamin = 0;struct lp_subtype **lp_typetbl;int lp_typetbl_len;struct lp_tlt **lp_tlts;int lp_tlts_len;//extern char lp_filename[];//extern char lp_cwd[];char **lp_searchpath = 0;int lp_searchpath_len = 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 stdoutstruct lp_value *lp_new_intv(int i) { struct lp_value *v = calloc(1, sizeof(struct lp_value)); v->v.i = i; v->t = I; return v;}struct lp_value *lp_new_doublev(double d) { struct lp_value *v = calloc(1, sizeof(struct lp_value)); v->v.d = d; v->t = D; return v;}struct lp_value *lp_new_stringv(char *s) { struct lp_value *v = calloc(1, sizeof(struct lp_value)); v->v.s = s; v->t = S; return v;}struct lp_value *lp_new_listv(struct lp_list *l){ struct lp_value *v = calloc(1, sizeof(struct lp_value)); v->v.l = l; v->t = LIST; return v;}struct lp_value *lp_new_blockv(struct lp_block *b){ struct lp_value *v = calloc(1, sizeof(struct lp_value)); v->v.b = b; v->t = b->type; return v;}struct lp_param *lp_new_param(char *name, char *source, struct lp_value *v){ struct lp_param *result = calloc(1, sizeof(struct lp_param)); result->source_file = source; result->name = name; result->v = v; return result;}struct lp_list *lp_new_list(void) { struct lp_list *l = calloc(1, sizeof(struct lp_list)); l->values = calloc(8, sizeof(struct lp_value *)); l->values_len = 8; l->values_pop = 0; l->linelen = 1; return l;}struct lp_block *lp_new_block(void){ struct lp_block *b = calloc(1, sizeof(struct lp_block)); b->params = calloc(8, sizeof(struct lp_param *)); b->params_len = 8; return b;}struct lp_list *lp_new_intlist(int *intarr, int len){ int i; struct lp_list *l = lp_new_list(); for(i = 0; i < len; i++) { lp_list_add(l, lp_new_intv(intarr[i])); } return l;}int 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 = calloc(1, sizeof(*result)); memcpy(result, b, sizeof(struct lp_block)); result->params = calloc(b->params_len, sizeof(result->params[0])); 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 = calloc(1, sizeof(*result)); memcpy(result, l, sizeof(struct lp_list)); result->values = calloc(l->values_len, sizeof(result->values[0])); 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 = calloc(1, 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: break; } return result;}static struct lp_param *copy_param(struct lp_param *p) { struct lp_param *result = calloc(1, 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 = calloc(1, 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", source);}void unparse_type(int t, FILE *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) { 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: if(v->v.d == 0.0) { fprintf(outfile, "0.0"); } else { 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, ", "); if(!(c % l->linelen)) { fprintf(outfile, "\n"); indent(outfile); } } 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++) { 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;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -