예제 #1
0
/* 
 * read all of the data from a SpiceStream and store it in the WaveFile
 * structure.
 */
WaveFile *wf_finish_read(SpiceStream *ss)
{
	WaveFile *wf;
	int rc;
	double ival;
	double *dvals;
	WvTable *wt;
	int state;
	double *spar = NULL;

	wf = g_new0(WaveFile, 1);
	wf->ss = ss;
	wf->tables = g_ptr_array_new();
	dvals = g_new(double, ss->ncols);

	state = 0;
	do {
		wt = wf_read_table(ss, wf, &state, &ival, dvals);
		if(wt) {
			ss_msg(DBG, "wf_finish_read", "table with %d rows; state=%d", wt->nvalues, state);
			wt->swindex = wf->wf_ntables;
			g_ptr_array_add(wf->tables, wt);
			if(!wt->name) {
				char tmp[128];
				sprintf(tmp, "tbl%d", wf->wf_ntables);
				wt->name = g_strdup(tmp);
			}
		} else {
			ss_msg(DBG, "wf_finish_read", "NULL table; state=%d", state);
		}
	} while(state > 0);

	g_free(dvals);
	g_free(spar);
	ss_close(ss);

	if(state < 0) {
		wf_free(wf);
		return NULL;
	} else {
		return wf;
	}
}
예제 #2
0
파일: ss_cazm.c 프로젝트: manasdas17/sp2sp
/*
 * 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;
}
예제 #3
0
파일: ss_cazm.c 프로젝트: manasdas17/sp2sp
/* Read row of values from ascii- or cazm- format file.
 * Possibly reusable for other future formats with lines of
 * whitespace-seperated values.
 * Returns:
 *	1 on success.  also fills in *ivar scalar and *dvars vector
 *	0 on EOF
 *	-1 on error  (may change some ivar/dvar values)
 */
static int sf_readrow_ascii(SpiceStream *sf, double *ivar, double *dvars)
{
	int i = 0;
	char *tok;

	if(fread_line(sf->fp, &sf->linebuf, &sf->lbufsize) == EOF)
	{
		return 0;
	}
	sf->lineno++;

	tok = strtok(sf->linebuf, " \t\n");
	if(!tok)
	{
		return 0;  /* blank line can indicate end of data */
	}

	/* check to see if it is numeric: ascii format is so loosly defined
	 * that we might read a load of garbage otherwise. */

	if(strspn(tok, "0123456789eE+-.") != strlen(tok))
	{
		ss_msg(ERR, "sf_readrow_ascii", "%s:%d: expected number; maybe this isn't an ascii data file at all?", sf->filename, sf->lineno, i);
		return -1;
	}

	*ivar = atof(tok);

	for(i = 0; i < sf->ncols-1; i++)
	{
		tok = strtok(NULL, " \t\n");
		if(!tok)
		{
			ss_msg(ERR, "sf_readrow_ascii", "%s:%d: data field %d missing", sf->filename, sf->lineno, i);
			return -1;
		}
		dvars[i] = atof(tok);
	}
	return 1;
}
예제 #4
0
static int
sf_getval_s3bin(SpiceStream *sf, double *dval)
{
	off64_t pos;
	double val;
	int i;

	if(sf->read_vals >= sf->expected_vals) {
		pos = ftello64(sf->fp);
		ss_msg(DBG, "sf_getval_s3bin", "past last expected value offset 0x%lx", (long) pos);
		return 0;
	}
	if(fread(&val, sizeof(double), 1, sf->fp) != 1) {
		pos = ftello64(sf->fp);
		ss_msg(ERR, "sf_getval_s3bin", "unexepected EOF in data at offset 0x%lx", (long) pos);
		return -1;
	}
	sf->read_vals++;

	*dval = val;
	return 1;
}
예제 #5
0
/*
 * Read row of values from a binay spice3 raw file
 */
