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.
33 #include "spicestream.h"
35 static int sf_readrow_nsout(SpiceStream
*sf
, double *ivar
, double *dvars
);
36 static char *msgid
= "nsout";
44 /* convert variable type string from out-file to
48 sf_str2type_nsout(char *s
)
50 if(strcasecmp(s
, "v") == 0)
52 else if(strcasecmp(s
, "i") == 0)
58 /* Read spice-type file header - nanosim "out" format */
60 sf_rdhdr_nsout(char *name
, FILE *fp
)
62 SpiceStream
*sf
= NULL
;
69 double voltage_resolution
= 1.0;
70 double current_resolution
= 1.0;
71 double time_resolution
= 1.0;
77 while(fread_line(fp
, &line
, &linesize
) != EOF
) {
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
);
89 key
= strtok(&line
[1], " \t");
91 ss_msg(ERR
, msgid
, "%s:%d: syntax error, expected \"keyword:\"", name
, lineno
);
95 if(strcmp(key
, "time_resolution") == 0) {
96 val
= strtok(NULL
, " \t\n");
98 ss_msg(ERR
, msgid
, "%s:%d: syntax error, expected number", name
, lineno
);
102 time_resolution
= atof(val
);
104 if(strcmp(key
, "current_resolution") == 0) {
105 val
= strtok(NULL
, " \t\n");
107 ss_msg(ERR
, msgid
, "%s:%d: syntax error, expected number", name
, lineno
);
111 current_resolution
= atof(val
);
113 if(strcmp(key
, "voltage_resolution") == 0) {
114 val
= strtok(NULL
, " \t\n");
116 ss_msg(ERR
, msgid
, "%s:%d: syntax error, expected number", name
, lineno
);
120 voltage_resolution
= atof(val
);
122 if(strcmp(key
, "index") == 0) {
123 nsv
= g_new0(struct nsvar
, 1);
125 val
= strtok(NULL
, " \t\n");
127 ss_msg(ERR
, msgid
, "%s:%d: syntax error, expected varname", name
, lineno
);
130 nsv
->name
= g_strdup(val
);
132 val
= strtok(NULL
, " \t\n");
134 ss_msg(ERR
, msgid
, "%s:%d: syntax error, expected var-index", name
, lineno
);
137 nsv
->index
= atoi(val
);
138 if(nsv
->index
> maxindex
)
139 maxindex
= nsv
->index
;
141 val
= strtok(NULL
, " \t\n");
143 ss_msg(ERR
, msgid
, "%s:%d: syntax error, expected variable type", name
, lineno
);
146 nsv
->type
= sf_str2type_nsout(val
);
147 vlist
= g_list_append(vlist
, nsv
);
151 if(isdigit(line
[0])) {
157 ss_msg(ERR
, msgid
, "%s:%d: no variable indices found in header", name
, lineno
);
160 ss_msg(ERR
, msgid
, "%s:%d: EOF without data-line in header", name
, lineno
);
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
);
174 sf
->ivar
->name
= g_strdup("TIME");
175 sf
->ivar
->type
= TIME
;
178 for(i
= 0; i
< ndvars
; i
++) {
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
;
197 sf
->lbufsize
= linesize
;
198 ss_msg(DBG
, msgid
, "Done with header at offset 0x%lx", (long) ftello64(sf
->fp
));
206 /* prevent ss_delete from cleaning up FILE*; ss_open callers
207 may rewind and try another format on failure. */
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.
219 sf_readrow_nsout(SpiceStream
*sf
, double *ivar
, double *dvars
)
234 v
= atof(sf
->linebuf
) * sf
->time_resolution
* 1e-9; /* ns */
237 // read and process dv lines until we see another iv line
238 while(fread_line(sf
->fp
, &sf
->linebuf
, &sf
->lbufsize
) != EOF
) {
240 if(sf
->linebuf
[0] == ';')
243 sidx
= strtok(sf
->linebuf
, " \t");
245 ss_msg(ERR
, msgid
, "%s:%d: expected value",
246 sf
->filename
, sf
->lineno
);
250 sval
= strtok(NULL
, " \t");
252 /* no value token: this is the ivar line for the
257 if(idx
<= sf
->maxindex
) {
258 sf
->datrow
[idx
] = atof(sval
);
262 for(i
= 0; i
< sf
->ndv
; i
++) {
264 dvar
= ss_dvar(sf
, i
);
268 scale
= sf
->voltage_resolution
;
271 scale
= sf
->current_resolution
;
274 dvars
[i
] = sf
->datrow
[ sf
->nsindexes
[i
] ] * scale
;