Merge branch 'pre-master' of ssh://git.code.sf.net/p/ngspice/ngspice into beta_jdm
Fixed some uses of const
Changed dstring to use allocations that are serialized by mutex when
needed
but can fail without terminating the program. Also changed calls to free()
to
use a replacement (txfree()) that will serialize when necessary.
Removed flag fields from Model_Info_t and Node_Info_t since they were no
longer required.
Reverted OK back to 0 in cmpp. There were issues with OK conflicting with
another macro definition of OK due to a header inclusion.
Added functions for writing new code model and UDN information.
Added function output_paths_from_lst_file() to extract paths in more
general
lst format.
Used new function fbget() in cmpp to get data from lst file.
Made reomval of trailing slash in cmpp an inline function for modularity.
Removed restrictions on line length and related items in cmpp by
dynamically
resizizng as required.
Reduced the number of allocation calls when storing model info and
user-defined type information in cmpp while reading lst files by doubling
the
size when resizing rather than increasing the size by 1. Also added checks
for
failure that were not present. These things were also done for
user-defined
types, which are processed in a similar way.
Fixed potential buffer overrun in cmpp function read_model_names() while
building the path. Also the path name is built more efficiently by
maintining
the current location in the output string instead of repeatedly finding it
via
strcat(). These things were also done for the corresponding function for
user-defined nodes.
To support versioning, a group of "filebuf" functions were written to get
the
path names and version numbers from a .lst file having a more flexible
format.
Added checks for failure in cmpp function read_model_names() while setting
the
name of the model and the function.
Developed a more modular and efficient method of testing for duplicate
SPICE
models, etc. in cmpp. Instead of nested for loops, the items are compared
in a
sorted order, so that a single pass needs to be done. This method also
avoids
the need of several flag variables that are used to check if a duplicate
is
being found multiple times. A related functions test_for_duplicates() was
written to perform a generic test of any of the uniquness conditions
checked,
along with a sort function and functions to report errors.
In cmpp, function fopen_cmpp was changed into a function that generates
the
file name but does not open the file (gen_filename()) followed by a
standard
fopen. This change prevented error messages from fopen_cmpp() from causing
an
access violation of the name of the file was not allocated properly. It
also
separtes the input file name from the output file name, so it is clearer
what
is being freed when the output file name is freed at the end of the
function.
Added checks for failure of fclose() in several places. Often a small file
is
not written at all on disk until fclose is called.
Added a function to write version 2 code model info into cminfo2.h. A
similar
function was written for udninfo.h.
Wrote functions to free Model_Info_t and Node_Info_t structures.
Added checks to all output file operations to ensure that the files that
are
generated are correct. This change involved adding tests to the individual
functions outputting data and adding return codes and checks of them in
functions doing output.
Combined several small file outputs into larger ones while adjusting the
format of the text being ouptut to keep the clarity of what is being
written
while reducing the number of function calls.
In functions like cmpp function dta_type_to_str(), strings were returned
directly instead of making a copy that was not necessary. This change
eliminated the copy, made the functions thread safe, and eliminated
allocations. The allocations were not checked for failure, so the change
also
prevented problems associated with failures of these allocations.
In value_to_string(), the elimination of the allocation and copy were not
possible due to retain the value of the string, but the allocation was
checked
for failure where it was not and the resize was also checked.
In integer_to_str(), a buffer size was used that was a function of the
size of
the data to fill it rather than an unrelated size that was most likely too
large. Also due to the reduced size, a stack-based buffer was used.
Fixed a bug in table-generator-b4-2d.sp where the plot names are incorrect
if
the script is called from a running instance of ngspice that has already
created some plot names that would cause conflicts. Also commented this
issue.
Added functions to the structure communicating between ngspice and code
models
to support required memory functions so that the code models, which are
running in the same address space, will have serialized allocations when
that
is required.
Reorganized memory allocations to allow for "raw" allocations that are
serialized when required. Essentially the allocation functions were
decomposed
into part that does not require serialization and part that does. Aside
from
exposing the "raw" allocations, this change made the functions clearer and
fixed an issue where free was being called without mutex protection when
it
would be required. Also, tstrdup() and tstrdup_raw() were written so that
serialization would be available in strdup(). If the other allocation
functions require serialization, then strdup() does also. There were some
issues fixed with the "garbage collect" versions of the allocation
functions.
moved src/misc/alloc.h to src/include/ngspice/alloc.h. This change was
done
because one of the builds (only MinGW) was having problems finding it in
one
case. The others were searching the include path while MinGW was using the
path of the including file as its base. While that issue may have been
corrected, this change was beneficial because there were many files
including
alloc.h through a long path of ../.. from include. As part of this change,
those includes were fixed also.
Loading code models and user-defined types was enhanced to handle
versioning.
Additionally, the copying of error messages along with a potential buffer
overrun was completely eliminated by using the string directly. Following
the
use, a macro FEEE_DLERR_MSG(msg) was added to free the string in Windows.
In
other OS where dlerror() does not require its string to be freed, the
macro
expands to nothing.
In cm_analog_alloc() the number of doubles required was corrected.
Fixed Maiefile.am to include new files.
Fixed the macro definition of strdup in Windows so that it will not
confilct
with the definition provided when CRT memory debugging is used.
Updated usage message for cmpp to provide information about the -p flag.
Added diagnostic messages when running cmpp if the macro DEBUG_CMPP is
enabled. These were entirely removed from the mainline code flow except
for a
single macro PRINT_CMPP_INFO(argc, argv)
Changed free functions in rm_ifs_table from txfree() to a regular free()
since
cmpp does not ever require mutex serialization. Also, its allocations are
done
using standard malloc(), calloc(), and realloc(), so free() is more
appropriate.
Modified change_extension() so that it will append a dot plus the new
extension
in the case where the original file does not have an extension. This case
is
not used in cmpp, but it seems more correct since the new extension being
supplied does not come with a leading dot.
Added check in call to change_extension() for failure.
Added function vprint_error() to cmpp/util.c and defined print_eror in
terms
of vprint_error(). The intent was to be able to call vprint_error()
directly.
Subsequent changes to the code removed the call to vprint_error(), but the
function was left since it is a useful utility function.
Modified src/xspice/icm/GNUmakefile.in to use cmpp -p to obtain a path
list.
Converted all code models supplied with ngspice to
1) Use the "talloc" functions so that their allocations will be serialized
when necesary
2) Check for allocation failure in all cases
3) Free resources on exit
4) Supply version information in the corresponding .lst file
Modified icm/dlmain.c to include version 2 information.
visualc/make-install-vngspiced.bat was changed in two ways. First sime
actions
were preceeded by checks to avoid error messages if they were
unconditionally
performed. Seond, code models were copied to a second location besides
the
destination used by a "production" ngspice. This second location along
with an
spinit file to use them allows debugging of multiple versions of
ngspice
concurrently.
visualc/xspice/aux-cfunc.bat was modified to print additional
diagnostic
messages during a build, much like the compiler outputs file names.
Also, cmpp
-p was made the method to get the list of directories. Finally, the
actions of
visualc/xspice/aux-udnfunc.bat were added to aux-cfunc.bat since that
file was
already doing two of the three actions, and calling aux-udnfunc.bat
alone or
in the wrong order would cause an error. aux-udnfunc.bat was commented
out and
probably should be removed at some later time.
This commit is contained in:
commit
da9bcc050f
|
|
@ -19,10 +19,10 @@
|
|||
# Add (optionally) --enable-relpath to avoid absolute paths when searching for code models.
|
||||
# It might be necessary to uncomment and run ./autogen.sh .
|
||||
|
||||
if test "$1" = "64"; then
|
||||
if [ ! -d "release64" ]; then
|
||||
mkdir release64
|
||||
if [ $? -ne 0 ]; then echo "mkdir release64 failed"; exit 1 ; fi
|
||||
if test "$1" = "32"; then
|
||||
if [ ! -d "release32" ]; then
|
||||
mkdir release32
|
||||
if [ $? -ne 0 ]; then echo "mkdir release32 failed"; exit 1 ; fi
|
||||
fi
|
||||
else
|
||||
if [ ! -d "release" ]; then
|
||||
|
|
@ -42,20 +42,20 @@ if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi
|
|||
#if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi
|
||||
|
||||
echo
|
||||
if test "$1" = "64"; then
|
||||
cd release64
|
||||
if [ $? -ne 0 ]; then echo "cd release64 failed"; exit 1 ; fi
|
||||
echo "configuring for 64 bit"
|
||||
echo
|
||||
# You may add --enable-adms to the following command for adding adms generated devices
|
||||
../configure --with-x --enable-xspice --enable-cider --with-readline=yes --enable-openmp --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
|
||||
else
|
||||
cd release
|
||||
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
|
||||
if test "$1" = "32"; then
|
||||
cd release32
|
||||
if [ $? -ne 0 ]; then echo "cd release32 failed"; exit 1 ; fi
|
||||
echo "configuring for 32 bit"
|
||||
echo
|
||||
# You may add --enable-adms to the following command for adding adms generated devices
|
||||
../configure --with-x --enable-xspice --enable-cider --with-readline=yes --enable-openmp --disable-debug CFLAGS="-m32 -O2" LDFLAGS="-m32 -s"
|
||||
else
|
||||
cd release
|
||||
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
|
||||
echo "configuring for 64 bit"
|
||||
echo
|
||||
# You may add --enable-adms to the following command for adding adms generated devices
|
||||
../configure --with-x --enable-xspice --enable-cider --with-readline=yes --enable-openmp --disable-debug CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
|
||||
fi
|
||||
if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
# (allows to generate either 32 or 64 bit executables by setting flag -m32 or -m64)
|
||||
# set path to compiler in msys/xx/etc/fstab (e.g. c:/MinGW64 /mingw)
|
||||
# start compiling with
|
||||
# './compile_min.sh' or './compile_min.sh 64'
|
||||
# './compile_min.sh 32' or './compile_min.sh'
|
||||
# As an (more recent) alternative install MSYS2 and the tools cited above.
|
||||
|
||||
# Options:
|
||||
|
|
@ -25,10 +25,10 @@
|
|||
# Add (optionally) --enable-relpath to avoid absolute paths when searching for code models.
|
||||
# It might be necessary to uncomment and run ./autogen.sh .
|
||||
|
||||
if test "$1" = "64"; then
|
||||
if [ ! -d "release64" ]; then
|
||||
mkdir release64
|
||||
if [ $? -ne 0 ]; then echo "mkdir release64 failed"; exit 1 ; fi
|
||||
if test "$1" = "32"; then
|
||||
if [ ! -d "release32" ]; then
|
||||
mkdir release32
|
||||
if [ $? -ne 0 ]; then echo "mkdir release32 failed"; exit 1 ; fi
|
||||
fi
|
||||
else
|
||||
if [ ! -d "release" ]; then
|
||||
|
|
@ -48,20 +48,20 @@ fi
|
|||
#if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi
|
||||
|
||||
echo
|
||||
if test "$1" = "64"; then
|
||||
cd release64
|
||||
if [ $? -ne 0 ]; then echo "cd release64 failed"; exit 1 ; fi
|
||||
echo "configuring for 64 bit"
|
||||
echo
|
||||
# You may add --enable-adms to the following command for adding adms generated devices
|
||||
../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --disable-debug prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
|
||||
else
|
||||
cd release
|
||||
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
|
||||
if test "$1" = "32"; then
|
||||
cd release32
|
||||
if [ $? -ne 0 ]; then echo "cd release32 failed"; exit 1 ; fi
|
||||
echo "configuring for 32 bit"
|
||||
echo
|
||||
# You may add --enable-adms to the following command for adding adms generated devices
|
||||
../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --disable-debug prefix="C:/Spice" CFLAGS="-m32 -O2" LDFLAGS="-m32 -s"
|
||||
else
|
||||
cd release
|
||||
if [ $? -ne 0 ]; then echo "cd release failed"; exit 1 ; fi
|
||||
echo "configuring for 64 bit"
|
||||
echo
|
||||
# You may add --enable-adms to the following command for adding adms generated devices
|
||||
../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --disable-debug prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s"
|
||||
fi
|
||||
if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ if test "x$ext_CFLAGS" != xyes; then
|
|||
else
|
||||
AC_DEFINE([NGDEBUG], [1], [Compile with debug info])
|
||||
if test "x$GCC" = xyes; then
|
||||
CFLAGS="-g -O1"
|
||||
CFLAGS="-g -O0"
|
||||
else
|
||||
CFLAGS="-g"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
logic test, PSPICE
|
||||
* requires 'set ngbehavior=psa'
|
||||
|
||||
v8 8 0 1 Pulse (0 1 0.45 1m 1m 5 10)
|
||||
v9 9 0 0
|
||||
|
||||
B1 1 0 V=~(~v(9)&v(8)) + 0.5
|
||||
|
||||
.control
|
||||
tran 1m 1
|
||||
plot v(1) v(8) v(9)
|
||||
listing
|
||||
.endc
|
||||
|
||||
.end
|
||||
|
|
@ -17,7 +17,7 @@ vdd dd 0 dc 'vcc'
|
|||
|
||||
* 10 MHz reference frequency
|
||||
* PULSE(V1 V2 TD TR TF PW PER)
|
||||
vref ref 0 dc 0 pulse(0 'vcc' 10n 1n 1n '1/fref/2' '1/fref')
|
||||
vref ref 0 dc 0 pulse(0 'vcc' 10n 2n 2n '1/fref/2' '1/fref')
|
||||
abridgeref [ref] [d_ref] adc_vbuf
|
||||
.model adc_vbuf adc_bridge(in_low = 0.5 in_high = 0.5)
|
||||
|
||||
|
|
@ -66,7 +66,10 @@ abridge-w1 [d_divout d_ref d_Un d_D] [s1 s2 u1 d1] dac1 ; change to d_u or d_Un
|
|||
|
||||
.control
|
||||
save cont s1 s2 u1 d1
|
||||
iplot cont
|
||||
let isbmode = $?batchmode
|
||||
if isbmode = 0
|
||||
iplot cont
|
||||
endif
|
||||
* calculate breakpoint for switching frequency
|
||||
let t1_3 = simtime/3
|
||||
set ti1_3 ="$&t1_3"
|
||||
|
|
@ -80,7 +83,7 @@ let pw2 = per2/2
|
|||
let per3=1/f3
|
||||
let pw3 = per3/2
|
||||
*simulate
|
||||
tran 0.1n $&simtime 0 0.5n uic
|
||||
tran 10n $&simtime 0 1n uic
|
||||
*change frequency after stopping
|
||||
* first pair of [] without spaces, second pair with spaces
|
||||
alter @vref[pulse] = [ 0 3.3 10n 1n 1n $&pw2 $&per2 ]
|
||||
|
|
@ -89,8 +92,11 @@ resume
|
|||
alter @vref[pulse] = [ 0 3.3 10n 1n 1n $&pw3 $&per3 ]
|
||||
resume
|
||||
rusage
|
||||
plot cont s1 s2+1.2 u1+2.4 d1+3.6 xlimit 15u 16u
|
||||
*plot cont
|
||||
if isbmode = 0
|
||||
plot cont s1 s2+1.2 u1+2.4 d1+3.6 xlimit 15u 16u
|
||||
else
|
||||
write pll.raw all
|
||||
endif
|
||||
.endc
|
||||
|
||||
*model = bsim3v3
|
||||
|
|
|
|||
|
|
@ -12,6 +12,13 @@
|
|||
* These tables will contain pure dc data. For transient simulation you may
|
||||
* need to add some capacitors to the device model for a 'real world' simulation.
|
||||
|
||||
* In case the script is called with existing DC* plots, must free up everyting
|
||||
* or the plot created will not be DC1, which will cause the later destroy
|
||||
* in the loop to remove the wrong one, and a new data sets will be added
|
||||
* at each loop iteration. Also the control variables like loopy will be hidden
|
||||
* in another plot.
|
||||
destroy all
|
||||
|
||||
*NMOS
|
||||
*.csparam vdstart=-0.1
|
||||
*.csparam vdstop=1.8
|
||||
|
|
@ -88,6 +95,9 @@ while lcy < ycount
|
|||
* end
|
||||
let xvec = i(vss)
|
||||
echo $&xvec >> $outfile
|
||||
|
||||
* Free the plot data that was just created. Then the name dc1 will be used
|
||||
* again.
|
||||
destroy dc1
|
||||
let loopy = loopy + vgstep
|
||||
let lcy = lcy + 1
|
||||
|
|
|
|||
|
|
@ -1151,7 +1151,7 @@ measure_parse_stdParams(
|
|||
)
|
||||
{
|
||||
int pCnt;
|
||||
char *p, *pName, *pValue;
|
||||
char *p, *pName = NULL, *pValue;
|
||||
double engVal1;
|
||||
|
||||
pCnt = 0;
|
||||
|
|
@ -1169,7 +1169,7 @@ measure_parse_stdParams(
|
|||
wl = wl->wl_next;
|
||||
continue;
|
||||
} else {
|
||||
sprintf(errbuf, "bad syntax of ??\n");
|
||||
sprintf(errbuf, "bad syntax. equal sign missing ?\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1179,7 +1179,8 @@ measure_parse_stdParams(
|
|||
}
|
||||
else {
|
||||
if (ft_numparse(&pValue, FALSE, &engVal1) < 0) {
|
||||
sprintf(errbuf, "bad syntax of ??\n");
|
||||
sprintf(errbuf, "bad syntax, cannot evaluate right hand side "
|
||||
"of %s=%s\n", pName, pValue);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1216,7 +1217,10 @@ measure_parse_stdParams(
|
|||
}
|
||||
|
||||
if (pCnt == 0) {
|
||||
sprintf(errbuf, "bad syntax of ??\n");
|
||||
if (pName)
|
||||
sprintf(errbuf, "bad syntax of %s\n", pName);
|
||||
else
|
||||
sprintf(errbuf, "bad syntax of\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1477,6 +1481,7 @@ get_measure2(
|
|||
)
|
||||
{
|
||||
wordlist *words, *wlTarg, *wlWhen;
|
||||
///XXX TODO -- errbuf can be overrun -- convert to dstring
|
||||
char errbuf[100];
|
||||
char *mAnalysis = NULL; // analysis type
|
||||
char *mName = NULL; // name given to the measured output
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ static int registry_value_to_ds(const char *sz_subkey,
|
|||
size_t n_byte_reserve = (size_t) n_byte_data + 1;
|
||||
if (ds_reserve(p_ds, n_byte_reserve) != 0) {
|
||||
(void) fprintf(cp_err,
|
||||
"Unable to reserve a buffer of %u bytes for data.\n",
|
||||
"Unable to reserve a buffer of %zu bytes for data.\n",
|
||||
n_byte_reserve);
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
|
|
@ -924,7 +924,8 @@ static void get_physical_processor_count(void)
|
|||
|
||||
/* Allocate buffer to get the info */
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX * const buf =
|
||||
(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *) malloc(n_byte_buf);
|
||||
(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *) TMALLOC(
|
||||
char, n_byte_buf);
|
||||
if (buf == (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *) NULL) {
|
||||
fprintf(cp_err,
|
||||
"Unable to allocate a buffer of %lu bytes "
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ DISPDEVICE device[] = {
|
|||
(disp_fn_Track_t *) nodev, (disp_fn_MakeMenu_t *) nodev, (disp_fn_MakeDialog_t *) nodev, (disp_fn_Input_t *) nodev,
|
||||
gen_DatatoScreen, },
|
||||
|
||||
{ "printf", 0, 0, 24, 80, 0, 0,
|
||||
{ "PrinterOnly", 0, 0, 24, 80, 0, 0,
|
||||
(disp_fn_Init_t *) nodev, (disp_fn_NewViewport_t *) nodev,
|
||||
(disp_fn_Close_t *) nop, (disp_fn_Clear_t *) nodev,
|
||||
(disp_fn_DrawLine_t *) nodev, (disp_fn_Arc_t *) nodev, (disp_fn_Text_t *) nodev,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
#include "ngspice/dvec.h"
|
||||
|
||||
|
||||
struct dvec *dvec_alloc(/* NOT const -- assigned to char */ char *name,
|
||||
struct dvec *dvec_alloc(
|
||||
/* not const -- given to non-const struct */ char *name,
|
||||
int type, short flags, int length, void *storage)
|
||||
{
|
||||
struct dvec * const rv = TMALLOC(struct dvec, 1);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ struct function_env
|
|||
char *body;
|
||||
char *params[N_PARAMS];
|
||||
int num_parameters;
|
||||
const char *accept;
|
||||
char *accept;
|
||||
} *functions;
|
||||
};
|
||||
|
||||
|
|
@ -7518,7 +7518,7 @@ static struct card *pspice_compat(struct card *oldcard)
|
|||
}
|
||||
}
|
||||
|
||||
/* replace & with && and | with || and *# with * # */
|
||||
/* replace & with && , | with || , *# with * # , and ~ with ! */
|
||||
for (card = newcard; card; card = card->nextcard) {
|
||||
char *t;
|
||||
char *cut_line = card->line;
|
||||
|
|
@ -7581,6 +7581,18 @@ static struct card *pspice_compat(struct card *oldcard)
|
|||
t = strstr(tt, "|");
|
||||
}
|
||||
}
|
||||
/* We may have '~' in path names or A devices */
|
||||
char *firsttok = nexttok(card->line); /* skip over whitespaces */
|
||||
if (ciprefix(".inc", firsttok) || ciprefix(".lib", firsttok) ||
|
||||
ciprefix("A", firsttok))
|
||||
continue;
|
||||
|
||||
if ((t = strstr(card->line, "~")) != NULL) {
|
||||
while (t) {
|
||||
*t = '!';
|
||||
t = strstr(t, "~");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* replace T_ABS by temp, T_REL_GLOBAL by dtemp, and T_MEASURED by TNOM
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ com_meas(wordlist *wl)
|
|||
May be in the next wl_word */
|
||||
if (token[strlen(token) - 1] == '=') {
|
||||
wl_index = wl_index->wl_next;
|
||||
if (wl_index == NULL) {
|
||||
line_in = wl_flatten(wl);
|
||||
fprintf(stderr, "\nError: meas failed due to missing token in \n meas %s \n\n", line_in);
|
||||
tfree(line_in);
|
||||
return;
|
||||
}
|
||||
vec_found = wl_index->wl_word;
|
||||
/* token may be already a value, maybe 'LAST', which we have to keep, or maybe a vector */
|
||||
if (!cieq(vec_found, "LAST")) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ extern void rem_controls(void);
|
|||
|
||||
extern IFsimulator SIMinfo;
|
||||
extern void spice_destroy_devices(void); /* FIXME need a better place */
|
||||
extern void pl_rempar(void); /* plotit.c */
|
||||
static void byemesg(void);
|
||||
static int confirm_quit(void);
|
||||
|
||||
|
|
@ -56,6 +57,7 @@ com_quit(wordlist *wl)
|
|||
gr_clean();
|
||||
cp_ccon(FALSE);
|
||||
|
||||
|
||||
/* Make sure the guy really wants to quit. */
|
||||
if (!ft_nutmeg)
|
||||
if (!noask && !confirm_quit())
|
||||
|
|
@ -90,6 +92,9 @@ com_quit(wordlist *wl)
|
|||
cp_destroy_keywords();
|
||||
destroy_ivars();
|
||||
#else
|
||||
/* remove plotting parameters */
|
||||
pl_rempar();
|
||||
|
||||
while (ft_curckt)
|
||||
com_remcirc(NULL);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ one_exp:
|
|||
|
||||
exp:
|
||||
TOK_NUM { $$ = PP_mknnode($1); }
|
||||
| TOK_STR { $$ = PP_mksnode($1); txfree($1); }
|
||||
| TOK_STR { $$ = PP_mksnode($1); txfree((void *) $1); }
|
||||
|
||||
| exp ',' exp { $$ = PP_mkbnode(PT_OP_COMMA, $1, $3); }
|
||||
| exp '+' exp { $$ = PP_mkbnode(PT_OP_PLUS, $1, $3); }
|
||||
|
|
@ -139,7 +139,7 @@ exp:
|
|||
| '~' exp { $$ = PP_mkunode(PT_OP_NOT, $2); }
|
||||
|
||||
| TOK_STR '(' exp ')' { $$ = PP_mkfnode($1, $3);
|
||||
txfree($1);
|
||||
txfree((void *) $1);
|
||||
if(!$$)
|
||||
YYABORT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,36 @@
|
|||
#include "graf.h"
|
||||
|
||||
static bool sameflag;
|
||||
|
||||
/* All these things are static so that "samep" will work.
|
||||
They are outside of plotit() to allow deleting */
|
||||
static double *xcompress = NULL, *xindices = NULL;
|
||||
static double *xlim = NULL, *ylim = NULL;
|
||||
static double *xdelta = NULL, *ydelta = NULL;
|
||||
static char *xlabel = NULL, *ylabel = NULL, *title = NULL;
|
||||
#ifdef TCL_MODULE
|
||||
#include "ngspice/tclspice.h"
|
||||
#endif
|
||||
|
||||
/* remove the malloced parameters upon ngspice quit */
|
||||
void pl_rempar(void)
|
||||
{
|
||||
txfree(xcompress);
|
||||
txfree(xindices);
|
||||
txfree(xlim);
|
||||
txfree(ylim);
|
||||
txfree(xdelta);
|
||||
txfree(ydelta);
|
||||
txfree(xlabel);
|
||||
txfree(ylabel);
|
||||
}
|
||||
|
||||
static struct dvec *vec_self(struct dvec *v);
|
||||
static struct dvec *vec_scale(struct dvec *v);
|
||||
static void find_axis_limits(double *lim, bool oneval, bool f_real,
|
||||
struct dvec *vecs,
|
||||
struct dvec *(*p_get_axis_dvec)(struct dvec *dvec),
|
||||
double *lims);
|
||||
|
||||
|
||||
static struct dvec *vec_self(struct dvec *v);
|
||||
static struct dvec *vec_scale(struct dvec *v);
|
||||
|
|
@ -258,11 +283,6 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* All these things are static so that "samep" will work. */
|
||||
static double *xcompress = NULL, *xindices = NULL;
|
||||
static double *xlim = NULL, *ylim = NULL;
|
||||
static double *xdelta = NULL, *ydelta = NULL;
|
||||
static char *xlabel = NULL, *ylabel = NULL, *title = NULL;
|
||||
static bool nointerp = FALSE;
|
||||
static GRIDTYPE gtype = GRID_LIN;
|
||||
static PLOTTYPE ptype = PLOT_LIN;
|
||||
|
|
@ -317,7 +337,11 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
|
|||
/* Build the plot command. This construction had been done with wordlists
|
||||
* and reversing, and flattening, but it is clearer as well as much more
|
||||
* efficient to use a dstring. */
|
||||
rc_ds |= ds_cat_printf(&ds_cline, "plot %s", wl_flatten(wwl->wl_next));
|
||||
{
|
||||
char * const flatstr = wl_flatten(wwl->wl_next);
|
||||
rc_ds |= ds_cat_printf(&ds_cline, "plot %s", flatstr);
|
||||
txfree(flatstr);
|
||||
}
|
||||
wl_free(wwl);
|
||||
|
||||
/* Add title, xlabel or ylabel, if available, with quotes ''. */
|
||||
|
|
@ -343,6 +367,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
|
|||
sameflag = getflag(wl, "samep");
|
||||
|
||||
if (!sameflag || !xlim) {
|
||||
txfree(xlim);
|
||||
xlim = getlims(wl, "xl", 2);
|
||||
if (!xlim) {
|
||||
xlim = getlims(wl, "xlimit", 2);
|
||||
|
|
@ -354,6 +379,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
|
|||
}
|
||||
|
||||
if (!sameflag || !ylim) {
|
||||
txfree(ylim);
|
||||
ylim = getlims(wl, "yl", 2);
|
||||
if (!ylim) {
|
||||
ylim = getlims(wl, "ylimit", 2);
|
||||
|
|
@ -365,6 +391,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
|
|||
}
|
||||
|
||||
if (!sameflag || !xcompress) {
|
||||
txfree(xcompress);
|
||||
xcompress = getlims(wl, "xcompress", 1);
|
||||
if (!xcompress) {
|
||||
xcompress = getlims(wl, "xcomp", 1);
|
||||
|
|
@ -376,6 +403,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
|
|||
}
|
||||
|
||||
if (!sameflag || !xindices) {
|
||||
txfree(xindices);
|
||||
xindices = getlims(wl, "xindices", 2);
|
||||
if (!xindices) {
|
||||
xindices = getlims(wl, "xind", 2);
|
||||
|
|
@ -387,6 +415,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
|
|||
}
|
||||
|
||||
if (!sameflag || !xdelta) {
|
||||
txfree(xdelta);
|
||||
xdelta = getlims(wl, "xdelta", 1);
|
||||
if (!xdelta) {
|
||||
xdelta = getlims(wl, "xdel", 1);
|
||||
|
|
@ -397,6 +426,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
|
|||
}
|
||||
|
||||
if (!sameflag || !ydelta) {
|
||||
txfree(ydelta);
|
||||
ydelta = getlims(wl, "ydelta", 1);
|
||||
if (!ydelta) {
|
||||
ydelta = getlims(wl, "ydel", 1);
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ int PS_NewViewport(GRAPH *graph)
|
|||
/* devdep initially contains name of output file */
|
||||
if ((plotfile = fopen((char*)graph->devdep, "w")) == NULL) {
|
||||
perror((char *) graph->devdep);
|
||||
free(graph->devdep);
|
||||
txfree(graph->devdep);
|
||||
graph->devdep = NULL;
|
||||
graph->n_byte_devdep = 0;
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -4,15 +4,15 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngspice/bool.h"
|
||||
#include "ngspice/cpextern.h"
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/wordlist.h"
|
||||
#include "ngspice/bool.h"
|
||||
|
||||
#include "variable.h"
|
||||
#include "terminal.h"
|
||||
#include "quote.h"
|
||||
#include "ngspice/cpextern.h"
|
||||
#include "streams.h"
|
||||
#include "terminal.h"
|
||||
#include "variable.h"
|
||||
|
||||
|
||||
bool cp_debug = FALSE;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
/*************
|
||||
* Header file for alloc.c
|
||||
* 1999 E. Rouat
|
||||
************/
|
||||
|
||||
#ifndef ngspice_ALLOC_H
|
||||
#define ngspice_ALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void *tmalloc(size_t num);
|
||||
void *tcalloc(size_t num, size_t size);
|
||||
void *trealloc(void *ptr, size_t num);
|
||||
void txfree(void *ptr);
|
||||
|
||||
#ifdef HAVE_LIBGC
|
||||
#include <gc/gc.h>
|
||||
|
||||
#define tmalloc_raw GC_malloc
|
||||
#define tcalloc_raw GC_calloc
|
||||
#define trealloc_raw GC_realloc
|
||||
|
||||
#else
|
||||
void *tmalloc_raw(size_t num);
|
||||
void *tcalloc_raw(size_t num, size_t size);
|
||||
void *trealloc_raw(void *ptr, size_t num);
|
||||
#endif
|
||||
|
||||
#endif /* include guard */
|
||||
|
|
@ -44,6 +44,7 @@ NON-STANDARD FEATURES
|
|||
#include "ngspice/cmconstants.h"
|
||||
#include "ngspice/cmproto.h"
|
||||
#include "ngspice/mifcmdat.h"
|
||||
#include "ngspice/mifproto.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ NON-STANDARD FEATURES
|
|||
/* The actual functions reside in ../ICM/CMutil.c */
|
||||
/* 12/17/90 */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ngspice/cmtypes.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
||||
|
|
@ -78,21 +78,11 @@ int cm_analog_set_temp_bkpt(double time);
|
|||
int cm_analog_set_perm_bkpt(double time);
|
||||
void cm_analog_not_converged(void);
|
||||
void cm_analog_auto_partial(void);
|
||||
|
||||
void cm_event_alloc(int tag, int bytes);
|
||||
void *cm_event_get_ptr(int tag, int timepoint);
|
||||
int cm_event_queue(double time);
|
||||
|
||||
char *cm_message_get_errmsg(void);
|
||||
int cm_message_send(char *msg);
|
||||
|
||||
#ifdef __GNUC__
|
||||
int cm_message_printf(const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2)));
|
||||
#else
|
||||
int cm_message_printf(const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
|
||||
int cm_message_send(const char *msg);
|
||||
double cm_netlist_get_c(void);
|
||||
double cm_netlist_get_l(void);
|
||||
|
||||
|
|
@ -111,9 +101,29 @@ FILE *cm_stream_err(void);
|
|||
|
||||
void *malloc_pj(size_t s);
|
||||
void *calloc_pj(size_t s1, size_t s2);
|
||||
void *realloc_pj(const void *ptr, size_t s);
|
||||
void free_pj(const void *ptr);
|
||||
void *realloc_pj(void *ptr, size_t s);
|
||||
void free_pj(void *ptr);
|
||||
void *tmalloc(size_t s);
|
||||
void *trealloc(void *ptr, size_t s);
|
||||
void txfree(void *ptr);
|
||||
const char *ngspice_version(void);
|
||||
void *tmalloc_raw(size_t s);
|
||||
void *tcalloc_raw(size_t n, size_t s);
|
||||
void *trealloc_raw(void *ptr, size_t s);
|
||||
char *tstrdup(const char *str_in);
|
||||
char *tstrdup_raw(const char *str_in);
|
||||
|
||||
FILE *fopen_with_path(const char *path, const char *mode);
|
||||
|
||||
#ifdef __GNUC__
|
||||
int cm_message_printf(const char *fmt, ...)
|
||||
__attribute__ ((format (__printf__, 1, 2)));
|
||||
#else
|
||||
int cm_message_printf(const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
#ifndef CM_IGNORE
|
||||
#define CM_IGNORE(x) (x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
struct coreInfo_t {
|
||||
/* MIF stuff */
|
||||
void ((*dllitf_MIF_INP2A)(CKTcircuit *, INPtables *, struct card *));
|
||||
char * ((*dllitf_MIFgetMod)(CKTcircuit *, char *, INPmodel **, INPtables *));
|
||||
char * ((*dllitf_MIFgetMod)(CKTcircuit *, const char *, INPmodel **,
|
||||
INPtables *));
|
||||
IFvalue * ((*dllitf_MIFgetValue)(CKTcircuit *, char **, int, INPtables *, char **));
|
||||
int ((*dllitf_MIFsetup)(SMPmatrix *, GENmodel *, CKTcircuit *, int *));
|
||||
int ((*dllitf_MIFunsetup)(GENmodel *, CKTcircuit *));
|
||||
|
|
@ -32,7 +33,7 @@ struct coreInfo_t {
|
|||
char * ((*dllitf_MIFgettok)(char **));
|
||||
char * ((*dllitf_MIFget_token)(char **, Mif_Token_Type_t *));
|
||||
Mif_Cntl_Src_Type_t ((*dllitf_MIFget_cntl_src_type)(Mif_Port_Type_t, Mif_Port_Type_t));
|
||||
char * ((*dllitf_MIFcopy)(char *));
|
||||
char * ((*dllitf_MIFcopy)(const char *));
|
||||
/* CM stuff */
|
||||
void ((*dllitf_cm_climit_fcn)(double, double, double, double, double, double,
|
||||
double, double, int, double *, double *, double *,
|
||||
|
|
@ -55,7 +56,7 @@ struct coreInfo_t {
|
|||
void * ((*dllitf_cm_event_get_ptr)(int, int));
|
||||
int ((*dllitf_cm_event_queue)(double));
|
||||
char * ((*dllitf_cm_message_get_errmsg)(void));
|
||||
int ((*dllitf_cm_message_send)(char *));
|
||||
int ((*dllitf_cm_message_send)(const char *));
|
||||
double ((*dllitf_cm_netlist_get_c)(void));
|
||||
double ((*dllitf_cm_netlist_get_l)(void));
|
||||
Complex_t ((*dllitf_cm_complex_set)(double, double));
|
||||
|
|
@ -71,11 +72,32 @@ struct coreInfo_t {
|
|||
/*Other stuff*/
|
||||
void * ((*dllitf_malloc_pj)(size_t));
|
||||
void * ((*dllitf_calloc_pj)(size_t, size_t));
|
||||
void * ((*dllitf_realloc_pj)(const void *, size_t));
|
||||
void ((*dllitf_free_pj)(const void *));
|
||||
void * ((*dllitf_realloc_pj)(void *, size_t));
|
||||
void ((*dllitf_free_pj)(void *));
|
||||
void * ((*dllitf_tmalloc)(size_t));
|
||||
void * ((*dllitf_trealloc)(const void *, size_t));
|
||||
void ((*dllitf_txfree)(const void *));
|
||||
void * ((*dllitf_trealloc)(void *, size_t));
|
||||
void ((*dllitf_txfree)(void *));
|
||||
|
||||
/*** VERSION 2 ADDITIONS ***/
|
||||
const char *(*dllitf_ngspice_version)(void);
|
||||
/* version string of ngspice using the cm */
|
||||
void *(*dllitf_tmalloc_raw)(size_t size);
|
||||
/* mutex-protected malloc() that will not
|
||||
* cause program termination on failure */
|
||||
void *(*dllitf_tcalloc_raw)(size_t num, size_t size);
|
||||
/* mutex-protected calloc() that will not
|
||||
* cause program termination on failure */
|
||||
void *(*dllitf_trealloc_raw)(void *p, size_t size);
|
||||
/* mutex-protected realloc() that will not
|
||||
* cause program termination on failure */
|
||||
char *(*dllitf_tstrdup)(const char *sz);
|
||||
/* mutex-protected strdup() that WILL
|
||||
* cause program termination on failure */
|
||||
char *(*dllitf_tstrdup_raw)(const char *sz);
|
||||
/* mutex-protected strdup() that will not
|
||||
* cause program termination on failure */
|
||||
};
|
||||
|
||||
#endif
|
||||
extern const struct coreInfo_t coreInfo;
|
||||
|
||||
#endif /* include guard */
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngspice/memory.h"
|
||||
|
||||
/* Error codes */
|
||||
#define DS_E_OK 0
|
||||
#define DS_E_INVALID (-1)
|
||||
|
|
@ -192,7 +194,7 @@ inline char *ds_free_move(DSTRING *p_ds, unsigned int opt)
|
|||
if (opt & DS_FREE_MOVE_OPT_FORCE_ALLOC) {
|
||||
/* Allocate to minimum size */
|
||||
size_t n_byte_alloc = p_ds->length + 1;
|
||||
char * const p_ret = (char *) malloc(n_byte_alloc);
|
||||
char * const p_ret = (char *) tmalloc_raw(n_byte_alloc);
|
||||
if (p_ret == (char *) NULL) {
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
|
@ -204,7 +206,7 @@ inline char *ds_free_move(DSTRING *p_ds, unsigned int opt)
|
|||
if (opt & DS_FREE_MOVE_OPT_COMPACT) {
|
||||
/* Allocate to minimum size */
|
||||
size_t n_byte_alloc = p_ds->length + 1;
|
||||
char * const p_ret = (char *) realloc(p_buf_active, n_byte_alloc);
|
||||
char * const p_ret = (char *) trealloc_raw(p_buf_active, n_byte_alloc);
|
||||
if (p_ret == (char *) NULL) {
|
||||
/* Realloc to smaller size somehow failed! */
|
||||
return (char *) NULL;
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@ struct dveclist {
|
|||
bool f_own_vector;
|
||||
};
|
||||
|
||||
struct dvec *dvec_alloc(/* NOT CONST -- assigned to const */ char *name,
|
||||
struct dvec *dvec_alloc(
|
||||
/* not const -- given to non-const struct */ char *name,
|
||||
int type, short flags, int length, void *storage);
|
||||
void dvec_realloc(struct dvec *v, int length, void *storage);
|
||||
void dvec_extend(struct dvec *v, int length);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ struct nscope {
|
|||
|
||||
/* A linked list of netlist line entries, associated for a specific reason */
|
||||
struct card_assoc {
|
||||
const char *name;
|
||||
char *name;
|
||||
struct card *line;
|
||||
struct card_assoc *next;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,33 +3,23 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
#define TMALLOC(t, n) (t*) tmalloc(sizeof(t) * (size_t)(n))
|
||||
#define TREALLOC(t, p, n) (t*) trealloc(p, sizeof(t) * (size_t)(n))
|
||||
#include "ngspice/alloc.h"
|
||||
|
||||
/* "Type" allocations */
|
||||
#define TMALLOC(t, n) (t *) tmalloc(sizeof(t) * (size_t)(n))
|
||||
#define TREALLOC(t, p, n) (t *) trealloc(p, sizeof(t) * (size_t)(n))
|
||||
|
||||
|
||||
#ifndef HAVE_LIBGC
|
||||
|
||||
extern void *tmalloc(size_t num);
|
||||
extern void *trealloc(const void *str, size_t num);
|
||||
extern void txfree(const void *ptr);
|
||||
|
||||
#define tfree(x) (txfree(x), (x) = 0)
|
||||
|
||||
#else
|
||||
|
||||
#include <gc/gc.h>
|
||||
|
||||
#define tmalloc(m) GC_malloc(m)
|
||||
#define trealloc(m, n) GC_realloc((m), (n))
|
||||
#ifdef HAVE_LIBGC
|
||||
#define tfree(m)
|
||||
#define txfree(m)
|
||||
|
||||
#else
|
||||
#define tfree(x) (txfree(x), (x) = 0)
|
||||
#endif /* HAVE_LIBGC */
|
||||
|
||||
|
||||
#include "ngspice/stringutil.h"
|
||||
|
||||
#define FREE(x) do { if(x) { txfree(x); (x) = NULL; } } while(0)
|
||||
#define FREE(x) do { if (x) { txfree(x); (x) = NULL; } } while(0)
|
||||
#define ZERO(PTR, TYPE) memset(PTR, 0, sizeof(TYPE))
|
||||
|
||||
|
||||
|
|
@ -59,4 +49,4 @@ extern void txfree(const void *ptr);
|
|||
|
||||
#endif /* CIDER */
|
||||
|
||||
#endif
|
||||
#endif /* include guard */
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ extern void MIF_INP2A(
|
|||
|
||||
extern char * MIFgetMod(
|
||||
CKTcircuit *ckt,
|
||||
char *name,
|
||||
const char *name,
|
||||
INPmodel **model,
|
||||
INPtables *tab
|
||||
);
|
||||
|
|
@ -152,7 +152,11 @@ extern Mif_Cntl_Src_Type_t MIFget_cntl_src_type(
|
|||
Mif_Port_Type_t out_port_type
|
||||
);
|
||||
|
||||
extern char *MIFcopy(char *);
|
||||
extern char *MIFcopy(const char *);
|
||||
|
||||
|
||||
#ifndef CM_IGNORE
|
||||
#define CM_IGNORE(x) (x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ extern double x_acosh(double);
|
|||
extern double x_atanh(double);
|
||||
#define hypot _hypot
|
||||
#endif
|
||||
#define strdup _strdup
|
||||
/////#define strdup _strdup
|
||||
#define unlink _unlink
|
||||
#define fileno _fileno
|
||||
#define getcwd _getcwd
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngspice/config.h"
|
||||
#include "ngspice/bool.h"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -722,6 +722,7 @@ append_to_stream(FILE *dest, FILE *source)
|
|||
SJB 25th April 2005 */
|
||||
static bool read_initialisation_file(const char *dir, const char *name)
|
||||
{
|
||||
char *full_name = (char *) NULL;
|
||||
const char *path;
|
||||
bool result = FALSE;
|
||||
|
||||
|
|
@ -735,7 +736,7 @@ static bool read_initialisation_file(const char *dir, const char *name)
|
|||
path = name;
|
||||
}
|
||||
else {
|
||||
path = tprintf("%s" DIR_PATHSEP "%s", dir, name);
|
||||
path = full_name = tprintf("%s" DIR_PATHSEP "%s", dir, name);
|
||||
if (!path) {
|
||||
return FALSE; /* memory allocation error */
|
||||
}
|
||||
|
|
@ -763,8 +764,8 @@ static bool read_initialisation_file(const char *dir, const char *name)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (path != name) { /* Allocated by tprintf() */
|
||||
txfree(path);
|
||||
if (full_name != (char *) NULL) { /* Allocated by tprintf() */
|
||||
txfree(full_name);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -776,7 +777,7 @@ static bool read_initialisation_file(const char *dir, const char *name)
|
|||
static void print_news(void)
|
||||
{
|
||||
if (News_File && *News_File) {
|
||||
const char * const fname = cp_tildexpand(News_File); /*DG Memory leak */
|
||||
char * const fname = cp_tildexpand(News_File); /*DG Memory leak */
|
||||
FILE * const fp = fopen(fname, "r");
|
||||
txfree(fname);
|
||||
if (fp) {
|
||||
|
|
|
|||
328
src/misc/alloc.c
328
src/misc/alloc.c
|
|
@ -1,16 +1,28 @@
|
|||
/**********
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
**********/
|
||||
|
||||
/* for thread handling */
|
||||
#if defined __MINGW32__ || defined _MSC_VER
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Memory alloction functions
|
||||
*/
|
||||
#include "ngspice/alloc.h"
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cpextern.h"
|
||||
|
||||
#if defined HAS_WINGUI || defined SHARED_MODULE
|
||||
#define EXIT(rc) controlled_exit(rc)
|
||||
#else
|
||||
#define EXIT(rc) exit(rc)
|
||||
#endif
|
||||
|
||||
static void overflow_error(size_t num, size_t size);
|
||||
static inline int product_overflow(size_t a, size_t b, size_t *p_n);
|
||||
|
||||
|
||||
#ifdef SHARED_MODULE
|
||||
|
|
@ -35,119 +47,269 @@ extern mutexType allocMutex;
|
|||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_LIBGC
|
||||
#ifdef HAVE_LIBGC
|
||||
|
||||
#include <gc/gc.h>
|
||||
|
||||
void *tmalloc(size_t num)
|
||||
{
|
||||
if (GC_malloc(num) == NULL) {
|
||||
EXIT(EXIT_FAILURE);
|
||||
}
|
||||
} /* end of function tmalloc */
|
||||
|
||||
|
||||
void *tcalloc(size_t num, size_t count)
|
||||
{
|
||||
if (GC_calloc(num, count) == NULL) {
|
||||
EXIT(EXIT_FAILURE);
|
||||
}
|
||||
} /* end of function tmalloc */
|
||||
|
||||
|
||||
|
||||
void *trealloc(size_t num, size_t count)
|
||||
{
|
||||
if (GC_calloc(num, count) == NULL) {
|
||||
EXIT(EXIT_FAILURE);
|
||||
}
|
||||
} /* end of function tmalloc */
|
||||
|
||||
|
||||
/* Free is noop for GC */
|
||||
void txfree(p)
|
||||
{
|
||||
NG_IGNORE(p);
|
||||
return;
|
||||
} /* end of function txfree */
|
||||
|
||||
|
||||
|
||||
#else
|
||||
/*saj For Tcl module locking*/
|
||||
#ifdef TCL_MODULE
|
||||
#include <tcl.h>
|
||||
#endif
|
||||
|
||||
/* Malloc num bytes and initialize to zero. Fatal error if the space can't
|
||||
* be tmalloc'd. Return NULL for a request for 0 bytes.
|
||||
* be tmalloc'd. Return NULL for a request for 0 bytes.
|
||||
*/
|
||||
|
||||
/* New implementation of tmalloc, it uses calloc and does not call memset() */
|
||||
|
||||
void *
|
||||
tmalloc(size_t num)
|
||||
void *tmalloc(size_t num)
|
||||
{
|
||||
void *s;
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_Mutex *alloc;
|
||||
alloc = Tcl_GetAllocMutex();
|
||||
#endif
|
||||
if (!num)
|
||||
return NULL;
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_MutexLock(alloc);
|
||||
#elif defined SHARED_MODULE
|
||||
mutex_lock(&allocMutex);
|
||||
#endif
|
||||
s = calloc(num,1);
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_MutexUnlock(alloc);
|
||||
#elif defined SHARED_MODULE
|
||||
mutex_unlock(&allocMutex);
|
||||
#endif
|
||||
if (!s){
|
||||
fprintf(stderr,"malloc: Internal Error: can't allocate %ld bytes. \n",(long)num);
|
||||
#if defined HAS_WINGUI || defined SHARED_MODULE
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
#else
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
if (num == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return(s);
|
||||
}
|
||||
void * const p = tmalloc_raw(num);
|
||||
if (p == NULL) {
|
||||
(void) fprintf(cp_err, "malloc: Internal Error: can't allocate "
|
||||
"%zd bytes. \n", num);
|
||||
EXIT(EXIT_FAILURE);
|
||||
}
|
||||
return memset(p, 0, num);
|
||||
} /* end of function tmalloc */
|
||||
|
||||
|
||||
void *
|
||||
trealloc(const void *ptr, size_t num)
|
||||
|
||||
/* A "raw" malloc with mutex protection. */
|
||||
void *tmalloc_raw(size_t num)
|
||||
{
|
||||
void *s;
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_Mutex *alloc;
|
||||
alloc = Tcl_GetAllocMutex();
|
||||
#endif
|
||||
if (!num) {
|
||||
if (ptr)
|
||||
free((void*) ptr);
|
||||
return NULL;
|
||||
}
|
||||
if (num == 0) { /* 0-byte request */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ptr)
|
||||
s = tmalloc(num);
|
||||
else {
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_Mutex *alloc;
|
||||
alloc = Tcl_GetAllocMutex();
|
||||
Tcl_MutexLock(alloc);
|
||||
#elif defined SHARED_MODULE
|
||||
mutex_lock(&allocMutex);
|
||||
mutex_lock(&allocMutex);
|
||||
#endif
|
||||
s = realloc((void*) ptr, num);
|
||||
void * const p = malloc(num);
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_MutexUnlock(alloc);
|
||||
Tcl_MutexUnlock(alloc);
|
||||
#elif defined SHARED_MODULE
|
||||
mutex_unlock(&allocMutex);
|
||||
mutex_unlock(&allocMutex);
|
||||
#endif
|
||||
}
|
||||
if (!s) {
|
||||
fprintf(stderr,"realloc: Internal Error: can't allocate %ld bytes.\n", (long)num);
|
||||
#if defined HAS_WINGUI || defined SHARED_MODULE
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
#else
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
return(s);
|
||||
}
|
||||
return p;
|
||||
} /* end of function tmalloc_raw */
|
||||
|
||||
|
||||
void
|
||||
txfree(const void *ptr)
|
||||
|
||||
/* calloc with mutex protection */
|
||||
void *tcalloc(size_t num, size_t size) {
|
||||
size_t n;
|
||||
if (product_overflow(num, size, &n)) {
|
||||
overflow_error(num, size);
|
||||
/* Fatal. No return */
|
||||
}
|
||||
|
||||
return tmalloc(n);
|
||||
} /* end of function tcalloc */
|
||||
|
||||
|
||||
|
||||
/* A "raw" calloc with mutex protection built from tmalloc_raw(). */
|
||||
void *tcalloc_raw(size_t num, size_t size)
|
||||
{
|
||||
size_t n;
|
||||
if (product_overflow(num, size, &n)) {
|
||||
return NULL;
|
||||
}
|
||||
void * const p = tmalloc_raw(n);
|
||||
return memset(p, 0, n);
|
||||
} /* end of function tmalloc_raw */
|
||||
|
||||
|
||||
|
||||
/* Realloc with mutex protection and exit if failure */
|
||||
void *trealloc(void *ptr, size_t num)
|
||||
{
|
||||
void *p_new = trealloc_raw(ptr, num);
|
||||
|
||||
if (num != 0 && p_new == NULL) {
|
||||
(void) fprintf(stderr, "realloc: Internal Error: "
|
||||
"can't allocate %zd bytes.\n",
|
||||
num);
|
||||
EXIT(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return p_new;
|
||||
} /* end of function trealloc */
|
||||
|
||||
|
||||
|
||||
/* A "raw" realloc with mutex protection */
|
||||
void *trealloc_raw(void *ptr, size_t num)
|
||||
{
|
||||
/*saj*/
|
||||
if (num == 0) { /* Acts like free() */
|
||||
if (ptr != NULL) {
|
||||
txfree((void*) ptr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ptr == NULL) { /* Acts like malloc() */
|
||||
return tmalloc_raw(num);
|
||||
}
|
||||
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_Mutex *alloc;
|
||||
alloc = Tcl_GetAllocMutex();
|
||||
Tcl_MutexLock(alloc);
|
||||
Tcl_Mutex *alloc;
|
||||
alloc = Tcl_GetAllocMutex();
|
||||
Tcl_MutexLock(alloc);
|
||||
#elif defined SHARED_MODULE
|
||||
mutex_lock(&allocMutex);
|
||||
#endif
|
||||
#ifdef SHARED_MODULE
|
||||
mutex_lock(&allocMutex);
|
||||
#endif
|
||||
if (ptr)
|
||||
free((void*) ptr);
|
||||
void * const p_new = realloc(ptr, num);
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_MutexUnlock(alloc);
|
||||
Tcl_MutexUnlock(alloc);
|
||||
#elif defined SHARED_MODULE
|
||||
mutex_unlock(&allocMutex);
|
||||
mutex_unlock(&allocMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
return p_new;
|
||||
} /* end of function trealloc_raw */
|
||||
|
||||
|
||||
|
||||
/* Free with mutex protection */
|
||||
void txfree(void *ptr)
|
||||
{
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_Mutex *alloc;
|
||||
alloc = Tcl_GetAllocMutex();
|
||||
Tcl_MutexLock(alloc);
|
||||
#endif
|
||||
#ifdef SHARED_MODULE
|
||||
mutex_lock(&allocMutex);
|
||||
#endif
|
||||
free(ptr);
|
||||
/*saj*/
|
||||
#ifdef TCL_MODULE
|
||||
Tcl_MutexUnlock(alloc);
|
||||
#elif defined SHARED_MODULE
|
||||
mutex_unlock(&allocMutex);
|
||||
#endif
|
||||
} /* end of function txfree */
|
||||
|
||||
|
||||
|
||||
|
||||
/* This function returns the product of a and b if it does not overflow.
|
||||
*
|
||||
* Return codes
|
||||
* 0: No overflow
|
||||
* 1: overflow
|
||||
*/
|
||||
static inline int product_overflow(size_t a, size_t b, size_t *p_n)
|
||||
{
|
||||
/* Some overflow conditions:
|
||||
* a == SIZE_MAX and b > 1
|
||||
* a > 1 and b == SIZE_MAX
|
||||
* a * b < a
|
||||
* a * b < b
|
||||
*/
|
||||
if (a == SIZE_MAX && b > 1 || a > 1 && b == SIZE_MAX) {
|
||||
return +1;
|
||||
}
|
||||
|
||||
const size_t n = a * b;
|
||||
if (n < a || n < b) {
|
||||
return +1;
|
||||
}
|
||||
|
||||
*p_n = n;
|
||||
return 0;
|
||||
} /* end of function product_overflow */
|
||||
|
||||
|
||||
|
||||
/* Print error related to allocating a product that cannot fit in a
|
||||
* size_t and exit. This function does not return. */
|
||||
static void overflow_error(size_t num, size_t size)
|
||||
{
|
||||
(void) fprintf(cp_err, "Cannot allocate %zu X %zu bytes: "
|
||||
"Product exceeds largest size_t = %zu.\n",
|
||||
num, size, SIZE_MAX);
|
||||
EXIT(EXIT_FAILURE);
|
||||
} /* end of function overflow_error */
|
||||
|
||||
|
||||
/* strdup must also be serialized since it performs an allocation. Note that
|
||||
* Microsoft has not had a single-threaded CRT since VS 2005 (Windows XP),
|
||||
* so, their _strdup can be safely used if desired. */
|
||||
/* Declared in cmproto.h */
|
||||
char *tstrdup(const char *str_in)
|
||||
{
|
||||
const size_t n_byte_alloc = strlen(str_in); + 1;
|
||||
char * const str_out = (char *) tmalloc(n_byte_alloc);
|
||||
/* Program execution would end in tmalloc() if the allocation fails */
|
||||
return memcpy(str_out, str_in, n_byte_alloc);
|
||||
} /* end of function tstrdup */
|
||||
|
||||
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
char *tstrdup_raw(const char *str_in)
|
||||
{
|
||||
const size_t n_byte_alloc = strlen(str_in); + 1;
|
||||
char * const str_out = (char *) tmalloc_raw(n_byte_alloc);
|
||||
if (str_out == (char *) NULL) {
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
return memcpy(str_out, str_in, n_byte_alloc);
|
||||
} /* end of function tstrdup_raw */
|
||||
|
||||
|
||||
|
||||
#endif /* #ifndef HAVE_LIBGC */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
/*************
|
||||
* Header file for alloc.c
|
||||
* 1999 E. Rouat
|
||||
************/
|
||||
|
||||
#ifndef ngspice_ALLOC_H
|
||||
#define ngspice_ALLOC_H
|
||||
|
||||
#ifndef HAVE_LIBGC
|
||||
void * tmalloc(size_t num);
|
||||
void * trealloc(const void *ptr, size_t num);
|
||||
void txfree(const void *ptr);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -4,13 +4,13 @@ DESCRIPTION:This file contains the routines for manipulating dynamic strings.
|
|||
----------------------------------------------------------------- */
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngspice/dstring.h"
|
||||
#include "ngspice/alloc.h"
|
||||
|
||||
|
||||
static int ds_reserve_internal(DSTRING *p_ds,
|
||||
|
|
@ -86,7 +86,7 @@ int ds_init(DSTRING *p_ds, char *p_buf, size_t length_string,
|
|||
void ds_free(DSTRING *p_ds)
|
||||
{
|
||||
if (p_ds->p_buf != p_ds->p_stack_buf) {
|
||||
free((void *) p_ds->p_buf);
|
||||
txfree((void *) p_ds->p_buf);
|
||||
}
|
||||
} /* end of function ds_free */
|
||||
|
||||
|
|
@ -212,7 +212,8 @@ static int ds_reserve_internal(DSTRING *p_ds,
|
|||
n_byte_alloc_min = n_byte_alloc_opt;
|
||||
}
|
||||
for ( ; ; ) {
|
||||
if ((p_buf_new = (char *) malloc(n_byte_alloc)) != (char *) NULL) {
|
||||
if ((p_buf_new = (char *) tmalloc_raw(
|
||||
n_byte_alloc)) != (char *) NULL) {
|
||||
break; /* Allocated OK */
|
||||
}
|
||||
|
||||
|
|
@ -230,7 +231,7 @@ static int ds_reserve_internal(DSTRING *p_ds,
|
|||
|
||||
/* If there already was a dynamic allocation, free it */
|
||||
if (p_ds->p_buf != p_ds->p_stack_buf) {
|
||||
free((void *) p_ds->p_buf);
|
||||
txfree((void *) p_ds->p_buf);
|
||||
}
|
||||
|
||||
/* Assign new active buffer and its size */
|
||||
|
|
@ -334,7 +335,7 @@ int ds_compact(DSTRING *p_ds)
|
|||
* free the allocation. */
|
||||
if (p_ds->n_byte_stack_buf >= n_byte_alloc_min) {
|
||||
(void) memcpy(p_ds->p_stack_buf, p_ds->p_buf, n_byte_alloc_min);
|
||||
free((void *) p_ds->p_buf);
|
||||
txfree((void *) p_ds->p_buf);
|
||||
p_ds->p_buf = p_ds->p_stack_buf;
|
||||
p_ds->n_byte_alloc = p_ds->n_byte_stack_buf;
|
||||
return DS_E_OK;
|
||||
|
|
@ -347,7 +348,7 @@ int ds_compact(DSTRING *p_ds)
|
|||
|
||||
/* Else realloc the heap buffer */
|
||||
{
|
||||
void *p = realloc(p_ds->p_buf, n_byte_alloc_min);
|
||||
void * const p = trealloc_raw(p_ds->p_buf, n_byte_alloc_min);
|
||||
if (p == NULL) {
|
||||
return DS_E_NO_MEMORY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,20 +42,22 @@
|
|||
#include <string.h> /* for strcpy, strcat*/
|
||||
#if (!defined HAS_WINGUI) && (!defined __MINGW32__) && (!defined _MSC_VER)
|
||||
#include <dlfcn.h> /* to load libraries*/
|
||||
typedef void * funptr_t;
|
||||
typedef void * funptr_t;
|
||||
#define FREE_DLERR_MSG(msg)
|
||||
#else /* ifdef HAS_WINGUI */
|
||||
#undef BOOLEAN
|
||||
#include <windows.h>
|
||||
typedef FARPROC funptr_t;
|
||||
void *dlopen (const char *, int);
|
||||
funptr_t dlsym (void *, const char *);
|
||||
int dlclose (void *);
|
||||
char *dlerror (void);
|
||||
void *dlopen(const char *, int);
|
||||
funptr_t dlsym(void *, const char *);
|
||||
char *dlerror(void);
|
||||
#define FREE_DLERR_MSG(msg) free_dlerr_msg(msg)
|
||||
static void free_dlerr_msg(char *msg);
|
||||
#define RTLD_LAZY 1 /* lazy function call binding */
|
||||
#define RTLD_NOW 2 /* immediate function call binding */
|
||||
#define RTLD_GLOBAL 4 /* symbols in this dlopen'ed obj are visible to other dlopen'ed objs */
|
||||
static char errstr[128];
|
||||
#endif /* ifndef HAS_WINGUI */
|
||||
|
||||
#include "ngspice/dllitf.h" /* the coreInfo Structure*/
|
||||
#include "ngspice/evtudn.h" /*Use defined nodes */
|
||||
|
||||
|
|
@ -400,115 +402,198 @@ int add_udn(int n,Evt_Udn_Info_t **udns){
|
|||
return 0;
|
||||
}
|
||||
|
||||
extern struct coreInfo_t coreInfo;
|
||||
|
||||
int load_opus(char *name){
|
||||
void *lib;
|
||||
const char *msg;
|
||||
int *num=NULL;
|
||||
struct coreInfo_t **core;
|
||||
SPICEdev **devs;
|
||||
Evt_Udn_Info_t **udns;
|
||||
funptr_t fetch;
|
||||
int load_opus(const char *name)
|
||||
{
|
||||
void *lib;
|
||||
char *msg;
|
||||
int num;
|
||||
SPICEdev **devs;
|
||||
Evt_Udn_Info_t **udns;
|
||||
funptr_t fetch;
|
||||
|
||||
lib = dlopen(name, RTLD_NOW);
|
||||
if (!lib) {
|
||||
msg = dlerror();
|
||||
printf("Error opening code model \"%s\": %s\n", name, msg);
|
||||
FREE_DLERR_MSG(msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Get code models defined by the library */
|
||||
if ((fetch = dlsym(lib, "CMdevNum2")) != (funptr_t) NULL) {
|
||||
/* Version 2 code models present */
|
||||
num = *(*(int * (*)(void)) fetch)();
|
||||
fetch = dlsym(lib, "CMdevs2");
|
||||
if (fetch != (funptr_t) NULL) {
|
||||
devs = (*(SPICEdev ** (*)(void)) fetch)();
|
||||
}
|
||||
else {
|
||||
msg = dlerror();
|
||||
printf("Error getting the list of version 2 devices: %s\n",
|
||||
msg);
|
||||
FREE_DLERR_MSG(msg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else { /* no version 2, so try version 1 */
|
||||
if ((fetch = dlsym(lib, "CMdevNum")) != (funptr_t) NULL) {
|
||||
num = *(*(int * (*)(void)) fetch)();
|
||||
fetch = dlsym(lib, "CMdevs");
|
||||
if (fetch != (funptr_t) NULL) {
|
||||
devs = (*(SPICEdev ** (*)(void)) fetch)();
|
||||
}
|
||||
else {
|
||||
msg = dlerror();
|
||||
printf("Error getting the list of version 1 devices: %s\n",
|
||||
msg);
|
||||
FREE_DLERR_MSG(msg);
|
||||
return 1;
|
||||
}
|
||||
} /* end of case that got version 1 */
|
||||
else { /* no version 2 or version 1 */
|
||||
msg = dlerror();
|
||||
printf("Error finding the number of devices: %s\n", msg);
|
||||
FREE_DLERR_MSG(msg);
|
||||
return 1;
|
||||
}
|
||||
} /* end of case of no version 2 */
|
||||
|
||||
add_device(num, devs, 1);
|
||||
|
||||
lib = dlopen(name,RTLD_NOW);
|
||||
if(!lib){
|
||||
msg = dlerror();
|
||||
printf("%s\n", msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fetch = dlsym(lib,"CMdevNum");
|
||||
if(fetch){
|
||||
num = ((int * (*)(void)) fetch) ();
|
||||
#ifdef TRACE
|
||||
printf("Got %u devices.\n",*num);
|
||||
printf("Got %u devices.\n", num);
|
||||
#endif
|
||||
}else{
|
||||
msg = dlerror();
|
||||
printf("%s\n", msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fetch = dlsym(lib,"CMdevs");
|
||||
if(fetch){
|
||||
devs = ((SPICEdev ** (*)(void)) fetch) ();
|
||||
}else{
|
||||
msg = dlerror();
|
||||
printf("%s\n", msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fetch = dlsym(lib,"CMgetCoreItfPtr");
|
||||
if(fetch){
|
||||
core = ((struct coreInfo_t ** (*)(void)) fetch) ();
|
||||
*core = &coreInfo;
|
||||
}else{
|
||||
msg = dlerror();
|
||||
printf("%s\n", msg);
|
||||
return 1;
|
||||
}
|
||||
add_device(*num,devs,1);
|
||||
/* Get user-defined ndes defined by the library */
|
||||
if ((fetch = dlsym(lib, "CMudnNum2")) != (funptr_t) NULL) {
|
||||
/* Version 2 user-defined types present */
|
||||
num = *(*(int * (*)(void)) fetch)();
|
||||
fetch = dlsym(lib, "CMudns2");
|
||||
if (fetch != (funptr_t) NULL) {
|
||||
udns = (*(Evt_Udn_Info_t ** (*)(void)) fetch)();
|
||||
}
|
||||
else {
|
||||
msg = dlerror();
|
||||
printf("Error getting the list of version 2 "
|
||||
"user-defined types: %s\n",
|
||||
msg);
|
||||
FREE_DLERR_MSG(msg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else { /* no version 2, so try version 1 */
|
||||
if ((fetch = dlsym(lib, "CMudnNum")) != (funptr_t) NULL) {
|
||||
num = *(*(int * (*)(void)) fetch)();
|
||||
fetch = dlsym(lib, "CMudns");
|
||||
if (fetch != (funptr_t) NULL) {
|
||||
udns = (*(Evt_Udn_Info_t ** (*)(void)) fetch)();
|
||||
}
|
||||
else {
|
||||
msg = dlerror();
|
||||
printf("Error getting the list of version 1 "
|
||||
"user-defined types: %s\n",
|
||||
msg);
|
||||
FREE_DLERR_MSG(msg);
|
||||
return 1;
|
||||
}
|
||||
} /* end of case that got version 1 */
|
||||
else { /* no version 2 or version 1 */
|
||||
msg = dlerror();
|
||||
printf("Error finding the number of "
|
||||
"user-defined types: %s\n", msg);
|
||||
FREE_DLERR_MSG(msg);
|
||||
return 1;
|
||||
}
|
||||
} /* end of case of no version 2 */
|
||||
|
||||
fetch = dlsym(lib,"CMudnNum");
|
||||
if(fetch){
|
||||
num = ((int * (*)(void)) fetch) ();
|
||||
add_udn(num, udns);
|
||||
#ifdef TRACE
|
||||
printf("Got %u udns.\n",*num);
|
||||
printf("Got %u udns.\n", num);
|
||||
#endif
|
||||
}else{
|
||||
msg = dlerror();
|
||||
printf("%s\n", msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fetch = dlsym(lib,"CMudns");
|
||||
if(fetch){
|
||||
udns = ((Evt_Udn_Info_t ** (*)(void)) fetch) ();
|
||||
}else{
|
||||
msg = dlerror();
|
||||
printf("%s\n", msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
add_udn(*num,udns);
|
||||
/* Give the code model access to facilities provided by ngspice. Note
|
||||
* that older versions of code models will not access the functions
|
||||
* added by newer versions of ngspice since it is unaware of them and
|
||||
* newer versions of code models will not use newer (undefined)
|
||||
* functions from ngspice because any of its models that use them
|
||||
* will not be recognized and used by ngspice. */
|
||||
if ((fetch = dlsym(lib,"CMgetCoreItfPtr")) != (funptr_t) NULL) {
|
||||
const struct coreInfo_t ** const core =
|
||||
(*(const struct coreInfo_t ** const (*)(void)) fetch)();
|
||||
*core = &coreInfo;
|
||||
}
|
||||
else {
|
||||
msg = dlerror();
|
||||
printf("Error getting interface pointer: %s\n", msg);
|
||||
FREE_DLERR_MSG(msg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
} /* end of function load_opus */
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) || defined(HAS_WINGUI) || defined(_MSC_VER)
|
||||
|
||||
void *dlopen(const char *name,int type)
|
||||
/* For reporting error message if formatting fails */
|
||||
static const char errstr_fmt[] =
|
||||
"Unable to find message in dlerr(). System code = %lu";
|
||||
static char errstr[sizeof errstr_fmt - 3 + 3 * sizeof(unsigned long)];
|
||||
|
||||
/* Emulations of POSIX dlopen(), dlsym(), and dlerror(). */
|
||||
void *dlopen(const char *name, int type)
|
||||
{
|
||||
NG_IGNORE(type);
|
||||
return LoadLibrary(name);
|
||||
NG_IGNORE(type);
|
||||
return LoadLibrary(name);
|
||||
}
|
||||
|
||||
funptr_t dlsym(void *hDll, const char *funcname)
|
||||
{
|
||||
return GetProcAddress(hDll, funcname);
|
||||
return GetProcAddress(hDll, funcname);
|
||||
}
|
||||
|
||||
char *dlerror(void)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
LPVOID lpMsgBuf;
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
strcpy(errstr,lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
return errstr;
|
||||
}
|
||||
#endif
|
||||
DWORD rc = FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (rc == 0) { /* FormatMessage failed */
|
||||
(void) sprintf(errstr, errstr_fmt, (unsigned long) GetLastError());
|
||||
return errstr;
|
||||
}
|
||||
|
||||
return lpMsgBuf; /* Return the formatted message */
|
||||
} /* end of function dlerror */
|
||||
|
||||
|
||||
|
||||
/* Free message related to dynamic loading */
|
||||
static void free_dlerr_msg(char *msg)
|
||||
{
|
||||
if (msg != errstr) { /* msg is an allocation */
|
||||
LocalFree(msg);
|
||||
}
|
||||
} /* end of function free_dlerr_msg */
|
||||
|
||||
|
||||
|
||||
#endif /* Windows emulation of dlopen, dlsym, and dlerr */
|
||||
#endif
|
||||
/*-------------------- end of XSPICE additions ----------------------*/
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ int num_devices(void);
|
|||
IFdevice **devices_ptr(void);
|
||||
SPICEdev **devices(void);
|
||||
#ifdef XSPICE
|
||||
int load_opus(char *);
|
||||
int load_opus(const char *);
|
||||
int DEVflag(int type);
|
||||
#endif
|
||||
#ifdef DEVLIB
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ expression: exp
|
|||
|
||||
exp:
|
||||
TOK_NUM { $$ = PT_mknnode($1); }
|
||||
| TOK_STR { $$ = PT_mksnode($1, ckt); txfree($1); }
|
||||
| TOK_STR { $$ = PT_mksnode($1, ckt); txfree((void *) $1); }
|
||||
|
||||
| exp '+' exp { $$ = PT_mkbnode("+", $1, $3); }
|
||||
| exp '-' exp { $$ = PT_mkbnode("-", $1, $3); }
|
||||
|
|
@ -100,7 +100,7 @@ exp:
|
|||
| TOK_STR '(' nonempty_arglist ')' { $$ = PT_mkfnode($1, $3);
|
||||
if (!$$)
|
||||
YYERROR;
|
||||
txfree($1); }
|
||||
txfree((void *) $1); }
|
||||
|
||||
| TOK_pnode
|
||||
|
||||
|
|
|
|||
|
|
@ -1080,8 +1080,8 @@ static struct History_info *init_history(void)
|
|||
}
|
||||
|
||||
{
|
||||
/* Initialize history buffer with a greeting */
|
||||
static const char cmd_welcome[] = "# Welcome to ngspice!";
|
||||
/* Initialize history buffer with empty input line */
|
||||
static const char cmd_welcome[] = "";
|
||||
(void) history_add(&p_hi, sizeof cmd_welcome - 1, cmd_welcome);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,8 @@ void cm_analog_alloc(
|
|||
}
|
||||
|
||||
/* Compute number of doubles needed and allocate space in ckt->CKTstates[i] */
|
||||
doubles_needed = bytes / (int) sizeof(double) + 1;
|
||||
doubles_needed =
|
||||
(bytes + (int) sizeof(double) - 1) / (int) sizeof(double);
|
||||
|
||||
/* Allocate space in instance struct for this state descriptor */
|
||||
if(here->num_state == 0) {
|
||||
|
|
@ -133,7 +134,8 @@ void cm_analog_alloc(
|
|||
else
|
||||
ckt->CKTstates[i] = TREALLOC(double, ckt->CKTstates[i], ckt->CKTnumStates);
|
||||
}
|
||||
}
|
||||
} /* end of function cm_analog_alloc */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -657,8 +659,7 @@ the instance name.
|
|||
*/
|
||||
|
||||
|
||||
int cm_message_send(
|
||||
char *msg) /* The message to output. */
|
||||
int cm_message_send(const char *msg) /* The message to output. */
|
||||
{
|
||||
MIFinstance *here;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/mif.h"
|
||||
#include "ngspice/cm.h"
|
||||
#include "ngspice/cpextern.h"
|
||||
#include "ngspice/dllitf.h"
|
||||
|
||||
/*how annoying!, needed for structure below*/
|
||||
static void *tcalloc(size_t a, size_t b) {
|
||||
return tmalloc(a*b); /* FIXME, tcalloc must zero !?!? */
|
||||
}
|
||||
#include "ngspice/alloc.h"
|
||||
|
||||
#ifdef HAVE_LIBGC
|
||||
static void no_free(const void *p) {
|
||||
|
|
@ -14,11 +11,31 @@ static void no_free(const void *p) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static FILE * no_file(void) {
|
||||
return NULL;
|
||||
/* Returns the version string for ngspice */
|
||||
static const char *get_ngspice_version(void)
|
||||
{
|
||||
const char *buf = VERSION;
|
||||
return buf;
|
||||
} /* end of function get_ngspice_version */
|
||||
|
||||
|
||||
/* Returns stdout, stdin, and stderr */
|
||||
static FILE *get_stdout(void)
|
||||
{
|
||||
return cp_out;
|
||||
}
|
||||
static FILE *get_stdin(void)
|
||||
{
|
||||
return cp_in;
|
||||
}
|
||||
static FILE *get_stderr(void)
|
||||
{
|
||||
return cp_err;
|
||||
}
|
||||
|
||||
struct coreInfo_t coreInfo =
|
||||
|
||||
|
||||
const struct coreInfo_t coreInfo =
|
||||
{
|
||||
MIF_INP2A,
|
||||
MIFgetMod,
|
||||
|
|
@ -65,24 +82,21 @@ struct coreInfo_t coreInfo =
|
|||
cm_complex_divide,
|
||||
cm_get_path,
|
||||
cm_get_circuit,
|
||||
no_file,
|
||||
no_file,
|
||||
no_file,
|
||||
#ifndef HAVE_LIBGC
|
||||
tmalloc,
|
||||
tcalloc,
|
||||
trealloc,
|
||||
txfree,
|
||||
tmalloc,
|
||||
trealloc,
|
||||
txfree
|
||||
#else
|
||||
GC_malloc,
|
||||
tcalloc,
|
||||
GC_realloc,
|
||||
no_free,
|
||||
GC_malloc,
|
||||
GC_realloc,
|
||||
no_free
|
||||
#endif
|
||||
&get_stdout,
|
||||
&get_stdin,
|
||||
&get_stderr,
|
||||
&tmalloc,
|
||||
&tcalloc,
|
||||
&trealloc,
|
||||
&txfree,
|
||||
&tmalloc,
|
||||
&trealloc,
|
||||
&txfree,
|
||||
/* Version 2 additions */
|
||||
&get_ngspice_version,
|
||||
&tmalloc_raw,
|
||||
&tcalloc_raw,
|
||||
&trealloc_raw,
|
||||
&tstrdup,
|
||||
&tstrdup_raw
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ bin_PROGRAMS = cmpp
|
|||
AM_CPPFLAGS = -I. -I$(srcdir)
|
||||
AM_YFLAGS = -d
|
||||
|
||||
cmpp_SOURCES = main.c cmpp.h \
|
||||
cmpp_SOURCES = main.c cmpp.h file_buffer.c file_buffer.h\
|
||||
pp_ifs.c pp_lst.c pp_mod.c read_ifs.c writ_ifs.c util.c \
|
||||
ifs_lex.l ifs_yacc.y ifs_yacc_y.h \
|
||||
mod_lex.l mod_yacc.y mod_yacc_y.h
|
||||
|
|
@ -42,7 +42,7 @@ if CROSS_COMPILING
|
|||
BUILT_SOURCES += build/cmpp$(BUILD_EXEEXT)
|
||||
CLEANFILES = build/cmpp$(BUILD_EXEEXT)
|
||||
|
||||
BUILD_CMPP_FILES = main.c \
|
||||
BUILD_CMPP_FILES = main.c file_buffer.c \
|
||||
pp_ifs.c pp_lst.c pp_mod.c read_ifs.c writ_ifs.c util.c \
|
||||
ifs_lex.c ifs_yacc.c \
|
||||
mod_lex.c mod_yacc.c
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ NON-STANDARD FEATURES
|
|||
============================================================================*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
@ -49,20 +50,25 @@ NON-STANDARD FEATURES
|
|||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#include <string.h>
|
||||
|
||||
/* If CRT debugging is being used so that crtdbg.h is included, strdup will
|
||||
* be defined to a debug version. In this case, strdup should not be
|
||||
* redefined to the standard version. */
|
||||
#ifndef strdup
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
#define unlink _unlink
|
||||
#define isatty _isatty
|
||||
#define fileno _fileno
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
#define GET_IFS_TABLE 0 /* Read the entire ifs table */
|
||||
#define GET_IFS_NAME 1 /* Get the C function name out of the table only */
|
||||
|
||||
#define MAX_PATH_LEN 1024 /* Maximum pathname length */
|
||||
#define MAX_NAME_LEN 1024 /* Maximum SPICE name length */
|
||||
#define MAX_FN_LEN 31 /* Maximum filename length */
|
||||
|
||||
|
||||
/* ******************************************************************** */
|
||||
|
|
@ -262,7 +268,9 @@ void preprocess_ifs_file(void);
|
|||
|
||||
void preprocess_lst_files(void);
|
||||
|
||||
void preprocess_mod_file(char *filename);
|
||||
void preprocess_mod_file(const char *filename);
|
||||
|
||||
int output_paths_from_lst_file(const char *filename);
|
||||
|
||||
|
||||
void init_error (char *program_name);
|
||||
|
|
@ -272,6 +280,7 @@ void print_error(const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2)
|
|||
#else
|
||||
void print_error(const char *fmt, ...);
|
||||
#endif
|
||||
void vprint_error(const char *fmt, va_list p);
|
||||
|
||||
void str_to_lower(char *s);
|
||||
|
||||
|
|
@ -281,8 +290,9 @@ int read_ifs_file(const char *filename, int mode, Ifs_Table_t *ifs_table);
|
|||
int write_ifs_c_file(const char *filename, Ifs_Table_t *ifs_table);
|
||||
|
||||
|
||||
FILE *fopen_cmpp(const char **path_p, const char *mode);
|
||||
char *gen_filename(const char *filename, const char *mode);
|
||||
|
||||
void rem_ifs_table(Ifs_Table_t *ifs_table);
|
||||
|
||||
/*
|
||||
* type safe variants of the <ctype.h> functions for char arguments
|
||||
|
|
|
|||
|
|
@ -0,0 +1,698 @@
|
|||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "file_buffer.h"
|
||||
#include "cmpp.h"
|
||||
|
||||
/* Default buffer size */
|
||||
#define N_BYTE_FILEBUF_INIT_DFLT 16384
|
||||
|
||||
|
||||
static int fb_fill(FILEBUF *p_fb);
|
||||
static int fbget_quoted_unescaped_string(FILEBUF *p_fb,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj);
|
||||
static size_t fb_make_space_at_end(FILEBUF *p_fb);
|
||||
static int fbget_quoted_string(FILEBUF *p_fb,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj);
|
||||
static int fbget_quoted_escaped_string(FILEBUF *p_fb,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj);
|
||||
static int fbget_unquoted_string(FILEBUF *p_fb,
|
||||
unsigned int n_type_wanted, FBTYPE *p_type_wanted,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj);
|
||||
static int fb_return_obj(FILEBUF *p_fb,
|
||||
unsigned int n_type_wanted, FBTYPE *p_type_wanted,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj);
|
||||
static int fb_return_string(FILEBUF *p_fb,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj);
|
||||
static int fb_skip_to_eol(FILEBUF *p_fb);
|
||||
static int fb_skip_whitespace(FILEBUF *p_fb);
|
||||
|
||||
|
||||
/* This function initializes a file-buffer read access to the named file.
|
||||
*
|
||||
* Parameters
|
||||
* filename: Name of file to be opened for reading
|
||||
* n_byte_buf_init: Intial buffer size. May be 0 for default size
|
||||
*
|
||||
* Return values
|
||||
* NULL: Error occurred. The value of errno will provide more details
|
||||
* Otherwise an initialized structure
|
||||
*/
|
||||
FILEBUF *fbopen(const char *filename, size_t n_byte_buf_init)
|
||||
{
|
||||
int xrc = 0;
|
||||
FILEBUF *p_fb = (FILEBUF *) NULL;
|
||||
|
||||
/* Set default buffer size if requested */
|
||||
if (n_byte_buf_init == 0) {
|
||||
n_byte_buf_init = N_BYTE_FILEBUF_INIT_DFLT;
|
||||
}
|
||||
|
||||
/* Allocate structure to return */
|
||||
if ((p_fb = (FILEBUF *) malloc(sizeof *p_fb)) == (FILEBUF *) NULL) {
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
p_fb->is_eof = false;
|
||||
p_fb->f_skip_to_eol = false;
|
||||
|
||||
/* Init resources for error recovery */
|
||||
p_fb->fp = (FILE *) NULL;
|
||||
p_fb->p_buf = (char *) NULL;
|
||||
|
||||
/* Allocate data buffer */
|
||||
if ((p_fb->p_buf = (char *) malloc(n_byte_buf_init)) == (char *) NULL) {
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
p_fb->n_byte_buf_alloc = n_byte_buf_init;
|
||||
p_fb->p_data_end = p_fb->p_data_cur = p_fb->p_buf;
|
||||
p_fb->p_buf_end = p_fb->p_buf + n_byte_buf_init;
|
||||
|
||||
/* p_fb->p_obj_undefined since no object yet */
|
||||
|
||||
/* Open file. It is opened in binary mode because the scanning will
|
||||
* handle all EOL chars, so any translations by the OS are almost
|
||||
* pure overhead. Also, not converting ensures that if fread returns
|
||||
* fewer than the requested number of chars, that read was to the
|
||||
* end of the file (if not an error). Otherwise an additional read
|
||||
* getting a size of 0 would be required. */
|
||||
if ((p_fb->fp = fopen(filename, "rb")) == (FILE *) NULL) {
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
EXITPOINT:
|
||||
/* Free resources on error */
|
||||
if (xrc != 0) {
|
||||
if (p_fb != (FILEBUF *) NULL) {
|
||||
const int errno_save = errno; /* save errno in case fbclose()
|
||||
* changes it */
|
||||
(void) fbclose(p_fb);
|
||||
errno = errno_save;
|
||||
p_fb = (FILEBUF *) NULL;
|
||||
}
|
||||
} /* end of case of error */
|
||||
|
||||
return p_fb;
|
||||
} /* end of function fbopen */
|
||||
|
||||
|
||||
|
||||
/* This function frees resources used by a FILEBUF.
|
||||
*
|
||||
* Parameter
|
||||
* p_fb: The address of the FILEBUF to free. This argument may be NULL.
|
||||
*
|
||||
* Return values
|
||||
* 0: OK
|
||||
* EOF: Error closing file. Details can be found using errno.
|
||||
*/
|
||||
int fbclose(FILEBUF *p_fb)
|
||||
{
|
||||
if (p_fb == (FILEBUF *) NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xrc = 0;
|
||||
|
||||
{
|
||||
void *p;
|
||||
if ((p = p_fb->p_buf) != NULL) {
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
FILE *fp;
|
||||
if ((fp = p_fb->fp) != (FILE *) NULL) {
|
||||
xrc = fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
free(p_fb);
|
||||
return xrc;
|
||||
} /* end of function fbclose */
|
||||
|
||||
|
||||
|
||||
/* This function gets the next object converting it to the most desired
|
||||
* type.
|
||||
*
|
||||
* Parameters
|
||||
* p_fb: FILEBUF pointer initialized using fbopen()
|
||||
* n_type_wanted: number of desired type conversions for data from highest
|
||||
* priority to lowest.
|
||||
* p_type_wanted: Desired type conversions for data from highest priority
|
||||
* to lowest.
|
||||
* p_type_found: Address to receive the type of the data obtained
|
||||
* p_fbobj: Address of an FBOBJ structure to receive the data
|
||||
*
|
||||
* Return codes
|
||||
* +1: EOF reached
|
||||
* 0: Normal return
|
||||
* -1: Error. Use errno for further details.
|
||||
*
|
||||
* Remarks
|
||||
* Type BUF_TYPE_STRING is always implicitly added to the list of wanted
|
||||
* types as the final choice, which any data will satisfy
|
||||
*
|
||||
* A string may be double-quoted. In this case the quotes are not supplied
|
||||
* to the caller as part of the data. Double-quoting ensures that a string
|
||||
* will not be converted to any other type. Within double quotes, a double
|
||||
* qoute and a backslash are escaped by a backslash, and a final unescaped
|
||||
* double quote is impilcitly added if EOF is reached when scanning for a
|
||||
* closing quote.
|
||||
*
|
||||
* A "*" or a "#" not within a quoted expression begins a comment that
|
||||
* extends to the end of the line.
|
||||
*
|
||||
* When called p_fb has data from the last get or it is the first call.
|
||||
*
|
||||
* Return Codes
|
||||
* +1: EOF
|
||||
* 0: Normal
|
||||
* -1: Error
|
||||
*/
|
||||
int fbget(FILEBUF *p_fb,
|
||||
unsigned int n_type_wanted, FBTYPE *p_type_wanted,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj)
|
||||
{
|
||||
/* Test for existing EOF */
|
||||
if (p_fb->is_eof && p_fb->p_data_cur == p_fb->p_data_end) { /* no data */
|
||||
return +1;
|
||||
}
|
||||
|
||||
/* Init to no object */
|
||||
p_fb->p_obj_start = (char *) NULL;
|
||||
|
||||
/* Skip the comment if the initiating character was processed during
|
||||
* the last call to fbget */
|
||||
if (p_fb->f_skip_to_eol) {
|
||||
const int rc = fb_skip_to_eol(p_fb);
|
||||
if (rc != 0) { /* EOF or error */
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const int rc = fb_skip_whitespace(p_fb);
|
||||
if (rc != 0) { /* EOF or error */
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Current char exists and starts the item */
|
||||
if (*p_fb->p_data_cur == '"') { /* quoted string */
|
||||
return fbget_quoted_string(p_fb, p_type_found, p_fbobj);
|
||||
}
|
||||
|
||||
/* Else unquoted string */
|
||||
return fbget_unquoted_string(p_fb, n_type_wanted, p_type_wanted,
|
||||
p_type_found, p_fbobj);
|
||||
} /* end of function fbget */
|
||||
|
||||
|
||||
|
||||
/* Get a quoted string given at a quote. On entry p_fb->p_data_cur points
|
||||
* to the quote starting the quoted string. On return it points to the first
|
||||
* character after the current item or equals p_fb->p_data_end if the
|
||||
* current item extens to the end of the current data string. */
|
||||
static int fbget_quoted_string(FILEBUF *p_fb,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj)
|
||||
{
|
||||
/* Advance past the opening quote to the true start of the string */
|
||||
if (++p_fb->p_data_cur == p_fb->p_data_end) {
|
||||
/* The leading quote ended the current data */
|
||||
const int rc = fb_fill(p_fb); /* Try to refill buffer */
|
||||
if (rc != 0) { /* EOF or error */
|
||||
if (rc < 0) { /* error */
|
||||
return -1;
|
||||
}
|
||||
/* Else EOF. This item is an empty string that ended without the
|
||||
* closing quote, so add an implicit closing quote, i.e., end
|
||||
* the string to form "".
|
||||
*
|
||||
* Since the object was started at the beginning of the buffer
|
||||
* and the buffer has at leat 1 byte a NULL to create the
|
||||
* string "" can be written here */
|
||||
*(p_fb->p_obj_end = p_fb->p_obj_start = p_fb->p_buf) = '\0';
|
||||
return fb_return_string(p_fb, p_type_found, p_fbobj);
|
||||
}
|
||||
/* Else data is now available at p_fb->p_data_cur */
|
||||
} /* end of case that at end of data from file */
|
||||
|
||||
/* Save the start of the string as the current position */
|
||||
p_fb->p_obj_start = p_fb->p_data_cur;
|
||||
|
||||
/* Continue processing as an unescaped string, unless the contrary
|
||||
* is found to be true */
|
||||
return fbget_quoted_unescaped_string(p_fb, p_type_found, p_fbobj);
|
||||
} /* end of function fbget_quoted_string */
|
||||
|
||||
|
||||
|
||||
/* Get a quoted string with no escape. The start has already been set on
|
||||
* entry. If an escape is found, processing continues as an escaped string */
|
||||
int fbget_quoted_unescaped_string(FILEBUF *p_fb,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj)
|
||||
{
|
||||
/* Step through characters until end or escape */
|
||||
char *p_data_cur = p_fb->p_data_cur;
|
||||
char *p_data_end = p_fb->p_data_end;
|
||||
for ( ; ; ) { /* continue until done */
|
||||
for ( ; p_data_cur != p_data_end; ++p_data_cur) { /* current data */
|
||||
const char ch_cur = *p_data_cur;
|
||||
if (ch_cur == '"') { /* Closing quote, so done */
|
||||
*(p_fb->p_obj_end = p_data_cur) = '\0';
|
||||
p_fb->p_data_cur = p_data_cur + 1;
|
||||
return fb_return_string(p_fb, p_type_found, p_fbobj);
|
||||
}
|
||||
if (ch_cur == '\\') { /* Escape */
|
||||
/* After an escape, data must be moved to fill in the gap
|
||||
* left by the escape character */
|
||||
p_fb->p_data_cur = p_data_cur; /* Reprocess the escape */
|
||||
return fbget_quoted_escaped_string(p_fb,
|
||||
p_type_found, p_fbobj);
|
||||
}
|
||||
/* Else the character is part of the quoted string */
|
||||
} /* end of loop over current text */
|
||||
|
||||
p_fb->p_data_cur = p_data_cur; /* update current position */
|
||||
const int rc = fb_fill(p_fb); /* Try to refill buffer */
|
||||
if (rc != 0) { /* EOF or error */
|
||||
if (rc < 0) { /* error */
|
||||
return -1;
|
||||
}
|
||||
/* Else EOF. Ended without closing quote, so add an implicit
|
||||
* closing quote, i.e., end the string. Since fb_fill()
|
||||
* did not return -1, there is at least 1 byte at the end of
|
||||
* the buffer where the read would have gone. */
|
||||
*(p_fb->p_obj_end = p_fb->p_data_cur) = '\0';
|
||||
return fb_return_string(p_fb, p_type_found, p_fbobj);
|
||||
}
|
||||
p_data_cur = p_fb->p_data_cur; /* Update after fill */
|
||||
p_data_end = p_fb->p_data_end;
|
||||
} /* end of loop processing until done or escape */
|
||||
} /* end of function fbget_quoted_unescaped_string */
|
||||
|
||||
|
||||
|
||||
/* Get a quoted string with an escape. The start has already been set on
|
||||
* entry */
|
||||
static int fbget_quoted_escaped_string(FILEBUF *p_fb,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj)
|
||||
{
|
||||
/* Step through characters until end */
|
||||
char *p_data_src = p_fb->p_data_cur; /* at current char */
|
||||
char *p_data_dst = p_data_src; /* at current char */
|
||||
char *p_data_end = p_fb->p_data_end;
|
||||
bool f_escape_in_progress = false;
|
||||
for ( ; ; ) { /* continue until done */
|
||||
for ( ; p_data_src != p_data_end; ++p_data_src) { /* current data */
|
||||
const char ch_cur = *p_data_src;
|
||||
if (f_escape_in_progress) { /* Always copy the char */
|
||||
f_escape_in_progress = false;
|
||||
*p_data_dst++ = ch_cur;
|
||||
}
|
||||
else { /* Not an escaped character */
|
||||
if (ch_cur == '"') { /* Closing quote, so done */
|
||||
p_fb->p_data_cur = p_data_src + 1;
|
||||
*(p_fb->p_obj_end = p_data_dst) = '\0';
|
||||
return fb_return_string(p_fb, p_type_found, p_fbobj);
|
||||
}
|
||||
if (ch_cur == '\\') { /* Escape */
|
||||
f_escape_in_progress = true;
|
||||
/* Do not copy the escape or advancd p_data_dst */
|
||||
}
|
||||
else { /* ordinary character */
|
||||
*p_data_dst++ = ch_cur;
|
||||
}
|
||||
} /* end of case of not an escaped character */
|
||||
/* Else the character is part of the quoted string */
|
||||
} /* end of loop over current text */
|
||||
|
||||
/* Indicate that there is no more unprocessed data */
|
||||
p_fb->p_data_end = p_fb->p_data_cur = p_data_dst;
|
||||
|
||||
/* If no pending escape, can switch back to unescaped version and
|
||||
* avoid the moves */
|
||||
if (!f_escape_in_progress) {
|
||||
return fbget_quoted_unescaped_string(p_fb, p_type_found,
|
||||
p_fbobj);
|
||||
}
|
||||
|
||||
/* Else escape must be processed, so continue with escaped version */
|
||||
const int rc = fb_fill(p_fb); /* Try to refill buffer */
|
||||
if (rc != 0) { /* EOF or error */
|
||||
if (rc < 0) { /* error */
|
||||
return -1;
|
||||
}
|
||||
/* Else EOF. Ended without closing quote, so add an implicit
|
||||
* closing quote, i.e., end the string. Since fb_fill()
|
||||
* did not return -1, there is at least 1 byte at the end of
|
||||
* the buffer where the read would have gone. */
|
||||
*(p_fb->p_obj_end = p_fb->p_data_cur) = '\0';
|
||||
return fb_return_string(p_fb, p_type_found, p_fbobj);
|
||||
}
|
||||
p_data_dst = p_data_src = p_fb->p_data_cur; /* Update after fill */
|
||||
p_data_end = p_fb->p_data_end;
|
||||
} /* end of loop processing until done or escape */
|
||||
} /* end of function fbget_quoted_escaped_string */
|
||||
|
||||
|
||||
|
||||
/* Get an unquoted string starting at the current position */
|
||||
static int fbget_unquoted_string(FILEBUF *p_fb,
|
||||
unsigned int n_type_wanted, FBTYPE *p_type_wanted,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj)
|
||||
{
|
||||
/* Save the start of the string as the current position */
|
||||
p_fb->p_obj_start = p_fb->p_data_cur;
|
||||
|
||||
static const signed char p_map[1 << CHAR_BIT] = {
|
||||
[(unsigned char ) ' '] = (signed char) +1,
|
||||
[(unsigned char ) '\t'] = (signed char) +1,
|
||||
[(unsigned char ) '\n'] = (signed char) +1,
|
||||
[(unsigned char ) '\r'] = (signed char) +1,
|
||||
[(unsigned char ) '\v'] = (signed char) +1,
|
||||
[(unsigned char ) '\f'] = (signed char) +1,
|
||||
[(unsigned char ) '*'] = (signed char) -1,
|
||||
[(unsigned char ) '#'] = (signed char) -1
|
||||
};
|
||||
/* Step through characters until whitespace or comment */
|
||||
char *p_data_cur = p_fb->p_data_cur;
|
||||
char *p_data_end = p_fb->p_data_end;
|
||||
for ( ; ; ) { /* continue until done */
|
||||
for ( ; p_data_cur != p_data_end; ++p_data_cur) { /* current data */
|
||||
const char ch_cur = *p_data_cur;
|
||||
const signed char map_cur = p_map[(unsigned char) ch_cur];
|
||||
if (map_cur != 0) { /* ws or comment start, so done */
|
||||
*(p_fb->p_obj_end = p_data_cur) = '\0';
|
||||
p_fb->p_data_cur = p_data_cur + 1; /* 1st char past string */
|
||||
p_fb->f_skip_to_eol = map_cur < 0;
|
||||
return fb_return_obj(p_fb, n_type_wanted, p_type_wanted,
|
||||
p_type_found, p_fbobj);
|
||||
}
|
||||
/* Else more of the string */
|
||||
} /* end of loop over current text */
|
||||
|
||||
p_fb->p_data_cur = p_data_cur; /* update current position */
|
||||
const int rc = fb_fill(p_fb); /* Try to refill buffer */
|
||||
if (rc != 0) { /* EOF or error */
|
||||
if (rc < 0) { /* error */
|
||||
return -1;
|
||||
}
|
||||
/* Else EOF. Ended without closing quote, so add an implicit
|
||||
* closing quote, i.e., end the string. Since fb_fill()
|
||||
* did not return -1, there is at least 1 byte at the end of
|
||||
* the buffer where the read would have gone. */
|
||||
*(p_fb->p_obj_end = p_fb->p_data_cur) = '\0';
|
||||
return fb_return_obj(p_fb, n_type_wanted, p_type_wanted,
|
||||
p_type_found, p_fbobj);
|
||||
}
|
||||
p_data_cur = p_fb->p_data_cur; /* Update after fill */
|
||||
p_data_end = p_fb->p_data_end;
|
||||
} /* end of loop processing until done or escape */
|
||||
} /* end of function fbget_unquoted_string */
|
||||
|
||||
|
||||
|
||||
/* This function fills the buffer. First it moves all data in the interval
|
||||
* [start current object, current position) to the beginning of the buffer.
|
||||
*
|
||||
* If there is no space left at the end of the buffer after the move (so
|
||||
* that the move did not occur and data extends to the end), the buffer is
|
||||
* doubled in size. In either case, the end of the buffer is filled with
|
||||
* data read from the file. */
|
||||
static int fb_fill(FILEBUF *p_fb)
|
||||
{
|
||||
/* Exit if EOF already */
|
||||
if (p_fb->is_eof) {
|
||||
return +1;
|
||||
}
|
||||
|
||||
/* Move the data in use to the front of the buffer if not already and
|
||||
* enlarge the buffer if still no space. Returned value is bytes
|
||||
* available at the end of the buffer at p_data_end */
|
||||
const size_t n_byte_read = fb_make_space_at_end(p_fb);
|
||||
if (n_byte_read == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const size_t n_got = fread(p_fb->p_data_end, 1, n_byte_read, p_fb->fp);
|
||||
if (n_got < n_byte_read) { /* EOF or error */
|
||||
if (ferror(p_fb->fp)) {
|
||||
return -1;
|
||||
}
|
||||
/* Else mark as EOF for subsequent calls */
|
||||
p_fb->is_eof = true;
|
||||
|
||||
if (n_got == 0) { /* Nothing to return for this call */
|
||||
return +1;
|
||||
}
|
||||
/* Else partial buffer to return */
|
||||
}
|
||||
|
||||
/* Extend the end of the data by the bytes obtained */
|
||||
p_fb->p_data_end += n_got;
|
||||
return 0;
|
||||
} /* end of function fb_fill */
|
||||
|
||||
|
||||
|
||||
/* Make space at the end of the buffer by moving data of current object
|
||||
* to the front of the buffer and enlarging if there is still no room
|
||||
*
|
||||
* Return value: Number of spaces that are free at the end of p_buf on
|
||||
* return. If 0, more space could not be obtained.
|
||||
*/
|
||||
static size_t fb_make_space_at_end(FILEBUF *p_fb)
|
||||
{
|
||||
const char * const p_obj_start = p_fb->p_obj_start;
|
||||
const char * const p_src = p_obj_start == (char *) NULL ?
|
||||
p_fb->p_data_cur : p_obj_start;
|
||||
char * const p_dst = p_fb->p_buf;
|
||||
|
||||
/* Shift data in use to the front of the buffer if not already */
|
||||
if (p_dst != p_src) { /* object is not at start of buffer */
|
||||
const size_t n = p_fb->p_data_end - p_src;
|
||||
if (n > 0) { /* Will be 0 if skipping whitespace and comments */
|
||||
(void) memmove(p_dst, p_src, n);
|
||||
}
|
||||
|
||||
/* Adjust pointers after the move */
|
||||
ptrdiff_t delta = p_src - p_dst;
|
||||
p_fb->p_data_cur -= delta;
|
||||
p_fb->p_data_end -= delta;
|
||||
|
||||
if (p_obj_start != (char *) NULL) {
|
||||
p_fb->p_obj_start -= delta;
|
||||
}
|
||||
/* never called when p_obj_end is valid */
|
||||
}
|
||||
else { /* already at front */
|
||||
if (p_fb->p_buf_end - p_fb->p_data_end == 0) {
|
||||
const size_t n_alloc_orig = p_fb->n_byte_buf_alloc;
|
||||
|
||||
/* For debugging, this added size can be made very small to
|
||||
* force many reallocs and to have strings end at "hard"
|
||||
* locations such as right before where a terminating null
|
||||
* should be added to a string */
|
||||
//const size_t n_added = 1;
|
||||
const size_t n_added = n_alloc_orig;
|
||||
|
||||
const size_t n_byte_buf_alloc_new = n_alloc_orig + n_added;
|
||||
void * const p = realloc(p_fb->p_buf, n_byte_buf_alloc_new);
|
||||
if (p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
/* Else allocation OK, so update buffer and internal pointers */
|
||||
ptrdiff_t delta = (char *) p - p_fb->p_buf;
|
||||
p_fb->p_buf = (char *) p;
|
||||
p_fb->p_buf_end = (char *) p + n_byte_buf_alloc_new;
|
||||
p_fb->n_byte_buf_alloc = n_byte_buf_alloc_new;
|
||||
p_fb->p_data_cur += delta;
|
||||
p_fb->p_data_end += delta;
|
||||
|
||||
if (p_obj_start != (char *) NULL) {
|
||||
p_fb->p_obj_start += delta;
|
||||
}
|
||||
/* never called when p_obj_end is valid */
|
||||
}
|
||||
}
|
||||
|
||||
return p_fb->p_buf_end - p_fb->p_data_end;
|
||||
} /* end of function fb_make_space_at_end */
|
||||
|
||||
|
||||
|
||||
/* Skip whitespace, including comments starting at the current position */
|
||||
static int fb_skip_whitespace(FILEBUF *p_fb)
|
||||
{
|
||||
static const signed char p_map[1 << CHAR_BIT] = {
|
||||
[(unsigned char ) ' '] = (signed char) +1,
|
||||
[(unsigned char ) '\t'] = (signed char) +1,
|
||||
[(unsigned char ) '\n'] = (signed char) +1,
|
||||
[(unsigned char ) '\r'] = (signed char) +1,
|
||||
[(unsigned char ) '\v'] = (signed char) +1,
|
||||
[(unsigned char ) '\f'] = (signed char) +1,
|
||||
[(unsigned char ) '*'] = (signed char) -1,
|
||||
[(unsigned char ) '#'] = (signed char) -1
|
||||
};
|
||||
/* Step through characters until not whitespace (including comments) */
|
||||
char *p_data_cur = p_fb->p_data_cur;
|
||||
char *p_data_end = p_fb->p_data_end;
|
||||
for ( ; ; ) { /* continue until done */
|
||||
for ( ; p_data_cur != p_data_end; ++p_data_cur) { /* current data */
|
||||
const char ch_cur = *p_data_cur;
|
||||
const signed char map_cur = p_map[(unsigned char) ch_cur];
|
||||
if (map_cur == 0) { /* not in ws or at comment start, so done */
|
||||
p_fb->p_data_cur = p_data_cur;
|
||||
return 0;
|
||||
}
|
||||
if (map_cur == -1) { /* a comment has started */
|
||||
p_fb->p_data_cur = p_data_cur + 1; /* after comment start */
|
||||
const int rc = fb_skip_to_eol(p_fb);
|
||||
if (rc != 0) { /* EOF or error */
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Update local variables. Note that p_fb->p_data_cur is at
|
||||
* the character after the comment, which is a \n or \r.
|
||||
* These characters are whitespace that will be skipped,
|
||||
* so incrementing past it in the ++p_data_cur of the for()
|
||||
* only skips a character that will be skipped anyhow.
|
||||
* (A long comment to say that
|
||||
* p_data_cur = p_fb->p_data_cur - 1 is not necessary.) */
|
||||
p_data_cur = p_fb->p_data_cur;
|
||||
p_data_end = p_fb->p_data_end;
|
||||
} /* end of comment processing */
|
||||
/* Else whitespace, which is skipped */
|
||||
} /* end of loop over current text */
|
||||
|
||||
p_fb->p_data_cur = p_data_cur; /* update current position */
|
||||
const int rc = fb_fill(p_fb); /* Try to refill buffer */
|
||||
if (rc != 0) { /* EOF or error */
|
||||
return rc;
|
||||
}
|
||||
/* Else got more text to process */
|
||||
p_data_cur = p_fb->p_data_cur; /* Update after fill */
|
||||
p_data_end = p_fb->p_data_end;
|
||||
} /* end of loop over text pieces */
|
||||
} /* end of function fb_skip_whitespace */
|
||||
|
||||
|
||||
|
||||
/* Skip text to EOL char, starting at the current position */
|
||||
static int fb_skip_to_eol(FILEBUF *p_fb)
|
||||
{
|
||||
/* Step through characters until not whitespace (including comments) */
|
||||
char *p_data_cur = p_fb->p_data_cur;
|
||||
char *p_data_end = p_fb->p_data_end;
|
||||
for ( ; ; ) { /* continue until done */
|
||||
for ( ; p_data_cur != p_data_end; ++p_data_cur) { /* current data */
|
||||
const char ch_cur = *p_data_cur;
|
||||
if (ch_cur == '\n' || ch_cur == '\r') {
|
||||
p_fb->p_data_cur = p_data_cur;
|
||||
return 0;
|
||||
}
|
||||
/* Else not EOL, which is skipped */
|
||||
} /* end of loop over current text */
|
||||
|
||||
p_fb->p_data_cur = p_data_cur; /* update current position */
|
||||
const int rc = fb_fill(p_fb); /* Try to refill buffer */
|
||||
if (rc != 0) { /* EOF or error */
|
||||
return rc;
|
||||
}
|
||||
/* Else got more text to process */
|
||||
p_data_cur = p_fb->p_data_cur; /* Update after fill */
|
||||
p_data_end = p_fb->p_data_end;
|
||||
} /* end of loop over text pieces */
|
||||
} /* end of function fb_skip_to_eol */
|
||||
|
||||
|
||||
|
||||
/* Return the data found in the most preferred format possible */
|
||||
static int fb_return_obj(FILEBUF *p_fb,
|
||||
unsigned int n_type_wanted, FBTYPE *p_type_wanted,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj)
|
||||
{
|
||||
const char * const p_obj_start = p_fb->p_obj_start; /* data to convert */
|
||||
const char * const p_obj_end = p_fb->p_obj_end;
|
||||
|
||||
/* Must test for null string separately since strto* does not set
|
||||
* errno in this case. Aside from that, it can only be returned
|
||||
* as a string anyhow. */
|
||||
if (p_obj_start != p_obj_end) { /* have a string besides "" */
|
||||
unsigned int i;
|
||||
for (i = 0; i < n_type_wanted; ++i) {
|
||||
FBTYPE type_cur = p_type_wanted[i];
|
||||
errno = 0;
|
||||
if (type_cur == BUF_TYPE_ULONG) {
|
||||
char *p_end;
|
||||
unsigned long val = strtoul(p_obj_start, &p_end, 10);
|
||||
/* Test for processing of full string. Note that checking
|
||||
* for the end of the string rather than a NULL handles the
|
||||
* case of an embedded NULL which the latter test would
|
||||
* not */
|
||||
if (errno == 0 && p_end == p_obj_end) {
|
||||
*p_type_found = BUF_TYPE_ULONG;
|
||||
p_fbobj->ulong_value = val;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (type_cur == BUF_TYPE_LONG) {
|
||||
char *p_end;
|
||||
long val = strtol(p_obj_start, &p_end, 10);
|
||||
if (errno == 0 && p_end == p_obj_end) {
|
||||
*p_type_found = BUF_TYPE_LONG;
|
||||
p_fbobj->long_value = val;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (type_cur == BUF_TYPE_DOUBLE) {
|
||||
char *p_end;
|
||||
double val = strtod(p_obj_start, &p_end);
|
||||
if (errno == 0 && p_end == p_obj_end) {
|
||||
*p_type_found = BUF_TYPE_DOUBLE;
|
||||
p_fbobj->dbl_value = val;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (type_cur == BUF_TYPE_STRING) {
|
||||
break; /* exit loop and use default return of string */
|
||||
}
|
||||
else { /* unknown type */
|
||||
print_error("Unknown output data type %d is ignored.",
|
||||
(int) type_cur);
|
||||
}
|
||||
} /* end of loop trying types */
|
||||
} /* end of case that string is not "" */
|
||||
|
||||
/* If no rquested type was converted OK or string requested, return as
|
||||
* a string */
|
||||
return fb_return_string(p_fb, p_type_found, p_fbobj);
|
||||
} /* end of function fb_return_obj */
|
||||
|
||||
|
||||
|
||||
/* Return string */
|
||||
static int fb_return_string(FILEBUF *p_fb,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj)
|
||||
{
|
||||
const char *p_data_start =
|
||||
p_fbobj->str_value.sz = p_fb->p_obj_start;
|
||||
p_fbobj->str_value.n_char = p_fb->p_obj_end - p_data_start;
|
||||
*p_type_found = BUF_TYPE_STRING;
|
||||
return 0;
|
||||
} /* end of function fb_return_string */
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef file_buffer_h_included
|
||||
#define file_buffer_h_included
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/* Null-terminated string prefixed by length excluding null */
|
||||
typedef struct Filebuf_len_str {
|
||||
size_t n_char; /* length of string excluding null termination */
|
||||
char *sz; /* Start of string */
|
||||
} FBSTRING;
|
||||
|
||||
/* Union for returned value */
|
||||
typedef union Filebuf_obj {
|
||||
FBSTRING str_value;
|
||||
unsigned long ulong_value;
|
||||
long long_value;
|
||||
double dbl_value;
|
||||
} FBOBJ;
|
||||
|
||||
/* Structure for getting file data */
|
||||
typedef struct Filebuf {
|
||||
FILE *fp; /* handle to file */
|
||||
bool is_eof; /* flag that EOF reached */
|
||||
bool f_skip_to_eol;
|
||||
/* Flag that text until the next EOL character should be
|
||||
* skipped before getting the next item from the buffer.
|
||||
* This flag is set when a comment terminates an item,
|
||||
* such as "abc# This is a comment." */
|
||||
size_t n_byte_buf_alloc; /* Allocated buffer size */
|
||||
char *p_buf; /* buffer to receive data from file */
|
||||
char *p_obj_start; /* start of object being returned */
|
||||
char *p_obj_end; /* byte past object being returned */
|
||||
char *p_data_cur; /* current position in buffer. Depending on
|
||||
* circumstances, it points to either the character
|
||||
* being processed or the next character to process */
|
||||
char *p_data_end; /* byte past end of data in buffer */
|
||||
char *p_buf_end; /* byte past end of allocated buffer size, equal to
|
||||
* p_buf + n_byte_buf_alloc, so it is redundant, but
|
||||
* convenient to have available */
|
||||
} FILEBUF;
|
||||
|
||||
/* Types of data */
|
||||
typedef enum FBtype {
|
||||
BUF_TYPE_STRING, /* value type string (always possible) */
|
||||
BUF_TYPE_ULONG, /* value type an unsigned int */
|
||||
BUF_TYPE_LONG, /* value type an int */
|
||||
BUF_TYPE_DOUBLE /* value type double */
|
||||
} FBTYPE;
|
||||
|
||||
|
||||
FILEBUF *fbopen(const char *filename, size_t n_byte_buf_init);
|
||||
int fbget(FILEBUF *p_fb, unsigned int n_type_wanted, FBTYPE *p_type_wanted,
|
||||
FBTYPE *p_type_found, FBOBJ *p_fbobj);
|
||||
int fbclose(FILEBUF *fbp);
|
||||
|
||||
|
||||
#endif /* include guard */
|
||||
|
|
@ -35,25 +35,37 @@ REFERENCED FILES
|
|||
NON-STANDARD FEATURES
|
||||
|
||||
None.
|
||||
|
||||
============================================================================*/
|
||||
#ifdef DEBUG_CMPP
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cmpp.h"
|
||||
|
||||
|
||||
#define USAGE_MSG "Usage: cmpp [-ifs] [-mod [<filename>]] [-lst]"
|
||||
#define USAGE_MSG \
|
||||
"Usage: cmpp [-ifs] | [-mod [<filename>]] | [-lst] | [-p fn.lst]"
|
||||
#define TOO_FEW_ARGS "ERROR - Too few arguments"
|
||||
#define TOO_MANY_ARGS "ERROR - Too many arguments"
|
||||
#define UNRECOGNIZED_ARGS "ERROR - Unrecognized argument"
|
||||
|
||||
|
||||
#ifdef DEBUG_CMPP
|
||||
#define PRINT_CMPP_INFO(argc, argv) print_cmpp_info(argc, argv);
|
||||
static void print_cmpp_info(int argc, char **argv);
|
||||
#else
|
||||
#define PRINT_CMPP_INFO(argc, argv)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
main
|
||||
|
||||
|
|
@ -61,9 +73,11 @@ Function main checks the validity of the command-line arguments
|
|||
supplied when the program is invoked and calls one of the three
|
||||
major functions as appropriate:
|
||||
|
||||
preprocess_ifs_file Process Interface Specification File.
|
||||
preprocess_mod_file Process Model Definition File.
|
||||
preprocess_lst_file Process Pathname List Files.
|
||||
preprocess_ifs_file Process Interface Specification File.
|
||||
preprocess_mod_file Process Model Definition File.
|
||||
preprocess_lst_file Process Pathname List Files.
|
||||
output_paths_from_lst_file Write paths from a list file to stdout
|
||||
to facilite building the code models
|
||||
|
||||
depending on the argument.
|
||||
*/
|
||||
|
|
@ -72,11 +86,11 @@ int main(
|
|||
int argc, /* Number of command line arguments */
|
||||
char *argv[]) /* Command line argument text */
|
||||
{
|
||||
|
||||
init_error (argv[0]);
|
||||
|
||||
/* Process command line arguments and vector to appropriate function */
|
||||
PRINT_CMPP_INFO(argc, argv)
|
||||
|
||||
/* Process command line arguments and vector to appropriate function */
|
||||
if(argc < 2) {
|
||||
print_error(TOO_FEW_ARGS);
|
||||
print_error(USAGE_MSG);
|
||||
|
|
@ -115,6 +129,26 @@ int main(
|
|||
print_error(USAGE_MSG);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[1],"-p") == 0) { /* Output paths from a list file */
|
||||
if (argc == 3) {
|
||||
const int n_item = output_paths_from_lst_file(argv[2]);
|
||||
if (n_item < 0) {
|
||||
print_error("Unable to print paths to stdout");
|
||||
exit(-1);
|
||||
}
|
||||
exit(n_item);
|
||||
}
|
||||
else { /* Wrong number of arguments */
|
||||
if (argc < 3) {
|
||||
print_error(TOO_FEW_ARGS);
|
||||
}
|
||||
else {
|
||||
print_error(TOO_MANY_ARGS);
|
||||
}
|
||||
print_error(USAGE_MSG);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
print_error(UNRECOGNIZED_ARGS);
|
||||
|
|
@ -123,5 +157,67 @@ int main(
|
|||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
} /* end of function main */
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_CMPP
|
||||
/* Print some debugging information for cmpp
|
||||
*
|
||||
* With the use of environment variables to locate files, it is helpful
|
||||
* to know some information about the program when debugging. If the
|
||||
* build of a code model fails due to cmpp, the macro can be enabled to
|
||||
* find the information needed to separately debug cmpp */
|
||||
static void print_cmpp_info(int argc, char **argv)
|
||||
{
|
||||
/* Print the program and its arguments */
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < argc; ++i) {
|
||||
(void) fprintf(stdout, "%s ", argv[i]);
|
||||
}
|
||||
(void) fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Print the current directory */
|
||||
{
|
||||
const DWORD n_char = GetCurrentDirectoryA(0, (char *) NULL);
|
||||
if (n_char > 0) {
|
||||
char *p_buf = (char *) malloc(n_char);
|
||||
if (p_buf != (char *) NULL) {
|
||||
if (GetCurrentDirectoryA(n_char, p_buf) != 0) {
|
||||
(void) fprintf(stdout, "Current Directory: \"%s\".\n",
|
||||
p_buf);
|
||||
}
|
||||
free(p_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print the CMPP_IDIR environment variable if defined */
|
||||
{
|
||||
const char * const ev = getenv("CMPP_IDIR");
|
||||
if (ev) {
|
||||
(void) fprintf(stdout, "CMPP_IDIR = \"%s\"\n", ev);
|
||||
}
|
||||
else {
|
||||
(void) fprintf(stdout, "CMPP_IDIR is not defined\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the CMPP_ODIR environment variable if defined */
|
||||
{
|
||||
const char * const ev = getenv("CMPP_ODIR");
|
||||
if (ev) {
|
||||
(void) fprintf(stdout, "CMPP_ODIR = \"%s\"\n", ev);
|
||||
}
|
||||
else {
|
||||
(void) fprintf(stdout, "CMPP_ODIR is not defined\n");
|
||||
}
|
||||
}
|
||||
} /* end of function print_cmpp_info */
|
||||
#endif /* #ifdef DEBUG_CMPP */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,9 +42,6 @@ NON-STANDARD FEATURES
|
|||
|
||||
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
preprocess_ifs_file
|
||||
|
||||
|
|
@ -65,7 +62,6 @@ void preprocess_ifs_file(void)
|
|||
|
||||
int status; /* Return status */
|
||||
|
||||
|
||||
/* Read the entire ifspec.ifs file and load the data into ifs_table */
|
||||
|
||||
status = read_ifs_file(IFSPEC_FILENAME,GET_IFS_TABLE,&ifs_table);
|
||||
|
|
@ -82,8 +78,56 @@ void preprocess_ifs_file(void)
|
|||
if(status != 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rem_ifs_table(&ifs_table);
|
||||
}
|
||||
|
||||
void rem_ifs_table(Ifs_Table_t *ifs_table)
|
||||
{
|
||||
/* Remove the ifs_table */
|
||||
free(ifs_table->name.c_fcn_name);
|
||||
free(ifs_table->name.description);
|
||||
free(ifs_table->name.model_name);
|
||||
|
||||
{
|
||||
Conn_Info_t * const p_conn = ifs_table->conn;
|
||||
const int num_conn = ifs_table->num_conn;
|
||||
int i;
|
||||
for (i = 0; i < num_conn; ++i) {
|
||||
Conn_Info_t *p_conn_cur = p_conn + i;
|
||||
free(p_conn_cur->name);
|
||||
free(p_conn_cur->description);
|
||||
free(p_conn_cur->default_type);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Param_Info_t * const p_param = ifs_table->param;
|
||||
const int num_param = ifs_table->num_param;
|
||||
int i;
|
||||
for (i = 0; i < num_param; ++i) {
|
||||
Param_Info_t *p_param_cur = p_param + i;
|
||||
free(p_param_cur->name);
|
||||
free(p_param_cur->description);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Inst_Var_Info_t * const p_inst_var = ifs_table->inst_var;
|
||||
const int num_inst_var = ifs_table->num_inst_var;
|
||||
int i;
|
||||
for(i = 0; i < num_inst_var; ++i) {
|
||||
Inst_Var_Info_t *p_inst_var_cur = p_inst_var + i;
|
||||
free(p_inst_var_cur->name);
|
||||
free(p_inst_var_cur->description);
|
||||
}
|
||||
}
|
||||
|
||||
free(ifs_table->conn);
|
||||
free(ifs_table->param);
|
||||
free(ifs_table->inst_var);
|
||||
} /* end of function rem_ifs_table */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -54,6 +54,7 @@ NON-STANDARD FEATURES
|
|||
|
||||
============================================================================*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -74,21 +75,33 @@ extern int mod_num_errors;
|
|||
|
||||
extern Ifs_Table_t *mod_ifs_table;
|
||||
|
||||
extern const char *current_filename;
|
||||
extern char *current_filename;
|
||||
extern char *prog_name;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static char *change_extension (char *filename, char *ext)
|
||||
/* Allocate and build a file name from the input filename by changing its
|
||||
* extension (text after the last '.') in filename to ext or append .ext if
|
||||
* the filename has no extension */
|
||||
static char *change_extension(const char *filename, const char *ext)
|
||||
{
|
||||
char *p = strrchr(filename, '.');
|
||||
size_t prefix_len = p ? (size_t) (p-filename+1) : strlen(filename);
|
||||
char *new_filename = malloc(prefix_len + strlen(ext) + 1);
|
||||
const char * const p = strrchr(filename, '.');
|
||||
const size_t prefix_len = p ? (size_t) (p - filename) : strlen(filename);
|
||||
const size_t ext_len = strlen(ext);
|
||||
char * const new_filename = malloc(prefix_len + ext_len + 2);
|
||||
/* +1 for '.' +1 for '\0' */
|
||||
if (new_filename == (char *) NULL) {
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
strncpy(new_filename, filename, prefix_len);
|
||||
strcpy(new_filename+prefix_len, ext);
|
||||
{
|
||||
char *p_cur = (char *) memcpy(new_filename, filename, prefix_len) +
|
||||
prefix_len;
|
||||
*p_cur++ = '.';
|
||||
(void) memcpy(p_cur, ext, ext_len + 1);
|
||||
}
|
||||
|
||||
return new_filename;
|
||||
}
|
||||
} /* end of function change_extension */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
|
@ -108,14 +121,12 @@ utilities.
|
|||
|
||||
|
||||
void preprocess_mod_file (
|
||||
char *filename) /* The file to read */
|
||||
const char *filename) /* The file to read */
|
||||
{
|
||||
|
||||
|
||||
Ifs_Table_t ifs_table; /* info read from ifspec.ifs file */
|
||||
int status; /* Return status */
|
||||
const char *output_filename;
|
||||
|
||||
Ifs_Table_t ifs_table; /* info read from ifspec.ifs file */
|
||||
int status; /* Return status */
|
||||
char *output_filename = (char *) NULL; /* .mod file being written */
|
||||
|
||||
/*
|
||||
* Read the entire ifspec.ifs file and load the data into ifs_table
|
||||
*/
|
||||
|
|
@ -125,42 +136,80 @@ void preprocess_mod_file (
|
|||
if (status != 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_filename = filename;
|
||||
|
||||
mod_yyin = fopen_cmpp (¤t_filename, "r");
|
||||
if (mod_yyin == NULL) {
|
||||
print_error("ERROR - Could not open input .mod file: %s", current_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
output_filename = change_extension (filename, "c");
|
||||
mod_yyout = fopen_cmpp (&output_filename, "w");
|
||||
/* Open the cfunc.mod file defining the code model function */
|
||||
if ((current_filename = gen_filename(filename, "r")) == (char *) NULL) {
|
||||
print_error("ERROR - Unable to build mod file name");
|
||||
exit(1);
|
||||
}
|
||||
if ((mod_yyin = fopen(current_filename, "r")) == (FILE *) NULL) {
|
||||
print_error("ERROR - Unable to open mod file \"%s\": %s",
|
||||
current_filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
{
|
||||
char *output_filename_base = (char *) NULL;
|
||||
if ((output_filename_base = change_extension(
|
||||
filename, "c")) == (char *) NULL) {
|
||||
print_error("ERROR - Could not change extension of "
|
||||
"\"%s\".", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((output_filename = gen_filename(
|
||||
output_filename_base, "w")) == (char *) NULL) {
|
||||
print_error("ERROR - Unable to build output file name");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
free(output_filename_base);
|
||||
}
|
||||
|
||||
if ((mod_yyout = fopen(output_filename, "w")) == (FILE *) NULL) {
|
||||
/* .c file could not be opened */
|
||||
print_error("ERROR - Could not open output .c file\"%s\": %s",
|
||||
output_filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (mod_yyout == NULL) {
|
||||
print_error("ERROR - Could not open output .c file: %s", output_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mod_ifs_table = &ifs_table;
|
||||
mod_num_errors = 0;
|
||||
|
||||
/* Define DEBUG_WITH_MOD_FILE to have the compiler use the cfunc.mod file for
|
||||
* deugging instead of the cfunc.c file. */
|
||||
#ifdef DEBUG_WITH_MOD_FILE
|
||||
fprintf (mod_yyout, "#line 1 \"%s\"\n", current_filename);
|
||||
#endif
|
||||
fprintf (mod_yyout, "#include \"ngspice/cm.h\"\n");
|
||||
fprintf (mod_yyout, "extern void %s(Mif_Private_t *);\n",
|
||||
ifs_table.name.c_fcn_name);
|
||||
ifs_table.name.c_fcn_name);
|
||||
#ifdef DEBUG_WITH_MOD_FILE
|
||||
fprintf (mod_yyout, "#line 1 \"%s\"\n", current_filename);
|
||||
#endif
|
||||
|
||||
mod_yylineno = 1;
|
||||
|
||||
if (mod_yyparse() || (mod_num_errors > 0)) {
|
||||
print_error("Error parsing .mod file: \"%s\"", current_filename);
|
||||
unlink (output_filename);
|
||||
exit (1);
|
||||
}
|
||||
fclose (mod_yyout);
|
||||
mod_yyrestart(NULL);
|
||||
}
|
||||
if (mod_yyparse() || (mod_num_errors > 0)) {
|
||||
print_error("Error parsing .mod file: \"%s\"", current_filename);
|
||||
unlink(output_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fclose(mod_yyout) != 0) {
|
||||
print_error("Error closing output file \"%s\": %s",
|
||||
current_filename, strerror(errno));
|
||||
unlink(output_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rem_ifs_table(&ifs_table);
|
||||
mod_yyrestart(NULL);
|
||||
free(output_filename);
|
||||
free(current_filename);
|
||||
} /* end of function preprocess_mod_file */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
|||
|
|
@ -47,7 +47,11 @@ NON-STANDARD FEATURES
|
|||
============================================================================*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ifs_yacc_y.h"
|
||||
|
||||
extern char *prog_name;
|
||||
|
|
@ -65,7 +69,7 @@ extern int ifs_num_errors;
|
|||
|
||||
static int read_ifs_table(FILE *fp, int mode, Ifs_Table_t *ifs_table);
|
||||
|
||||
const char *current_filename;
|
||||
char *current_filename;
|
||||
|
||||
/* *********************************************************************** */
|
||||
|
||||
|
|
@ -94,35 +98,42 @@ int read_ifs_file(
|
|||
int mode, /* Get names only or get everything? */
|
||||
Ifs_Table_t *ifs_table) /* Table to put info in */
|
||||
{
|
||||
|
||||
FILE *fp; /* Ifs file pointer */
|
||||
|
||||
int status; /* returned status from function */
|
||||
|
||||
|
||||
FILE *fp = (FILE *) NULL; /* Ifs file pointer */
|
||||
int status = 0; /* returned status from function */
|
||||
|
||||
|
||||
/* Open the ifs file for read access */
|
||||
|
||||
fp = fopen_cmpp(&filename, "r");
|
||||
|
||||
if(fp == NULL) {
|
||||
perror (prog_name);
|
||||
print_error("ERROR - File not found: %s", filename);
|
||||
return -1;
|
||||
/* Open the model pathname file */
|
||||
if ((current_filename = gen_filename(filename, "r")) == (char *) NULL) {
|
||||
print_error("ERROR - Unable to build full file name");
|
||||
return -1;
|
||||
}
|
||||
if ((fp = fopen(current_filename, "r")) == (FILE *) NULL) {
|
||||
print_error("ERROR - Unable to open \"%s\": %s",
|
||||
current_filename, strerror(errno));
|
||||
status = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
/* Get the stuff from the file into the ifs_table struct. Here mode
|
||||
* defines the data that will be added to the structure */
|
||||
status = read_ifs_table(fp, mode, ifs_table);
|
||||
|
||||
EXITPOINT:
|
||||
/* Close file and return */
|
||||
if (fp != (FILE *) NULL) {
|
||||
if (fclose(fp) != 0) {
|
||||
print_error("ERROR - Unable to close \"%s\": %s",
|
||||
current_filename, strerror(errno));
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
|
||||
current_filename = filename;
|
||||
|
||||
/* Get the stuff from the file into the ifs_table struct */
|
||||
|
||||
status = read_ifs_table(fp, mode, ifs_table);
|
||||
|
||||
/* Close file and return */
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return(status);
|
||||
|
||||
}
|
||||
free(current_filename);
|
||||
current_filename = (char *) NULL;
|
||||
return status;
|
||||
} /* end of function read_ifs_file */
|
||||
|
||||
|
||||
|
||||
|
|
@ -146,10 +157,13 @@ static int read_ifs_table(
|
|||
int mode, /* Get names only or get everything? */
|
||||
Ifs_Table_t *ifs_table) /* Table to put info in */
|
||||
{
|
||||
|
||||
assert (ifs_table);
|
||||
assert (fp);
|
||||
|
||||
ifs_table->name.description =
|
||||
ifs_table->name.c_fcn_name =
|
||||
ifs_table->name.model_name = NULL;
|
||||
|
||||
ifs_yylineno = 1;
|
||||
ifs_yyin = fp;
|
||||
parser_just_names = (mode == GET_IFS_NAME) ? true : false;
|
||||
|
|
|
|||
|
|
@ -84,16 +84,21 @@ void print_error(const char *fmt, ...)
|
|||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
fprintf(stderr, "%s: ", prog_name);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
vprint_error(fmt, ap);
|
||||
va_end(ap);
|
||||
} /* end of function print_error */
|
||||
|
||||
|
||||
|
||||
void vprint_error(const char *fmt, va_list p_arg)
|
||||
{
|
||||
fprintf(stderr, "%s: ", prog_name);
|
||||
vfprintf(stderr, fmt, p_arg);
|
||||
fprintf(stderr, "\n");
|
||||
} /* end of functoin vprint_error */
|
||||
|
||||
|
||||
|
||||
/* Convert a string to all lower case */
|
||||
void str_to_lower(char *s)
|
||||
{
|
||||
|
|
@ -110,24 +115,22 @@ void str_to_lower(char *s)
|
|||
/* If *path_p is relative, prefix with the value of the CMPP output or
|
||||
* input environment variable. Open the file and return the path that
|
||||
* was used to open it. */
|
||||
FILE *fopen_cmpp(const char **path_p, const char *mode)
|
||||
char *gen_filename(const char *filename, const char *mode)
|
||||
{
|
||||
const char *path = *path_p;
|
||||
char *buf = (char *) NULL;
|
||||
|
||||
/* If absoulte path, prefix with CMPP_ODIR/CMPP_IDIR env value */
|
||||
if (!is_absolute_pathname(path)) { /* relative path */
|
||||
if (!is_absolute_pathname(filename)) { /* relative path */
|
||||
const char *e = getenv((*mode == 'w' || *mode == 'a') ?
|
||||
"CMPP_ODIR" : "CMPP_IDIR");
|
||||
if (e) { /* have env var */
|
||||
const size_t len_prefix = strlen(e);
|
||||
const size_t len_path = strlen(path);
|
||||
const size_t n_char = len_prefix + len_path + 1;
|
||||
const size_t len_filename = strlen(filename);
|
||||
const size_t n_char = len_prefix + len_filename + 1;
|
||||
|
||||
/* Allocate buffer to build full file name */
|
||||
if ((buf = (char *) malloc(n_char + 1)) == (char *) NULL) {
|
||||
*path_p = (char *) NULL;
|
||||
return (FILE *) NULL;
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
/* Build the full file name */
|
||||
|
|
@ -136,24 +139,21 @@ FILE *fopen_cmpp(const char **path_p, const char *mode)
|
|||
(void) memcpy(p_cur, e, len_prefix);
|
||||
p_cur += len_prefix;
|
||||
*p_cur++ = DIR_TERM_UNIX;
|
||||
(void) memcpy(p_cur, path, len_path + 1);
|
||||
(void) memcpy(p_cur, filename, len_filename + 1);
|
||||
}
|
||||
} /* end of case that env variable found */
|
||||
} /* end of case that path is absolute */
|
||||
|
||||
/* If did not build full file name yet, copy the original
|
||||
* name of the file */
|
||||
/* If did not build full file name yet, make the original
|
||||
* name of the file the full file name */
|
||||
if (buf == (char *) NULL) {
|
||||
if ((buf = strdup(path)) == (char *) NULL) { /* failed */
|
||||
*path_p = (char *) NULL;
|
||||
return (FILE *) NULL;
|
||||
if ((buf = strdup(filename)) == (char *) NULL) { /* failed */
|
||||
return (char *) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return copy of file name and opened file */
|
||||
*path_p = buf;
|
||||
return fopen(buf, mode);
|
||||
} /* end of function fopen_cmpp */
|
||||
return buf;
|
||||
} /* end of function gen_filename */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -340,6 +340,7 @@ static void EVTcreate_state(
|
|||
{
|
||||
new_state = state_data->free[inst_index];
|
||||
state_data->free[inst_index] = new_state->next;
|
||||
new_state->next = NULL; // reusing dirty memory: next must be reset
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,14 +44,30 @@ clean:
|
|||
|
||||
#-----------------------------------------------------------------------------
|
||||
NGSRCDIR = $(CURDIR)/../../../../src
|
||||
|
||||
COMPILE = $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(VIS_CFLAGS)
|
||||
dstring.o : $(NGSRCDIR)/misc/dstring.c $(NGSRCDIR)/include/ngspice/dstring.h
|
||||
$(COMPILE) -I $(NGSRCDIR)/include/ngspice -o $@ -c $<
|
||||
$(COMPILE) -I $(NGSRCDIR)/include -o $@ -c $<
|
||||
|
||||
ifdef cm
|
||||
|
||||
modlst := $(shell cat $(srcdir)/$(cm)/modpath.lst)
|
||||
udnlst := $(shell cat $(srcdir)/$(cm)/udnpath.lst)
|
||||
# These will work for a simpler format of the .lst files with # comments and
|
||||
# version information on the same line.
|
||||
# sed removes comment lines of form [space]#[text]
|
||||
# awk keeps the name of the path only, removing version number if present
|
||||
# $$ and \# are escapes for Makefile
|
||||
#modlst := $(shell cat $(srcdir)/$(cm)/modpath.lst | sed -e '/^[ \t]*\#/d' |\
|
||||
# awk '{ print $$1 }')
|
||||
#udnlst := $(shell cat $(srcdir)/$(cm)/udnpath.lst | sed -e '/^[ \t]*\#/d' |\
|
||||
# awk '{ print $$1 }')
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
cmpp = ../cmpp/cmpp.exe
|
||||
else
|
||||
cmpp = ../cmpp/cmpp
|
||||
endif
|
||||
modlst := $(shell $(cmpp) -p $(srcdir)/$(cm)/modpath.lst)
|
||||
udnlst := $(shell $(cmpp) -p $(srcdir)/$(cm)/udnpath.lst)
|
||||
|
||||
|
||||
cm-dirs := $(cm) $(udnlst:%=$(cm)/%) $(modlst:%=$(cm)/%)
|
||||
cm-dep-dirs := $(cm-dirs:%=%/.deps)
|
||||
|
|
|
|||
|
|
@ -65,10 +65,6 @@ NON-STANDARD FEATURES
|
|||
#define DIR_PATHSEP "/"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||
|
||||
struct filesource_state {
|
||||
|
|
@ -149,27 +145,8 @@ NON-STANDARD FEATURES
|
|||
|
||||
|
||||
/*=== CM_FILESOURCE ROUTINE ===*/
|
||||
|
||||
|
||||
static void
|
||||
cm_filesource_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Local_Data_t *loc = STATIC_VAR (locdata);
|
||||
if (loc->state->fp)
|
||||
fclose(loc->state->fp);
|
||||
free(loc->state);
|
||||
free(loc->amplinterval);
|
||||
free(loc->timeinterval);
|
||||
free(loc->indata->datavec);
|
||||
free(loc->indata);
|
||||
free(loc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cm_filesource_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
|
||||
void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
||||
{
|
||||
|
|
@ -189,18 +166,39 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
|
||||
int count;
|
||||
|
||||
CALLBACK = cm_filesource_callback;
|
||||
|
||||
/*** allocate static storage for *loc ***/
|
||||
STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t ));
|
||||
loc = STATIC_VAR (locdata);
|
||||
if ((loc = (Local_Data_t *) (STATIC_VAR(locdata) = tcalloc_raw(1,
|
||||
sizeof(Local_Data_t)))) == (Local_Data_t *) NULL) {
|
||||
cm_message_send("Unable to allocate Local_Data_t "
|
||||
"in cm_filesource()");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate storage for internal state */
|
||||
loc->timeinterval = (double*)calloc(2, sizeof(double));
|
||||
loc->amplinterval = (double*)calloc(2 * (size_t) size, sizeof(double));
|
||||
loc->state = (struct filesource_state*)malloc(sizeof(struct filesource_state));
|
||||
loc->indata = (struct infiledata*)malloc(sizeof(struct infiledata));
|
||||
loc->indata->datavec = (double*)malloc(sizeof(double) * stepsize * 1000);
|
||||
loc->timeinterval = (double *) tcalloc_raw(2, sizeof(double));
|
||||
loc->amplinterval = (double *) tcalloc_raw(2 * (size_t) size,
|
||||
sizeof(double));
|
||||
loc->state = (struct filesource_state *) tcalloc_raw(1,
|
||||
sizeof(struct filesource_state)); /* calloc to null fp */
|
||||
loc->indata = (struct infiledata *) tmalloc_raw(
|
||||
sizeof(struct infiledata));
|
||||
loc->indata->datavec = (double *) tmalloc_raw(sizeof(double) *
|
||||
stepsize * 1000);
|
||||
|
||||
/* Check allocations */
|
||||
if (loc->timeinterval == (double *) NULL ||
|
||||
loc->amplinterval == (double *) NULL ||
|
||||
loc->state == (struct filesource_state *) NULL ||
|
||||
loc->indata == (struct infiledata *) NULL ||
|
||||
loc->indata->datavec == (double *) NULL) {
|
||||
cm_message_send("Unable to allocate Local_Data_t fields "
|
||||
"in cm_filesource()");
|
||||
cm_filesource_callback(mif_private, MIF_CB_DESTROY);
|
||||
return;
|
||||
}
|
||||
|
||||
CALLBACK = cm_filesource_callback;
|
||||
|
||||
loc->indata->vecallocated = stepsize * 1000;
|
||||
loc->indata->maxoccupied = 0;
|
||||
loc->indata->actpointer = 0;
|
||||
|
|
@ -210,13 +208,21 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
loc->state->fp = fopen_with_path(PARAM(file), "r");
|
||||
loc->state->atend = 0;
|
||||
if (!loc->state->fp) {
|
||||
char *lbuffer, *p;
|
||||
char *lbuffer;
|
||||
lbuffer = getenv("NGSPICE_INPUT_DIR");
|
||||
if (lbuffer && *lbuffer) {
|
||||
p = (char*) malloc(strlen(lbuffer) + strlen(DIR_PATHSEP) + strlen(PARAM(file)) + 1);
|
||||
sprintf(p, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(file));
|
||||
loc->state->fp = fopen(p, "r");
|
||||
free(p);
|
||||
char *p;
|
||||
if ((p = (char *) tmalloc_raw(strlen(lbuffer) +
|
||||
strlen(DIR_PATHSEP) + strlen(PARAM(file)) + 1)) ==
|
||||
(char *) NULL) {
|
||||
cm_message_send("Unable to allocate buffer "
|
||||
"for building file name in cm_filesource()");
|
||||
}
|
||||
else {
|
||||
sprintf(p, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(file));
|
||||
loc->state->fp = fopen(p, "r");
|
||||
txfree(p);
|
||||
}
|
||||
}
|
||||
if (!loc->state->fp) {
|
||||
cm_message_printf("cannot open file %s", PARAM(file));
|
||||
|
|
@ -237,18 +243,23 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
loc->state->atend = 1;
|
||||
break;
|
||||
}
|
||||
cpdel = cp = strdup(line);
|
||||
if ((cpdel = cp = tstrdup_raw(line)) == (char *) NULL) {
|
||||
cm_message_send("Unable to duplicate string "
|
||||
"cm_filesource()");
|
||||
loc->state->atend = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* read the time channel; update the time difference */
|
||||
while (*cp && isspace_c(*cp))
|
||||
++cp;
|
||||
if (*cp == '*' || *cp == '#' || *cp == ';') {
|
||||
free(cpdel);
|
||||
txfree(cpdel);
|
||||
continue;
|
||||
}
|
||||
t = strtod(cp, &cp2);
|
||||
if (cp2 == cp) {
|
||||
free(cpdel);
|
||||
txfree(cpdel);
|
||||
continue;
|
||||
}
|
||||
cp = cp2;
|
||||
|
|
@ -265,11 +276,13 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
If not, add another 1000*size doubles */
|
||||
if (count > loc->indata->vecallocated - size) {
|
||||
loc->indata->vecallocated += size * 1000;
|
||||
loc->indata->datavec = (double*)realloc(loc->indata->datavec, sizeof(double) * loc->indata->vecallocated);
|
||||
}
|
||||
if(loc->indata->datavec == NULL){
|
||||
cm_message_printf("cannot allocate enough memory");
|
||||
break; // loc->state->atend = 1;
|
||||
void * const p = trealloc_raw(loc->indata->datavec,
|
||||
sizeof(double) * loc->indata->vecallocated);
|
||||
if (p == NULL) {
|
||||
cm_message_printf("cannot allocate enough memory");
|
||||
break; // loc->state->atend = 1;
|
||||
}
|
||||
loc->indata->datavec = (double *) p;
|
||||
}
|
||||
loc->indata->datavec[count++] = t;
|
||||
|
||||
|
|
@ -287,7 +300,7 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
t += PARAM(amploffset[i]);
|
||||
loc->indata->datavec[count++] = t;
|
||||
}
|
||||
free(cpdel);
|
||||
txfree(cpdel);
|
||||
}
|
||||
loc->indata->maxoccupied = count;
|
||||
|
||||
|
|
@ -345,4 +358,48 @@ void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc.
|
|||
for (i = 0; i < size; ++i)
|
||||
OUTPUT(out[i]) = loc->amplinterval[2 * i + 1];
|
||||
}
|
||||
}
|
||||
} /* end of function cm_filesource */
|
||||
|
||||
|
||||
|
||||
static void cm_filesource_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Local_Data_t *loc = (Local_Data_t *) STATIC_VAR(locdata);
|
||||
if (loc == (Local_Data_t *) NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (loc->state != (struct filesource_state *) NULL) {
|
||||
if (loc->state->fp != (FILE *) NULL) {
|
||||
fclose(loc->state->fp);
|
||||
}
|
||||
txfree(loc->state);
|
||||
}
|
||||
|
||||
if (loc->amplinterval != (double *) NULL) {
|
||||
txfree(loc->amplinterval);
|
||||
}
|
||||
|
||||
if (loc->timeinterval != (double *) NULL) {
|
||||
txfree(loc->timeinterval);
|
||||
}
|
||||
|
||||
if (loc->indata) {
|
||||
if (loc->indata->datavec) {
|
||||
txfree(loc->indata->datavec);
|
||||
}
|
||||
txfree(loc->indata);
|
||||
}
|
||||
|
||||
txfree(loc);
|
||||
|
||||
STATIC_VAR(locdata) = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_filesource_callback */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
climit
|
||||
divide
|
||||
d_dt
|
||||
gain
|
||||
hyst
|
||||
ilimit
|
||||
int
|
||||
limit
|
||||
mult
|
||||
multi_input_pwl
|
||||
oneshot
|
||||
pwl
|
||||
sine
|
||||
slew
|
||||
square
|
||||
summer
|
||||
s_xfer
|
||||
triangle
|
||||
file_source
|
||||
#Directory Version
|
||||
climit 1
|
||||
divide 1
|
||||
d_dt 1
|
||||
gain 1
|
||||
hyst 1
|
||||
ilimit 1
|
||||
int 1
|
||||
limit 1
|
||||
mult 1
|
||||
multi_input_pwl 1
|
||||
oneshot 2
|
||||
pwl 2
|
||||
sine 2
|
||||
slew 1
|
||||
square 1
|
||||
summer 1
|
||||
s_xfer 2
|
||||
triangle 1
|
||||
file_source 2
|
||||
|
|
|
|||
|
|
@ -155,6 +155,8 @@ NON-STANDARD FEATURES
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void cm_oneshot_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
|
||||
void cm_oneshot(ARGS) /* structure holding parms,
|
||||
inputs, outputs, etc. */
|
||||
{
|
||||
|
|
@ -251,24 +253,31 @@ void cm_oneshot(ARGS) /* structure holding parms,
|
|||
cm_analog_alloc(OUTPUT_OLD,sizeof(double));
|
||||
|
||||
/*** allocate static storage for *loc ***/
|
||||
STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t ));
|
||||
loc = STATIC_VAR (locdata);
|
||||
if ((loc = (Local_Data_t *) (STATIC_VAR(locdata) = tcalloc_raw(1,
|
||||
sizeof(Local_Data_t)))) == (Local_Data_t *) NULL) {
|
||||
cm_message_send("Unable to allocate Local_Data_t "
|
||||
"in cm_oneshot()");
|
||||
cm_oneshot_callback(mif_private, MIF_CB_DESTROY);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate storage for breakpoint domain & pulse width values */
|
||||
x = loc->control = (double *) calloc((size_t) cntl_size, sizeof(double));
|
||||
if (!x) {
|
||||
if ((x = loc->control = (double *) tcalloc_raw((size_t) cntl_size,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_send(oneshot_allocation_error);
|
||||
cm_oneshot_callback(mif_private, MIF_CB_DESTROY);
|
||||
return;
|
||||
}
|
||||
y = loc->pw = (double *) calloc((size_t) pw_size, sizeof(double));
|
||||
if (!y) {
|
||||
if ((y = loc->pw = (double *) tcalloc_raw((size_t) pw_size,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_send(oneshot_allocation_error);
|
||||
cm_oneshot_callback(mif_private, MIF_CB_DESTROY);
|
||||
return;
|
||||
}
|
||||
CALLBACK = cm_oneshot_callback;
|
||||
|
||||
loc->tran_init = FALSE;
|
||||
|
||||
}
|
||||
} /* end of initialization */
|
||||
|
||||
if(ANALYSIS == MIF_DC) {
|
||||
|
||||
|
|
@ -339,7 +348,12 @@ void cm_oneshot(ARGS) /* structure holding parms,
|
|||
|
||||
OUTPUT(out) = output_low;
|
||||
} else {
|
||||
loc = STATIC_VAR (locdata);
|
||||
if ((loc = (Local_Data_t *) STATIC_VAR(locdata)) ==
|
||||
(Local_Data_t *) NULL) {
|
||||
cm_message_send("Attempt to use uninitialized Local_Data_t "
|
||||
"in cm_oneshot()");
|
||||
return;
|
||||
}
|
||||
x = loc->control;
|
||||
y = loc->pw;
|
||||
|
||||
|
|
@ -544,5 +558,28 @@ void cm_oneshot(ARGS) /* structure holding parms,
|
|||
ac_gain.imag= 0.0;
|
||||
AC_GAIN(out,clk) = ac_gain;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_oneshot */
|
||||
|
||||
|
||||
|
||||
/* This function frees resources when called with reason argument
|
||||
* MIF_CB_DESTROY */
|
||||
static void cm_oneshot_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Local_Data_t *loc = STATIC_VAR(locdata);
|
||||
if (loc == (Local_Data_t *) NULL) {
|
||||
break;
|
||||
}
|
||||
txfree(loc->control);
|
||||
txfree(loc->pw);
|
||||
txfree(loc);
|
||||
STATIC_VAR(locdata) = (Local_Data_t *) NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_oneshot_callback */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -229,19 +229,30 @@ cm_pwl_callback(ARGS, Mif_Callback_Reason_t reason)
|
|||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
double *last_x_value = STATIC_VAR (last_x_value);
|
||||
double *x = STATIC_VAR (x);
|
||||
double *y = STATIC_VAR (y);
|
||||
free(last_x_value);
|
||||
free(x);
|
||||
free(y);
|
||||
void *p = STATIC_VAR(last_x_value);
|
||||
if (p != NULL) {
|
||||
txfree(p);
|
||||
}
|
||||
|
||||
p = STATIC_VAR(x);
|
||||
if (p != NULL) {
|
||||
txfree(p);
|
||||
}
|
||||
|
||||
p = STATIC_VAR(y);
|
||||
if (p != NULL) {
|
||||
txfree(p);
|
||||
}
|
||||
|
||||
STATIC_VAR (last_x_value) = NULL;
|
||||
STATIC_VAR (x) = NULL;
|
||||
STATIC_VAR (y) = NULL;
|
||||
STATIC_VAR (y) = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end of function cm_pwl_callback */
|
||||
|
||||
|
||||
|
||||
/*=== CM_PWL ROUTINE ================*/
|
||||
|
||||
|
|
@ -270,10 +281,11 @@ void cm_pwl(ARGS) /* structure holding parms,
|
|||
|
||||
Mif_Complex_t ac_gain;
|
||||
|
||||
CALLBACK = cm_pwl_callback;
|
||||
|
||||
char *allocation_error="\n***ERROR***\nPWL: Allocation calloc failed!\n";
|
||||
char *limit_error="\n***ERROR***\nPWL: Violation of 50% rule in breakpoints!\n";
|
||||
static const char * const allocation_error = "\n***ERROR***\n"
|
||||
"PWL: Allocation failed!\n";
|
||||
static const char * const limit_error = "\n***ERROR***\n"
|
||||
"PWL: Violation of 50% rule in breakpoints!\n";
|
||||
|
||||
/* Retrieve frequently used parameters... */
|
||||
|
||||
|
|
@ -282,25 +294,22 @@ void cm_pwl(ARGS) /* structure holding parms,
|
|||
size = PARAM_SIZE(x_array);
|
||||
|
||||
|
||||
|
||||
if (INIT==1) { /* First pass...allocate storage for previous value... */
|
||||
|
||||
/* Allocate storage for last_x_value */
|
||||
STATIC_VAR(last_x_value) = (double *) malloc(sizeof(double));
|
||||
last_x_value = (double *) STATIC_VAR(last_x_value);
|
||||
|
||||
/* Allocate storage for breakpoint domain & range values */
|
||||
STATIC_VAR(x) = (double *) calloc((size_t) size, sizeof(double));
|
||||
x = (double *) STATIC_VAR(x);
|
||||
if (!x) {
|
||||
cm_message_send(allocation_error);
|
||||
}
|
||||
|
||||
STATIC_VAR(y) = (double *) calloc((size_t) size, sizeof(double));
|
||||
y = (double *) STATIC_VAR(y);
|
||||
if (!y) {
|
||||
cm_message_send(allocation_error);
|
||||
last_x_value = (double *) (STATIC_VAR(last_x_value) = tmalloc_raw(
|
||||
sizeof(double)));
|
||||
x = (double *) (STATIC_VAR(x) = tcalloc_raw((size_t) size,
|
||||
sizeof(double)));
|
||||
y = (double *) (STATIC_VAR(y) = tcalloc_raw((size_t) size,
|
||||
sizeof(double)));
|
||||
if (last_x_value == (double *) NULL ||
|
||||
x == (double *) NULL || y == (double *) NULL) {
|
||||
cm_message_send(allocation_error);
|
||||
cm_pwl_callback(mif_private, MIF_CB_DESTROY);
|
||||
return;
|
||||
}
|
||||
CALLBACK = cm_pwl_callback;
|
||||
|
||||
/* Retrieve x and y values. */
|
||||
for (i=0; i<size; i++) {
|
||||
|
|
@ -310,19 +319,18 @@ void cm_pwl(ARGS) /* structure holding parms,
|
|||
|
||||
}
|
||||
else {
|
||||
|
||||
last_x_value = (double *) STATIC_VAR(last_x_value);
|
||||
|
||||
x = (double *) STATIC_VAR(x);
|
||||
|
||||
y = (double *) STATIC_VAR(y);
|
||||
|
||||
/* Need only check one since will be all alloc or none will */
|
||||
if (last_x_value == (double *) NULL) {
|
||||
cm_message_send("attempt to use unallocated x and y values");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* See if input_domain is absolute...if so, test against */
|
||||
/* breakpoint segments for violation of 50% rule... */
|
||||
if (PARAM(fraction) == MIF_FALSE) {
|
||||
|
|
@ -538,5 +546,5 @@ void cm_pwl(ARGS) /* structure holding parms,
|
|||
ac_gain.imag= 0.0;
|
||||
AC_GAIN(out,in) = ac_gain;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_pwl */
|
||||
|
||||
|
|
|
|||
|
|
@ -208,18 +208,23 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
double *in; /* pointer to the input */
|
||||
double in_offset; /* input offset */
|
||||
double *gain; /* pointer to the gain */
|
||||
double **den_coefficient; /* dynamic array that holds the denominator
|
||||
coefficients */
|
||||
double **old_den_coefficient;/* dynamic array that holds the old
|
||||
denonminator coefficients */
|
||||
double **num_coefficient; /* dynamic array that holds the numerator
|
||||
coefficients */
|
||||
double **old_num_coefficient;/* dynamic array that holds the old numerator
|
||||
coefficients */
|
||||
double **den_coefficient = (double **) NULL;
|
||||
/* dynamic array that holds the denominator
|
||||
* coefficients */
|
||||
double **old_den_coefficient = (double **) NULL;
|
||||
/* dynamic array that holds the old
|
||||
* denonminator coefficients */
|
||||
double **num_coefficient = (double **) NULL;
|
||||
/* dynamic array that holds the numerator
|
||||
* coefficients */
|
||||
double **old_num_coefficient = (double **) NULL;
|
||||
/* dynamic array that holds the old numerator
|
||||
* coefficients */
|
||||
double factor; /* gain factor in case the highest
|
||||
denominator coefficient is not 1 */
|
||||
double **integrator; /* outputs of the integrators */
|
||||
double **old_integrator; /* previous integrator outputs */
|
||||
double **integrator = (double **) NULL; /* outputs of the integrators */
|
||||
double **old_integrator = (double **) NULL;
|
||||
/* previous integrator outputs */
|
||||
double null; /* dummy pointer for use with the
|
||||
integrate function */
|
||||
double pout_pin; /* partial out wrt in */
|
||||
|
|
@ -246,8 +251,9 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
int den_size; /* size of the denominator coefficient array */
|
||||
int num_size; /* size of the numerator coefficient array */
|
||||
|
||||
char *num_size_error="\n***ERROR***\nS_XFER: Numerator coefficient array size greater than\ndenominator coefficiant array size.\n";
|
||||
|
||||
const char * const num_size_error="\n***ERROR***\n"
|
||||
"S_XFER: Numerator coefficient array size greater than\n"
|
||||
"denominator coefficiant array size.\n";
|
||||
|
||||
|
||||
/** Retrieve frequently used parameters (used by all analyses)... **/
|
||||
|
|
@ -267,41 +273,62 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
return;
|
||||
}
|
||||
|
||||
/* We have to allocate memory and use cm_analog_alloc, because the
|
||||
* ITP variables are not functional */
|
||||
integrator = (double **) tcalloc_raw((size_t) den_size,
|
||||
sizeof(double *));
|
||||
old_integrator = (double **) tcalloc_raw((size_t) den_size,
|
||||
sizeof(double *));
|
||||
|
||||
/* Allocate storage for coefficient values */
|
||||
den_coefficient = (double **) tcalloc_raw((size_t) den_size,
|
||||
sizeof(double *));
|
||||
old_den_coefficient = (double **) tcalloc_raw((size_t) den_size,
|
||||
sizeof(double *));
|
||||
|
||||
num_coefficient = (double **) tcalloc_raw((size_t) num_size,
|
||||
sizeof(double *));
|
||||
old_num_coefficient = (double **) tcalloc_raw((size_t) num_size,
|
||||
sizeof(double *));
|
||||
|
||||
if (integrator == (double **) NULL ||
|
||||
old_integrator == (double **) NULL ||
|
||||
den_coefficient == (double **) NULL ||
|
||||
old_den_coefficient == (double **) NULL ||
|
||||
num_coefficient == (double **) NULL ||
|
||||
old_num_coefficient == (double **) NULL) {
|
||||
if (INIT == 1) {
|
||||
/* If init step, execute cm_analog_alloc() calls anyhow
|
||||
* in case the function is called again and the above
|
||||
* allocations succeed on that call. Under those conditions
|
||||
* access violations would occur without the
|
||||
* cm_analog_alloc() calls. */
|
||||
const int n = 2 * den_size + num_size + 3;
|
||||
for (i = 0; i < n; ++i) {
|
||||
cm_analog_alloc(i, sizeof(double));
|
||||
}
|
||||
}
|
||||
|
||||
cm_message_send("Unable to allocate arrays of double pointers "
|
||||
"for integrator and coefficients in cm_s_xfer()");
|
||||
goto EXITPOINT;
|
||||
} /* end of double ** allocations */
|
||||
|
||||
/** Test for INIT; if so, allocate storage, otherwise, retrieve previous **/
|
||||
/** timepoint input values as necessary in subsequent analysis sections... **/
|
||||
|
||||
if (INIT==1) { /* First pass...allocate storage for previous values... */
|
||||
|
||||
/* Allocate rotational storage for integrator outputs, in & out */
|
||||
|
||||
|
||||
/***** The following two lines may be unnecessary in the final version *****/
|
||||
|
||||
/* We have to allocate memory and use cm_analog_alloc, because the ITP variables
|
||||
are not functional */
|
||||
|
||||
integrator = (double **) calloc((size_t) den_size, sizeof(double *));
|
||||
old_integrator = (double **) calloc((size_t) den_size, sizeof(double *));
|
||||
|
||||
/* Allocate storage for coefficient values */
|
||||
|
||||
den_coefficient = (double **) calloc((size_t) den_size, sizeof(double *));
|
||||
old_den_coefficient = (double **) calloc((size_t) den_size, sizeof(double *));
|
||||
|
||||
num_coefficient = (double **) calloc((size_t) num_size, sizeof(double *));
|
||||
old_num_coefficient = (double **) calloc((size_t) num_size, sizeof(double *));
|
||||
|
||||
for (i=0; i < (2*den_size + num_size + 3); i++)
|
||||
/* Do allocs */
|
||||
for (i=0; i < (2*den_size + num_size + 3); i++) {
|
||||
cm_analog_alloc(i,sizeof(double));
|
||||
}
|
||||
|
||||
/* ITP_VAR_SIZE(den) = den_size; */
|
||||
|
||||
/* gain = (double *) calloc(1,sizeof(double));
|
||||
/* gain = (double *) tcalloc_raw(1, sizeof(double));
|
||||
ITP_VAR(total_gain) = gain;
|
||||
ITP_VAR_SIZE(total_gain) = 1.0; */
|
||||
|
||||
// Retrieve pointers
|
||||
|
||||
for (i=0; i<den_size; i++) {
|
||||
integrator[i] = (double *) cm_analog_get_ptr(i,0);
|
||||
old_integrator[i] = (double *) cm_analog_get_ptr(i,0);
|
||||
|
|
@ -322,13 +349,8 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
|
||||
gain = (double *) cm_analog_get_ptr(2*den_size+num_size+2,0);
|
||||
|
||||
}else { /* Allocation was not necessary...retrieve previous values */
|
||||
|
||||
/* Set pointers to storage locations for in, out, and integrators...*/
|
||||
|
||||
integrator = (double **) calloc((size_t) den_size, sizeof(double *));
|
||||
old_integrator = (double **) calloc((size_t) den_size, sizeof(double *));
|
||||
|
||||
}
|
||||
else { /* Allocation was not necessary...retrieve previous values */
|
||||
for (i=0; i<den_size; i++) {
|
||||
integrator[i] = (double *) cm_analog_get_ptr(i,0);
|
||||
old_integrator[i] = (double *) cm_analog_get_ptr(i,1);
|
||||
|
|
@ -341,8 +363,6 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
/* Set den_coefficient & gain pointers to ITP values */
|
||||
/* for denominator coefficients & gain... */
|
||||
|
||||
old_den_coefficient = (double **) calloc((size_t) den_size, sizeof(double));
|
||||
den_coefficient = (double **) calloc((size_t) den_size, sizeof(double));
|
||||
|
||||
for(i=den_size;i<2*den_size;i++){
|
||||
old_den_coefficient[i-den_size] = (double *) cm_analog_get_ptr(i,1);
|
||||
|
|
@ -350,8 +370,6 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
*(den_coefficient[i-den_size]) = *(old_den_coefficient[i-den_size]);
|
||||
}
|
||||
|
||||
num_coefficient = (double **) calloc((size_t) num_size, sizeof(double));
|
||||
old_num_coefficient = (double **) calloc((size_t) num_size, sizeof(double));
|
||||
|
||||
for(i=2*den_size;i<2*den_size+num_size;i++){
|
||||
old_num_coefficient[i-2*den_size] = (double *) cm_analog_get_ptr(i,1);
|
||||
|
|
@ -417,7 +435,7 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
/* Test denominator highest order coefficient...if that value */
|
||||
/* is other than 1.0, then divide all denominator coefficients */
|
||||
/* and the gain by that value... */
|
||||
// if ( (factor = PARAM(den_coeff[den_size-1])) != 1.0 ) {
|
||||
// if ( (factor = PARAM(den_coeff[den_size-1])) != 1.0 )
|
||||
if ( (factor = *den_coefficient[den_size-1]) != 1.0 ) {
|
||||
for (i=0; i<den_size; i++) {
|
||||
*(den_coefficient[i]) = *(den_coefficient[i]) / factor;
|
||||
|
|
@ -428,7 +446,6 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
/* only need to adjust gain value. */
|
||||
*gain = PARAM(gain);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -436,7 +453,7 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
if (ANALYSIS != MIF_AC) {
|
||||
|
||||
/**** DC Analysis - Not needed JPM 10/29/91 *****************/
|
||||
/* if (ANALYSIS == MIF_DC) {
|
||||
/* if (ANALYSIS == MIF_DC) {
|
||||
|
||||
?* Test to see if a term exists for the zero-th order
|
||||
denom coeff...
|
||||
|
|
@ -470,7 +487,7 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
|
||||
|
||||
|
||||
else {
|
||||
else
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -600,18 +617,27 @@ void cm_s_xfer(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
AC_GAIN(out,in) = ac_gain;
|
||||
}
|
||||
|
||||
/* free all allocated memory */
|
||||
if(integrator) free(integrator);
|
||||
if(old_integrator) free(old_integrator);
|
||||
if(den_coefficient) free(den_coefficient);
|
||||
if(old_den_coefficient) free(old_den_coefficient);
|
||||
if(num_coefficient) free(num_coefficient);
|
||||
if(old_num_coefficient) free(old_num_coefficient);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
EXITPOINT:
|
||||
/* free all allocated memory */
|
||||
if (old_integrator != (double **) NULL) {
|
||||
txfree(old_integrator);
|
||||
}
|
||||
if (integrator != (double **) NULL) {
|
||||
txfree(integrator);
|
||||
}
|
||||
if (den_coefficient != (double **) NULL) {
|
||||
txfree(den_coefficient);
|
||||
}
|
||||
if (old_den_coefficient != (double **) NULL) {
|
||||
txfree(old_den_coefficient);
|
||||
}
|
||||
if (num_coefficient != (double **) NULL) {
|
||||
txfree(num_coefficient);
|
||||
}
|
||||
if (old_num_coefficient != (double **) NULL) {
|
||||
txfree(old_num_coefficient);
|
||||
}
|
||||
} /* end of function cm_s_xfer */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -56,10 +56,12 @@ NON-STANDARD FEATURES
|
|||
|
||||
/*=== CONSTANTS ========================*/
|
||||
|
||||
char *square_allocation_error = "\n**** Error ****\nSQUARE: Error allocating square block storage \n";
|
||||
char *square_limit_error = "\n**** Error ****\nSQUARE: Smoothing domain value too large \n";
|
||||
char *square_freq_clamp = "\n**** WARNING ****\nSQUARE: Frequency extrapolation limited to 1e-16 \n";
|
||||
char *square_array_error = "\n**** Error ****\nSQUARE: Size of control array different than frequency array \n";
|
||||
const char * const square_freq_clamp =
|
||||
"\n**** WARNING ****\nSQUARE: Frequency extrapolation limited "
|
||||
"to 1e-16 \n";
|
||||
const char * const square_array_error =
|
||||
"\n**** Error ****\nSQUARE: Size of control array different "
|
||||
"than frequency array \n";
|
||||
|
||||
#define INT1 1
|
||||
#define T1 2
|
||||
|
|
|
|||
|
|
@ -57,9 +57,12 @@ NON-STANDARD FEATURES
|
|||
|
||||
/*=== CONSTANTS ========================*/
|
||||
|
||||
char *triangle_allocation_error = "\n**** Error ****\nTRIANGLE: Error allocating triangle block storage \n";
|
||||
char *triangle_freq_clamp = "\n**** Warning ****\nTRIANGLE: Extrapolated Minimum Frequency Set to 1e-16 Hz \n";
|
||||
char *triangle_array_error = "\n**** Error ****\nTRIANGLE: Size of control array different than frequency array \n";
|
||||
const char * const triangle_freq_clamp =
|
||||
"\n**** Warning ****\nTRIANGLE: Extrapolated Minimum Frequency "
|
||||
"Set to 1e-16 Hz \n";
|
||||
const char * const triangle_array_error =
|
||||
"\n**** Error ****\nTRIANGLE: Size of control array different "
|
||||
"than frequency array \n";
|
||||
|
||||
#define INT1 1
|
||||
#define T1 2
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ NON-STANDARD FEATURES
|
|||
|
||||
==============================================================================*/
|
||||
|
||||
static void cm_d_genlut_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
|
||||
/*=== CM_D_LUT ROUTINE ===*/
|
||||
|
||||
/************************************************
|
||||
|
|
@ -166,10 +168,15 @@ void cm_d_genlut(ARGS)
|
|||
/*** Setup required state variables ***/
|
||||
|
||||
if (INIT) { /* initial pass */
|
||||
|
||||
/* allocate storage for the lookup table */
|
||||
STATIC_VAR (locdata) = calloc((size_t) tablelen, sizeof(Digital_t));
|
||||
lookup_table = STATIC_VAR (locdata);
|
||||
if ((lookup_table = (Digital_t *) (STATIC_VAR(locdata) = tcalloc_raw(
|
||||
(size_t) tablelen, sizeof(Digital_t)))) ==
|
||||
(Digital_t *) NULL) {
|
||||
cm_message_send("Unable to allocate Digital_t structure "
|
||||
"in cm_d_genlut()");
|
||||
return;
|
||||
}
|
||||
CALLBACK = cm_d_genlut_callback;
|
||||
|
||||
/* allocate storage for the outputs */
|
||||
cm_event_alloc(0, osize * (int) sizeof(Digital_t));
|
||||
|
|
@ -216,10 +223,15 @@ void cm_d_genlut(ARGS)
|
|||
lookup_table[idx].state = UNKNOWN;
|
||||
lookup_table[idx].strength = UNDETERMINED;
|
||||
}
|
||||
} else { /* Retrieve previous values */
|
||||
|
||||
}
|
||||
else { /* Retrieve previous values */
|
||||
/* retrieve lookup table */
|
||||
lookup_table = STATIC_VAR (locdata);
|
||||
if ((lookup_table = (Digital_t *) STATIC_VAR(locdata)) ==
|
||||
(Digital_t *) NULL) {
|
||||
cm_message_send("Attempt to use unallocated lookup_table "
|
||||
"in cm_d_genlut()");
|
||||
return;
|
||||
}
|
||||
|
||||
/* retrieve storage for the inputs and outputs */
|
||||
out = (Digital_t *) cm_event_get_ptr(0, 0);
|
||||
|
|
@ -383,4 +395,24 @@ void cm_d_genlut(ARGS)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end of function cm_d_genlut */
|
||||
|
||||
|
||||
|
||||
/* This function frees resources when called with reason argument
|
||||
* MIF_CB_DESTROY */
|
||||
static void cm_d_genlut_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
void * const p = STATIC_VAR(locdata);
|
||||
if (p != NULL) {
|
||||
txfree(p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_d_genlut_callback */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ NON-STANDARD FEATURES
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||
|
||||
|
||||
static void cm_d_lut_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
|
||||
|
||||
|
||||
|
|
@ -132,10 +133,15 @@ void cm_d_lut(ARGS)
|
|||
/*** Setup required state variables ***/
|
||||
|
||||
if (INIT) { /* initial pass */
|
||||
|
||||
/* allocate storage for the lookup table */
|
||||
STATIC_VAR (locdata) = calloc((size_t) tablelen, sizeof(Digital_State_t));
|
||||
lookup_table = STATIC_VAR (locdata);
|
||||
if ((lookup_table = (Digital_State_t *) (STATIC_VAR (locdata) =
|
||||
tcalloc_raw((size_t) tablelen, sizeof(Digital_State_t)))) ==
|
||||
(Digital_State_t *) NULL) {
|
||||
cm_message_send("Unable to allocate Digital_t structure "
|
||||
"in cm_d_lut()");
|
||||
return;
|
||||
}
|
||||
CALLBACK = cm_d_lut_callback;
|
||||
|
||||
/* allocate storage for the outputs */
|
||||
cm_event_alloc(0, sizeof(Digital_State_t));
|
||||
|
|
@ -251,4 +257,24 @@ void cm_d_lut(ARGS)
|
|||
}
|
||||
|
||||
OUTPUT_STRENGTH(out) = STRONG;
|
||||
}
|
||||
} /* end of function cm_d_lut */
|
||||
|
||||
|
||||
|
||||
/* This function frees resources when called with reason argument
|
||||
* MIF_CB_DESTROY */
|
||||
static void cm_d_lut_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
void * const p = STATIC_VAR(locdata);
|
||||
if (p != NULL) {
|
||||
txfree(p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_d_genlut_callback */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -277,16 +277,16 @@ void cm_d_osc(ARGS)
|
|||
|
||||
/* Allocate storage for breakpoint domain & freq. range values */
|
||||
|
||||
x = (double *) calloc((size_t) cntl_size, sizeof(double));
|
||||
x = (double *) tcalloc_raw((size_t) cntl_size, sizeof(double));
|
||||
if (!x) {
|
||||
cm_message_send(d_osc_allocation_error);
|
||||
return;
|
||||
}
|
||||
|
||||
y = (double *) calloc((size_t) freq_size, sizeof(double));
|
||||
y = (double *) tcalloc_raw((size_t) freq_size, sizeof(double));
|
||||
if (!y) {
|
||||
cm_message_send(d_osc_allocation_error);
|
||||
if(x) free(x);
|
||||
txfree(x);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -394,8 +394,8 @@ void cm_d_osc(ARGS)
|
|||
|
||||
|
||||
|
||||
if(x) free(x);
|
||||
if(y) free(y);
|
||||
txfree(x);
|
||||
txfree(y);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ typedef enum token_type_s {CNV_NO_TOK,CNV_STRING_TOK} Cnv_Token_Type_t;
|
|||
|
||||
|
||||
|
||||
static void free_local_data(Local_Data_t *loc);
|
||||
static void cm_d_source_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
|
||||
|
||||
|
||||
|
|
@ -144,6 +146,8 @@ NON-STANDARD FEATURES
|
|||
NONE
|
||||
|
||||
==============================================================================*/
|
||||
///XXX TODO: The CNVgettok, etc. functions are repeated in d_sorce and
|
||||
///XXX TODO d_state. They should be put in a common place and built once
|
||||
|
||||
/*=== Static CNVgettok ROUTINE ================*/
|
||||
/*
|
||||
|
|
@ -153,21 +157,20 @@ 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);
|
||||
if ((buf = (char *) tmalloc_raw(strlen(*s) + 1)) == (char *) NULL) {
|
||||
cm_message_send("Unable to allocate buffer in CNVgettok()");
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
/* skip over any white space */
|
||||
|
||||
|
|
@ -180,18 +183,17 @@ static char *CNVgettok(char **s)
|
|||
switch(**s) {
|
||||
|
||||
case '\0': /* End of string found */
|
||||
if(buf) free(buf);
|
||||
return(NULL);
|
||||
|
||||
txfree(buf);
|
||||
return (char *) 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 == ',')
|
||||
(! ( isspace_c(**s) || (**s == '=') ||
|
||||
(**s == '(') || (**s == ')') ||
|
||||
(**s == ',')
|
||||
) ) ) {
|
||||
buf[i] = **s;
|
||||
i++;
|
||||
|
|
@ -210,13 +212,20 @@ static char *CNVgettok(char **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);
|
||||
{
|
||||
char * const ret_str = (char *) tmalloc_raw(strlen(buf) + 1);
|
||||
if (ret_str == (char *) NULL) {
|
||||
cm_message_send("Unable to allocate return buffer "
|
||||
"in CNVgettok()");
|
||||
return (char *) NULL;
|
||||
}
|
||||
strcpy(ret_str, buf);
|
||||
txfree(buf);
|
||||
|
||||
if(buf) free(buf);
|
||||
return ret_str;
|
||||
}
|
||||
} /* end of function CNVgettok */
|
||||
|
||||
return(ret_str);
|
||||
}
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
|
@ -267,21 +276,16 @@ is returned. The original input string is undisturbed.
|
|||
*/
|
||||
|
||||
static char *CNVget_token(char **s, Cnv_Token_Type_t *type)
|
||||
|
||||
{
|
||||
|
||||
char *ret_str; /* storage for returned string */
|
||||
|
||||
/* storage for returned string */
|
||||
/* get the token from the input line */
|
||||
|
||||
ret_str = CNVgettok(s);
|
||||
char * const ret_str = CNVgettok(s);
|
||||
|
||||
|
||||
/* if no next token, return */
|
||||
|
||||
if(ret_str == NULL) {
|
||||
if (ret_str == (char *) NULL) {
|
||||
*type = CNV_NO_TOK;
|
||||
return(NULL);
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
/* else, determine and return token type */
|
||||
|
|
@ -295,8 +299,7 @@ static char *CNVget_token(char **s, Cnv_Token_Type_t *type)
|
|||
}
|
||||
|
||||
return(ret_str);
|
||||
}
|
||||
|
||||
} /* end of function CNVget_token */
|
||||
|
||||
|
||||
|
||||
|
|
@ -695,7 +698,6 @@ NON-STANDARD FEATURES
|
|||
|
||||
static int cm_read_source(FILE *source, Local_Data_t *loc)
|
||||
{
|
||||
int n; /* loop index */
|
||||
int i, /* indexing variable */
|
||||
j, /* indexing variable */
|
||||
num_tokens; /* number of tokens in a given string */
|
||||
|
|
@ -735,7 +737,7 @@ static int cm_read_source(FILE *source, Local_Data_t *loc)
|
|||
while ( type != CNV_NO_TOK ) {
|
||||
token = CNVget_token(&s, &type);
|
||||
if (token)
|
||||
free(token);
|
||||
txfree(token);
|
||||
j++;
|
||||
}
|
||||
num_tokens = j;
|
||||
|
|
@ -749,9 +751,13 @@ static int cm_read_source(FILE *source, Local_Data_t *loc)
|
|||
s = base_address;
|
||||
|
||||
/* set storage space for bits in a row and set them to 0*/
|
||||
loc->all_data[i] = (char*)malloc(sizeof(char) * (size_t) loc->width);
|
||||
for (n = 0; n < loc->width; n++)
|
||||
loc->all_data[i][n] = 0;
|
||||
if ((loc->all_data[i] = (char *) tcalloc_raw(
|
||||
(size_t) loc->width,
|
||||
sizeof(char))) == (char *) NULL) {
|
||||
cm_message_send("Unable to allocate buffer "
|
||||
"for all_data bits in cm_d_source()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Retrieve each token, analyze, and **/
|
||||
/** store the timepoint and bit information **/
|
||||
|
|
@ -807,7 +813,7 @@ static int cm_read_source(FILE *source, Local_Data_t *loc)
|
|||
}
|
||||
}
|
||||
if (token)
|
||||
free(token);
|
||||
txfree(token);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
@ -910,7 +916,9 @@ void cm_d_source(ARGS)
|
|||
*s; /* main string variable */
|
||||
|
||||
|
||||
char *loading_error = "\nERROR **\n D_SOURCE: source.in file was not read successfully. \n";
|
||||
const char *loading_error =
|
||||
"\nERROR **\n D_SOURCE: source.in file "
|
||||
"was not read successfully.";
|
||||
|
||||
Local_Data_t *loc; /* Pointer to local static data, not to be included
|
||||
in the state vector (save memory!) */
|
||||
|
|
@ -928,10 +936,16 @@ void cm_d_source(ARGS)
|
|||
char *lbuffer, *p;
|
||||
lbuffer = getenv("NGSPICE_INPUT_DIR");
|
||||
if (lbuffer && *lbuffer) {
|
||||
p = (char*) malloc(strlen(lbuffer) + strlen(DIR_PATHSEP) + strlen(PARAM(input_file)) + 1);
|
||||
p = (char *) tmalloc_raw(strlen(lbuffer) +
|
||||
strlen(DIR_PATHSEP) + strlen(PARAM(input_file)) + 1);
|
||||
if (p == (char *) NULL) {
|
||||
cm_message_send("Unable to allocate buffer "
|
||||
"for building file name in cm_d_source()");
|
||||
return;
|
||||
}
|
||||
sprintf(p, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(input_file));
|
||||
source = fopen(p, "r");
|
||||
free(p);
|
||||
txfree(p);
|
||||
}
|
||||
if (!source)
|
||||
cm_message_printf("cannot open file %s", PARAM(input_file));
|
||||
|
|
@ -952,8 +966,12 @@ void cm_d_source(ARGS)
|
|||
}
|
||||
|
||||
/*** allocate static storage for *loc ***/
|
||||
STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t ));
|
||||
loc = STATIC_VAR (locdata);
|
||||
if ((loc = (Local_Data_t *) (STATIC_VAR(locdata) = tcalloc_raw(1,
|
||||
sizeof(Local_Data_t)))) == (Local_Data_t *) NULL) {
|
||||
cm_message_send("Unable to allocate buffer "
|
||||
"for building file name in cm_d_source()");
|
||||
return;
|
||||
}
|
||||
|
||||
/*** allocate storage for *index, *bits & *timepoint ***/
|
||||
|
||||
|
|
@ -976,8 +994,22 @@ void cm_d_source(ARGS)
|
|||
loc->width = PORT_SIZE(out);
|
||||
|
||||
/*** allocate storage for **all_data, & *all_timepoints ***/
|
||||
loc->all_timepoints = (double*)calloc((size_t) i, sizeof(double));
|
||||
loc->all_data = (char**)calloc((size_t) i, sizeof(char*));
|
||||
if ((loc->all_timepoints = (double *) tcalloc_raw((size_t) i,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_send("Unable to allocate all_timepoints "
|
||||
"in cm_d_source()");
|
||||
free_local_data(loc);
|
||||
STATIC_VAR(locdata) = NULL;
|
||||
return;
|
||||
}
|
||||
if ((loc->all_data = (char **) tcalloc_raw((size_t) i,
|
||||
sizeof(char *))) == (char **) NULL) {
|
||||
cm_message_send("Unable to allocate all_data "
|
||||
"in cm_d_source()");
|
||||
free_local_data(loc);
|
||||
STATIC_VAR(locdata) = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send file pointer and the two array storage pointers */
|
||||
/* to "cm_read_source()". This will return after */
|
||||
|
|
@ -993,36 +1025,50 @@ void cm_d_source(ARGS)
|
|||
err=1;
|
||||
}
|
||||
|
||||
/* close source file */
|
||||
if (source) {
|
||||
fclose(source);
|
||||
}
|
||||
|
||||
if (err) { /* problem occurred in load...send error msg. */
|
||||
cm_message_send(loading_error);
|
||||
|
||||
switch (err)
|
||||
{
|
||||
case -1:
|
||||
cm_message_send(" Allocation failure "
|
||||
"while allocating memory for bits" );
|
||||
break;
|
||||
case 2:
|
||||
cm_message_send(" d_source word length and number of columns in file differ.\n" );
|
||||
cm_message_send(" d_source word length and number of columns in file differ." );
|
||||
break;
|
||||
case 3:
|
||||
cm_message_send(" Time values in first column have to increase monotonically.\n");
|
||||
cm_message_send(" Time values in first column have to increase monotonically.");
|
||||
break;
|
||||
case 4:
|
||||
cm_message_send(" Unknown bit value.\n");
|
||||
cm_message_send(" Unknown bit value.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* close source file */
|
||||
if (source)
|
||||
fclose(source);
|
||||
free_local_data(loc);
|
||||
STATIC_VAR(locdata) = NULL;
|
||||
return;
|
||||
}
|
||||
CALLBACK = cm_d_source_callback;
|
||||
}
|
||||
else { /*** Retrieve previous values ***/
|
||||
if ((loc = (Local_Data_t *) STATIC_VAR (locdata)) ==
|
||||
(Local_Data_t *) NULL) {
|
||||
cm_message_send("Attempt to use unallocated Local_Data_t "
|
||||
"in cm_d_source()");
|
||||
}
|
||||
|
||||
/** Retrieve info... **/
|
||||
row_index = (int *) cm_event_get_ptr(0,0);
|
||||
row_index_old = (int *) cm_event_get_ptr(0,1);
|
||||
|
||||
loc = STATIC_VAR (locdata);
|
||||
|
||||
/* Set old values to new... */
|
||||
*row_index = *row_index_old;
|
||||
|
|
@ -1147,7 +1193,59 @@ void cm_d_source(ARGS)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end of function cm_d_source */
|
||||
|
||||
|
||||
|
||||
/* This function frees resources when called with reason argument
|
||||
* MIF_CB_DESTROY */
|
||||
static void cm_d_source_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Local_Data_t *loc = (Local_Data_t *) STATIC_VAR(locdata);
|
||||
if (loc != (Local_Data_t *) NULL) {
|
||||
free_local_data(loc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_d_state_callback */
|
||||
|
||||
|
||||
|
||||
static void free_local_data(Local_Data_t *loc)
|
||||
{
|
||||
/* Immediate return if no structure */
|
||||
if (loc == (Local_Data_t *) NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Free all_data and internal allocations */
|
||||
{
|
||||
char ** const all_data = loc->all_data;
|
||||
if (all_data != (char **) NULL) {
|
||||
const int n = loc->width;
|
||||
int i;
|
||||
for (i = 0; i != n; ++i) { /* free individual allocs */
|
||||
if (all_data[i] != (char *) NULL) {
|
||||
txfree(all_data[i]);
|
||||
}
|
||||
}
|
||||
txfree(all_data);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free all_timepoints */
|
||||
{
|
||||
void * const p = loc->all_timepoints;
|
||||
if (p != NULL) {
|
||||
txfree(p);
|
||||
}
|
||||
}
|
||||
|
||||
txfree(loc);
|
||||
} /* end of function free_local_data */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -150,9 +150,8 @@ typedef char line_t[82]; /* A SPICE size line. <= 80 characters plus '\n\0' */
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void cm_d_state_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
static void free_state_fields(State_Table_t *p_state);
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
|
|
@ -201,18 +200,19 @@ is returned. The original input string is undisturbed.
|
|||
*/
|
||||
|
||||
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);
|
||||
if ((buf = (char *) tmalloc_raw(strlen(*s) + 1)) == (char *) NULL) {
|
||||
cm_message_send("Unable to allocate buffer in CNVgettok()");
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
/* skip over any white space */
|
||||
|
||||
|
|
@ -225,9 +225,8 @@ static char *CNVgettok(char **s)
|
|||
switch(**s) {
|
||||
|
||||
case '\0': /* End of string found */
|
||||
if(buf) free(buf);
|
||||
return(NULL);
|
||||
|
||||
txfree(buf);
|
||||
return (char *) NULL;
|
||||
|
||||
default: /* Otherwise, we are dealing with a */
|
||||
/* string representation of a number */
|
||||
|
|
@ -255,13 +254,20 @@ static char *CNVgettok(char **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);
|
||||
{
|
||||
char * const ret_str = (char *) tmalloc_raw(strlen(buf) + 1);
|
||||
if (ret_str == (char *) NULL) {
|
||||
cm_message_send("Unable to allocate return buffer "
|
||||
"in CNVgettok()");
|
||||
return (char *) NULL;
|
||||
}
|
||||
strcpy(ret_str, buf);
|
||||
txfree(buf);
|
||||
|
||||
if(buf) free(buf);
|
||||
return ret_str;
|
||||
}
|
||||
} /* end of function CNVgettok */
|
||||
|
||||
return(ret_str);
|
||||
}
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
|
@ -312,21 +318,16 @@ is returned. The original input string is undisturbed.
|
|||
*/
|
||||
|
||||
static char *CNVget_token(char **s, Cnv_Token_Type_t *type)
|
||||
|
||||
{
|
||||
|
||||
char *ret_str; /* storage for returned string */
|
||||
|
||||
/* storage for returned string */
|
||||
/* get the token from the input line */
|
||||
|
||||
ret_str = CNVgettok(s);
|
||||
char * const ret_str = CNVgettok(s);
|
||||
|
||||
|
||||
/* if no next token, return */
|
||||
|
||||
if(ret_str == NULL) {
|
||||
if (ret_str == (char *) NULL) {
|
||||
*type = CNV_NO_TOK;
|
||||
return(NULL);
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
/* else, determine and return token type */
|
||||
|
|
@ -340,8 +341,7 @@ static char *CNVget_token(char **s, Cnv_Token_Type_t *type)
|
|||
}
|
||||
|
||||
return(ret_str);
|
||||
}
|
||||
|
||||
} /* end of function CNVget_token */
|
||||
|
||||
|
||||
|
||||
|
|
@ -395,8 +395,6 @@ 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;
|
||||
|
|
@ -482,8 +480,7 @@ double *p_value ) /* OUT - The numerical value */
|
|||
scale_factor = 1.0e-3;
|
||||
break;
|
||||
}
|
||||
if(islower_c(c1))
|
||||
c1 = toupper_c(c1);
|
||||
c1 = toupper_c(c1);
|
||||
if(c1 == 'E')
|
||||
scale_factor = 1.0e6;
|
||||
else if(c1 == 'I')
|
||||
|
|
@ -1807,11 +1804,26 @@ void cm_d_state(ARGS)
|
|||
|
||||
|
||||
/* assign storage for arrays to pointers in states table */
|
||||
states->state = (int *) calloc((size_t) (states->depth + 1), sizeof(int));
|
||||
states->bits = (short *) calloc((size_t) (states->num_outputs * states->depth / 4 + 1), sizeof(short));
|
||||
states->inputs = (short *) calloc((size_t) (states->num_inputs * states->depth / 8 + 1), sizeof(short));
|
||||
states->next_state = (int *) calloc((size_t) (states->depth + 1), sizeof(int));
|
||||
|
||||
states->state = (int *) tcalloc_raw(
|
||||
(size_t) (states->depth + 1), sizeof(int));
|
||||
states->bits = (short *) tcalloc_raw(
|
||||
(size_t) (states->num_outputs * states->depth / 4 + 1),
|
||||
sizeof(short));
|
||||
states->inputs = (short *) tcalloc_raw(
|
||||
(size_t) (states->num_inputs * states->depth / 8 + 1),
|
||||
sizeof(short));
|
||||
states->next_state = (int *) tcalloc_raw(
|
||||
(size_t) (states->depth + 1), sizeof(int));
|
||||
if (states->state == (int *) NULL ||
|
||||
states->bits == (short *) NULL ||
|
||||
states->inputs == (short *) NULL ||
|
||||
states->next_state == (int *) NULL) {
|
||||
cm_message_send("Unable to allocate state fields "
|
||||
"in cm_d_state()");
|
||||
free_state_fields(states);
|
||||
return;
|
||||
}
|
||||
CALLBACK = cm_d_state_callback;
|
||||
|
||||
/* Initialize *state, *bits, *inputs & *next_state to zero */
|
||||
for (i=0; i<states->depth; i++) {
|
||||
|
|
@ -1872,7 +1884,7 @@ void cm_d_state(ARGS)
|
|||
|
||||
/* declare load values */
|
||||
|
||||
// for (i=0; i<states->num_outputs; i++) {
|
||||
// for (i=0; i<states->num_outputs; i++)
|
||||
for (i=0; i<states->num_inputs; i++) {
|
||||
LOAD(in[i]) = PARAM(input_load);
|
||||
}
|
||||
|
|
@ -1885,6 +1897,14 @@ void cm_d_state(ARGS)
|
|||
else { /**** Retrieve previous values ****/
|
||||
|
||||
states = (State_Table_t *) cm_event_get_ptr(0,0);
|
||||
/* Need only check one allocation since will either be all
|
||||
* allocated or not */
|
||||
if (states->state == (int *) NULL) {
|
||||
cm_message_send("Attempt to use unallocated state arrays "
|
||||
"in cm_d_state()");
|
||||
return;
|
||||
}
|
||||
|
||||
states_old = (State_Table_t *) cm_event_get_ptr(0,1);
|
||||
// Copy storage
|
||||
*states = *states_old;
|
||||
|
|
@ -2089,7 +2109,49 @@ void cm_d_state(ARGS)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end of function cm_d_state */
|
||||
|
||||
|
||||
|
||||
/* This function frees resources when called with reason argument
|
||||
* MIF_CB_DESTROY */
|
||||
static void cm_d_state_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
CM_IGNORE(mif_private);
|
||||
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
State_Table_t *p_state =
|
||||
(State_Table_t *) cm_event_get_ptr(0, 0);
|
||||
free_state_fields(p_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_d_state_callback */
|
||||
|
||||
|
||||
|
||||
/* Free fields in State_Table_t structure */
|
||||
static void free_state_fields(State_Table_t *p_state)
|
||||
{
|
||||
void *p;
|
||||
if ((p = p_state->state) != NULL) {
|
||||
txfree(p);
|
||||
p_state->state = (int *) NULL;
|
||||
}
|
||||
if ((p = p_state->bits) != NULL) {
|
||||
txfree(p);
|
||||
p_state->bits = (short *) NULL;
|
||||
}
|
||||
if ((p = p_state->inputs) != NULL) {
|
||||
txfree(p);
|
||||
p_state->inputs = (short *) NULL;
|
||||
}
|
||||
if ((p = p_state->next_state) != NULL) {
|
||||
txfree(p);
|
||||
p_state->next_state = (int *) NULL;
|
||||
}
|
||||
} /* end of function free_state_fields */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,29 @@
|
|||
adc_bridge
|
||||
dac_bridge
|
||||
d_and
|
||||
d_buffer
|
||||
d_dff
|
||||
d_dlatch
|
||||
d_fdiv
|
||||
d_genlut
|
||||
d_inverter
|
||||
d_jkff
|
||||
d_lut
|
||||
d_nand
|
||||
d_nor
|
||||
d_open_c
|
||||
d_open_e
|
||||
d_or
|
||||
d_osc
|
||||
d_pulldown
|
||||
d_pullup
|
||||
d_ram
|
||||
d_source
|
||||
d_srff
|
||||
d_srlatch
|
||||
d_state
|
||||
d_tff
|
||||
d_tristate
|
||||
d_xnor
|
||||
d_xor
|
||||
#Directory Version
|
||||
adc_bridge 1
|
||||
dac_bridge 1
|
||||
d_and 1
|
||||
d_buffer 1
|
||||
d_dff 1
|
||||
d_dlatch 1
|
||||
d_fdiv 1
|
||||
d_genlut 2
|
||||
d_inverter 1
|
||||
d_jkff 1
|
||||
d_lut 2
|
||||
d_nand 1
|
||||
d_nor 1
|
||||
d_open_c 1
|
||||
d_open_e 1
|
||||
d_or 1
|
||||
d_osc 2
|
||||
d_pulldown 1
|
||||
d_pullup 1
|
||||
d_ram 1
|
||||
d_source 2
|
||||
d_srff 1
|
||||
d_srlatch 1
|
||||
d_state 2
|
||||
d_tff 1
|
||||
d_tristate 1
|
||||
d_xnor 1
|
||||
d_xor 1
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "ngspice/evtudn.h"
|
||||
#include "ngspice/inpdefs.h"
|
||||
#include "cmextrn.h"
|
||||
#include "dlmain.h"
|
||||
#include "udnextrn.h"
|
||||
|
||||
|
||||
|
|
@ -26,19 +27,31 @@
|
|||
// Do not modify anything below this line
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SPICEdev *cmDEVices[] = {
|
||||
const SPICEdev * const cmDEVices[] = {
|
||||
#include "cminfo.h"
|
||||
NULL
|
||||
NULL
|
||||
};
|
||||
|
||||
int cmDEVicesCNT = sizeof(cmDEVices)/sizeof(SPICEdev *)-1;
|
||||
const SPICEdev * const cmDEVices2[] = {
|
||||
#include "cminfo2.h"
|
||||
NULL
|
||||
};
|
||||
|
||||
Evt_Udn_Info_t *cmEVTudns[] = {
|
||||
const int cmDEVicesCNT = sizeof(cmDEVices) / sizeof(SPICEdev *) - 1;
|
||||
const int cmDEVicesCNT2 = sizeof(cmDEVices2) / sizeof(SPICEdev *) - 1;
|
||||
|
||||
const Evt_Udn_Info_t * const cmEVTudns[] = {
|
||||
#include "udninfo.h"
|
||||
NULL
|
||||
NULL
|
||||
};
|
||||
|
||||
int cmEVTudnCNT = sizeof(cmEVTudns)/sizeof(Evt_Udn_Info_t *)-1;
|
||||
const Evt_Udn_Info_t * const cmEVTudns2[] = {
|
||||
#include "udninfo2.h"
|
||||
NULL
|
||||
};
|
||||
|
||||
const int cmEVTudnCNT = sizeof(cmEVTudns) / sizeof(Evt_Udn_Info_t *) - 1;
|
||||
const int cmEVTudnCNT2 = sizeof(cmEVTudns2) / sizeof(Evt_Udn_Info_t *) - 1;
|
||||
|
||||
// Pointer to core info structure containing pointers to core functions.
|
||||
struct coreInfo_t *coreitf;
|
||||
|
|
@ -62,39 +75,60 @@ struct coreInfo_t *coreitf;
|
|||
#endif
|
||||
|
||||
extern CM_EXPORT void *CMdevs(void);
|
||||
extern CM_EXPORT void *CMdevs2(void);
|
||||
extern CM_EXPORT void *CMdevNum(void);
|
||||
extern CM_EXPORT void *CMdevNum2(void);
|
||||
extern CM_EXPORT void *CMudns(void);
|
||||
extern CM_EXPORT void *CMudns2(void);
|
||||
extern CM_EXPORT void *CMudnNum(void);
|
||||
extern CM_EXPORT void *CMudnNum2(void);
|
||||
extern CM_EXPORT void *CMgetCoreItfPtr(void);
|
||||
|
||||
extern void *tmalloc(size_t num);
|
||||
extern void *trealloc(const void *str, size_t num);
|
||||
extern void txfree(const void *ptr);
|
||||
|
||||
|
||||
// This one returns the device table
|
||||
CM_EXPORT void *CMdevs(void) {
|
||||
return (void *)cmDEVices;
|
||||
CM_EXPORT void *CMdevs(void)
|
||||
{
|
||||
return (void *) cmDEVices;
|
||||
}
|
||||
CM_EXPORT void *CMdevs2(void)
|
||||
{
|
||||
return (void *) cmDEVices2;
|
||||
}
|
||||
|
||||
// This one returns the device count
|
||||
CM_EXPORT void *CMdevNum(void) {
|
||||
return (void *)&cmDEVicesCNT;
|
||||
CM_EXPORT void *CMdevNum(void)
|
||||
{
|
||||
return (void *) &cmDEVicesCNT;
|
||||
}
|
||||
CM_EXPORT void *CMdevNum2(void)
|
||||
{
|
||||
return (void *) &cmDEVicesCNT2;
|
||||
}
|
||||
|
||||
// This one returns the UDN table
|
||||
CM_EXPORT void *CMudns(void) {
|
||||
return (void *)cmEVTudns;
|
||||
CM_EXPORT void *CMudns(void)
|
||||
{
|
||||
return (void *) cmEVTudns;
|
||||
}
|
||||
CM_EXPORT void *CMudns2(void)
|
||||
{
|
||||
return (void *) cmEVTudns2;
|
||||
}
|
||||
|
||||
// This one returns the UDN count
|
||||
CM_EXPORT void *CMudnNum(void) {
|
||||
return (void *)&cmEVTudnCNT;
|
||||
CM_EXPORT void *CMudnNum(void)
|
||||
{
|
||||
return (void *) &cmEVTudnCNT;
|
||||
}
|
||||
CM_EXPORT void *CMudnNum2(void)
|
||||
{
|
||||
return (void *) &cmEVTudnCNT2;
|
||||
}
|
||||
|
||||
// This one returns the pointer to the pointer to the core interface structure
|
||||
CM_EXPORT void *CMgetCoreItfPtr(void) {
|
||||
return (void *)(&coreitf);
|
||||
return (void *)(&coreitf);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -103,23 +137,27 @@ CM_EXPORT void *CMgetCoreItfPtr(void) {
|
|||
// These functions call the real core functions of SPICE OPUS using the
|
||||
// pointers in coreitf structure.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/* Declared in mifproto.h */
|
||||
void MIF_INP2A(
|
||||
CKTcircuit *ckt, /* circuit structure to put mod/inst structs in */
|
||||
INPtables *tab, /* symbol table for node names, etc. */
|
||||
struct card *current /* the card we are to parse */
|
||||
) {
|
||||
)
|
||||
{
|
||||
(coreitf->dllitf_MIF_INP2A)(ckt,tab,current);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
char * MIFgetMod(
|
||||
CKTcircuit *ckt,
|
||||
char *name,
|
||||
const char *name,
|
||||
INPmodel **model,
|
||||
INPtables *tab
|
||||
) {
|
||||
return (coreitf->dllitf_MIFgetMod)(ckt,name,model,tab);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
IFvalue * MIFgetValue(
|
||||
CKTcircuit *ckt,
|
||||
char **line,
|
||||
|
|
@ -131,6 +169,7 @@ IFvalue * MIFgetValue(
|
|||
}
|
||||
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFsetup(
|
||||
SMPmatrix *matrix,
|
||||
GENmodel *inModel,
|
||||
|
|
@ -140,6 +179,7 @@ int MIFsetup(
|
|||
return (coreitf->dllitf_MIFsetup)(matrix,inModel,ckt,state);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFunsetup(
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt
|
||||
|
|
@ -147,6 +187,7 @@ int MIFunsetup(
|
|||
return (coreitf->dllitf_MIFunsetup)(inModel,ckt);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFload(
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt
|
||||
|
|
@ -155,6 +196,7 @@ int MIFload(
|
|||
}
|
||||
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFmParam(
|
||||
int param_index,
|
||||
IFvalue *value,
|
||||
|
|
@ -163,6 +205,7 @@ int MIFmParam(
|
|||
return (coreitf->dllitf_MIFmParam)(param_index,value,inModel);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFask(
|
||||
CKTcircuit *ckt,
|
||||
GENinstance *inst,
|
||||
|
|
@ -173,6 +216,7 @@ int MIFask(
|
|||
return (coreitf->dllitf_MIFask)(ckt,inst,param_index,value,select);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFmAsk(
|
||||
CKTcircuit *ckt,
|
||||
GENmodel *inModel,
|
||||
|
|
@ -182,6 +226,7 @@ int MIFmAsk(
|
|||
return (coreitf->dllitf_MIFmAsk)(ckt,inModel,param_index,value);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFtrunc(
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt,
|
||||
|
|
@ -190,6 +235,7 @@ int MIFtrunc(
|
|||
return (coreitf->dllitf_MIFtrunc)(inModel,ckt,timeStep);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFconvTest(
|
||||
GENmodel *inModel,
|
||||
CKTcircuit *ckt
|
||||
|
|
@ -197,24 +243,28 @@ int MIFconvTest(
|
|||
return (coreitf->dllitf_MIFconvTest)(inModel,ckt);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFdelete(
|
||||
GENinstance *inst
|
||||
) {
|
||||
return (coreitf->dllitf_MIFdelete)(inst);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
int MIFmDelete(
|
||||
GENmodel *gen_model
|
||||
) {
|
||||
return (coreitf->dllitf_MIFmDelete)(gen_model);
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
void MIFdestroy(
|
||||
void
|
||||
) {
|
||||
(coreitf->dllitf_MIFdestroy)();
|
||||
}
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
char *MIFgettok(
|
||||
char **s
|
||||
) {
|
||||
|
|
@ -222,6 +272,7 @@ char *MIFgettok(
|
|||
}
|
||||
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
char *MIFget_token(
|
||||
char **s,
|
||||
Mif_Token_Type_t *type
|
||||
|
|
@ -230,6 +281,7 @@ char *MIFget_token(
|
|||
}
|
||||
|
||||
|
||||
/* Declared in mifproto.h */
|
||||
Mif_Cntl_Src_Type_t MIFget_cntl_src_type(
|
||||
Mif_Port_Type_t in_port_type,
|
||||
Mif_Port_Type_t out_port_type
|
||||
|
|
@ -237,11 +289,16 @@ Mif_Cntl_Src_Type_t MIFget_cntl_src_type(
|
|||
return (coreitf->dllitf_MIFget_cntl_src_type)(in_port_type,out_port_type);
|
||||
}
|
||||
|
||||
char *MIFcopy(char *c) {
|
||||
/* Declared in mifproto.h */
|
||||
char *MIFcopy(const char *c) {
|
||||
return (coreitf->dllitf_MIFcopy)(c);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void cm_climit_fcn(double in, double in_offset, double cntl_upper,
|
||||
double cntl_lower, double lower_delta,
|
||||
double upper_delta, double limit_range,
|
||||
|
|
@ -256,6 +313,7 @@ void cm_climit_fcn(double in, double in_offset, double cntl_upper,
|
|||
|
||||
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void cm_smooth_corner(double x_input, double x_center, double y_center,
|
||||
double domain, double lower_slope, double upper_slope,
|
||||
double *y_output, double *dy_dx) {
|
||||
|
|
@ -263,6 +321,7 @@ void cm_smooth_corner(double x_input, double x_center, double y_center,
|
|||
upper_slope,y_output,dy_dx);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void cm_smooth_discontinuity(double x_input, double x_lower, double y_lower,
|
||||
double x_upper, double y_upper,
|
||||
double *y_output, double *dy_dx) {
|
||||
|
|
@ -270,143 +329,260 @@ void cm_smooth_discontinuity(double x_input, double x_lower, double y_lower,
|
|||
y_output,dy_dx);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
double cm_smooth_pwl(double x_input, double *x, double *y, int size,
|
||||
double input_domain, double *dout_din) {
|
||||
return (coreitf->dllitf_cm_smooth_pwl)(x_input,x,y,size,input_domain,dout_din);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
double cm_analog_ramp_factor(void) {
|
||||
return (coreitf->dllitf_cm_analog_ramp_factor)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void cm_analog_alloc(int tag, int bytes) {
|
||||
(coreitf->dllitf_cm_analog_alloc)(tag,bytes);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void *cm_analog_get_ptr(int tag, int timepoint) {
|
||||
return (coreitf->dllitf_cm_analog_get_ptr)(tag,timepoint);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
int cm_analog_integrate(double integrand, double *integral, double *partial) {
|
||||
return (coreitf->dllitf_cm_analog_integrate)(integrand,integral,partial);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
int cm_analog_converge(double *state) {
|
||||
return (coreitf->dllitf_cm_analog_converge)(state);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
int cm_analog_set_temp_bkpt(double time) {
|
||||
return (coreitf->dllitf_cm_analog_set_temp_bkpt)(time);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
int cm_analog_set_perm_bkpt(double time) {
|
||||
return (coreitf->dllitf_cm_analog_set_perm_bkpt)(time);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void cm_analog_not_converged(void) {
|
||||
(coreitf->dllitf_cm_analog_not_converged)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void cm_analog_auto_partial(void) {
|
||||
(coreitf->dllitf_cm_analog_auto_partial)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void cm_event_alloc(int tag, int bytes){
|
||||
(coreitf->dllitf_cm_event_alloc)(tag,bytes);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void *cm_event_get_ptr(int tag, int timepoint) {
|
||||
return (coreitf->dllitf_cm_event_get_ptr)(tag,timepoint);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
int cm_event_queue(double time) {
|
||||
return (coreitf->dllitf_cm_event_queue)(time);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
char *cm_message_get_errmsg(void) {
|
||||
return (coreitf->dllitf_cm_message_get_errmsg)();
|
||||
}
|
||||
|
||||
int cm_message_send(char *msg) {
|
||||
/* Declared in cmproto.h */
|
||||
int cm_message_send(const char *msg) {
|
||||
return (coreitf->dllitf_cm_message_send)(msg);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
double cm_netlist_get_c(void) {
|
||||
return (coreitf->dllitf_cm_netlist_get_c)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
double cm_netlist_get_l(void) {
|
||||
return (coreitf->dllitf_cm_netlist_get_l)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
Complex_t cm_complex_set(double real, double imag) {
|
||||
return (coreitf->dllitf_cm_complex_set)(real,imag);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
Complex_t cm_complex_add(Complex_t x, Complex_t y) {
|
||||
return (coreitf->dllitf_cm_complex_add)(x,y);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
Complex_t cm_complex_subtract(Complex_t x, Complex_t y) {
|
||||
return (coreitf->dllitf_cm_complex_subtract)(x,y);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
Complex_t cm_complex_multiply(Complex_t x, Complex_t y) {
|
||||
return (coreitf->dllitf_cm_complex_multiply)(x,y);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
Complex_t cm_complex_divide(Complex_t x, Complex_t y) {
|
||||
return (coreitf->dllitf_cm_complex_divide)(x,y);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
char * cm_get_path(void) {
|
||||
return (coreitf->dllitf_cm_get_path)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
CKTcircuit *cm_get_circuit(void) {
|
||||
return (coreitf->dllitf_cm_get_circuit)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
FILE * cm_stream_out(void) {
|
||||
return (coreitf->dllitf_cm_stream_out)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
FILE * cm_stream_in(void) {
|
||||
return (coreitf->dllitf_cm_stream_in)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
FILE * cm_stream_err(void) {
|
||||
return (coreitf->dllitf_cm_stream_err)();
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void * malloc_pj(size_t s) {
|
||||
return (coreitf->dllitf_malloc_pj)(s);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void * calloc_pj(size_t s1, size_t s2) {
|
||||
return (coreitf->dllitf_calloc_pj)(s1,s2);
|
||||
}
|
||||
|
||||
void * realloc_pj(const void *ptr, size_t s) {
|
||||
/* Declared in cmproto.h */
|
||||
void * realloc_pj(void *ptr, size_t s) {
|
||||
return (coreitf->dllitf_realloc_pj)(ptr,s);
|
||||
}
|
||||
|
||||
void free_pj(const void *ptr) {
|
||||
/* Declared in cmproto.h */
|
||||
void free_pj(void *ptr) {
|
||||
(coreitf->dllitf_free_pj)(ptr);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void * tmalloc(size_t s) {
|
||||
return (coreitf->dllitf_tmalloc)(s);
|
||||
}
|
||||
|
||||
void * trealloc(const void *ptr, size_t s) {
|
||||
/* Declared in cmproto.h */
|
||||
void * trealloc(void *ptr, size_t s) {
|
||||
return (coreitf->dllitf_trealloc)(ptr,s);
|
||||
}
|
||||
|
||||
void txfree(const void *ptr) {
|
||||
/* Declared in cmproto.h */
|
||||
void txfree(void *ptr) {
|
||||
(coreitf->dllitf_txfree)(ptr);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
int
|
||||
cm_message_printf(const char *fmt, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
char *p = buf;
|
||||
int size = sizeof(buf);
|
||||
int rv;
|
||||
|
||||
for (;;) {
|
||||
|
||||
int nchars;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
nchars = vsnprintf(p, (size_t) size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (nchars == -1) { // compatibility to old implementations
|
||||
size *= 2;
|
||||
} else if (size < nchars + 1) {
|
||||
size = nchars + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == buf)
|
||||
p = tmalloc((size_t) size * sizeof(char));
|
||||
else
|
||||
p = trealloc(p, (size_t) size * sizeof(char));
|
||||
}
|
||||
|
||||
rv = cm_message_send(p);
|
||||
if (p != buf)
|
||||
txfree(p);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**** V E R S I O N 2 A D D I T I O N S ***/
|
||||
/* Declared in cmproto.h */
|
||||
const char *ngspice_version(void)
|
||||
{
|
||||
return (*coreitf->dllitf_ngspice_version)();
|
||||
}
|
||||
|
||||
/* Wrapper functions around interface function pointers that are used to get
|
||||
* access to "raw" malloc(), calloc(), and realloc() under mutex protection
|
||||
* when necessary */
|
||||
/* Declared in cmproto.h */
|
||||
void *tmalloc_raw(size_t s)
|
||||
{
|
||||
return (*coreitf->dllitf_tmalloc_raw)(s);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void *tcalloc_raw(size_t n, size_t s)
|
||||
{
|
||||
return (*coreitf->dllitf_tcalloc_raw)(n, s);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
void *trealloc_raw(void *ptr, size_t s)
|
||||
{
|
||||
return (*coreitf->dllitf_trealloc_raw)(ptr, s);
|
||||
}
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
char *tstrdup(const char *sz_in)
|
||||
{
|
||||
return (*coreitf->dllitf_tstrdup)(sz_in);
|
||||
} /* end of function tstrdup */
|
||||
|
||||
/* Declared in cmproto.h */
|
||||
char *tstrdup_raw(const char *sz_in)
|
||||
{
|
||||
return (*coreitf->dllitf_tstrdup_raw)(sz_in);
|
||||
} /* end of function tstrdup_raw */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
fopen_with_path()
|
||||
|
|
@ -416,13 +592,16 @@ Then searches for (and opens) <infile> an a sequence from
|
|||
Infile_Path/<infile>
|
||||
NGSPICE_INPUT_DIR/<infile>, where the path is given by the environmental variable
|
||||
<infile>, where the path is the current directory
|
||||
|
||||
Requires version 2 due to DSTRING, which uses raw allocations.
|
||||
*/
|
||||
#define DFLT_BUF_SIZE 256
|
||||
/* Declared in cmproto.h */
|
||||
FILE *fopen_with_path(const char *path, const char *mode)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
if((path[0] != '/') && (path[1] != ':')) { /* path absolue (probably) */
|
||||
if ((path[0] != '/') && (path[1] != ':')) { /* path absolue (probably) */
|
||||
// const char *x = getenv("ngspice_vpath");
|
||||
const char *x = cm_get_path();
|
||||
if (x) {
|
||||
|
|
@ -439,7 +618,7 @@ FILE *fopen_with_path(const char *path, const char *mode)
|
|||
/* Try opening file. If fail, try using NGSPICE_INPUT_DIR
|
||||
* env variable location */
|
||||
if ((fp = fopen(ds_get_buf(&ds), mode)) == (FILE *) NULL) {
|
||||
char *y = getenv("NGSPICE_INPUT_DIR");
|
||||
const char * const y = getenv("NGSPICE_INPUT_DIR");
|
||||
if (y && *y) { /* have env var and not "" */
|
||||
int rc_ds = 0;
|
||||
/* Build <env var>/path and try opening. If the env var
|
||||
|
|
@ -489,39 +668,3 @@ FILE *fopen_with_path(const char *path, const char *mode)
|
|||
|
||||
|
||||
|
||||
int
|
||||
cm_message_printf(const char *fmt, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
char *p = buf;
|
||||
int size = sizeof(buf);
|
||||
int rv;
|
||||
|
||||
for (;;) {
|
||||
|
||||
int nchars;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
nchars = vsnprintf(p, (size_t) size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (nchars == -1) { // compatibility to old implementations
|
||||
size *= 2;
|
||||
} else if (size < nchars + 1) {
|
||||
size = nchars + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (p == buf)
|
||||
p = tmalloc((size_t) size * sizeof(char));
|
||||
else
|
||||
p = trealloc(p, (size_t) size * sizeof(char));
|
||||
}
|
||||
|
||||
rv = cm_message_send(p);
|
||||
if (p != buf)
|
||||
txfree(p);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef dlmain_h_included
|
||||
#define dlmain_h_included
|
||||
|
||||
#include "ngspice/cmproto.h"
|
||||
#include "ngspice/mifproto.h"
|
||||
#include "ngspice/dllitf.h"
|
||||
|
||||
struct coreInfo_t *coreitf;
|
||||
|
||||
#endif /* dlmain.h */
|
||||
|
|
@ -75,7 +75,7 @@ cm_spice2poly_callback(ARGS, Mif_Callback_Reason_t reason)
|
|||
case MIF_CB_DESTROY: {
|
||||
Mif_Inst_Var_Data_t *p = STATIC_VAR_INST(acgains);
|
||||
if(p->element) {
|
||||
free(p->element);
|
||||
txfree(p->element);
|
||||
p->element = NULL;
|
||||
}
|
||||
break;
|
||||
|
|
@ -89,15 +89,15 @@ void spice2poly (ARGS)
|
|||
{
|
||||
int num_inputs; /* Number of inputs to model */
|
||||
int num_coefs; /* Number of coefficients */
|
||||
int *exp; /* List of exponents in products */
|
||||
int *exp = (int *) NULL; /* List of exponents in products */
|
||||
/* One for each input */
|
||||
|
||||
int i; /* Counter */
|
||||
int j; /* Counter */
|
||||
int k; /* Counter */
|
||||
|
||||
double *in; /* Values of inputs to model */
|
||||
double *coef; /* Values of coefficients */
|
||||
double *in = (double *) NULL; /* Values of inputs to model */
|
||||
double *coef = (double *) NULL; /* Values of coefficients */
|
||||
|
||||
double sum; /* Temporary for accumulating sum of terms */
|
||||
double product; /* Temporary for accumulating product */
|
||||
|
|
@ -112,10 +112,16 @@ void spice2poly (ARGS)
|
|||
/* array */
|
||||
|
||||
if(INIT) {
|
||||
CALLBACK = cm_spice2poly_callback;
|
||||
Mif_Inst_Var_Data_t *p = STATIC_VAR_INST(acgains);
|
||||
p -> size = num_inputs;
|
||||
p -> element = (Mif_Value_t *) malloc((size_t) num_inputs * sizeof(Mif_Value_t));
|
||||
if ((p->element = (Mif_Value_t *) tmalloc_raw((size_t) num_inputs *
|
||||
sizeof(Mif_Value_t))) == (Mif_Value_t *) NULL) {
|
||||
cm_message_send("Unable to allocate element array "
|
||||
"in spice2poly()");
|
||||
return;
|
||||
}
|
||||
CALLBACK = cm_spice2poly_callback;
|
||||
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
STATIC_VAR(acgains[i]) = 0.0;
|
||||
}
|
||||
|
|
@ -133,19 +139,34 @@ void spice2poly (ARGS)
|
|||
|
||||
/* Get input values and coefficients to local storage for faster access */
|
||||
|
||||
in = (double *) malloc((size_t) num_inputs * sizeof(double));
|
||||
if ((in = (double *) tmalloc_raw((size_t) num_inputs *
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_send("Unable to allocate array for inputs "
|
||||
"in spice2poly()");
|
||||
goto EXITPOINT;
|
||||
}
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
in[i] = INPUT(in[i]);
|
||||
|
||||
num_coefs = PARAM_SIZE(coef);
|
||||
|
||||
coef = (double *) malloc((size_t) num_coefs * sizeof(double));
|
||||
if ((coef = (double *) tmalloc_raw((size_t) num_coefs *
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_send("Unable to allocate array for coef "
|
||||
"in spice2poly()");
|
||||
goto EXITPOINT;
|
||||
}
|
||||
for(i = 0; i < num_coefs; i++)
|
||||
coef[i] = PARAM(coef[i]);
|
||||
|
||||
|
||||
/* Allocate the array of exponents used in computing the poly terms */
|
||||
exp = (int *) malloc((size_t) num_inputs * sizeof(int));
|
||||
if ((exp = (int *) tmalloc_raw((size_t) num_inputs *
|
||||
sizeof(int))) == (int *) NULL) {
|
||||
cm_message_send("Unable to allocate array for exp "
|
||||
"in spice2poly()");
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
/* Initialize the exponents to zeros */
|
||||
for(i = 0; i < num_inputs; i++)
|
||||
|
|
@ -211,12 +232,20 @@ void spice2poly (ARGS)
|
|||
}
|
||||
|
||||
/* Free the allocated items and return */
|
||||
free(in);
|
||||
free(coef);
|
||||
free(exp);
|
||||
EXITPOINT:
|
||||
if (in != (double *) NULL) {
|
||||
txfree(in);
|
||||
}
|
||||
if (coef != (double *) NULL) {
|
||||
txfree(coef);
|
||||
}
|
||||
if (exp != (int *) NULL) {
|
||||
txfree(exp);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
} /* end of function spice2poly */
|
||||
|
||||
|
||||
|
||||
/* Function evterm computes the value of x**n */
|
||||
|
|
@ -309,5 +338,55 @@ stmt80: PWRSEQ(1) = PWRSEQ(1) + 1;
|
|||
|
||||
stmt100: return;
|
||||
|
||||
|
||||
#if 0
|
||||
/* First cut at a "normal" translation. Would suggest doing the
|
||||
* translation independently and checking for differences */
|
||||
if (pdim == 1) {
|
||||
++pwrseq[0];
|
||||
return;
|
||||
}
|
||||
|
||||
for (k = pdim; k != 0; --k) {
|
||||
if (pwrseq[k - 1] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == 0) {
|
||||
++pwrseq[0];
|
||||
return;
|
||||
}
|
||||
|
||||
if (k != pdim) {
|
||||
--pwrseq[k - 1];
|
||||
++pwrseq[k];
|
||||
return;
|
||||
}
|
||||
|
||||
km1 = k - 1;
|
||||
for (i = 1; i <= km1; i++) {
|
||||
if (pwrseq[i - 1] != 0) {
|
||||
psum = 1;
|
||||
k = pdim;
|
||||
for ( ; ; ) {
|
||||
if (pwrseq[k - 2] >= 1) {
|
||||
break;
|
||||
}
|
||||
psum += pwrseq[k - 1];
|
||||
pwrseq[k - 1] = 0;
|
||||
--k;
|
||||
}
|
||||
|
||||
pwrseq[k - 1] += psum;
|
||||
--pwrseq[k - 2];
|
||||
return;
|
||||
}
|
||||
}
|
||||
pwrseq[1 - 1] = pwrseq[pdim - 1] + 1;
|
||||
pwrseq[pdim - 1] = 0;
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
icm_spice2poly
|
||||
#Directory Version
|
||||
icm_spice2poly 1
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ sf_alloc(int n /* number of elements */,
|
|||
|
||||
/* Use calloc so that any internal allocations will be set to NULL to
|
||||
* facilitate error recovery */
|
||||
if ((ptr = calloc(n, size)) == NULL) {
|
||||
if ((ptr = tcalloc_raw(n, size)) == NULL) {
|
||||
cm_message_printf("%s: cannot allocate %zd bytes : ",
|
||||
__FILE__, n * size);
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -97,10 +97,10 @@ sf_eno_close (sf_eno ent)
|
|||
int i;
|
||||
const int n = ent->order;
|
||||
for (i = 0; i < n; i++) {
|
||||
free (ent->diff[i]);
|
||||
txfree (ent->diff[i]);
|
||||
}
|
||||
free (ent->diff);
|
||||
free (ent);
|
||||
txfree (ent->diff);
|
||||
txfree (ent);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -129,10 +129,10 @@ sf_eno2_close (sf_eno2 pnt)
|
|||
sf_eno_close (pnt->jnt);
|
||||
for (i2 = 0; i2 < pnt->n2; i2++)
|
||||
sf_eno_close (pnt->ent[i2]);
|
||||
free (pnt->f);
|
||||
free (pnt->f1);
|
||||
free (pnt->ent);
|
||||
free (pnt);
|
||||
txfree (pnt->f);
|
||||
txfree (pnt->f1);
|
||||
txfree (pnt->ent);
|
||||
txfree (pnt);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ EXITPOINT:
|
|||
if (xrc != 0) {
|
||||
if (pnt != (sf_eno3) NULL) {
|
||||
sf_eno3_close(pnt);
|
||||
free(pnt);
|
||||
txfree(pnt);
|
||||
pnt = (sf_eno3) NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -146,14 +146,14 @@ sf_eno3_close(sf_eno3 pnt)
|
|||
for (i3 = 0; i3 < pnt->n3; i3++) {
|
||||
for (i2 = 0; i2 < pnt->n2; i2++)
|
||||
sf_eno_close (pnt->ent[i3][i2]);
|
||||
free (pnt->ent[i3]);
|
||||
txfree(pnt->ent[i3]);
|
||||
}
|
||||
free (pnt->ent);
|
||||
free (pnt->f[0]);
|
||||
free (pnt->f);
|
||||
free (pnt->f1[0]);
|
||||
free (pnt->f1);
|
||||
free (pnt);
|
||||
txfree(pnt->ent);
|
||||
txfree(pnt->f[0]);
|
||||
txfree(pnt->f);
|
||||
txfree(pnt->f1[0]);
|
||||
txfree(pnt->f1);
|
||||
txfree(pnt);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
table2D
|
||||
table3D
|
||||
#Directory version
|
||||
table2D 2
|
||||
table3D 2
|
||||
|
|
|
|||
|
|
@ -20,13 +20,15 @@ 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);
|
||||
if ((buf = (char *) tmalloc_raw(strlen(*s) + 1)) == (char *) NULL) {
|
||||
cm_message_printf("cannot allocate buffer to tokenize");
|
||||
return (char *) NULL;
|
||||
}
|
||||
|
||||
/* skip over any white space */
|
||||
|
||||
|
|
@ -39,8 +41,9 @@ char *CNVgettok(char **s)
|
|||
switch (**s) {
|
||||
|
||||
case '\0': /* End of string found */
|
||||
if (buf)
|
||||
free(buf);
|
||||
if (buf) {
|
||||
txfree(buf);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
|
||||
|
|
@ -70,12 +73,15 @@ char *CNVgettok(char **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;
|
||||
{
|
||||
char * const ret_str = (char *) tmalloc_raw(strlen(buf) + 1);
|
||||
if (ret_str == (char *) NULL) {
|
||||
return (char *) NULL;
|
||||
}
|
||||
(void) strcpy(ret_str, buf);
|
||||
txfree(buf);
|
||||
return ret_str;
|
||||
}
|
||||
} /* end of function CNVgettok */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef gettokens_h_included
|
||||
#define gettokens_h_included
|
||||
|
||||
/* Type definition for each possible token returned. */
|
||||
typedef enum token_type_s { CNV_NO_TOK, CNV_STRING_TOK } Cnv_Token_Type_t;
|
||||
|
||||
char * CNVget_token(char **s, Cnv_Token_Type_t *type);
|
||||
char *CNVgettok(char **s);
|
||||
int cnv_get_spice_value(char *str, double *p_value);
|
||||
#endif /* gettokens_h_included */
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#include "eno2.h"
|
||||
#include "eno3.h"
|
||||
|
||||
typedef struct {
|
||||
int ix; /* size of array in x */
|
||||
int iy; /* size of array in y */
|
||||
int iz; /* size of array in z */
|
||||
|
||||
sf_eno3 newtable; /* the table, code borrowed from madagascar project */
|
||||
|
||||
/* Input values corresponding to each index. They define the value
|
||||
* in the domain at each index value */
|
||||
double *xcol; /* array of doubles in x */
|
||||
double *ycol; /* array of doubles in y */
|
||||
double *zcol; /* array of doubles in z */
|
||||
|
||||
double ***table; /* f(xi, yj, zk) */
|
||||
} Table3_Data_t;
|
||||
|
||||
void free_local_data(Table3_Data_t *loc);
|
||||
|
||||
|
||||
Table3_Data_t *init_local_data(const char *filename, int order);
|
||||
|
||||
/* Finds difference between column values */
|
||||
static inline double get_local_diff(int n, double *col, int ind)
|
||||
{
|
||||
if (ind >= n - 1) {
|
||||
return col[n - 1] - col[n - 2];
|
||||
}
|
||||
if (ind <= 0) {
|
||||
return col[1] - col[0];
|
||||
}
|
||||
return 0.5 * (col[ind + 1] - col[ind - 1]);
|
||||
} /* end of function get_local_diff */
|
||||
|
||||
|
||||
|
||||
|
|
@ -72,6 +72,7 @@ NON-STANDARD FEATURES
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "support/gettokens.h"
|
||||
#include "mada/eno2.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -88,7 +89,6 @@ typedef struct {
|
|||
double **table; /* f(xi, yj) */
|
||||
} Table2_Data_t;
|
||||
|
||||
typedef Table2_Data_t Local_Data_t;
|
||||
|
||||
/*=== MACROS ===========================*/
|
||||
|
||||
|
|
@ -98,19 +98,8 @@ typedef Table2_Data_t Local_Data_t;
|
|||
#define DIR_PATHSEP "/"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||
|
||||
struct filesource_state {
|
||||
FILE *fp;
|
||||
long pos;
|
||||
unsigned char atend;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -118,74 +107,12 @@ struct filesource_state {
|
|||
|
||||
double BilinearInterpolation(double x, double y,
|
||||
int xind, int yind, double **td);
|
||||
extern char *CNVgettok(char **s);
|
||||
int cnv_get_spice_value(char *str, double *p_value);
|
||||
static void cm_table2D_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
extern int findCrossOver(double arr[], int n, double x);
|
||||
|
||||
static void free_local_data(Table2_Data_t *loc);
|
||||
static inline double get_local_diff(int n, double *col, int ind);
|
||||
static Table2_Data_t *init_local_data(const char *filename, int order);
|
||||
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
FUNCTION cnv_get_spice_value()
|
||||
|
||||
AUTHORS
|
||||
|
||||
??? Bill Kuhn
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
30 Sep 1991 Jeffrey P. Murray
|
||||
|
||||
SUMMARY
|
||||
|
||||
This function takes as input a string token from a SPICE
|
||||
deck and returns a floating point equivalent value.
|
||||
|
||||
INTERFACES
|
||||
|
||||
FILE ROUTINE CALLED
|
||||
|
||||
N/A N/A
|
||||
|
||||
RETURNED VALUE
|
||||
|
||||
Returns the floating point value in pointer *p_value. Also
|
||||
returns an integer representing successful completion.
|
||||
|
||||
GLOBAL VARIABLES
|
||||
|
||||
NONE
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
NONE
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
|
||||
|
||||
|
||||
static void cm_table2D_callback(ARGS,
|
||||
Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Table2_Data_t *loc = STATIC_VAR(locdata);
|
||||
if (loc) {
|
||||
free_local_data(loc);
|
||||
STATIC_VAR(locdata) = loc = NULL;
|
||||
}
|
||||
break;
|
||||
} /* end of case MIF_CB_DESTROY */
|
||||
} /* end of switch over reason being called */
|
||||
} /* end of function cm_table2D_callback */
|
||||
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
FUNCTION void cm_table2D()
|
||||
|
|
@ -262,7 +189,8 @@ void cm_table2D(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
}
|
||||
|
||||
/* return immediately if there was an initialization error */
|
||||
if ((loc = STATIC_VAR(locdata)) == (Table2_Data_t *) NULL) {
|
||||
if ((loc = (Table2_Data_t *) STATIC_VAR(locdata)) ==
|
||||
(Table2_Data_t *) NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -345,11 +273,10 @@ void cm_table2D(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
}
|
||||
else {
|
||||
Mif_Complex_t ac_gain;
|
||||
ac_gain.real = PARAM(gain) * derivval[0] / xdiff;
|
||||
ac_gain.imag= 0.0;
|
||||
ac_gain.real = PARAM(gain) * derivval[0] / xdiff;
|
||||
AC_GAIN(out, inx) = ac_gain;
|
||||
ac_gain.real = PARAM(gain) * derivval[1] / ydiff;
|
||||
ac_gain.imag= 0.0;
|
||||
AC_GAIN(out, iny) = ac_gain;
|
||||
}
|
||||
} /* end of function cm_table2D */
|
||||
|
|
@ -357,12 +284,11 @@ void cm_table2D(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
|
||||
|
||||
/* This function initializes local data */
|
||||
static Table2_Data_t *init_local_data(const char *filename, int order)
|
||||
static Table2_Data_t *init_local_data(const char *filename, int interporder)
|
||||
{
|
||||
int xrc = 0;
|
||||
int ix = 0, /* elements in a row */
|
||||
iy = 0; /* number of rows */
|
||||
|
||||
double **table_data;
|
||||
double tmp;
|
||||
FILE *fp = (FILE *) NULL; /* Handle to file */
|
||||
|
|
@ -373,12 +299,11 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
size_t lFileRead; /* Length of file read in */
|
||||
int lLineCount; /* Current line number */
|
||||
size_t lTotalChar; /* Total characters read */
|
||||
int interporder; /* order of interpolation for eno */
|
||||
Table2_Data_t *loc = (Table2_Data_t *) NULL; /* local data */
|
||||
|
||||
|
||||
/* Allocate static storage for *loc */
|
||||
if ((loc = (Table2_Data_t *) calloc(1,
|
||||
if ((loc = (Table2_Data_t *) tcalloc_raw(1,
|
||||
sizeof(Table2_Data_t))) == (Table2_Data_t *) NULL) {
|
||||
cm_message_printf("cannot allocate memory for lookup table.");
|
||||
xrc = -1;
|
||||
|
|
@ -394,7 +319,7 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
if (!fp) { /* Standard open attempt failed */
|
||||
const char * const lbuffer = getenv("NGSPICE_INPUT_DIR");
|
||||
if (lbuffer && *lbuffer) {
|
||||
char * const p = (char *) malloc(strlen(lbuffer) +
|
||||
char * const p = (char *) tmalloc_raw(strlen(lbuffer) +
|
||||
strlen(DIR_PATHSEP) +
|
||||
strlen(filename) + 1);
|
||||
if (p == (char *) NULL) {
|
||||
|
|
@ -406,7 +331,7 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
(void) sprintf(p, "%s%s%s",
|
||||
lbuffer, DIR_PATHSEP, filename);
|
||||
fp = fopen(p, "r");
|
||||
free(p);
|
||||
txfree(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -431,9 +356,9 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
}
|
||||
|
||||
/* create string to hold the whole file */
|
||||
cFile = calloc(lFileLen + 1, sizeof(char));
|
||||
cFile = tcalloc_raw(lFileLen + 1, sizeof(char));
|
||||
/* create another string long enough for file manipulation */
|
||||
cThisLine = calloc(lFileLen + 1, sizeof(char));
|
||||
cThisLine = tcalloc_raw(lFileLen + 1, sizeof(char));
|
||||
if (cFile == NULL || cThisLine == NULL) {
|
||||
cm_message_printf("Insufficient memory to read file %s",
|
||||
filename);
|
||||
|
|
@ -494,7 +419,7 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
cnv_get_spice_value(cThisLinePtr, &tmp);
|
||||
loc->ix = ix = (int) tmp;
|
||||
/* generate row data structure (x) */
|
||||
if ((loc->xcol = (double *) calloc((size_t) ix,
|
||||
if ((loc->xcol = (double *) tcalloc_raw((size_t) ix,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate row structure.");
|
||||
xrc = -1;
|
||||
|
|
@ -505,7 +430,7 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
cnv_get_spice_value(cThisLinePtr, &tmp);
|
||||
loc->iy = iy = (int) tmp;
|
||||
/* generate column data structure (y) */
|
||||
if ((loc->ycol = (double *) calloc((size_t) iy,
|
||||
if ((loc->ycol = (double *) tcalloc_raw((size_t) iy,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate colum structure.");
|
||||
xrc = -1;
|
||||
|
|
@ -522,7 +447,7 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
goto EXITPOINT;
|
||||
}
|
||||
cnv_get_spice_value(token, &loc->xcol[i++]);
|
||||
free(token);
|
||||
txfree(token);
|
||||
token = CNVgettok(&cThisLinePtr);
|
||||
}
|
||||
if (i < ix) {
|
||||
|
|
@ -541,7 +466,7 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
goto EXITPOINT;
|
||||
}
|
||||
cnv_get_spice_value(token, &loc->ycol[i++]);
|
||||
free(token);
|
||||
txfree(token);
|
||||
token = CNVgettok(&cThisLinePtr);
|
||||
}
|
||||
if (i < iy) {
|
||||
|
|
@ -556,7 +481,6 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
}
|
||||
|
||||
/* generate table core */
|
||||
interporder = order;
|
||||
/* boundary limits set to param 'order' aren't recognized,
|
||||
so limit them here */
|
||||
if (interporder < 2) {
|
||||
|
|
@ -569,40 +493,33 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
int n1, int n2 : data dimensions */
|
||||
if ((loc->newtable = sf_eno2_init(
|
||||
interporder, ix, iy)) == (sf_eno2) NULL) {
|
||||
cm_message_printf("eno2 initialization failure.");
|
||||
cm_message_send("eno2 initialization failure.");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
|
||||
}
|
||||
|
||||
/* create table_data in memory */
|
||||
/* data [n2][n1] */
|
||||
if ((loc->table = table_data = (double **) calloc((size_t) iy,
|
||||
if ((loc->table = table_data = (double **) tcalloc_raw((size_t) iy,
|
||||
sizeof(double *))) == (double **) NULL) {
|
||||
cm_message_printf("Unable to allocate data table.");
|
||||
free(cFile);
|
||||
free(cThisLine);
|
||||
free_local_data(loc);
|
||||
return (Local_Data_t *) NULL;
|
||||
cm_message_send("Unable to allocate data table.");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < iy; i++) {
|
||||
if ((table_data[i] = (double *) calloc((size_t) ix,
|
||||
if ((table_data[i] = (double *) tcalloc_raw((size_t) ix,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate data table "
|
||||
"row %d", i + 1);
|
||||
free(cFile);
|
||||
free(cThisLine);
|
||||
free_local_data(loc);
|
||||
return (Local_Data_t *) NULL;
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loc->table = table_data; /* give to local data structure */
|
||||
|
||||
|
||||
/* continue reading f(x,y) values from cFile */
|
||||
lLineCount = 0;
|
||||
|
|
@ -634,10 +551,8 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
if (lTotalChar >= lFileLen) {
|
||||
cm_message_printf("Not enough data in file %s",
|
||||
filename);
|
||||
free(cFile);
|
||||
free(cThisLine);
|
||||
free_local_data(loc);
|
||||
return (Local_Data_t *) NULL;
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
lLineCount--; /* we count only real lines */
|
||||
continue;
|
||||
|
|
@ -658,7 +573,7 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
* structure table_data */
|
||||
cnv_get_spice_value(token, &tmpval);
|
||||
table_data[lLineCount - 1][i++] = tmpval;
|
||||
free(token);
|
||||
txfree(token);
|
||||
token = CNVgettok(&cThisLinePtr);
|
||||
}
|
||||
if (i < ix) {
|
||||
|
|
@ -676,10 +591,10 @@ static Table2_Data_t *init_local_data(const char *filename, int order)
|
|||
EXITPOINT:
|
||||
/* free the file and memory allocated */
|
||||
if (cFile != (char *) NULL) {
|
||||
free(cFile);
|
||||
txfree(cFile);
|
||||
}
|
||||
if (cThisLine != (char *) NULL) {
|
||||
free(cThisLine);
|
||||
txfree(cThisLine);
|
||||
}
|
||||
if (fp != (FILE *) NULL) {
|
||||
(void) fclose(fp);
|
||||
|
|
@ -697,7 +612,7 @@ EXITPOINT:
|
|||
|
||||
|
||||
|
||||
/* Free memory allocations in Local_Data_t structure */
|
||||
/* Free memory allocations in Table2_Data_t structure */
|
||||
static void free_local_data(Table2_Data_t *loc)
|
||||
{
|
||||
if (loc == (Table2_Data_t *) NULL) {
|
||||
|
|
@ -709,16 +624,24 @@ static void free_local_data(Table2_Data_t *loc)
|
|||
int i;
|
||||
int n_y = loc->iy;
|
||||
for (i = 0; i < n_y; i++) {
|
||||
free(loc->table[i]);
|
||||
txfree(loc->table[i]);
|
||||
}
|
||||
|
||||
free(loc->table);
|
||||
txfree(loc->table);
|
||||
}
|
||||
|
||||
free(loc->xcol);
|
||||
free(loc->ycol);
|
||||
sf_eno2_close(loc->newtable);
|
||||
free(loc);
|
||||
if (loc->xcol != (double *) NULL) {
|
||||
txfree(loc->xcol);
|
||||
}
|
||||
if (loc->ycol != (double *) NULL) {
|
||||
txfree(loc->ycol);
|
||||
}
|
||||
|
||||
if (loc->newtable != (sf_eno2) NULL) {
|
||||
sf_eno2_close(loc->newtable);
|
||||
}
|
||||
|
||||
txfree(loc);
|
||||
} /* end of function free_local_data */
|
||||
|
||||
|
||||
|
|
@ -737,3 +660,21 @@ static inline double get_local_diff(int n, double *col, int ind)
|
|||
|
||||
|
||||
|
||||
/* This function frees resources when called with reason argument
|
||||
* MIF_CB_DESTROY */
|
||||
static void cm_table2D_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Table2_Data_t *loc = (Table2_Data_t *) STATIC_VAR(locdata);
|
||||
if (loc) {
|
||||
free_local_data(loc);
|
||||
STATIC_VAR(locdata) = NULL;
|
||||
}
|
||||
break;
|
||||
} /* end of case MIF_CB_DESTROY */
|
||||
} /* end of switch over reason being called */
|
||||
} /* end of function cm_table2D_callback */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@ typedef struct {
|
|||
double ***table; /* f(xi, yj, zk) */
|
||||
} Table3_Data_t;
|
||||
|
||||
typedef Table3_Data_t Local_Data_t;
|
||||
|
||||
/*=== MACROS ===========================*/
|
||||
|
||||
|
|
@ -102,10 +101,6 @@ typedef Table3_Data_t Local_Data_t;
|
|||
#define DIR_PATHSEP "/"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
|
||||
|
||||
|
||||
|
|
@ -113,76 +108,15 @@ typedef Table3_Data_t Local_Data_t;
|
|||
|
||||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||
|
||||
extern char *CNVgettok(char **s);
|
||||
extern double TrilinearInterpolation(double x, double y, double z, int xind, int yind, int zind, double ***td);
|
||||
int cnv_get_spice_value(char *str, double *p_value);
|
||||
extern double TrilinearInterpolation(double x, double y, double z,
|
||||
int xind, int yind, int zind, double ***td);
|
||||
static void cm_table3D_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
extern int findCrossOver(double arr[], int n, double x);
|
||||
|
||||
static void free_local_data(Table3_Data_t *loc);
|
||||
static inline double get_local_diff(int n, double *col, int ind);
|
||||
static Table3_Data_t *init_local_data(const char *filename, int order);
|
||||
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
FUNCTION cnv_get_spice_value()
|
||||
|
||||
AUTHORS
|
||||
|
||||
??? Bill Kuhn
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
30 Sep 1991 Jeffrey P. Murray
|
||||
|
||||
SUMMARY
|
||||
|
||||
This function takes as input a string token from a SPICE
|
||||
deck and returns a floating point equivalent value.
|
||||
|
||||
INTERFACES
|
||||
|
||||
FILE ROUTINE CALLED
|
||||
|
||||
N/A N/A
|
||||
|
||||
RETURNED VALUE
|
||||
|
||||
Returns the floating point value in pointer *p_value. Also
|
||||
returns an integer representing successful completion.
|
||||
|
||||
GLOBAL VARIABLES
|
||||
|
||||
NONE
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
NONE
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void cm_table3D_callback(ARGS,
|
||||
Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Table3_Data_t *loc = STATIC_VAR(locdata);
|
||||
if (loc) {
|
||||
free_local_data(loc);
|
||||
STATIC_VAR(locdata) = loc = NULL;
|
||||
}
|
||||
break;
|
||||
} /* end of case MIF_CB_DESTROY */
|
||||
} /* end of switch over reason being called */
|
||||
} /* end of function cm_table2D_callback */
|
||||
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
FUNCTION void cm_table3D()
|
||||
|
|
@ -261,7 +195,8 @@ void cm_table3D(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
}
|
||||
|
||||
/* return immediately if there was an initialization error */
|
||||
if ((loc = STATIC_VAR(locdata)) == (Table3_Data_t *) NULL) {
|
||||
if ((loc = (Table3_Data_t *) STATIC_VAR(locdata)) ==
|
||||
(Table3_Data_t *) NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -362,15 +297,13 @@ void cm_table3D(ARGS) /* structure holding parms, inputs, outputs, etc. */
|
|||
}
|
||||
else {
|
||||
Mif_Complex_t ac_gain;
|
||||
ac_gain.real = PARAM(gain) * derivval[0] / xdiff;
|
||||
ac_gain.imag= 0.0;
|
||||
ac_gain.real = PARAM(gain) * derivval[0] / xdiff;
|
||||
AC_GAIN(out, inx) = ac_gain;
|
||||
ac_gain.real = PARAM(gain) * derivval[1] / ydiff;
|
||||
ac_gain.imag= 0.0;
|
||||
AC_GAIN(out, iny) = ac_gain;
|
||||
ac_gain.real = PARAM(gain) * derivval[2] / zdiff;
|
||||
ac_gain.imag= 0.0;
|
||||
AC_GAIN(out, iny) = ac_gain;
|
||||
AC_GAIN(out, inz) = ac_gain;
|
||||
}
|
||||
} /* end of function cm_table3D */
|
||||
|
||||
|
|
@ -398,7 +331,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
|
||||
|
||||
/* Allocate static storage for *loc */
|
||||
if ((loc = (Table3_Data_t *) calloc(1,
|
||||
if ((loc = (Table3_Data_t *) tcalloc_raw(1,
|
||||
sizeof(Table3_Data_t))) == (Table3_Data_t *) NULL) {
|
||||
cm_message_printf("cannot allocate memory for lookup table.");
|
||||
xrc = -1;
|
||||
|
|
@ -414,7 +347,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
if (!fp) { /* Standard open attempt failed */
|
||||
const char * const lbuffer = getenv("NGSPICE_INPUT_DIR");
|
||||
if (lbuffer && *lbuffer) {
|
||||
char * const p = (char *) malloc(strlen(lbuffer) +
|
||||
char * const p = (char *) tmalloc_raw(strlen(lbuffer) +
|
||||
strlen(DIR_PATHSEP) +
|
||||
strlen(filename) + 1);
|
||||
if (p == (char *) NULL) {
|
||||
|
|
@ -426,7 +359,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
(void) sprintf(p, "%s%s%s",
|
||||
lbuffer, DIR_PATHSEP, filename);
|
||||
fp = fopen(p, "r");
|
||||
free(p);
|
||||
txfree(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -451,9 +384,9 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
}
|
||||
|
||||
/* create string to hold the whole file */
|
||||
cFile = calloc(lFileLen + 1, sizeof(char));
|
||||
cFile = tcalloc_raw(lFileLen + 1, sizeof(char));
|
||||
/* create another string long enough for file manipulation */
|
||||
cThisLine = calloc(lFileLen + 1, sizeof(char));
|
||||
cThisLine = tcalloc_raw(lFileLen + 1, sizeof(char));
|
||||
if (cFile == NULL || cThisLine == NULL) {
|
||||
cm_message_printf("Insufficient memory to read file %s",
|
||||
filename);
|
||||
|
|
@ -514,7 +447,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
cnv_get_spice_value(cThisLinePtr, &tmp);
|
||||
loc->ix = ix = (int) tmp;
|
||||
/* generate row data structure (x) */
|
||||
if ((loc->xcol = (double *) calloc((size_t) ix,
|
||||
if ((loc->xcol = (double *) tcalloc_raw((size_t) ix,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate row structure.");
|
||||
xrc = -1;
|
||||
|
|
@ -525,7 +458,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
cnv_get_spice_value(cThisLinePtr, &tmp);
|
||||
loc->iy = iy = (int) tmp;
|
||||
/* generate column data structure (y) */
|
||||
if ((loc->ycol = (double *) calloc((size_t) iy,
|
||||
if ((loc->ycol = (double *) tcalloc_raw((size_t) iy,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate colum structure.");
|
||||
xrc = -1;
|
||||
|
|
@ -536,7 +469,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
cnv_get_spice_value(cThisLinePtr, &tmp);
|
||||
loc->iz = iz = (int) tmp;
|
||||
/* generate column data structure (z) */
|
||||
if ((loc->zcol = (double *) calloc((size_t) iz,
|
||||
if ((loc->zcol = (double *) tcalloc_raw((size_t) iz,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate \"z\" structure.");
|
||||
xrc = -1;
|
||||
|
|
@ -553,7 +486,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
goto EXITPOINT;
|
||||
}
|
||||
cnv_get_spice_value(token, &loc->xcol[i++]);
|
||||
free(token);
|
||||
txfree(token);
|
||||
token = CNVgettok(&cThisLinePtr);
|
||||
}
|
||||
if (i < ix) {
|
||||
|
|
@ -572,7 +505,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
goto EXITPOINT;
|
||||
}
|
||||
cnv_get_spice_value(token, &loc->ycol[i++]);
|
||||
free(token);
|
||||
txfree(token);
|
||||
token = CNVgettok(&cThisLinePtr);
|
||||
}
|
||||
if (i < iy) {
|
||||
|
|
@ -591,7 +524,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
goto EXITPOINT;
|
||||
}
|
||||
cnv_get_spice_value(token, &loc->zcol[i++]);
|
||||
free(token);
|
||||
txfree(token);
|
||||
token = CNVgettok(&cThisLinePtr);
|
||||
}
|
||||
if (i < iz) {
|
||||
|
|
@ -618,16 +551,16 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
int n1, int n2, int n3 : data dimensions */
|
||||
if ((loc->newtable = sf_eno3_init(
|
||||
interporder, ix, iy, iz)) == (sf_eno3) NULL) {
|
||||
cm_message_printf("eno3 initialization failure.");
|
||||
cm_message_send("eno3 initialization failure.");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
||||
/* create table_data in memory */
|
||||
/* data [n3][n2][n1] */
|
||||
if ((loc->table = table_data = (double ***) calloc((size_t) iz,
|
||||
if ((loc->table = table_data = (double ***) tcalloc_raw((size_t) iz,
|
||||
sizeof(double **))) == (double ***) NULL) {
|
||||
cm_message_printf("Unable to allocate data table.");
|
||||
cm_message_send("Unable to allocate data table.");
|
||||
xrc = -1;
|
||||
goto EXITPOINT;
|
||||
}
|
||||
|
|
@ -635,7 +568,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
{
|
||||
int i, j;
|
||||
for (i = 0; i < iz; i++) {
|
||||
if ((table_data[i] = (double **) calloc((size_t) iy,
|
||||
if ((table_data[i] = (double **) tcalloc_raw((size_t) iy,
|
||||
sizeof(double *))) == (double **) NULL) {
|
||||
cm_message_printf("Unable to allocate data table "
|
||||
"z=%d",
|
||||
|
|
@ -644,7 +577,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
goto EXITPOINT;
|
||||
}
|
||||
for (j = 0; j < iy; j++) {
|
||||
if ((table_data[i][j] = (double *) calloc((size_t) ix,
|
||||
if ((table_data[i][j] = (double *) tcalloc_raw((size_t) ix,
|
||||
sizeof(double))) == (double *) NULL) {
|
||||
cm_message_printf("Unable to allocate data table "
|
||||
"z=%d y=%d",
|
||||
|
|
@ -709,7 +642,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
|
||||
table_data[lTableCount][lLineCount][i++] = tmpval;
|
||||
|
||||
free(token);
|
||||
txfree(token);
|
||||
token = CNVgettok(&cThisLinePtr);
|
||||
}
|
||||
if (i < ix) {
|
||||
|
|
@ -730,10 +663,10 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder)
|
|||
EXITPOINT:
|
||||
/* free the file and memory allocated */
|
||||
if (cFile != (char *) NULL) {
|
||||
free(cFile);
|
||||
txfree(cFile);
|
||||
}
|
||||
if (cThisLine != (char *) NULL) {
|
||||
free(cThisLine);
|
||||
txfree(cThisLine);
|
||||
}
|
||||
if (fp != (FILE *) NULL) {
|
||||
(void) fclose(fp);
|
||||
|
|
@ -760,24 +693,35 @@ static void free_local_data(Table3_Data_t *loc)
|
|||
|
||||
/* Free data table and related values */
|
||||
if (loc->table) {
|
||||
int i, j;
|
||||
int i;
|
||||
int n_y = loc->iy;
|
||||
int n_z = loc->iz;
|
||||
for (i = 0; i < n_z; i++) {
|
||||
int j;
|
||||
for (j = 0; j < n_y; j++) {
|
||||
free(loc->table[i][j]);
|
||||
txfree(loc->table[i][j]);
|
||||
}
|
||||
free(loc->table[i]);
|
||||
txfree(loc->table[i]);
|
||||
}
|
||||
|
||||
free(loc->table);
|
||||
txfree(loc->table);
|
||||
}
|
||||
|
||||
free(loc->xcol);
|
||||
free(loc->ycol);
|
||||
free(loc->zcol);
|
||||
sf_eno3_close(loc->newtable);
|
||||
free(loc);
|
||||
if (loc->xcol != (double *) NULL) {
|
||||
txfree(loc->xcol);
|
||||
}
|
||||
if (loc->ycol != (double *) NULL) {
|
||||
txfree(loc->ycol);
|
||||
}
|
||||
if (loc->zcol != (double *) NULL) {
|
||||
txfree(loc->zcol);
|
||||
}
|
||||
|
||||
if (loc->newtable != (sf_eno3) NULL) {
|
||||
sf_eno3_close(loc->newtable);
|
||||
}
|
||||
|
||||
txfree(loc);
|
||||
} /* end of function free_local_data */
|
||||
|
||||
|
||||
|
|
@ -795,6 +739,25 @@ static inline double get_local_diff(int n, double *col, int ind)
|
|||
} /* end of function get_local_diff */
|
||||
|
||||
|
||||
|
||||
/* This function frees resources when called with reason argument
|
||||
* MIF_CB_DESTROY */
|
||||
static void cm_table3D_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Table3_Data_t *loc = (Table3_Data_t *) STATIC_VAR(locdata);
|
||||
if (loc) {
|
||||
free_local_data(loc);
|
||||
STATIC_VAR(locdata) = NULL;
|
||||
}
|
||||
break;
|
||||
} /* end of case MIF_CB_DESTROY */
|
||||
} /* end of switch over reason being called */
|
||||
} /* end of function cm_table3D_callback */
|
||||
|
||||
|
||||
|
||||
/* These includes add functions from extra source code files,
|
||||
* still using the standard XSPICE procedure of cmpp-ing cfunc.mod
|
||||
* and then only compiling the resulting *.c file.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
aswitch
|
||||
capacitor
|
||||
cmeter
|
||||
core
|
||||
inductor
|
||||
lcouple
|
||||
lmeter
|
||||
potentiometer
|
||||
zener
|
||||
memristor
|
||||
sidiode
|
||||
#Directory Version
|
||||
aswitch 1
|
||||
capacitor 1
|
||||
cmeter 1
|
||||
core 1
|
||||
inductor 1
|
||||
lcouple 1
|
||||
lmeter 1
|
||||
potentiometer 1
|
||||
zener 2
|
||||
memristor 1
|
||||
sidiode 1
|
||||
|
|
|
|||
|
|
@ -86,19 +86,7 @@ typedef struct {
|
|||
|
||||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||
|
||||
|
||||
static void
|
||||
cm_sidiode_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Local_Data_t *loc = STATIC_VAR (locdata);
|
||||
free(loc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cm_sidiode_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
|
@ -127,11 +115,12 @@ void cm_sidiode(ARGS) /* structure holding parms,
|
|||
|
||||
double grev, goff, gon, Va, Vb, Vc, Vd, hEpsilon, hRevepsilon;
|
||||
|
||||
CALLBACK = cm_sidiode_callback;
|
||||
|
||||
/* allocate static storage for *loc */
|
||||
STATIC_VAR(locdata) = calloc (1, sizeof(Local_Data_t));
|
||||
loc = STATIC_VAR(locdata);
|
||||
if ((loc = (Local_Data_t *) (STATIC_VAR(locdata) = tcalloc_raw(1,
|
||||
sizeof(Local_Data_t)))) == (Local_Data_t *) NULL) {
|
||||
cm_message_send("Unable to allocate locdata in cm_sidiode().");
|
||||
}
|
||||
CALLBACK = cm_sidiode_callback;
|
||||
|
||||
goff = 1./PARAM(roff);
|
||||
gon = 1./PARAM(ron);
|
||||
|
|
@ -177,8 +166,14 @@ void cm_sidiode(ARGS) /* structure holding parms,
|
|||
loc->goff = goff;
|
||||
loc->gon = gon;
|
||||
}
|
||||
else
|
||||
loc = STATIC_VAR(locdata);
|
||||
else {
|
||||
if ((loc = (Local_Data_t *) STATIC_VAR(locdata)) ==
|
||||
(Local_Data_t *) NULL) {
|
||||
cm_message_send("Attempt to use uninitialized locdata "
|
||||
"in cm_sidiode()");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Calculate diode current Id and its derivative deriv=dId/dVin */
|
||||
|
|
@ -233,4 +228,24 @@ void cm_sidiode(ARGS) /* structure holding parms,
|
|||
ac_gain.imag= 0.0;
|
||||
AC_GAIN(ds,ds) = ac_gain;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_sidiode */
|
||||
|
||||
|
||||
|
||||
/* This function frees resources when called with reason argument
|
||||
* MIF_CB_DESTROY */
|
||||
static void cm_sidiode_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
Local_Data_t *loc = (Local_Data_t *) STATIC_VAR(locdata);
|
||||
if (loc != (Local_Data_t *) NULL) {
|
||||
txfree(loc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_sidiode_callback */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -69,9 +69,9 @@ NON-STANDARD FEATURES
|
|||
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
|
||||
|
||||
|
||||
static void cm_zener_callback(ARGS, Mif_Callback_Reason_t reason);
|
||||
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
FUNCTION void cm_zener()
|
||||
|
|
@ -174,16 +174,25 @@ void cm_zener(ARGS) /* structure holding parms,
|
|||
if (INIT==1) { /* First pass...allocate storage for previous value... */
|
||||
|
||||
/* Allocate storage for frequencies */
|
||||
STATIC_VAR(previous_voltage) = (double *) malloc(sizeof(double));
|
||||
previous_voltage = (double *) STATIC_VAR(previous_voltage);
|
||||
if ((previous_voltage = (double *) (STATIC_VAR(previous_voltage) =
|
||||
tmalloc_raw(sizeof(double)))) == (double *) NULL) {
|
||||
cm_message_send("Unable to allocate memory for previous "
|
||||
"voltage in cm_zener()");
|
||||
return;
|
||||
}
|
||||
CALLBACK = cm_zener_callback;
|
||||
|
||||
/* Set previous_voltage value to zero... */
|
||||
*previous_voltage = 0.0;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
previous_voltage = (double *) STATIC_VAR(previous_voltage);
|
||||
if ((previous_voltage = (double *) STATIC_VAR(
|
||||
previous_voltage)) == (double *) NULL) {
|
||||
cm_message_send("Attempt to use uninitialized previous "
|
||||
"voltage in cm_zener()");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -352,5 +361,23 @@ void cm_zener(ARGS) /* structure holding parms,
|
|||
ac_gain.imag= 0.0;
|
||||
AC_GAIN(z,z) = ac_gain;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_zener */
|
||||
|
||||
|
||||
|
||||
static void cm_zener_callback(ARGS, Mif_Callback_Reason_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case MIF_CB_DESTROY: {
|
||||
double * const p_prev_voltage =
|
||||
(double *) STATIC_VAR(previous_voltage);
|
||||
if (p_prev_voltage != (double *) NULL) {
|
||||
txfree(p_prev_voltage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end of function cm_zener_callback */
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
d_to_real
|
||||
real_delay
|
||||
real_gain
|
||||
real_to_v
|
||||
#Directory Version
|
||||
d_to_real 1
|
||||
real_delay 1
|
||||
real_gain 1
|
||||
real_to_v 1
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
int
|
||||
real
|
||||
#Directory Version
|
||||
int 1
|
||||
real 1
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@ Ipc_Status_t ipc_transport_get_line (
|
|||
NG_IGNORE(wait);
|
||||
|
||||
printf ("GET_LINE\n");
|
||||
gets (str);
|
||||
fgets (str, 512, stdin);
|
||||
char *tmp = strchr(str, '\n');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
*len = (int) strlen (str);
|
||||
return IPC_STATUS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ successful, and an error string on failure.
|
|||
|
||||
char *MIFgetMod(
|
||||
CKTcircuit *ckt, /* The circuit structure */
|
||||
char *name, /* The name of the model to look for */
|
||||
const char *name, /* The name of the model to look for */
|
||||
INPmodel **model, /* The model found/created */
|
||||
INPtables *tab /* Table of model info from first pass */
|
||||
)
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ MIFcopy
|
|||
This function allocates a new copy of a string.
|
||||
*/
|
||||
|
||||
char *MIFcopy(char *str)
|
||||
char *MIFcopy(const char *str)
|
||||
{
|
||||
if(str)
|
||||
return copy(str);
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ if "%3" == "64" goto b64
|
|||
set dst=c:\Spiced
|
||||
set cmsrc=.\codemodels\Win32\Debug
|
||||
|
||||
mkdir %dst%\bin
|
||||
mkdir %dst%\lib\ngspice
|
||||
mkdir %dst%\share\ngspice\scripts
|
||||
if not exist "%dst%\bin\" mkdir "%dst%\bin"
|
||||
if not exist "%dst%\lib\ngspice\" mkdir "%dst%\lib\ngspice"
|
||||
if not exist "%dst%\share\ngspice\scripts\" mkdir "%dst%\share\ngspice\scripts"
|
||||
|
||||
copy "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\x86\Microsoft.VC140.OPENMP\vcomp140.dll" %dst%\bin\
|
||||
copy %cmsrc%\analog.cm %dst%\lib\ngspice\analog.cm
|
||||
|
|
@ -24,6 +24,8 @@ copy %cmsrc%\spice2poly.cm %dst%\lib\ngspice\spice2poly.cm
|
|||
copy .\spinit_all %dst%\share\ngspice\scripts\spinit
|
||||
copy .\spinitd .\spinit
|
||||
|
||||
|
||||
|
||||
if "%2" == "fftw" goto copy2
|
||||
if "%3" == "fftw" goto copy2
|
||||
|
||||
|
|
@ -40,10 +42,9 @@ goto end
|
|||
set dst=c:\Spice64d
|
||||
set cmsrc=.\codemodels\x64\Debug
|
||||
|
||||
mkdir %dst%\bin
|
||||
mkdir %dst%\lib\ngspice
|
||||
mkdir %dst%\share\ngspice\scripts
|
||||
|
||||
if not exist "%dst%\bin\" mkdir "%dst%\bin"
|
||||
if not exist "%dst%\lib\ngspice\" mkdir "%dst%\lib\ngspice"
|
||||
if not exist "%dst%\share\ngspice\scripts\" mkdir "%dst%\share\ngspice\scripts"
|
||||
copy "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\x64\Microsoft.VC140.OPENMP\vcomp140.dll" %dst%\bin\
|
||||
copy %cmsrc%\analog64.cm %dst%\lib\ngspice\analog.cm
|
||||
copy %cmsrc%\digital64.cm %dst%\lib\ngspice\digital.cm
|
||||
|
|
@ -54,6 +55,18 @@ copy %cmsrc%\spice2poly64.cm %dst%\lib\ngspice\spice2poly.cm
|
|||
copy .\spinit_all %dst%\share\ngspice\scripts\spinit
|
||||
copy .\spinitd64 .\spinit
|
||||
|
||||
REM ADDED TO ALLOW USE OF CODE MODELS OF THE CURRENT SOLUTION
|
||||
set ngspice_home=%1
|
||||
echo Adding code models to the directory of the ngspice program
|
||||
copy %cmsrc%\analog64.cm %ngspice_home%\analog64.cm
|
||||
copy %cmsrc%\digital64.cm %ngspice_home%\digital64.cm
|
||||
copy %cmsrc%\table64.cm %ngspice_home%\table64.cm
|
||||
copy %cmsrc%\xtraevt64.cm %ngspice_home%\xtraevt64.cm
|
||||
copy %cmsrc%\xtradev64.cm %ngspice_home%\xtradev64.cm
|
||||
copy %cmsrc%\spice2poly64.cm %ngspice_home%\spice2poly64.cm
|
||||
copy spinit_dbg64_src %ngspice_home%\spinit
|
||||
REM END OF ADDED TO ALLOW USE OF CODE MODELS OF THE CURRENT SOLUTION
|
||||
|
||||
if "%2" == "fftw" goto copy2-64
|
||||
if "%3" == "fftw" goto copy2-64
|
||||
|
||||
|
|
|
|||
|
|
@ -33,27 +33,27 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseOMP|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseOMP|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
* Standard ngspice init file
|
||||
alias exit quit
|
||||
alias acct rusage all
|
||||
set x11lineararcs
|
||||
*set rndseed=12
|
||||
** ascii rawfile **
|
||||
set filetype=ascii
|
||||
** frontend debug output **
|
||||
*set ngdebug
|
||||
** asking after quit **
|
||||
*set askquit
|
||||
** set the number of threads in openmp
|
||||
** default (if compiled with --enable-openmp) is: 2
|
||||
set num_threads=4
|
||||
set interactive
|
||||
set stepsizelimit
|
||||
|
||||
strcmp __flag $program "ngspice"
|
||||
if $__flag = 0
|
||||
|
||||
* Load the codemodels
|
||||
codemodel spice2poly64.cm
|
||||
codemodel analog64.cm
|
||||
codemodel digital64.cm
|
||||
codemodel xtradev64.cm
|
||||
codemodel xtraevt64.cm
|
||||
codemodel table64.cm
|
||||
|
||||
|
||||
end
|
||||
unset __flag
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
* Standard ngspice init file
|
||||
alias exit quit
|
||||
alias acct rusage all
|
||||
set x11lineararcs
|
||||
*set rndseed=12
|
||||
** ascii rawfile **
|
||||
set filetype=ascii
|
||||
** frontend debug output **
|
||||
*set ngdebug
|
||||
** asking after quit **
|
||||
*set askquit
|
||||
** set the number of threads in openmp
|
||||
** default (if compiled with --enable-openmp) is: 2
|
||||
set num_threads=4
|
||||
set interactive
|
||||
set stepsizelimit
|
||||
|
||||
strcmp __flag $program "ngspice"
|
||||
if $__flag = 0
|
||||
|
||||
* Load the codemodels
|
||||
echo "Loading code models"
|
||||
codemodel spice2poly.cm
|
||||
codemodel analog.cm
|
||||
codemodel digital.cm
|
||||
codemodel xtradev.cm
|
||||
codemodel xtraevt.cm
|
||||
codemodel table.cm
|
||||
|
||||
|
||||
end
|
||||
unset __flag
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -22,30 +22,30 @@
|
|||
<ProjectName>analog</ProjectName>
|
||||
<ProjectGuid>{8271FEA2-8AC0-4B6D-BAEA-A503D37B5DB2}</ProjectGuid>
|
||||
<RootNamespace>icmanalog</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
|
|||
|
|
@ -1,24 +1,79 @@
|
|||
rem invoke as
|
||||
rem .\aux-cfunc.bat analog
|
||||
|
||||
REM sub is the parent directory of all of the code models and user types that
|
||||
REM are being built
|
||||
set sub=%1
|
||||
|
||||
set CMPP_IDIR=../../src/xspice/icm/%sub%
|
||||
set CMPP_ODIR=icm/%sub%
|
||||
if not exist icm\%sub% mkdir icm\%sub%
|
||||
.\bin\cmpp -lst
|
||||
|
||||
for /F %%n in (..\..\src\xspice\icm\%sub%\modpath.lst) do (
|
||||
set CMPP_IDIR=../../src/xspice/icm/%sub%/%%n
|
||||
set CMPP_ODIR=icm/%sub%/%%n
|
||||
if not exist icm\%sub%\%%n mkdir icm\%sub%\%%n
|
||||
.\bin\cmpp -ifs
|
||||
.\bin\cmpp -mod
|
||||
pushd icm\%sub%\%%n
|
||||
if exist %%n-cfunc.c del %%n-cfunc.c
|
||||
if exist %%n-ifspec.c del %%n-ifspec.c
|
||||
rename cfunc.c %%n-cfunc.c
|
||||
rename ifspec.c %%n-ifspec.c
|
||||
popd
|
||||
|
||||
REM Step 1: Process the .lst files for code models and nodes to create
|
||||
REM source files and related outputs
|
||||
echo Processing lst files for code model and user-defined nodes ^
|
||||
at src/xspice/icm/%sub%
|
||||
|
||||
echo CMPP_IDIR=../../src/xspice/icm/%sub%
|
||||
set CMPP_IDIR=../../src/xspice/icm/%sub%
|
||||
|
||||
echo CMPP_ODIR=icm/%sub%
|
||||
set CMPP_ODIR=icm/%sub%
|
||||
if not exist "icm\%sub%" mkdir "icm\%sub%"
|
||||
echo running cmpp.exe -lst
|
||||
bin\cmpp.exe -lst
|
||||
|
||||
|
||||
|
||||
REM Step 2: For each path in in modpath.lst prepare the directory for a build
|
||||
REM Test for any code models and process if found
|
||||
REM ERRORLEVEL = -1 if cannot read modpath.lst file; else = # paths found
|
||||
echo Processing paths in ..\..\src\xspice\icm\%sub%\modpath.lst
|
||||
set cmpp_cmd=bin\cmpp.exe -p "..\..\src\xspice\icm\%sub%\modpath.lst"
|
||||
%cmpp_cmd% > NUL
|
||||
if %ERRORLEVEL% LSS 0 goto ERROR_EXIT_CM
|
||||
if %ERRORLEVEL% EQU 0 goto UDN
|
||||
for /F "tokens=*" %%n in ('%cmpp_cmd%') do (
|
||||
echo CMPP_IDIR=../../src/xspice/icm/%sub%/%%n
|
||||
set CMPP_IDIR=../../src/xspice/icm/%sub%/%%n
|
||||
|
||||
echo CMPP_ODIR=icm/%sub%/%%n
|
||||
set CMPP_ODIR=icm/%sub%/%%n
|
||||
if not exist "icm\%sub%\%%n" mkdir "icm\%sub%\%%n"
|
||||
echo running cmpp.exe -ifs
|
||||
bin\cmpp.exe -ifs
|
||||
echo running cmpp.exe -mod
|
||||
bin\cmpp.exe -mod
|
||||
pushd "icm\%sub%\%%n"
|
||||
if exist "%%n-cfunc.c" del "%%n-cfunc.c"
|
||||
if exist "%%n-ifspec.c" del "%%n-ifspec.c"
|
||||
rename cfunc.c "%%n-cfunc.c"
|
||||
rename ifspec.c "%%n-ifspec.c"
|
||||
popd
|
||||
)
|
||||
|
||||
|
||||
:UDN
|
||||
REM Step 3: For each path in in udnpath.lst prepare the directory for a build
|
||||
REM Test for any user-defined types and process if found
|
||||
REM ERRORLEVEL = -1 if cannot read udnpath.lst file; else = # paths found
|
||||
echo Processing paths in ..\..\src\xspice\icm\%sub%\udnpath.lst
|
||||
set cmpp_cmd=bin\cmpp.exe -p "..\..\src\xspice\icm\%sub%\udnpath.lst"
|
||||
%cmpp_cmd% > NUL
|
||||
if %ERRORLEVEL% LSS 0 goto ERROR_EXIT_UDN
|
||||
if %ERRORLEVEL% EQU 0 goto EXIT
|
||||
for /F "tokens=*" %%n in ('%cmpp_cmd%') do (
|
||||
if not exist "icm\%sub%\%%n" mkdir "icm\%sub%\%%n"
|
||||
copy /Y "..\..\src\xspice\icm\%sub%\%%n\udnfunc.c" ^
|
||||
"icm\%sub%\%%n\%%n-udnfunc.c"
|
||||
)
|
||||
|
||||
:EXIT
|
||||
exit 0
|
||||
|
||||
:ERROR_EXIT_MOD
|
||||
echo "Unable to obtain paths for code models"
|
||||
exit -1
|
||||
|
||||
:ERROR_EXIT_UDN
|
||||
echo "Unable to obtain paths for user-defined types"
|
||||
exit -1
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
rem invoke as
|
||||
rem .\aux-udnfunc.bat xtraevt
|
||||
|
||||
set sub=%1
|
||||
|
||||
for /F %%n in (..\..\src\xspice\icm\%sub%\udnpath.lst) do (
|
||||
if not exist icm\%sub%\%%n mkdir icm\%sub%\%%n
|
||||
copy /Y ..\..\src\xspice\icm\%sub%\%%n\udnfunc.c icm\%sub%\%%n\%%n-udnfunc.c
|
||||
)
|
||||
REM
|
||||
REM set sub=%1
|
||||
REM
|
||||
REM for /F %%n in (..\..\src\xspice\icm\%sub%\udnpath.lst) do (
|
||||
REM echo Processing paths in ..\..\src\xspice\icm\%sub%\udnpath.lst
|
||||
REM for /F "tokens=*" %%n in ('bin\cmpp.exe ^
|
||||
REM -p "..\..\src\xspice\icm\%sub%\udnpath.lst"') do (
|
||||
REM if not exist "icm\%sub%\%%n" mkdir "icm\%sub%\%%n"
|
||||
REM copy /Y "..\..\src\xspice\icm\%sub%\%%n\udnfunc.c" ^
|
||||
REM "icm\%sub%\%%n\%%n-udnfunc.c"
|
||||
REM )
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@
|
|||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;YY_NO_UNISTD_H;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\xspice\cmpp</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\xspice\cmpp;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
|
@ -106,7 +106,7 @@
|
|||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\xspice\cmpp</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\xspice\cmpp;</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
|
@ -128,7 +128,7 @@
|
|||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\xspice\cmpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\xspice\cmpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
|
@ -145,7 +145,7 @@
|
|||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;YY_NO_UNISTD_H;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<AdditionalIncludeDirectories>..\..\..\src\xspice\cmpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\src\xspice\cmpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
|
@ -169,11 +169,13 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\src\xspice\cmpp\cmpp.h" />
|
||||
<ClInclude Include="..\..\..\src\xspice\cmpp\file_buffer.h" />
|
||||
<ClInclude Include="..\..\..\src\xspice\cmpp\ifs_yacc_y.h" />
|
||||
<ClInclude Include=".\tmp-bison\ifs_yacc.h" />
|
||||
<ClInclude Include=".\tmp-bison\mod_yacc.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\src\xspice\cmpp\file_buffer.c" />
|
||||
<ClCompile Include="..\..\..\src\xspice\cmpp\main.c" />
|
||||
<ClCompile Include="..\..\..\src\xspice\cmpp\pp_ifs.c" />
|
||||
<ClCompile Include="..\..\..\src\xspice\cmpp\pp_lst.c" />
|
||||
|
|
|
|||
|
|
@ -22,30 +22,30 @@
|
|||
<ProjectName>digital</ProjectName>
|
||||
<ProjectGuid>{9ABEC5F2-F6C6-41DE-88AB-02460A07F46E}</ProjectGuid>
|
||||
<RootNamespace>icmanalog</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
|
|||
|
|
@ -22,30 +22,30 @@
|
|||
<ProjectName>spice2poly</ProjectName>
|
||||
<ProjectGuid>{D701EA0E-B8B0-41D6-A90E-A0D8233F15FB}</ProjectGuid>
|
||||
<RootNamespace>icmanalog</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
|
|||
|
|
@ -22,30 +22,30 @@
|
|||
<ProjectName>table</ProjectName>
|
||||
<ProjectGuid>{7A6473F5-AFED-4910-88D2-6204DA829832}</ProjectGuid>
|
||||
<RootNamespace>icmanalog</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
|
|||
|
|
@ -22,30 +22,30 @@
|
|||
<ProjectName>xtradev</ProjectName>
|
||||
<ProjectGuid>{4BB60215-9A09-4192-9DB6-1A0CA823AFCA}</ProjectGuid>
|
||||
<RootNamespace>icmanalog</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
|
|||
|
|
@ -22,30 +22,30 @@
|
|||
<ProjectName>xtraevt</ProjectName>
|
||||
<ProjectGuid>{13500662-AF0B-4AB6-9AF9-BC3E07B5C1C6}</ProjectGuid>
|
||||
<RootNamespace>icmanalog</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
|
|
|||
Loading…
Reference in New Issue