static int
sf_readrow_s3bin(SpiceStream *sf, double *ivar, double *dvars)
{
	int i, rc;
	double v;
	double dummy;
	
	if((sf->flags & SSF_PUSHBACK) == 0) {
		rc = sf_getval_s3bin(sf, &v);
		if(rc == 0)		/* file EOF */
			return 0;
		if(rc < 0)
			return -1;
		if(sf->ivar->ncols == 2) {
			rc = sf_getval_s3bin(sf, &dummy);
			if(rc == 0)		/* file EOF */
				return 0;
			if(rc < 0)
				return -1;
		}
		if(v < sf->ivval) {
			/* independent-variable value decreased, this must
			 * be the start of another sweep.  hold the value and
			 * return flag to caller.
			 */
			sf->ivval = v;
			sf->flags |= SSF_PUSHBACK;
			return -2;
		} else {
			sf->ivval = v;
			*ivar = v;
		}
	} else {
		/* iv value for start of new sweep was read last time */
		sf->flags &= ~SSF_PUSHBACK;
		*ivar = sf->ivval;
	}

	for(i = 0; i < sf->ncols-1; i++) {
		if(sf_getval_s3bin(sf, &dvars[i]) != 1) {
			ss_msg(WARN, "sf_readrow_s3bin", "%s: EOF or error reading data field %d in row %d; file is incomplete.", sf->filename, i, sf->read_rows);
			return 0;
		}
	}

	sf->read_rows++;
	return 1;
}
예제 #6
0
/* 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;
}
예제 #7
0
/*
 * Read row of values from an ascii spice3 raw file
 */
static int
sf_readrow_s3raw(SpiceStream *sf, double *ivar, double *dvars)
{
	int i;
	int frownum;
	char *tok;
	double v;
 
	if((sf->flags & SSF_PUSHBACK) == 0) {
		tok = sf_nexttoken(sf);
		if(!tok) {
			return 0;
//			ss_msg(ERR, msgid, "%s:%d: expected row number", 
//			       sf->filename, sf->lineno);
//			return -1;
		}
		if(!isdigit(*tok)) {
			ss_msg(WARN, msgid, "%s:%d: expected row number, got \"%s\". Note: only one dataset per file is supported, extra garbage ignored", 
			       sf->filename, sf->lineno, tok);
			return 0;
		}
		frownum = atoi(tok);
		/* todo: check for expected and maximum row number */

		tok = sf_nexttoken(sf);
		if(!tok) {
			ss_msg(WARN, msgid, "%s:%d: expected ivar value", 
			       sf->filename, sf->lineno);
			return -1;
		}
		v = atof(tok);
		if(v < sf->ivval) {
			/* independent-variable value decreased, this must
			 * be the start of another sweep.  hold the value and
			 * return flag to caller.
			 */
			sf->ivval = v;
			sf->flags |= SSF_PUSHBACK;
			return -2;
		} else {
			sf->ivval = v;
			*ivar = v;
		}
	} else {
		/* iv value for start of new sweep was read last time */
		sf->flags &= ~SSF_PUSHBACK;
		*ivar = sf->ivval;
	}
	
	for(i = 0; i < sf->ndv; i++) {
		SpiceVar *dv;
		dv = &sf->dvar[i];

		tok = sf_nexttoken(sf);
		if(!tok) {
			ss_msg(ERR, msgid, "%s:%d: expected value", 
			       sf->filename, sf->lineno);
			return -1;
		}
		dvars[dv->col-1] = atof(tok);

		if(dv->ncols > 1) {
			tok = strchr(tok, ',');
			if(!tok || !*(tok+1)) {
				ss_msg(ERR, msgid, "%s:%d: expected second value", 
				       sf->filename, sf->lineno);
				return -1;
			}
			tok++;
			dvars[dv->col] = atof(tok);
		}
	}
	sf->read_rows++;
	return 1;
}
예제 #8
0
/*
 * read data for a single table (sweep or segment) from spicestream.
 * on entry:
 *	state=0: no previous data; dvals is allocated but garbage
 *	state=1: first row of data is in *ivalp, and vals[].
 * on exit:
 *	return NULL: fatal error, *statep=-1
 *	return non-NULL: valid wvtable*
 *
 *	state=-1 fatal error
 *	state=0: successful completion of reading whole file
 * 	state=1:  finished table but more tables remain,
 *			none of the next table has yet been read
 * 	state=2:  finished table but more tables remain and
 *		*ivalp,dvals[] contain first row of next table.
 */
