Enable spice notations like 2n or 5m in filesource inputs
Tests that spaces or tabs are o.k.
This commit is contained in:
parent
53564f2b98
commit
4ed89173f2
|
|
@ -1,12 +1,12 @@
|
|||
* input test
|
||||
0 0 1
|
||||
10e-6 0.1 0.9
|
||||
20e-6 0.2 0.8
|
||||
30e-6 0.3 0.7
|
||||
40e-6 0.4 0.6
|
||||
50e-6 0.5 0.5
|
||||
60e-6 0.6 0.4
|
||||
70e-6 0.7 0.3
|
||||
80e-6 0.8 0.2
|
||||
90e-6 0.9 0.1
|
||||
100e-6 1 0
|
||||
0 0 1m
|
||||
10u 0.1m 0.9m
|
||||
20u 0.2m 0.8m
|
||||
30u 0.3m 0.7m
|
||||
40u 0.4m 0.6m
|
||||
50u 0.5m 0.5m
|
||||
60u 0.6m 0.4m
|
||||
70u 0.7m 0.3m
|
||||
80u 0.8m 0.2m
|
||||
90u 0.9m 0.1m
|
||||
100u 1m 0
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ AUTHORS
|
|||
27 Feb 2017 Marcel Hendrix
|
||||
23 JUL 2018 Holger Vogt
|
||||
11 Aug 2025 Holger Vogt
|
||||
01 Aug 2026 Holger Vogt
|
||||
|
||||
|
||||
MODIFICATIONS
|
||||
|
|
@ -55,8 +56,8 @@ NON-STANDARD FEATURES
|
|||
|
||||
/*=== CONSTANTS ========================*/
|
||||
|
||||
|
||||
|
||||
#define OK 0
|
||||
#define FAIL 1
|
||||
|
||||
/*=== MACROS ===========================*/
|
||||
|
||||
|
|
@ -104,13 +105,220 @@ typedef struct {
|
|||
|
||||
} Local_Data_t;
|
||||
|
||||
typedef char line_t[82]; /* A SPICE size line. <= 80 characters plus '\n\0' */
|
||||
|
||||
|
||||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||
|
||||
|
||||
/*=== Static CNV_get_spice_value ROUTINE =============*/
|
||||
|
||||
/*
|
||||
Function takes as input a string token from a SPICE
|
||||
deck and returns a floating point equivalent value.
|
||||
*/
|
||||
|
||||
|
||||
static int cnv_get_spice_value(
|
||||
char *str, /* IN - The value text e.g. 1.2K */
|
||||
double *p_value ) /* OUT - The numerical value */
|
||||
{
|
||||
|
||||
|
||||
/* the following were "int4" devices - jpm */
|
||||
size_t len;
|
||||
size_t i;
|
||||
int n_matched;
|
||||
|
||||
line_t val_str;
|
||||
|
||||
/*char *suffix;*/
|
||||
char c = ' ';
|
||||
char c1;
|
||||
|
||||
double scale_factor;
|
||||
double value;
|
||||
|
||||
|
||||
/* Scan the input string looking for an alpha character that is not */
|
||||
/* 'e' or 'E'. Such a character is assumed to be an engineering */
|
||||
/* suffix as defined in the Spice 2G.6 user's manual. */
|
||||
|
||||
len = strlen(str);
|
||||
if( len > (sizeof(val_str) - 1))
|
||||
len = sizeof(val_str) - 1;
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
c = str[i];
|
||||
if( isalpha_c(c) && (c != 'E') && (c != 'e') )
|
||||
break;
|
||||
else if( isspace_c(c) )
|
||||
break;
|
||||
else
|
||||
val_str[i] = c;
|
||||
}
|
||||
val_str[i] = '\0';
|
||||
|
||||
|
||||
/* Determine the scale factor */
|
||||
|
||||
if( (i >= len) || (! isalpha_c(c)) )
|
||||
scale_factor = 1.0;
|
||||
else {
|
||||
|
||||
if(isupper_c(c))
|
||||
c = tolower_c(c);
|
||||
|
||||
switch(c) {
|
||||
|
||||
case 't':
|
||||
scale_factor = 1.0e12;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
scale_factor = 1.0e9;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
scale_factor = 1.0e3;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
scale_factor = 1.0e-6;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
scale_factor = 1.0e-9;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
scale_factor = 1.0e-12;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
scale_factor = 1.0e-15;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
scale_factor = 1.0e-18;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
i++;
|
||||
if(i >= len) {
|
||||
scale_factor = 1.0e-3;
|
||||
break;
|
||||
}
|
||||
c1 = str[i];
|
||||
if(! isalpha_c(c1)) {
|
||||
scale_factor = 1.0e-3;
|
||||
break;
|
||||
}
|
||||
if(islower_c(c1))
|
||||
c1 = toupper_c(c1);
|
||||
if(c1 == 'E')
|
||||
scale_factor = 1.0e6;
|
||||
else if(c1 == 'I')
|
||||
scale_factor = 25.4e-6;
|
||||
else
|
||||
scale_factor = 1.0e-3;
|
||||
break;
|
||||
|
||||
default:
|
||||
scale_factor = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the numeric portion to a float and multiply by the */
|
||||
/* scale factor. */
|
||||
|
||||
n_matched = sscanf(val_str,"%le",&value);
|
||||
|
||||
if(n_matched < 1) {
|
||||
*p_value = 0.0;
|
||||
return(FAIL);
|
||||
}
|
||||
|
||||
*p_value = value * scale_factor;
|
||||
return(OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=== Static CNVgettok ROUTINE ================*/
|
||||
/*
|
||||
Get the next token from the input string. The input string pointer
|
||||
is advanced to the following token and the token from the input
|
||||
string is copied to malloced storage and a pointer to that storage
|
||||
is returned. The original input string is undisturbed.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static char *CNVgettok(char **s)
|
||||
|
||||
{
|
||||
|
||||
char *buf; /* temporary storage to copy token into */
|
||||
/*char *temp;*/ /* temporary storage to copy token into */
|
||||
char *ret_str; /* storage for returned string */
|
||||
|
||||
int i;
|
||||
|
||||
/* allocate space big enough for the whole string */
|
||||
|
||||
buf = (char *) malloc(strlen(*s) + 1);
|
||||
|
||||
/* skip over any white space */
|
||||
|
||||
while(isspace_c(**s) || (**s == '=') ||
|
||||
(**s == '(') || (**s == ')') || (**s == ','))
|
||||
(*s)++;
|
||||
|
||||
/* isolate the next token */
|
||||
|
||||
switch(**s) {
|
||||
|
||||
case '\0': /* End of string found */
|
||||
if(buf) free(buf);
|
||||
return(NULL);
|
||||
|
||||
|
||||
default: /* Otherwise, we are dealing with a */
|
||||
/* string representation of a number */
|
||||
/* or a mess o' characters. */
|
||||
i = 0;
|
||||
while( (**s != '\0') &&
|
||||
(! ( isspace_c(**s) || (**s == '=') ||
|
||||
(**s == '(') || (**s == ')') ||
|
||||
(**s == ',')
|
||||
) ) ) {
|
||||
buf[i] = **s;
|
||||
i++;
|
||||
(*s)++;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
/* skip over white space up to next token */
|
||||
|
||||
while(isspace_c(**s) || (**s == '=') ||
|
||||
(**s == '(') || (**s == ')') || (**s == ','))
|
||||
(*s)++;
|
||||
|
||||
/* make a copy using only the space needed by the string length */
|
||||
|
||||
|
||||
ret_str = (char *) malloc(strlen(buf) + 1);
|
||||
ret_str = strcpy(ret_str,buf);
|
||||
|
||||
if(buf) free(buf);
|
||||
|
||||
return(ret_str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
FUNCTION void cm_filesource()
|
||||
|
|
@ -277,13 +485,14 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
free(cpdel);
|
||||
continue;
|
||||
}
|
||||
t = strtod(cp, &cp2);
|
||||
if (cp2 == cp) {
|
||||
char *ncp = CNVgettok(&cp);
|
||||
int ret = cnv_get_spice_value(ncp, &t);
|
||||
free(ncp);
|
||||
if (ret == FAIL) {
|
||||
free(cpdel);
|
||||
terr = MIF_TRUE;
|
||||
continue;
|
||||
}
|
||||
cp = cp2;
|
||||
if (!PARAM_NULL(timescale))
|
||||
t *= PARAM(timescale);
|
||||
if (!PARAM_NULL(timerelative) && PARAM(timerelative) == MIF_TRUE)
|
||||
|
|
@ -295,7 +504,7 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
|
||||
/* before storing, check if vector size is large enough.
|
||||
If not, add another 1000*size doubles */
|
||||
if (count > (int) loc->indata->vecallocated - size) {
|
||||
if (count > (int) loc->indata->vecallocated - stepsize) {
|
||||
loc->indata->vecallocated += (size_t) (size * 1000);
|
||||
void * const p = realloc(loc->indata->datavec,
|
||||
sizeof(double) * loc->indata->vecallocated);
|
||||
|
|
@ -311,12 +520,13 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
for (i = 0; i < size; ++i) {
|
||||
while (*cp && (isspace_c(*cp) || *cp == ','))
|
||||
++cp;
|
||||
d = strtod(cp, &cp2);
|
||||
if (cp2 == cp) {
|
||||
char *ncp = CNVgettok(&cp);
|
||||
int ret = cnv_get_spice_value(ncp, &d);
|
||||
free(ncp);
|
||||
if (ret == FAIL) {
|
||||
derr = MIF_TRUE;
|
||||
break;
|
||||
}
|
||||
cp = cp2;
|
||||
if (i < amplscalesize)
|
||||
d *= PARAM(amplscale[i]);
|
||||
if (i < amploffssize)
|
||||
|
|
|
|||
Loading…
Reference in New Issue