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:
Jim Monte 2020-01-28 23:56:07 -05:00
commit da9bcc050f
100 changed files with 7547 additions and 4808 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 "

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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")) {

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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>

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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;
};

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -9,7 +9,6 @@
#include <stdarg.h>
#include <string.h>
#include "ngspice/config.h"
#include "ngspice/bool.h"

View File

@ -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) {

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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 ----------------------*/

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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
};

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 (&current_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

View File

@ -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;

View File

@ -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

View File

@ -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
{

View File

@ -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)

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

10
src/xspice/icm/dlmain.h Normal file
View File

@ -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 */

View File

@ -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
}

View File

@ -1 +1,2 @@
icm_spice2poly
#Directory Version
icm_spice2poly 1

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,2 +1,3 @@
table2D
table3D
#Directory version
table2D 2
table3D 2

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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.

View 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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -1,2 +1,3 @@
int
real
#Directory Version
int 1
real 1

View File

@ -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;
}

View File

@ -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 */
)

View File

@ -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);

View File

@ -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

View File

@ -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">

31
visualc/spinit_dbg64_src Normal file
View File

@ -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

32
visualc/spinit_dbg_src Normal file
View File

@ -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

View File

@ -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">

View File

@ -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

View File

@ -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 )

View File

@ -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" />

View File

@ -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">

View File

@ -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">

View File

@ -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">

View File

@ -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">

View File

@ -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">