Used Win32 function PathIsRelativeA() to identify an absolute path instead of checking the string since the system function may handle more cases (network shares, etc.). Also reviewed formatting that was done on inpcom.c by a code beautifier in an earlier commit. Nearly all of it was an improvement, but a few cases were reverted back to closer to the original form. One particular instance was comments where a list of steps was given one per line.

This commit is contained in:
Jim Monte 2019-12-09 23:01:28 -05:00 committed by Holger Vogt
parent eddd2827ec
commit be8bd7b40e
1 changed files with 231 additions and 197 deletions

View File

@ -9,6 +9,13 @@ Author: 1985 Wayne A. Christopher
Central function is inp_readall()
*/
/* Note: Must include shlwapi.h before ngspice header defining BOOL due
* to conflict */
#ifdef _WIN32
#include <shlwapi.h> /* for definition of PathIsRelativeA() */
#pragma comment(lib, "Shlwapi.lib")
#endif
#include "ngspice/ngspice.h"
#include "ngspice/compatmode.h"
@ -47,8 +54,8 @@ Author: 1985 Wayne A. Christopher
/*#define TRACE*/
/* globals -- wanted to avoid complicating inp_readall interface */
#define N_LIBRARIES 1000
#define N_PARAMS 1000
#define N_LIBRARIES 1000
#define N_PARAMS 1000
#define N_SUBCKT_W_PARAMS 4000
#define NPARAMS 10000
@ -69,7 +76,8 @@ struct names {
int num_names;
};
struct function_env {
struct function_env
{
struct function_env *up;
struct function {
@ -79,10 +87,11 @@ struct function_env {
char *params[N_PARAMS];
int num_parameters;
const char *accept;
} * functions;
} *functions;
};
struct func_temper {
struct func_temper
{
char *funcname;
int subckt_depth;
int subckt_count;
@ -307,7 +316,7 @@ static struct library *read_a_lib(char *y, char *dir_name)
return NULL;
}
#if defined(__MINGW32__) || defined(_MSC_VER)
#if defined(_WIN32)
yy = _fullpath(NULL, y_resolved, 0);
#else
yy = realpath(y_resolved, NULL);
@ -342,8 +351,8 @@ static struct library *read_a_lib(char *y, char *dir_name)
fclose(newfp);
}
tfree(yy);
tfree(y_resolved);
txfree(yy);
txfree(y_resolved);
return lib;
}
@ -556,13 +565,21 @@ static COMPATMODE_T ngspice_compat_mode(void)
store contents in string new_title
process .lib lines
read file and library name, open file using fcn inp_pathopen()
read file contents and put into struct libraries[].deck, one entry per .lib
line process .inc lines read file and library name, open file using fcn
inp_pathopen() read file contents and add lines to cc make line entry lower
case allow for shell end of line continuation (\\) add '+' to beginning of
next line add line entry to list cc add '.global gnd' add libraries find
library section add lines add .end card strip end-of-line comments make
continuation lines a single line
read file contents and put into struct libraries[].deck, one entry per .lib line
process .inc lines
read file and library name, open file using fcn inp_pathopen()
read file contents and add lines to cc
make line entry lower case
allow for shell end of line continuation (\\)
add '+' to beginning of next line
add line entry to list cc
add '.global gnd'
add libraries
find library section
add lines
add .end card
strip end-of-line comments
make continuation lines a single line
*** end of processing for command files ***
start preparation of input deck for numparam
...
@ -716,16 +733,16 @@ struct card *inp_readall(FILE *fp, char *dir_name, bool comfile, bool intfile,
for (t = cc->nextcard; t; t = t->nextcard) {
if (*(t->line) == '*')
continue;
fprintf(fd, "%6d %6d %s\n", t->linenum_orig, t->linenum,
t->line);
fprintf(fd, "%6d %6d %s\n",
t->linenum_orig, t->linenum, t->line);
}
fprintf(fd,
"\n****************** complete deck "
"***************\n\n");
/* now completely */
for (t = cc; t; t = t->nextcard)
fprintf(fd, "%6d %6d %s\n", t->linenum_orig, t->linenum,
t->line);
fprintf(fd, "%6d %6d %s\n",
t->linenum_orig, t->linenum, t->line);
fclose(fd);
fprintf(stdout,
@ -763,8 +780,8 @@ struct inp_read_t inp_read(
int line_count = 0;
#endif
char *new_title = NULL;
int line_number =
1; /* sjb - renamed to avoid confusion with struct card */
int line_number = 1;
/* sjb - renamed to avoid confusion with struct card */
int line_number_orig = 1;
int cirlinecount = 0; /* length of circarray */
static int is_control = 0; /* We are reading from a .control section */
@ -828,8 +845,9 @@ struct inp_read_t inp_read(
#else
buffer = readline(fp);
if (!buffer)
if (!buffer) {
break;
}
#endif
}
@ -839,8 +857,9 @@ struct inp_read_t inp_read(
printf("in inp_read, just read %s", buffer);
#endif
if (!buffer)
if (!buffer) {
continue;
}
/* OK -- now we have loaded the next line into 'buffer'. Process it.
*/
@ -983,10 +1002,9 @@ struct inp_read_t inp_read(
end->linenum = line_number++;
end->linenum_orig = line_number_inc++;
}
end->linenum =
line_number++; /* SJB - renumber the last line */
end->linenum_orig =
line_number_inc++; /* SJB - renumber the last line */
end->linenum = line_number++; /* SJB - renumber last line */
end->linenum_orig = line_number_inc++;
/* SJB - renumber the last line */
}
/* Fix the buffer up a bit. */
@ -1122,10 +1140,10 @@ struct inp_read_t inp_read(
}
*s = '\0'; /* Zap the newline. */
if ((s - 1) >= buffer &&
*(s - 1) ==
'\r') /* Zop the carriage return under windows */
*(s - 1) = '\0';
if ((s - 1) >= buffer && s[- 1] == '\r') {
/* Zap the carriage return under windows */
s[- 1] = '\0';
}
}
/* find the true .end command out of .endc, .ends, .endl, .end
@ -1214,17 +1232,18 @@ struct inp_read_t inp_read(
}
static bool is_absolute_pathname(const char *p)
/* Returns true if path is an absolute path and false if it is a
* relative path. No check is done for the existance of the path. */
inline static bool is_absolute_pathname(const char *path)
{
#if defined(__MINGW32__) || defined(_MSC_VER)
/* /... or \... or D:\... or D:/... */
return p[0] == DIR_TERM || p[0] == DIR_TERM_LINUX ||
(isalpha_c(p[0]) && p[1] == ':' &&
(p[2] == DIR_TERM_LINUX || p[2] == DIR_TERM));
#ifdef _WIN32
return !PathIsRelativeA(path);
#else
return p[0] == DIR_TERM;
return path[0] == DIR_TERM;
#endif
}
} /* end of funciton is_absolute_pathname */
#if 0
@ -1232,7 +1251,7 @@ static bool is_absolute_pathname(const char *p)
static bool
is_plain_filename(const char *p)
{
#if defined(__MINGW32__) || defined(_MSC_VER)
#if defined(_WIN32)
return
!strchr(p, DIR_TERM) &&
!strchr(p, DIR_TERM_LINUX);
@ -1270,7 +1289,7 @@ static char *inp_pathresolve(const char *name)
struct variable *v;
struct stat st;
#if defined(__MINGW32__) || defined(_MSC_VER)
#if defined(_WIN32)
/* If variable 'mingwpath' is set: convert mingw /d/... to d:/... */
if (cp_getvar("mingwpath", CP_BOOL, NULL, 0) &&
@ -1299,8 +1318,8 @@ static char *inp_pathresolve(const char *name)
switch (v->va_type) {
case CP_STRING:
cp_wstrip(v->va_string);
(void) sprintf(
buf, "%s%s%s", v->va_string, DIR_PATHSEP, name);
(void) sprintf(buf, "%s%s%s",
v->va_string, DIR_PATHSEP, name);
break;
case CP_NUM:
(void) sprintf(buf, "%d%s%s", v->va_num, DIR_PATHSEP, name);
@ -1729,9 +1748,11 @@ static bool chk_for_line_continuation(char *line)
//
// change .macro --> .subckt
// .eom --> .ends
// .subckt name 1 2 3 params: w=9u l=180n --> .subckt name 1 2 3 w=9u
// l=180n .subckt name (1 2 3) --> .subckt name 1 2 3 x1 (1 2 3) --> x1
// 1 2 3 .param func1(x,y) = {x*y} --> .func func1(x,y) {x*y}
// .subckt name 1 2 3 params: w=9u l=180n -->
// .subckt name 1 2 3 w=9u l=180n
// .subckt name (1 2 3) --> .subckt name 1 2 3
// x1 (1 2 3) --> x1 1 2 3
// .param func1(x,y) = {x*y} --> .func func1(x,y) {x*y}
static void inp_fix_macro_param_func_paren_io(struct card *card)
{
@ -1758,8 +1779,8 @@ static void inp_fix_macro_param_func_paren_io(struct card *card)
if (ciprefix(".subckt", card->line) || ciprefix("x", card->line)) {
/* remove () */
str_ptr = skip_non_ws(
card->line); // skip over .subckt, instance name
str_ptr = skip_non_ws(card->line);
// skip over .subckt, instance name
str_ptr = skip_ws(str_ptr);
if (ciprefix(".subckt", card->line)) {
str_ptr = skip_non_ws(str_ptr); // skip over subckt name
@ -1774,9 +1795,9 @@ static void inp_fix_macro_param_func_paren_io(struct card *card)
}
str_ptr++;
}
card->line = inp_remove_ws(
card->line); /* remove the extra white spaces just
introduced */
/* Remove the extra white spaces just introduced */
card->line = inp_remove_ws(card->line);
}
}
@ -1915,66 +1936,69 @@ static int is_a_modelname(const char *s)
/* not beeing a valid number */
testval = strtod(s, &st);
/* conversion failed, so no number */
if (eq(s, st))
if (eq(s, st)) {
return TRUE;
}
/* test if we have a true number */
else if (*st == '\0' || isspace(*st))
if (*st == '\0' || isspace(*st)) {
return FALSE;
else {
/* look for the scale factor (alphabetic) and skip it.
* INPevaluate will not do it because is does not swallow
* the scale factor from the string.
*/
switch (*st) {
case 't':
case 'T':
case 'g':
case 'G':
case 'k':
case 'K':
case 'u':
case 'U':
case 'n':
case 'N':
case 'p':
case 'P':
case 'f':
case 'F':
st = st + 1;
break;
case 'm':
case 'M':
if (((st[1] == 'E') || (st[1] == 'e')) &&
((st[2] == 'G') || (st[2] == 'g'))) {
st = st + 3; /* Meg */
}
else if (((st[1] == 'I') || (st[1] == 'i')) &&
((st[2] == 'L') || (st[2] == 'l'))) {
st = st + 3; /* Mil */
}
else {
st = st + 1; /* m, milli */
}
break;
default:
break;
}
/* test if we have a true scale factor */
if (*st == '\0' || isspace(*st))
return FALSE;
}
/* test if people use Ohms, F, H for RLC, like pF or uOhms */
if (ciprefix("ohms", st))
st = st + 4;
else if (ciprefix("farad", st))
st = st + 5;
else if (ciprefix("henry", st))
st = st + 5;
else if ((*st == 'f') || (*st == 'h'))
/* look for the scale factor (alphabetic) and skip it.
* INPevaluate will not do it because is does not swallow
* the scale factor from the string.
*/
switch (*st) {
case 't':
case 'T':
case 'g':
case 'G':
case 'k':
case 'K':
case 'u':
case 'U':
case 'n':
case 'N':
case 'p':
case 'P':
case 'f':
case 'F':
st = st + 1;
break;
case 'm':
case 'M':
if (((st[1] == 'E') || (st[1] == 'e')) &&
((st[2] == 'G') || (st[2] == 'g'))) {
st = st + 3; /* Meg */
}
else if (((st[1] == 'I') || (st[1] == 'i')) &&
((st[2] == 'L') || (st[2] == 'l'))) {
st = st + 3; /* Mil */
}
else {
st = st + 1; /* m, milli */
}
break;
default:
break;
}
/* test if we have a true scale factor */
if (*st == '\0' || isspace(*st))
return FALSE;
if (*st == '\0' || isspace(*st))
return FALSE;
/* test if people use Ohms, F, H for RLC, like pF or uOhms */
if (ciprefix("ohms", st))
st = st + 4;
else if (ciprefix("farad", st))
st = st + 5;
else if (ciprefix("henry", st))
st = st + 5;
else if ((*st == 'f') || (*st == 'h'))
st = st + 1;
if (*st == '\0' || isspace(*st)) {
return FALSE;
}
/* token starts with non alphanum character */
@ -2213,7 +2237,7 @@ static void comment_out_unused_subckt_models(struct card *start_card)
}
if (remove_subckt)
*line = '*';
*line = '*'; /* make line a comment */
#if 0
else if (has_models &&
(ciprefix(".model", line) || ciprefix(".cmodel", line))) {
@ -2306,7 +2330,7 @@ static char *inp_spawn_brace(char *s)
/*-------------------------------------------------------------------------*
removes " " quotes, returns lower case letters,
replaces non-printable characterss with '_', however if
replaces non-printable characters with '_', however if
non-printable character is the only character in a line,
replace it by '*'
*-------------------------------------------------------------------------*/
@ -2378,8 +2402,7 @@ static void inp_stripcomments_deck(struct card *c, bool cf)
* Comments on a continuation line (i.e. line begining with '+') are allowed
* and are removed before lines are stitched.
* Lines that contain only an end-of-line comment with or without leading
white
* space are also allowed.
* white space are also allowed.
If there is only white space before the end-of-line comment the
the whole line is converted to a normal comment line (i.e. one that
@ -4759,11 +4782,11 @@ static void inp_compat(struct card *card)
}
// Exxx n1 n2 int1 0 1
ckt_array[0] = tprintf("%s %s %s %s_int1 0 1", title_tok,
node1, node2, title_tok);
ckt_array[0] = tprintf("%s %s %s %s_int1 0 1",
title_tok, node1, node2, title_tok);
// BExxx int1 0 V = {equation}
ckt_array[1] = tprintf("b%s %s_int1 0 v = %s", title_tok,
title_tok, str_ptr);
ckt_array[1] = tprintf("b%s %s_int1 0 v = %s",
title_tok, title_tok, str_ptr);
// comment out current variable e line
*(card->line) = '*';
@ -4820,8 +4843,8 @@ static void inp_compat(struct card *card)
}
else
m_token = copy("1");
ckt_array[0] = tprintf("%s %s %s %s_int1 0 %s", title_tok,
node1, node2, title_tok, m_token);
ckt_array[0] = tprintf("%s %s %s %s_int1 0 %s",
title_tok, node1, node2, title_tok, m_token);
// skip "table"
cut_line = skip_ws(cut_line);
if (!ciprefix("table", cut_line)) {
@ -4834,9 +4857,8 @@ static void inp_compat(struct card *card)
if (*cut_line == '=')
*cut_line++ = ' ';
// get the expression
str_ptr = gettok_char(&cut_line, '{', FALSE, FALSE);
expression = gettok_char(
&cut_line, '}', TRUE, TRUE); /* expression */
str_ptr = gettok_char(&cut_line, '{', FALSE, FALSE);
expression = gettok_char(&cut_line, '}', TRUE, TRUE);
if (!expression || !str_ptr) {
fprintf(stderr, "Error: bad syntax in line %d\n %s\n",
card->linenum_orig, card->line);
@ -4936,11 +4958,11 @@ static void inp_compat(struct card *card)
// Gxxx n1 n2 int1 0 1
// or
// Gxxx n1 n2 int1 0 m='expr'
ckt_array[0] = tprintf("%s %s %s %s_int1 0 %s", title_tok,
node1, node2, title_tok, m_token);
ckt_array[0] = tprintf("%s %s %s %s_int1 0 %s",
title_tok, node1, node2, title_tok, m_token);
// BGxxx int1 0 V = {equation}
ckt_array[1] = tprintf("b%s %s_int1 0 v = %s", title_tok,
title_tok, str_ptr);
ckt_array[1] = tprintf("b%s %s_int1 0 v = %s",
title_tok, title_tok, str_ptr);
// comment out current variable g line
*(card->line) = '*';
@ -4980,14 +5002,14 @@ static void inp_compat(struct card *card)
vbFxxx int1 0 0
*/
// Fxxx n1 n2 VBFxxx -1
ckt_array[0] = tprintf("%s %s %s vb%s -1", title_tok, node1,
node2, title_tok);
ckt_array[0] = tprintf("%s %s %s vb%s -1",
title_tok, node1, node2, title_tok);
// BFxxx BFxxx_int1 0 I = I(vnam)*{equation}
ckt_array[1] = tprintf("b%s %s_int1 0 i = i(%s) * (%s)",
title_tok, title_tok, vnamstr, equastr);
// VBFxxx int1 0 0
ckt_array[2] =
tprintf("vb%s %s_int1 0 dc 0", title_tok, title_tok);
ckt_array[2] = tprintf("vb%s %s_int1 0 dc 0",
title_tok, title_tok);
// comment out current variable f line
*(card->line) = '*';
// insert new three lines immediately after current line
@ -5026,8 +5048,8 @@ static void inp_compat(struct card *card)
vbHxxx int1 0 0
*/
// Hxxx n1 n2 VBHxxx -1
ckt_array[0] = tprintf("%s %s %s vb%s -1", title_tok, node1,
node2, title_tok);
ckt_array[0] = tprintf("%s %s %s vb%s -1",
title_tok, node1, node2, title_tok);
// BHxxx BHxxx_int1 0 I = I(vnam)*{equation}
ckt_array[1] = tprintf("b%s %s_int1 0 i = i(%s) * (%s)",
title_tok, title_tok, vnamstr, equastr);
@ -5323,8 +5345,8 @@ static void inp_compat(struct card *card)
}
}
// Fxxx n-aux 0 Bxxx 1
ckt_array[0] = tprintf(
"f%s %s_int2 0 b%s -1", title_tok, title_tok, title_tok);
ckt_array[0] = tprintf("f%s %s_int2 0 b%s -1",
title_tok, title_tok, title_tok);
// Lxxx n-aux 0 1
ckt_array[1] = tprintf("l%s %s_int2 0 1", title_tok, title_tok);
// Bxxx n1 n2 V = v(n-aux) * equation
@ -5378,13 +5400,13 @@ static void inp_compat(struct card *card)
* + <TD=td> <FROM=val> <TO=val>
* + <CROSS=# | CROSS=LAST> <RISE=#|RISE=LAST> <FALL=#|FALL=LAST>
*
* .MEASURE {DC|AC|TRAN} result FIND out_variable WHEN
out_variable2=val
* .MEASURE {DC|AC|TRAN} result FIND out_variable
* + WHEN out_variable2=val
* + <TD=td> <FROM=val> <TO=val>
* + <CROSS=# | CROSS=LAST> <RISE=#|RISE=LAST> <FALL=#|FALL=LAST>
*
* .MEASURE {DC|AC|TRAN} result FIND out_variable WHEN
out_variable2=out_variable3
* .MEASURE {DC|AC|TRAN} result FIND out_variable
* + WHEN out_variable2=out_variable3
* + <TD=td>
* + <CROSS=# | CROSS=LAST> <RISE=#|RISE=LAST> <FALL=#|FALL=LAST>
*
@ -5392,7 +5414,7 @@ static void inp_compat(struct card *card)
* + <FROM=val> <TO=val>
*
* .MEASURE {DC|AC|TRAN} result {AVG|MIN|MAX|MIN_AT|MAX_AT|PP|RMS}
out_variable
* + out_variable
* + <TD=td> <FROM=val> <TO=val>
*
* .MEASURE {DC|AC|TRAN} result INTEG<RAL> out_variable
@ -5400,22 +5422,20 @@ static void inp_compat(struct card *card)
*
* .MEASURE {DC|AC|TRAN} result DERIV<ATIVE> out_variable AT=val
*
* .MEASURE {DC|AC|TRAN} result DERIV<ATIVE> out_variable WHEN
out_variable2=val
* .MEASURE {DC|AC|TRAN} result DERIV<ATIVE> out_variable
* + WHEN out_variable2=val
* + <TD=td>
* + <CROSS=# | CROSS=LAST> <RISE=#|RISE=LAST> <FALL=#|FALL=LAST>
*
* .MEASURE {DC|AC|TRAN} result DERIV<ATIVE> out_variable WHEN
out_variable2=out_variable3
* .MEASURE {DC|AC|TRAN} result DERIV<ATIVE> out_variable
* + WHEN out_variable2=out_variable3
* + <TD=td>
* + <CROSS=# | CROSS=LAST> <RISE=#|RISE=LAST> <FALL=#|FALL=LAST>
The user may set any out_variable to par(' expr ').
We have to replace this by v(pa_xx) and generate a B source line.
*
-----------------------------------------------------------------
*/
* ------------------------------------------------------------ */
if (ciprefix(".meas", curr_line)) {
if (strstr(curr_line, "par(") == NULL)
continue;
@ -5436,15 +5456,16 @@ static void inp_compat(struct card *card)
// find expression
beg_ptr = end_ptr = str_ptr + 5;
while ((*end_ptr != ' ') && (*end_ptr != '=') &&
(*end_ptr != '\0'))
(*end_ptr != '\0')) {
end_ptr++;
}
exp_ptr = copy_substring(beg_ptr, end_ptr - 2);
cut_line = str_ptr;
// generate node
out_ptr = tprintf("pa_%02d", (int) pai);
// Bout_ptr out_ptr 0 V = v(expr_ptr)
ckt_array[pai] = tprintf(
"b%s %s 0 v = %s", out_ptr, out_ptr, exp_ptr);
ckt_array[pai] = tprintf("b%s %s 0 v = %s",
out_ptr, out_ptr, exp_ptr);
ckt_array[++pai] = NULL;
// length of the replacement V(out_ptr)
del_ptr = copy_ptr = tprintf("v(%s)", out_ptr);
@ -5472,8 +5493,8 @@ static void inp_compat(struct card *card)
// generate node
out_ptr = tprintf("pa_%02d", (int) pai);
// Bout_ptr out_ptr 0 V = v(expr_ptr)
ckt_array[pai] = tprintf(
"b%s %s 0 v = %s", out_ptr, out_ptr, exp_ptr);
ckt_array[pai] = tprintf("b%s %s 0 v = %s",
out_ptr, out_ptr, exp_ptr);
ckt_array[++pai] = NULL;
// length of the replacement V(out_ptr)
del_ptr = copy_ptr = tprintf("v(%s)", out_ptr);
@ -5539,8 +5560,8 @@ static void inp_compat(struct card *card)
// generate node
out_ptr = tprintf("pa_%02d", (int) pai);
// Bout_ptr out_ptr 0 V = v(expr_ptr)
ckt_array[pai] = tprintf(
"b%s %s 0 v = %s", out_ptr, out_ptr, exp_ptr);
ckt_array[pai] = tprintf("b%s %s 0 v = %s",
out_ptr, out_ptr, exp_ptr);
ckt_array[++pai] = NULL;
// length of the replacement V(out_ptr)
del_ptr = copy_ptr = tprintf("%s", out_ptr);
@ -5558,7 +5579,7 @@ static void inp_compat(struct card *card)
tfree(out_ptr);
}
// or we have '={par({ ... })}'
else if (ciprefix("={par({", (str_ptr - 2))) {
else if (ciprefix("={par({", str_ptr - 2)) {
// find myoutput
beg_ptr = end_ptr = str_ptr - 2;
@ -5572,8 +5593,8 @@ static void inp_compat(struct card *card)
end_ptr++;
exp_ptr = copy_substring(beg_ptr, end_ptr - 3);
// Bout_ptr out_ptr 0 V = v(expr_ptr)
ckt_array[pai] = tprintf(
"b%s %s 0 v = %s", out_ptr, out_ptr, exp_ptr);
ckt_array[pai] = tprintf("b%s %s 0 v = %s",
out_ptr, out_ptr, exp_ptr);
ckt_array[++pai] = NULL;
// length of the replacement V(out_ptr)
del_ptr = copy_ptr = tprintf("%s", out_ptr);
@ -5807,15 +5828,17 @@ static bool inp_temper_compat(struct card *card)
* and other keywords like TEMPER. --> Only parameter replacement in numparam
*/
static char *inp_modify_exp(char *expr)
static char *inp_modify_exp(/* NOT CONST */ char *expr)
{
char *s;
wordlist *wl = NULL, *wlist = NULL;
/* scan the expression and remove all '{' and '}' */
for (s = expr; *s; s++)
if ((*s == '{') || (*s == '}'))
/* Scan the expression and replace all '{' and '}' with ' ' */
for (s = expr; *s; s++) {
if ((*s == '{') || (*s == '}')) {
*s = ' ';
}
}
/* scan the expression */
s = expr;
@ -5860,8 +5883,9 @@ static char *inp_modify_exp(char *expr)
else if ((c == '>') || (c == '<') || (c == '!') || (c == '=')) {
/* >=, <=, !=, ==, <>, ... */
char *beg = s++;
if ((*s == '=') || (*s == '<') || (*s == '>'))
if ((*s == '=') || (*s == '<') || (*s == '>')) {
s++;
}
wl->wl_word = copy_substring(beg, s);
}
else if ((c == '|') || (c == '&')) {
@ -5876,8 +5900,9 @@ static char *inp_modify_exp(char *expr)
int i = 0;
if (((c == 'v') || (c == 'i')) && (s[1] == '(')) {
while (*s != ')')
while (*s != ')') {
buf[i++] = *s++;
}
buf[i++] = *s++;
buf[i] = '\0';
wl->wl_word = copy(buf);
@ -5927,8 +5952,9 @@ static char *inp_modify_exp(char *expr)
double dvalue = INPevaluate(&s, &error1, 0);
wl->wl_word = tprintf("%18.10e", dvalue);
/* skip the `unit', FIXME INPevaluate() should do this */
while (isalpha_c(*s))
while (isalpha_c(*s)) {
s++;
}
}
else { /* strange char */
printf("Preparing expression for numparam\nWhat is this?\n%s\n",
@ -6257,9 +6283,11 @@ static void inp_fix_temper_in_param(struct card *deck)
sub_count[j] = 0;
/* first pass: determine all .param with temper inside and replace by
.func .param xxx1 = 'temper + 25' will become .func xxx1() 'temper +
25'
*/
* .func
* .param xxx1 = 'temper + 25'
* will become
* .func xxx1() 'temper + 25'
*/
card = deck;
for (; card; card = card->nextcard) {
@ -6858,7 +6886,8 @@ static void inp_vdmos_model(struct card *deck)
/* storage for devices which get voltage source added */
struct replace_currm {
struct replace_currm
{
struct card *s_start;
struct card *cline;
char *rtoken;
@ -6989,8 +7018,9 @@ static void inp_meas_current(struct card *deck)
}
/* return if we did not find any i( */
if (rep == NULL)
if (rep == NULL) {
return;
}
/* scan through all the devices, search for xyz, modify node 1 by adding
_vmeas, add a line with zero voltage v_xyz, having original node 1 and
@ -7069,8 +7099,8 @@ static void inp_meas_current(struct card *deck)
/* Add _vmeas only once to first device node.
Continue if we already have modified device "tok" */
if (!strstr(node1, "_vmeas")) {
new_line = tprintf(
"%s %s_vmeas_%d %s", tok, node1, sn, curr_line);
new_line = tprintf("%s %s_vmeas_%d %s",
tok, node1, sn, curr_line);
tfree(card->line);
card->line = new_line;
}
@ -7079,8 +7109,8 @@ static void inp_meas_current(struct card *deck)
/* We have already added a line v_xyz to the deck */
if (!ciprefix(new_tok, card->nextcard->line)) {
/* add new line */
new_line = tprintf(
"%s %s %s_vmeas_%d 0", new_tok, node1, node1, sn);
new_line = tprintf("%s %s %s_vmeas_%d 0",
new_tok, node1, node1, sn);
/* insert new_line after card->line */
insert_new_line(card, new_line, card->linenum + 1, 0);
}
@ -7102,12 +7132,13 @@ static void inp_meas_current(struct card *deck)
}
/* replace the E source TABLE function by a B source pwl
(used by ST OpAmps and comparators).
E_RO_3 VB_3 VB_4 VALUE={ TABLE( V(VCCP,VCCN), 2 , 35 , 3.3 , 15 , 5 , 10
)*I(VreadIo)} will become BE_RO_3_1 TABLE_NEW_1 0 v = pwl( V(VCCP,VCCN), 2
, 35 , 3.3 , 15 , 5 , 10 ) E_RO_3 VB_3 VB_4 VALUE={
V(TABLE_NEW_1)*I(VreadIo)}
*/
* (used by ST OpAmps and comparators).
* E_RO_3 VB_3 VB_4 VALUE={ TABLE( V(VCCP,VCCN), 2 , 35 , 3.3 , 15 , 5 , 10
* )*I(VreadIo)}
* will become
* BE_RO_3_1 TABLE_NEW_1 0 v = pwl( V(VCCP,VCCN), 2 , 35 , 3.3 , 15 , 5 , 10
* ) E_RO_3 VB_3 VB_4 VALUE={ V(TABLE_NEW_1)*I(VreadIo)}
*/
static void replace_table(struct card *startcard)
{
struct card *card;
@ -7124,8 +7155,8 @@ static void replace_table(struct card *startcard)
/* get the table function */
char *tabfun = gettok_char(&ftablebeg, ')', TRUE, TRUE);
/* the new e line */
char *neweline = tprintf(
"%s v(table_new_%d)%s", begline, numb, ftablebeg);
char *neweline = tprintf("%s v(table_new_%d)%s",
begline, numb, ftablebeg);
char *newbline =
tprintf("btable_new_%d table_new_%d 0 v=pwl%s",
numb, numb, tabfun + 5);
@ -7182,8 +7213,8 @@ static struct card *find_model(struct card *startcard,
controlled_exit(1);
}
/* we have got it */
char *newmodcard = tprintf(".model %s %s %s%s", newmname,
newmtype, origmodline, endstr);
char *newmodcard = tprintf(".model %s %s %s%s",
newmname, newmtype, origmodline, endstr);
char *tmpstr = strstr(newmodcard, ")(");
if (tmpstr) {
tmpstr[0] = ' ';
@ -7206,7 +7237,7 @@ static struct card *find_model(struct card *startcard,
}
/* do the .model replacement required by ako (a kind of)
* PSPICE does not support ested .subckt definitions, so
* PSPICE does not support nested .subckt definitions, so
* a simple structure is needed: search for ako:modelname,
* then for modelname in the subcircuit or in the top level.
* .model qorig npn (BF=48 IS=2e-7)
@ -7360,8 +7391,8 @@ static bool del_models(struct vsmodels *vsmodel)
* add .functions limit, pwr, pwrs, stp, if, int
* replace
S1 D S DG GND SWN
.MODEL SWN VSWITCH(VON = { 0.55 } VOFF = { 0.49 } RON = { 1 / (2 * M*(W /
LE)*(KPN / 2) * 10) } ROFF = { 1G })
.MODEL SWN VSWITCH(VON = { 0.55 } VOFF = { 0.49 }
RON = { 1 / (2 * M*(W / LE)*(KPN / 2) * 10) } ROFF = { 1G })
* by
as1 %vd(DG GND) % gd(D S) aswn
.model aswn aswitch(cntl_off={0.49} cntl_on={0.55} r_off={1G}
@ -7468,8 +7499,8 @@ static struct card *pspice_compat(struct card *oldcard)
tctok[-1] = '\0';
char *newstring;
if (tc1 && tc2)
newstring =
tprintf("%s tc1=%s tc2=%s", cut_line, tc1, tc2);
newstring = tprintf("%s tc1=%s tc2=%s",
cut_line, tc1, tc2);
else if (tc1)
newstring = tprintf("%s tc1=%s", cut_line, tc1);
else {
@ -7616,8 +7647,9 @@ static struct card *pspice_compat(struct card *oldcard)
while (*cut_line && !isspace(*cut_line))
if (!isdigit(*cut_line++))
is_node4 = FALSE; // already model name
if (is_node4)
if (is_node4) {
cut_line = nexttok(cut_line); // model name
}
}
if (cut_line && *cut_line &&
atof(cut_line) > 0.0) { // size of area is a real number
@ -7667,12 +7699,12 @@ static struct card *pspice_compat(struct card *oldcard)
/* replace
* S1 D S DG GND SWN
* .MODEL SWN VSWITCH ( VON = {0.55} VOFF = {0.49}
RON={1/(2*M*(W/LE)*(KPN/2)*10)} ROFF={1G} )
* RON={1/(2*M*(W/LE)*(KPN/2)*10)} ROFF={1G} )
* by
* a1 %v(DG) %gd(D S) swa
* .MODEL SWA aswitch(cntl_off=0.49 cntl_on=0.55 r_off=1G
r_on={1/(2*M*(W/LE)*(KPN/2)*10)} log=TRUE)
* r_on={1/(2*M*(W/LE)*(KPN/2)*10)} log=TRUE)
*
* simple hierachy, as nested subcircuits are not allowed in PSPICE */
/* first scan: find the vswitch models, transform them and put them into a
@ -7827,9 +7859,11 @@ static void pspice_compat_a(struct card *oldcard)
* Replace
* D1 A K SDMOD
* .MODEL SDMOD D (Roff=1000 Ron=0.7 Rrev=0.2 Vfwd=1 Vrev=10 Revepsilon=0.2
* Epsilon=0.2 Ilimit=7 Revilimit=7) by ad1 a k asdmod .model asdmod
* sidiode(Roff=1000 Ron=0.7 Rrev=0.2 Vfwd=1 Vrev=10 Revepsilon=0.2
* Epsilon=0.2 Ilimit=7 Revilimit=7)
* Epsilon=0.2 Ilimit=7 Revilimit=7)
* by
* ad1 a k asdmod
* .model asdmod sidiode(Roff=1000 Ron=0.7 Rrev=0.2 Vfwd=1 Vrev=10
* Revepsilon=0.2 Epsilon=0.2 Ilimit=7 Revilimit=7)
*/
struct card *ltspice_compat(struct card *oldcard)
{
@ -7856,13 +7890,13 @@ struct card *ltspice_compat(struct card *oldcard)
/* replace
* D1 A K SDMOD
* .MODEL SDMOD D (Roff=1000 Ron=0.7 Rrev=0.2 Vfwd=1 Vrev=10
Revepsilon=0.2 Epsilon=0.2 Ilimit=7 Revilimit=7)
* Revepsilon=0.2 Epsilon=0.2 Ilimit=7 Revilimit=7)
* by
* a1 a k SDMOD
* .model SDMOD sidiode(Roff=1000 Ron=0.7 Rrev=0.2 Vfwd=1 Vrev=10
Revepsilon=0.2 Epsilon=0.2 Ilimit=7 Revilimit=7)
* Revepsilon=0.2 Epsilon=0.2 Ilimit=7 Revilimit=7)
* Do this if one of the parameters, which are uncommon to standard diode
model, has been found.
* model, has been found.
* simple hierachy, as nested subcircuits are not allowed in PSPICE */
@ -7961,14 +7995,14 @@ struct card *ltspice_compat(struct card *oldcard)
if ((nesting > 0) &&
find_a_model(modelsfound, stoks[3], subcktline->line)) {
tfree(card->line);
card->line = tprintf("a%s %s %s a%s", stoks[0], stoks[1],
stoks[2], stoks[3]);
card->line = tprintf("a%s %s %s a%s",
stoks[0], stoks[1], stoks[2], stoks[3]);
}
/* if model is not within same subcircuit, search at top level */
else if (find_a_model(modelsfound, stoks[3], "top")) {
tfree(card->line);
card->line = tprintf("a%s %s %s a%s", stoks[0], stoks[1],
stoks[2], stoks[3]);
card->line = tprintf("a%s %s %s a%s",
stoks[0], stoks[1], stoks[2], stoks[3]);
}
for (i = 0; i < 4; i++)
tfree(stoks[i]);