WvTable *
wf_read_table(SpiceStream *ss, WaveFile *wf,
	      int *statep, double *ivalp, double *dvals)
{
	WvTable *wt;
	int row;
	WaveVar *dv;
	double last_ival;
	double spar;
	int rc, i, j;

	if(ss->nsweepparam > 0) {		
		if(ss->nsweepparam == 1) {
			if(ss_readsweep(ss, &spar) <= 0) {
				*statep = -1;
				return NULL;
			}
		} else {
			ss_msg(ERR, "wf_read_table", "nsweepparam=%d; multidimentional sweeps not supported\n", ss->nsweepparam);
			*statep = -1;
			return NULL;
		}
	}
	wt = wvtable_new(wf);
	if(ss->nsweepparam == 1) {	
		wt->swval = spar;
		wt->name = g_strdup(ss->spar[0].name);
	} else {
		wt->swval = 0;
	}
	
	if(*statep == 2) {
		wf_set_point(wt->iv->wds, row, *ivalp);
		for(i = 0; i < wt->wt_ndv; i++) {
			dv = &wt->dv[i];
			for(j = 0; j < dv->wv_ncols; j++)
				wf_set_point(&dv->wds[j], row,
					     dvals[dv->sv->col - 1 + j ]);
		}
		row = 1;
		wt->nvalues = 1;
		last_ival = *ivalp;
	} else {
		row = 0;
		wt->nvalues = 0;
		last_ival = -1.0e29;
	}

	while((rc = ss_readrow(ss, ivalp, dvals)) > 0) {
		if(row > 0 && *ivalp < last_ival) {
			if(row == 1) {
				ss_msg(ERR, "wavefile_read", "independent variable is not nondecreasing at row %d; ival=%g last_ival=%g\n", row, *ivalp, last_ival);
				wt_free(wt);
				*statep = -1;
				return NULL;
				
			} else {
				*statep = 2;
				return wt;
			}
		}
		last_ival = *ivalp;
		wf_set_point(wt->iv->wds, row, *ivalp);
		for(i = 0; i < wt->wt_ndv; i++) {
			dv = &wt->dv[i];
			for(j = 0; j < dv->wv_ncols; j++)
				wf_set_point(&dv->wds[j], row,
					     dvals[dv->sv->col - 1 + j ]);
		}
		row++;
		wt->nvalues++;
	}
	if(rc == -2)
		*statep = 1;
	else if(rc < 0) {
		wt_free(wt);
		*statep = -1;
		return NULL;
	} else {
		*statep = 0;
	}
	return wt;
}
예제 #9
0
/*
 * Read a waveform data file.
 *  If the format name is non-NULL, only tries reading in specified format.
 *  If format not specified, tries to guess based on filename, and if
 *  that fails, tries all of the readers until one sucedes.
 *  Returns NULL on failure after printing an error message.
 * 
 * TODO: use some kind of callback or exception so that client
 * can put the error messages in a GUI or somthing.
 */
