@ -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 ) ;
tx free ( yy ) ;
tx free ( 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 = 180 n - - > . subckt name 1 2 3 w = 9u
/ / l = 180 n . 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 = 180 n - - >
/ / . subckt name 1 2 3 w = 9u l = 180 n
/ / . 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 " , t itle_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 \n What 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 , newm type , 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 n ested . 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 = { 1 G } )
. MODEL SWN VSWITCH ( VON = { 0.55 } VOFF = { 0.49 }
RON = { 1 / ( 2 * M * ( W / LE ) * ( KPN / 2 ) * 10 ) } ROFF = { 1 G } )
* by
as1 % vd ( DG GND ) % gd ( D S ) aswn
. model aswn aswitch ( cntl_off = { 0.49 } cntl_on = { 0.55 } r_off = { 1 G }
@ -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 = { 1 G } )
* RON = { 1 / ( 2 * M * ( W / LE ) * ( KPN / 2 ) * 10 ) } ROFF = { 1 G } )
* by
* a1 % v ( DG ) % gd ( D S ) swa
* . MODEL SWA aswitch ( cntl_off = 0.49 cntl_on = 0.55 r_off = 1 G
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 ] ) ;