Ignore all generated/compiled files
[gwave-svn.git] / spicefile / ss_nsout.c
blob1d4a498303685ac25cc9146b59d0ec28e1ffdc5b
1 /*
2 * ss_nsout.c: routines for SpiceStream that handle the ".out" file format
3 * from Synopsis' nanosim.
5 * Copyright (C) 2004 Stephen G. Tell
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "ssintern.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <float.h>
31 #include <config.h>
32 #include <glib.h>
33 #include "spicestream.h"
35 static int sf_readrow_nsout(SpiceStream *sf, double *ivar, double *dvars);
36 static char *msgid = "nsout";
38 struct nsvar {
39 char *name;
40 int index;
41 VarType type;
44 /* convert variable type string from out-file to
45 * our type numbers
47 static VarType
48 sf_str2type_nsout(char *s)
50 if(strcasecmp(s, "v") == 0)
51 return VOLTAGE;
52 else if(strcasecmp(s, "i") == 0)
53 return CURRENT;
54 else return UNKNOWN;
58 /* Read spice-type file header - nanosim "out" format */
59 SpiceStream *
60 sf_rdhdr_nsout(char *name, FILE *fp)
62 SpiceStream *sf = NULL;
63 char *line = NULL;
64 int lineno = 0;
65 int linesize = 1024;
66 char *key, *val;
67 int got_ivline = 0;
68 int ndvars;
69 double voltage_resolution = 1.0;
70 double current_resolution = 1.0;
71 double time_resolution = 1.0;
72 GList *vlist = NULL;
73 struct nsvar *nsv;
74 int i;
75 int maxindex = 0;
77 while(fread_line(fp, &line, &linesize) != EOF) {
78 lineno++;
79 if(lineno == 1 && strncmp(line, ";! output_format", 16)) {
80 /* not an out file; bail out */
81 ss_msg(DBG, msgid, "%s:%d: Doesn't look like an ns-out file; \"output_format\" expected\n", name, lineno);
83 return NULL;
85 if(line[0] == ';')
86 continue;
88 if(line[0] == '.') {
89 key = strtok(&line[1], " \t");
90 if(!key) {
91 ss_msg(ERR, msgid, "%s:%d: syntax error, expected \"keyword:\"", name, lineno);
92 g_free(line);
93 return NULL;
95 if(strcmp(key, "time_resolution") == 0) {
96 val = strtok(NULL, " \t\n");
97 if(!val) {
98 ss_msg(ERR, msgid, "%s:%d: syntax error, expected number", name, lineno);
99 g_free(line);
100 return NULL;
102 time_resolution = atof(val);
104 if(strcmp(key, "current_resolution") == 0) {
105 val = strtok(NULL, " \t\n");
106 if(!val) {
107 ss_msg(ERR, msgid, "%s:%d: syntax error, expected number", name, lineno);
108 g_free(line);
109 return NULL;
111 current_resolution = atof(val);
113 if(strcmp(key, "voltage_resolution") == 0) {
114 val = strtok(NULL, " \t\n");
115 if(!val) {
116 ss_msg(ERR, msgid, "%s:%d: syntax error, expected number", name, lineno);
117 g_free(line);
118 return NULL;
120 voltage_resolution = atof(val);
122 if(strcmp(key, "index") == 0) {
123 nsv = g_new0(struct nsvar, 1);
125 val = strtok(NULL, " \t\n");
126 if(!val) {
127 ss_msg(ERR, msgid, "%s:%d: syntax error, expected varname", name, lineno);
128 goto err;
130 nsv->name = g_strdup(val);
132 val = strtok(NULL, " \t\n");
133 if(!val) {
134 ss_msg(ERR, msgid, "%s:%d: syntax error, expected var-index", name, lineno);
135 goto err;
137 nsv->index = atoi(val);
138 if(nsv->index > maxindex)
139 maxindex = nsv->index;
141 val = strtok(NULL, " \t\n");
142 if(!val) {
143 ss_msg(ERR, msgid, "%s:%d: syntax error, expected variable type", name, lineno);
144 goto err;
146 nsv->type = sf_str2type_nsout(val);
147 vlist = g_list_append(vlist, nsv);
151 if(isdigit(line[0])) {
152 got_ivline = 1;
153 break;
156 if(!vlist) {
157 ss_msg(ERR, msgid, "%s:%d: no variable indices found in header", name, lineno);
159 if(!got_ivline) {
160 ss_msg(ERR, msgid, "%s:%d: EOF without data-line in header", name, lineno);
161 goto err;
163 ndvars = g_list_length(vlist);
165 sf = ss_new(fp, name, ndvars, 0);
166 sf->time_resolution = time_resolution;
167 sf->current_resolution = current_resolution;
168 sf->voltage_resolution = voltage_resolution;
169 sf->maxindex = maxindex;
170 sf->datrow = g_new0(double, maxindex+1);
171 sf->nsindexes = g_new0(int, ndvars);
172 sf->ncols = 1;
173 sf->ntables = 1;
174 sf->ivar->name = g_strdup("TIME");
175 sf->ivar->type = TIME;
176 sf->ivar->col = 0;
178 for(i = 0; i < ndvars; i++) {
179 SpiceVar *dvar;
181 nsv = g_list_nth_data(vlist, i);
183 dvar = ss_spicevar_new(nsv->name, nsv->type, sf->ncols, 1);
184 g_ptr_array_add(sf->dvarp, dvar);
185 sf->ncols += dvar->ncols;
187 sf->nsindexes[i] = nsv->index;
188 ss_msg(DBG, msgid, "dv[%d] \"%s\" nsindex=%d",
189 i, dvar->name, sf->nsindexes[i]);
192 sf->readrow = sf_readrow_nsout;
193 sf->read_rows = 0;
195 sf->lineno = lineno;
196 sf->linebuf = line;
197 sf->lbufsize = linesize;
198 ss_msg(DBG, msgid, "Done with header at offset 0x%lx", (long) ftello64(sf->fp));
200 return sf;
201 err:
202 if(line)
203 g_free(line);
204 if(sf) {
205 sf->fp = NULL;
206 /* prevent ss_delete from cleaning up FILE*; ss_open callers
207 may rewind and try another format on failure. */
208 ss_delete(sf);
210 return NULL;
214 * Read row of values from an out-format file
215 * upon call, line buffer should always contain the
216 * independent-variable line that starts this set of values.
218 static int
219 sf_readrow_nsout(SpiceStream *sf, double *ivar, double *dvars)
221 int i;
222 int idx;
223 char *sidx;
224 char *sval;
225 double v;
226 double scale;
227 SpiceVar *dvp;
229 if(feof(sf->fp)) {
230 return 0;
233 // process iv line
234 v = atof(sf->linebuf) * sf->time_resolution * 1e-9; /* ns */
235 *ivar = v;
237 // read and process dv lines until we see another iv line
238 while(fread_line(sf->fp, &sf->linebuf, &sf->lbufsize) != EOF) {
239 sf->lineno++;
240 if(sf->linebuf[0] == ';')
241 continue;
243 sidx = strtok(sf->linebuf, " \t");
244 if(!sidx) {
245 ss_msg(ERR, msgid, "%s:%d: expected value",
246 sf->filename, sf->lineno);
247 return -1;
250 sval = strtok(NULL, " \t");
251 if(!sval)
252 /* no value token: this is the ivar line for the
253 next row */
254 break;
256 idx = atoi(sidx);
257 if(idx <= sf->maxindex) {
258 sf->datrow[idx] = atof(sval);
262 for(i = 0; i < sf->ndv; i++) {
263 SpiceVar *dvar;
264 dvar = ss_dvar(sf, i);
265 scale = 1.0;
266 switch(dvar->type) {
267 case VOLTAGE:
268 scale = sf->voltage_resolution;
269 break;
270 case CURRENT:
271 scale = sf->current_resolution;
272 break;
274 dvars[i] = sf->datrow[ sf->nsindexes[i] ] * scale;
277 return 1;