/* * Process a header line from an ascii or cazm format file. * Returns a filled-in SpiceStream* with variable information. */ static SpiceStream *ascii_process_header(char *line, VarType ivtype, char *fname, int lineno) { SpiceStream *sf; char *signam; int dvsize = 64; signam = strtok(line, " \t\n"); if(!signam) { ss_msg(ERR, "ascii_process_header", "%s:%d: syntax error in header", fname, lineno); return NULL; } /* a bit of a hack: get ss_new to allocate additional * dvars, then only use the entries we need or allocate more */ sf = ss_new(NULL, fname, dvsize, 0); if(ivtype == UNKNOWN) { if(strcasecmp(signam, "time") == 0) sf->ivar->type = TIME; } else { sf->ivar->type = ivtype; } sf->ivar->name = g_strdup(signam); sf->ivar->col = 0; sf->ivar->ncols = 1; sf->ndv = 0; sf->ncols = 1; sf->ntables = 1; while((signam = strtok(NULL, " \t\n")) != NULL) { if(sf->ndv >= dvsize) { dvsize *= 2; sf->dvar = g_realloc(sf->dvar, dvsize * sizeof(SpiceVar)); } sf->dvar[sf->ndv].name = g_strdup(signam); sf->dvar[sf->ndv].type = UNKNOWN; sf->dvar[sf->ndv].col = sf->ncols; sf->dvar[sf->ndv].ncols = 1; sf->ndv++; sf->ncols++; } sf->readrow = sf_readrow_ascii; return sf; }
void finish (int mode) { if (mode == SS_WRITE) { ss_val r = ss_new (store, 0, 4, ss_tab_finish (table), ss_dict_finish (package_files_dict), ss_dict_finish (file_packages_dict), ss_dict_finish (package_info_dict)); ss_set_root (store, r); ss_maybe_gc (store); } }
/* Read spice-type file header - Berkeley Spice3 "raw" format */ SpiceStream * sf_rdhdr_s3raw(char *name, FILE *fp) { SpiceStream *sf = NULL; char *line = NULL; char *signam; int lineno = 0; int linesize = 1024; int dvsize = 128; char *key, *val; int nvars, npoints; int got_nvars = 0; int got_values = 0; int dtype_complex = 0; int binary = 0; char *vnum, *vname, *vtypestr; int i; while(fread_line(fp, &line, &linesize) != EOF) { lineno++; if(lineno == 1 && strncmp(line, "Title: ", 7)) { /* not a spice3raw file; bail out */ ss_msg(DBG, msgid, "%s:%d: Doesn't look like a spice3raw file; \"Title:\" expected\n", name, lineno); return NULL; } key = strtok(line, ":"); if(!key) { ss_msg(ERR, msgid, "%s:%d: syntax error, expected \"keyword:\"", name, lineno); g_free(line); return NULL; } if(strcmp(key, "Flags") == 0) { while(val = strtok(NULL, " ,\t\n")) { if(strcmp(val, "real") == 0) { dtype_complex = 0; } if(strcmp(val, "complex") == 0) { dtype_complex = 1; } } } else if(strcmp(key, "No. Variables") == 0) { val = strtok(NULL, " \t\n"); if(!val) { ss_msg(ERR, msgid, "%s:%d: syntax error, expected integer", name, lineno); g_free(line); return NULL; } nvars = atoi(val); got_nvars = 1; } else if(strcmp(key, "No. Points") == 0) { val = strtok(NULL, " \t\n"); if(!val) { ss_msg(ERR, msgid, "%s:%d: syntax error, expected integer", name, lineno); g_free(line); return NULL; } npoints = atoi(val); } else if(strcmp(key, "Variables") == 0) { if(!got_nvars) { ss_msg(ERR, msgid, "%s:%d: \"Variables:\" before \"No. Variables:\"", name, lineno, i); goto err; } sf = ss_new(fp, name, nvars-1, 0); sf->ncols = 1; sf->ntables = 1; /* first variable may be described on the same line * as "Variables:" keyword */ vnum = strtok(NULL, " \t\n"); for(i = 0; i < nvars; i++) { if(i || !vnum) { if(fread_line(fp, &line, &linesize) == EOF) { ss_msg(ERR, msgid, "%s:%d: Unexpected EOF in \"Variables:\" at var %d", name, lineno, i); goto err; } lineno++; vnum = strtok(line, " \t\n"); } vname = strtok(NULL, " \t\n"); vtypestr = strtok(NULL, " \t\n"); if(!vnum || !vname || !vtypestr) { ss_msg(ERR, msgid, "%s:%d: expected number name type", name, lineno); goto err; } if(i == 0) { /* assume Ind.Var. first */ sf->ivar->name = g_strdup(vname); sf->ivar->type = sf_str2type_s3raw(vtypestr); sf->ivar->col = 0; /* ivar can't really be two-column, this is a flag that says to discard 2nd point */ if(dtype_complex) sf->ivar->ncols = 2; else sf->ivar->ncols = 1; } else { sf->dvar[i-1].name = g_strdup(vname); sf->dvar[i-1].type = sf_str2type_s3raw(vtypestr); sf->dvar[i-1].col = sf->ncols; if(dtype_complex) sf->dvar[i-1].ncols = 2; else sf->dvar[i-1].ncols = 1; sf->ncols += sf->dvar[i-1].ncols; } } } else if(strcmp(key, "Values") == 0) { got_values = 1; break; } else if(strcmp(key, "Binary") == 0) { binary = 1; got_values = 1; break; } if(got_values) break; } if(!sf) { ss_msg(ERR, msgid, "%s:%d: no \"Variables:\" section in header", name, lineno); goto err; } if(!got_values) { ss_msg(ERR, msgid, "%s:%d: EOF without \"Values:\" in header", name, lineno); goto err; } if(binary) { sf->readrow = sf_readrow_s3bin; } else { sf->readrow = sf_readrow_s3raw; } sf->read_rows = 0; sf->expected_vals = npoints * (sf->ncols + (dtype_complex ? 1 : 0)); ss_msg(DBG, msgid, "expecting %d values\n", sf->expected_vals); sf->lineno = lineno; sf->linebuf = line; sf->lbufsize = linesize; ss_msg(DBG, msgid, "Done with header at offset 0x%lx\n", (long) ftello64(sf->fp)); return sf; err: if(line) g_free(line); if(sf) { sf->fp = NULL; /* prevent ss_delete from cleaning up FILE*; ss_open callers may rewind and try another format on failure. */ ss_delete(sf); } return NULL; }
ss_val cons (ss_val car, ss_val cdr) { return ss_new (store, 0, 2, car, cdr); }