handling "Index" column in prn files

This commit is contained in:
Edward Arthur Bingham 2024-06-15 12:49:25 -04:00
parent 36537366f6
commit 5fb34a3741
3 changed files with 193 additions and 173 deletions

View File

@ -39,6 +39,7 @@ void spicestream_construct( SpiceStream *ss, char *filename, char *format, WaveT
spicestream_read_rows, spicestream_destroy ); spicestream_read_rows, spicestream_destroy );
ss->filename = filename; ss->filename = filename;
ss->format = format; ss->format = format;
ss->idxcol = -1;
/* open file */ /* open file */
ss->linebuf = fdbuf_new ( filename, "r", 0); ss->linebuf = fdbuf_new ( filename, "r", 0);

View File

@ -71,6 +71,7 @@ struct _SpiceStream {
int currow; int currow;
/* some more variables for .wav */ /* some more variables for .wav */
int bps; /* bit per sample */ int bps; /* bit per sample */
int idxcol; // throw away any index column
}; };

View File

@ -55,42 +55,42 @@ ascii_process_header(SpiceStream *ss, char *line, VarType ivtype );
*/ */
int sf_rdhdr_cazm( SpiceStream *ss ) int sf_rdhdr_cazm( SpiceStream *ss )
{ {
int done = 0; int done = 0;
VarType ivtype; VarType ivtype;
char *line; char *line;
int ret; int ret;
while( ! done) { while( ! done) {
if ( (line = fdbuf_get_line(ss->linebuf)) == NULL || if ( (line = fdbuf_get_line(ss->linebuf)) == NULL ||
fdbuf_get_lineno(ss->linebuf) > 30) { fdbuf_get_lineno(ss->linebuf) > 30) {
return 0; return 0;
} }
/* "section header" line */ /* "section header" line */
if(strncmp (line, "TRANSIENT", 9) == 0) { if(strncmp (line, "TRANSIENT", 9) == 0) {
ivtype = TIME; ivtype = TIME;
done = 1; done = 1;
} else if (strncmp(line, "AC ANALYSIS", 11) == 0) { } else if (strncmp(line, "AC ANALYSIS", 11) == 0) {
ivtype = FREQUENCY; ivtype = FREQUENCY;
done = 1; done = 1;
} else if (strncmp(line, "TRANSFER", 8) == 0) { } else if (strncmp(line, "TRANSFER", 8) == 0) {
/* DC transfer function - ivar might also be current, /* DC transfer function - ivar might also be current,
* but we can't tell */ * but we can't tell */
ivtype = VOLTAGE; ivtype = VOLTAGE;
done = 1; done = 1;
} }
} }
/* /*
* line after header contains signal names * line after header contains signal names
* first one is assumed to be the independent variable. * first one is assumed to be the independent variable.
*/ */
if ( (line = fdbuf_get_line(ss->linebuf)) == NULL ) { if ( (line = fdbuf_get_line(ss->linebuf)) == NULL ) {
return 0; return 0;
} }
ret = ascii_process_header(ss, line, ivtype ); ret = ascii_process_header(ss, line, ivtype );
msg_dbg("%s : 'cazm' file format with %d columns", ss->filename, ss->ncols); msg_dbg("%s : 'cazm' file format with %d columns", ss->filename, ss->ncols);
return ret; return ret;
} }
@ -99,39 +99,39 @@ int sf_rdhdr_cazm( SpiceStream *ss )
*/ */
int sf_rdhdr_ascii( SpiceStream *ss ) int sf_rdhdr_ascii( SpiceStream *ss )
{ {
char *cp; char *cp;
char *line; char *line;
int ret; int ret;
/* /*
* first line is expected to contain space-seperated * first line is expected to contain space-seperated
* variable names. * variable names.
* first one is assumed to be the independent variable. * first one is assumed to be the independent variable.
*/ */
if ( (line = fdbuf_get_line(ss->linebuf)) == NULL) { if ( (line = fdbuf_get_line(ss->linebuf)) == NULL) {
return 0; return 0;
} }
/* /*
* Check for non-ascii characters in header, to reject * Check for non-ascii characters in header, to reject
* binary files. * binary files.
*/ */
for (cp = line; *cp; cp++) { for (cp = line; *cp; cp++) {
if ( ! isgraph(*cp) && *cp != ' ' && *cp != '\t') { if ( ! isgraph(*cp) && *cp != ' ' && *cp != '\t') {
return -1; return -1;
} }
} }
/* /*
* Remove some characters at beginning of the line * Remove some characters at beginning of the line
*/ */
cp = line + strspn( line, "#! " ) ; /* skip characters in arg 2 */ cp = line + strspn( line, "#! " ) ; /* skip characters in arg 2 */
if ( cp > line ) { if ( cp > line ) {
dbuf_strcpy( (DBuf *) ss->linebuf, cp); dbuf_strcpy( (DBuf *) ss->linebuf, cp);
} }
ret = ascii_process_header(ss, ((DBuf *) ss->linebuf)->s, UNKNOWN ); ret = ascii_process_header(ss, ((DBuf *) ss->linebuf)->s, UNKNOWN );
msg_dbg("%s : 'ascii' file format with %d columns", ss->filename, ss->ncols); msg_dbg("%s : 'ascii' file format with %d columns", ss->filename, ss->ncols);
return ret; return ret;
} }
@ -139,40 +139,50 @@ int sf_rdhdr_ascii( SpiceStream *ss )
* Process a header line from an ascii or cazm format file. * Process a header line from an ascii or cazm format file.
* Returns a filled-in SpiceStream* with variable information. * Returns a filled-in SpiceStream* with variable information.
*/ */
static int static int
ascii_process_header(SpiceStream *ss, char *line, VarType ivtype ) ascii_process_header(SpiceStream *ss, char *line, VarType ivtype )
{ {
char *signam; char *signam;
signam = strtok(line, " \t\n"); signam = strtok(line, " \t\n");
if ( ! signam) { if ( ! signam) {
msg_error(_("line %d: syntax error in header"), fdbuf_get_lineno(ss->linebuf)); msg_error(_("line %d: syntax error in header"), fdbuf_get_lineno(ss->linebuf));
return -1; return -1;
} }
if ( ivtype == UNKNOWN) { if (app_strcasestr(signam, "index") ) {
if (app_strcasestr(signam, "time") ) { ss->idxcol = 0;
ivtype = TIME; // Skip to next token in header
} signam = strtok(NULL, " \t\n");
} if ( ! signam) {
spicestream_var_add( ss, signam, ivtype, 1 ); msg_error(_("line %d: syntax error in header"), fdbuf_get_lineno(ss->linebuf));
return -1;
}
}
ss->ntables = 1; if ( ivtype == UNKNOWN) {
ss->ncols = 1; if (app_strcasestr(signam, "time") ) {
while ((signam = strtok(NULL, " \t\n")) != NULL) { ivtype = TIME;
spicestream_var_add( ss, signam, UNKNOWN, 1 ); }
ss->ncols++; }
} spicestream_var_add( ss, signam, ivtype, 1 );
/* give a name to the set from filename */ ss->ntables = 1;
if ( (signam = strrchr( ss->filename, '/')) ) { ss->ncols = 1;
signam++; while ((signam = strtok(NULL, " \t\n")) != NULL) {
} else { spicestream_var_add( ss, signam, UNKNOWN, 1 );
signam = ss->filename; ss->ncols++;
} }
dataset_dup_setname(ss->wds, signam );
ss->flags = SSF_PUSHBACK | SSF_NORDHDR | SSF_CPVARS; /* give a name to the set from filename */
return 1; if ( (signam = strrchr( ss->filename, '/')) ) {
signam++;
} else {
signam = ss->filename;
}
dataset_dup_setname(ss->wds, signam );
ss->flags = SSF_PUSHBACK | SSF_NORDHDR | SSF_CPVARS;
return 1;
} }
@ -189,89 +199,97 @@ ascii_process_header(SpiceStream *ss, char *line, VarType ivtype )
int sf_readrow_ascii(SpiceStream *ss) int sf_readrow_ascii(SpiceStream *ss)
{ {
int i; int i;
char *tok; char *tok;
char *line; char *line;
if ( (line = fdbuf_get_line(ss->linebuf)) == NULL) { if ( (line = fdbuf_get_line(ss->linebuf)) == NULL) {
return 0; /* EOF */ return 0; /* EOF */
} }
tok = strtok(line, " \t\n"); tok = strtok(line, " \t\n");
if ( ! tok) { if ( ! tok) {
return -2; /* blank line can indicate end of data */ return -2; /* blank line can indicate end of data */
} }
/* // skip index column
* check to see if it is numeric: ascii format is so loosly defined if (ss->idxcol >= 0) {
* that we might read a load of garbage otherwise. tok = strtok(NULL, " \t\n");
*/ if ( ! tok) {
if (strspn(tok, "0123456789eE+-.") != strlen(tok)) { return -2; /* blank line can indicate end of data */
msg_error(_("%s:\nline %d: expected number; maybe this isn't an ascii data file at all?"), }
ss->filename, ss->linebuf->lineno ); }
return -1;
}
double val = g_ascii_strtod(tok, NULL); /*
spicestream_val_add( ss, val); * 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)) {
msg_error(_("%s:\nline %d: expected number; maybe this isn't an ascii data file at all?"),
ss->filename, ss->linebuf->lineno );
return -1;
}
for (i = 0; i < ss->ncols - 1; i++) { double val = g_ascii_strtod(tok, NULL);
tok = strtok(NULL, " \t\n"); spicestream_val_add( ss, val);
if ( ! tok) {
msg_error(_("%s:%d: data field %d missing"), for (i = 0; i < ss->ncols - 1; i++) {
ss->linebuf->filename, ss->linebuf->lineno ); tok = strtok(NULL, " \t\n");
return -1; if ( ! tok) {
} msg_error(_("%s:%d: data field %d missing"),
val = g_ascii_strtod(tok, NULL); ss->linebuf->filename, ss->linebuf->lineno );
spicestream_val_add( ss, val); return -1;
} }
return 1; val = g_ascii_strtod(tok, NULL);
spicestream_val_add( ss, val);
}
return 1;
} }
void sf_write_file_ascii( FILE *fd, WaveTable *wt, char *fmt) void sf_write_file_ascii( FILE *fd, WaveTable *wt, char *fmt)
{ {
int i; int i;
int j; int j;
int k = 0; int k = 0;
char *c = ""; char *c = "";
char format[64]; char format[64];
WDataSet *wds = wavetable_get_dataset( wt, k); WDataSet *wds = wavetable_get_dataset( wt, k);
WaveVar *var = g_ptr_array_index( wds->vars, 0); WaveVar *var = g_ptr_array_index( wds->vars, 0);
// double min = wavevar_val_get_min(var); // double min = wavevar_val_get_min(var);
// double max = wavevar_val_get_max(var); // double max = wavevar_val_get_max(var);
// fprintf( stdout, "min %f, max %f\n", min, max); // fprintf( stdout, "min %f, max %f\n", min, max);
for ( i = 0 ; i < wds->ncols ; i++ ){ for ( i = 0 ; i < wds->ncols ; i++ ){
var = g_ptr_array_index( wds->vars, i); var = g_ptr_array_index( wds->vars, i);
fprintf( fd, "%s%s", c, var->varName); fprintf( fd, "%s%s", c, var->varName);
c = " "; c = " ";
} }
fprintf( fd, "\n"); fprintf( fd, "\n");
if ( ! fmt ) { if ( ! fmt ) {
fmt = "%.10g"; fmt = "%.10g";
} }
sprintf( format, "%%s%s", fmt ); sprintf( format, "%%s%s", fmt );
while ( (wds = wavetable_get_dataset( wt, k )) ){ while ( (wds = wavetable_get_dataset( wt, k )) ){
if ( k > 0 ) { if ( k > 0 ) {
fprintf( fd, "\n"); fprintf( fd, "\n");
} }
for ( i = 0 ; i < wds->nrows ; i++ ){ for ( i = 0 ; i < wds->nrows ; i++ ){
c = ""; c = "";
for ( j = 0 ; j < wds->ncols ; j++ ){ for ( j = 0 ; j < wds->ncols ; j++ ){
double val = dataset_val_get( wds, i, j ); double val = dataset_val_get( wds, i, j );
if ( j == 0 ){ if ( j == 0 ){
fprintf( fd, fmt, val); fprintf( fd, fmt, val);
} else { } else {
fprintf( fd, format, c, val); fprintf( fd, format, c, val);
} }
c = " "; c = " ";
} }
fprintf( fd, "\n"); fprintf( fd, "\n");
} }
k++; k++;
} }
} }