WaveFile *wf_read(char *name, char *format)
{
	FILE *fp;
	SpiceStream *ss;
	int i;

	unsigned int tried = 0; /* bitmask of formats. */

	g_assert(NFormats <= 8*sizeof(tried));
	fp = fopen64(name, "r");
	if(fp == NULL) {
		perror(name);
		return NULL;
	}

	if(format == NULL) {
		for(i = 0; i < NFormats; i++) {
			if(!format_tab[i].creg) {
				format_tab[i].creg = regexp_compile(format_tab[i].fnrexp);
			}
			if(regexp_test(format_tab[i].creg, name))
			{
				tried |= 1<<i;
				ss = ss_open_internal(fp, name, format_tab[i].name);
				if(ss) {
					ss_msg(INFO, "wf_read", "%s: read with format \"%s\"", name, format_tab[i].name);
					return wf_finish_read(ss);
				}

				if(fseek(fp, 0L, SEEK_SET) < 0) {
					perror(name);
					return NULL;
				}
					
			}
		}
		if(tried == 0)
			ss_msg(INFO, "wf_read", "%s: couldn't guess a format from filename suffix.", name);
		/* no success with formats whose regexp matched filename,
		* try the others.
		*/
		for(i = 0; i < NFormats; i++) {
			if((tried & (1<<i)) == 0) {
				ss = ss_open_internal(fp, name, format_tab[i].name);
				if(ss)
					return wf_finish_read(ss);
				tried |= 1<<i;
				if(fseek(fp, 0L, SEEK_SET) < 0) {
					perror(name);
					return NULL;
				}
			}
		}
		ss_msg(ERR, "wf_read", "%s: couldn't read with any format\n", name);
		return NULL;
	} else { /* use specified format only */
		ss = ss_open_internal(fp, name, format);
		if(ss)
			return wf_finish_read(ss);
		else
			return NULL;
	}
}
예제 #10
0
파일: ss_nsout.c 프로젝트: manasdas17/sp2sp
/* Read spice-type file header - nanosim "out" format */
SpiceStream *
sf_rdhdr_nsout(char *name, FILE *fp)
{
	SpiceStream *sf = NULL;
	char *line = NULL;
	int lineno = 0;
	int linesize = 1024;
	char *key, *val;
	int got_ivline = 0;
	int ndvars;
	double voltage_resolution = 1.0;
	double current_resolution = 1.0;
	double time_resolution = 1.0;
	GList *vlist = NULL;
	struct nsvar *nsv;
	int i;
	int maxindex = 0;

	while(fread_line(fp, &line, &linesize) != EOF)
	{
		lineno++;
		if(lineno == 1 && strncmp(line, ";! output_format", 16))
		{
			/* not an out file; bail out */
			ss_msg(DBG, msgid, "%s:%d: Doesn't look like an ns-out file; \"output_format\" expected\n", name, lineno);

			return NULL;
		}
		if(line[0] == ';')
			continue;

		if(line[0] == '.')
		{
			key = strtok(&line[1], " \t");
			if(!key)
			{
				ss_msg(ERR, msgid, "%s:%d: syntax error, expected \"keyword:\"", name, lineno);
				g_free(line);
				return NULL;
			}
			if(strcmp(key, "time_resolution") == 0)
			{
				val = strtok(NULL, " \t\n");
				if(!val)
				{
					ss_msg(ERR, msgid, "%s:%d: syntax error, expected number", name, lineno);
					g_free(line);
					return NULL;
				}
				time_resolution = atof(val);
			}
			if(strcmp(key, "current_resolution") == 0)
			{
				val = strtok(NULL, " \t\n");
				if(!val)
				{
					ss_msg(ERR, msgid, "%s:%d: syntax error, expected number", name, lineno);
					g_free(line);
					return NULL;
				}
				current_resolution = atof(val);
			}
			if(strcmp(key, "voltage_resolution") == 0)
			{
				val = strtok(NULL, " \t\n");
				if(!val)
				{
					ss_msg(ERR, msgid, "%s:%d: syntax error, expected number", name, lineno);
					g_free(line);
					return NULL;
				}
				voltage_resolution = atof(val);
			}
			if(strcmp(key, "index") == 0)
			{
				nsv = g_new0(struct nsvar, 1);

				val = strtok(NULL, " \t\n");
				if(!val)
				{
					ss_msg(ERR, msgid, "%s:%d: syntax error, expected varname", name, lineno);
					goto err;
				}
				nsv->name = g_strdup(val);

				val = strtok(NULL, " \t\n");
				if(!val)
				{
					ss_msg(ERR, msgid, "%s:%d: syntax error, expected var-index", name, lineno);
					goto err;
				}
				nsv->index = atoi(val);
				if(nsv->index > maxindex)
					maxindex = nsv->index;

				val = strtok(NULL, " \t\n");
				if(!val)
				{
					ss_msg(ERR, msgid, "%s:%d: syntax error, expected variable type", name, lineno);
					goto err;
				}
				nsv->type = sf_str2type_nsout(val);
				vlist = g_list_append(vlist, nsv);
			}
		}