From 4dff827763f7872c963ac99cac9842e0e7447de6 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 4 Mar 2020 14:46:35 +0100 Subject: [PATCH 01/20] prevent crash if premature exit (without ckt) --- src/frontend/runcoms2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/runcoms2.c b/src/frontend/runcoms2.c index cb42e38ab..7f2d10826 100644 --- a/src/frontend/runcoms2.c +++ b/src/frontend/runcoms2.c @@ -243,7 +243,8 @@ com_remcirc(wordlist *wl) #if defined(XSPICE) && defined(SIMULATOR) /* remove event queues, if XSPICE and not nutmeg */ - EVTunsetup(ft_curckt->ci_ckt); + if (ft_curckt->ci_ckt) + EVTunsetup(ft_curckt->ci_ckt); #endif if_cktfree(ft_curckt->ci_ckt, ft_curckt->ci_symtab); From 3012f096237bdb65f7c7b02bc59cbc834bff89fa Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 4 Mar 2020 14:47:31 +0100 Subject: [PATCH 02/20] remove false bracket in EXT_ASC --- src/frontend/wdisp/windisp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 9ed9df0df..98845d978 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -161,7 +161,7 @@ int WIN_Init(void) TheWndClass.cbClsExtra = 0; TheWndClass.cbWndExtra = sizeof(GRAPH *); - if (!RegisterClass(&TheWndClass)) { + if (!RegisterClass(&TheWndClass)) return 1; #else @@ -179,7 +179,8 @@ int WIN_Init(void) TheWndClassW.hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(2)); TheWndClassW.cbClsExtra = 0; TheWndClassW.cbWndExtra = sizeof(GRAPH *); - if (!RegisterClassW(&TheWndClassW)) return 1; + if (!RegisterClassW(&TheWndClassW)) + return 1; #endif IsRegistered = 1; } From bc3fe34781620b34c8db95b9266c04a6c92951d9 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 4 Mar 2020 22:44:20 +0100 Subject: [PATCH 03/20] work around a bug in MINGW Reported in https://github.com/msys2/MINGW-packages/issues/6254 --- src/misc/string.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/misc/string.c b/src/misc/string.c index 7aaf87c03..2b9cf1c29 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -106,6 +106,23 @@ char *tvprintf(const char *fmt, va_list args) * usage, but both return negative values (possibly -1) on an * encoding error, which would lead to an infinte loop (until * memory was exhausted) with the old behavior */ + +#ifdef __MINGW32__ + /* mingw still shows the 'old behavior' */ + if (nchars == -1) { // compatibility to old implementations + size *= 2; + } + else if (size < nchars + 1) { + size = nchars + 1; + } + else { + break; + } + /* limit memory usage */ + if (size > 100000) { + controlled_exit(-1); + } +#else if (nchars < 0) { controlled_exit(-1); } @@ -118,7 +135,7 @@ char *tvprintf(const char *fmt, va_list args) * that would have been written if the buffer were large enough * excluding the terminiating null. */ size = nchars + 1; /* min required allocation size */ - +#endif /* Allocate a larger buffer */ if (p == buf) { p = TMALLOC(char, size); From ac8eab8e8cf981494ea994a4da8b61a8c24ed710 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 4 Mar 2020 22:45:30 +0100 Subject: [PATCH 04/20] make code compile with MINGW (preliminary) --- src/winmain.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index cbacdd7d4..849fecdd4 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -12,6 +12,10 @@ #ifdef HAS_WINGUI +#ifndef _WIN32 +#define _WIN32 +#endif + #define STRICT // strict type checking #define WIN32_LEAN_AND_MEAN #include // standard Windows calls @@ -27,7 +31,10 @@ #include #include #include - +#ifndef _MSC_VER +#include +#include +#endif #include "hist_info.h" /* history management */ #include "ngspice/bool.h" /* bool defined as unsigned char */ @@ -107,6 +114,7 @@ static LPCWSTR hwElementClassNameW = L"ElementClass"; static LPCWSTR hwSourceWindowNameW = L"SourceDisplay"; static LPCWSTR hwAnalyseWindowNameW = L"AnalyseDisplay"; #endif + static size_t TBufEnd = 0; /* Pointer to \0 */ static char TBuffer[TBufSize + 1]; /* Text buffer */ static SBufLine SBuffer; /* Input buffer */ @@ -624,7 +632,7 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) /* for utf-8 the number of characters is not the number of bytes returned */ GetWindowTextW(hwnd, WBuffer, sizeof SBuffer - (sizeof CRLF - 1)); WideCharToMultiByte(CP_UTF8, 0, WBuffer, - -1, SBuffer, sizeof SBuffer - 1, NULL, NULL); + -1, SBuffer, sizeof SBuffer - 1, NULL, FALSE); /* retrive here the number of bytes returned */ const int n_char_returned = (int)strlen(SBuffer); tfree(WBuffer); @@ -961,12 +969,14 @@ MakeArgcArgv(char *cmdline, int *argc, char ***argv) #ifdef EXT_ASC int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) -#elif __MINGW32__ /* MINGW bug not knowing wWinMain */ -int WINAPI -WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR nolpszCmdLine, _In_ int nCmdShow) #else +#ifdef _MSC_VER int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR wlpszCmdLine, _In_ int nCmdShow) +#else +int WINAPI // MINGW bug not knowing wWinMain +WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR nolpszCmdLine, _In_ int nCmdShow) +#endif #endif { int ix, iy; /* width and height of screen */ @@ -988,11 +998,13 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR #ifndef EXT_ASC /* convert wchar to utf-8 */ - +#ifdef _MSC_VER + char lpszCmdLine[1024]; + WideCharToMultiByte(CP_UTF8, 0, wlpszCmdLine, -1, lpszCmdLine, 1023, NULL, FALSE); +#else /* MINGW not knowing wWinMain https://github.com/coderforlife/mingw-unicode-main/blob/master/mingw-unicode-gui.c */ -#ifdef __MINGW32__ NG_IGNORE(nolpszCmdLine); char lpszCmdLine[1024]; wchar_t *lpCmdLine = GetCommandLineW(); @@ -1013,9 +1025,6 @@ wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR } } WideCharToMultiByte(CP_UTF8, 0, lpCmdLine, -1, lpszCmdLine, 1023, NULL, NULL); -#else - char lpszCmdLine[1024]; - WideCharToMultiByte(CP_UTF8, 0, wlpszCmdLine, -1, lpszCmdLine, 1023, NULL, NULL); #endif #endif /* fill global variables */ From 506098b10c0acb1897aa5b6078cee5c055bdf667 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 4 Mar 2020 22:46:19 +0100 Subject: [PATCH 05/20] compile oinstruction for MINGW UNICODE is not yet working, only extended ASCII --- compile_min.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/compile_min.sh b/compile_min.sh index fdf26a6e2..35d1436ba 100755 --- a/compile_min.sh +++ b/compile_min.sh @@ -25,6 +25,8 @@ # Add (optionally) --enable-relpath to avoid absolute paths when searching for code models. # It might be necessary to uncomment and run ./autogen.sh . +SECONDS=0 + if test "$1" = "32"; then if [ ! -d "release32" ]; then mkdir release32 @@ -38,8 +40,8 @@ else fi # If compiling sources from git, you may need to uncomment the following two lines: -#./autogen.sh -#if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi +./autogen.sh +if [ $? -ne 0 ]; then echo "./autogen.sh failed"; exit 1 ; fi # Alternatively, if compiling sources from git, and want to add adms created devices, # you may need to uncomment the following two lines (and don't forget to add adms option @@ -54,14 +56,14 @@ if test "$1" = "32"; then 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" + ../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --disable-debug --disable-utf8 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" + ../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --disable-debug --disable-utf8 prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi @@ -82,5 +84,8 @@ make install 2>&1 | tee make_install.log exitcode=${PIPESTATUS[0]} if [ $exitcode -ne 0 ]; then echo "make install failed"; exit 1 ; fi +ELAPSED="Elapsed compile time: $(($SECONDS / 3600))hrs $((($SECONDS / 60) % 60))min $(($SECONDS % 60))sec" +echo +echo $ELAPSED echo "success" exit 0 From b1116283c80c8288af11092b83536eda02e83729 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 4 Mar 2020 22:51:59 +0100 Subject: [PATCH 06/20] remove outdated function GlobalMemoryStatus(&ms) --- src/frontend/com_sysinfo.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/frontend/com_sysinfo.c b/src/frontend/com_sysinfo.c index c66358a73..424cdd64c 100644 --- a/src/frontend/com_sysinfo.c +++ b/src/frontend/com_sysinfo.c @@ -13,8 +13,6 @@ #include "com_commands.h" #ifdef _WIN32 -//#define WIN32_LEAN_AND_MEAN - #undef BOOLEAN #include #include @@ -403,7 +401,6 @@ static void set_static_system_info(void) /* Get memory information */ static int get_sysmem(struct sys_memory *memall) { -#if (_WIN32_WINNT >= 0x0500) /* Windows 2000+ */ MEMORYSTATUSEX ms; ms.dwLength = sizeof(MEMORYSTATUSEX); if (GlobalMemoryStatusEx(&ms) == FALSE) { @@ -413,17 +410,6 @@ static int get_sysmem(struct sys_memory *memall) memall->free_m = ms.ullAvailPhys; memall->swap_t = ms.ullTotalPageFile; memall->swap_f = ms.ullAvailPageFile; -#else - MEMORYSTATUS ms; - ms.dwLength = sizeof(MEMORYSTATUS); - if (GlobalMemoryStatus(&ms) == FALSE) { - return -1; - } - memall->size_m = ms.dwTotalPhys; - memall->free_m = ms.dwAvailPhys; - memall->swap_t = ms.dwTotalPageFile; - memall->swap_f = ms.dwAvailPageFile; -#endif return 0; } /* end of function get_sysmem */ From 7bee475de17e96064d26b3cfa9927c29c829c919 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Thu, 5 Mar 2020 13:15:52 +0100 Subject: [PATCH 07/20] Instantiations of string and dstring functions as inline This will remove the redundant-decls warning --- src/misc/dstring.c | 28 ++++++++++++++-------------- src/misc/string.c | 10 +++++----- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/misc/dstring.c b/src/misc/dstring.c index 51df2f55a..a02de3078 100644 --- a/src/misc/dstring.c +++ b/src/misc/dstring.c @@ -15,17 +15,17 @@ DESCRIPTION:This file contains the routines for manipulating dynamic strings. static int ds_reserve_internal(DSTRING *p_ds, size_t n_byte_alloc_opt, size_t n_byte_alloc_min); -/* Instantiations of dstring functions in case inlining is not performed */ -int ds_cat_str(DSTRING *p_ds, const char *sz); -int ds_cat_char(DSTRING *p_ds, char c); -int ds_cat_ds(DSTRING *p_ds_dst, const DSTRING *p_ds_src); -int ds_cat_mem(DSTRING *p_ds, const char *p_src, size_t n_char); -int ds_set_length(DSTRING *p_ds, size_t length); -void ds_clear(DSTRING *p_ds); -char *ds_free_move(DSTRING *p_ds, unsigned int opt); -char *ds_get_buf(DSTRING *p_ds); -size_t ds_get_length(const DSTRING *p_ds); -size_t ds_get_buf_size(const DSTRING *p_ds); +/* Instantiations of dstring functions */ +extern inline int ds_cat_str(DSTRING *p_ds, const char *sz); +extern inline int ds_cat_char(DSTRING *p_ds, char c); +extern inline int ds_cat_ds(DSTRING *p_ds_dst, const DSTRING *p_ds_src); +extern inline int ds_cat_mem(DSTRING *p_ds, const char *p_src, size_t n_char); +extern inline int ds_set_length(DSTRING *p_ds, size_t length); +extern inline void ds_clear(DSTRING *p_ds); +extern inline char *ds_free_move(DSTRING *p_ds, unsigned int opt); +extern inline char *ds_get_buf(DSTRING *p_ds); +extern inline size_t ds_get_length(const DSTRING *p_ds); +extern inline size_t ds_get_buf_size(const DSTRING *p_ds); /* This function initalizes a dstring using *p_buf as the initial backing @@ -85,7 +85,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 */ @@ -229,7 +229,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 */ @@ -333,7 +333,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; diff --git a/src/misc/string.c b/src/misc/string.c index 2b9cf1c29..a3d1dfe12 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -14,11 +14,11 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include "ngspice/dstring.h" -/* Instantiations of string functions in case inlining is not performed */ -char *copy(const char *str); -char *copy_substring(const char *str, const char *end); -int scannum(const char *str); -int substring(const char *sub, const char *str); +/* Instantiations of string functions */ +extern inline char *copy(const char *str); +extern inline char *copy_substring(const char *str, const char *end); +extern inline int scannum(const char *str); +extern inline int substring(const char *sub, const char *str); From 1a407f9b67b59f276e7613a46042f8fc1129a305 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Thu, 5 Mar 2020 22:51:29 +0100 Subject: [PATCH 08/20] set the proper preprocessor flag __MINGW32__ --- src/frontend/plotting/gnuplot.c | 2 +- src/include/ngspice/ngspice.h | 2 +- src/misc/util.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index 96a77fd5d..ea5b372e8 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -161,7 +161,7 @@ void ft_gnuplot(double *xlims, double *ylims, } /* Set up the file header. */ -#if !defined(__MINGW__) && !defined(_MSC_VER) && !defined(__CYGWIN__) +#if !defined(__MINGW32__) && !defined(_MSC_VER) && !defined(__CYGWIN__) fprintf(file, "set terminal X11 noenhanced\n"); #elif defined(__CYGWIN__) #ifndef EXT_ASC diff --git a/src/include/ngspice/ngspice.h b/src/include/ngspice/ngspice.h index 8b3293176..0b4f6e710 100644 --- a/src/include/ngspice/ngspice.h +++ b/src/include/ngspice/ngspice.h @@ -219,7 +219,7 @@ extern double x_atanh(double); #endif #ifndef EXT_ASC -#if defined(__MINGW__) || defined(_MSC_VER) +#if defined(__MINGW32__) || defined(_MSC_VER) #define fopen newfopen extern FILE *newfopen(const char *fn, const char* md); #endif diff --git a/src/misc/util.c b/src/misc/util.c index 132560903..d438337ff 100644 --- a/src/misc/util.c +++ b/src/misc/util.c @@ -260,7 +260,7 @@ ngdirname(const char *name) /* Replacement for fopen, when using wide chars (utf-16) */ #ifndef EXT_ASC -#if defined(__MINGW__) || defined(_MSC_VER) +#if defined(__MINGW32__) || defined(_MSC_VER) #undef BOOLEAN #include FILE * From 2b905607c3a232d1bf21e76b0aa8c5bb51d7d676 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Mar 2020 14:51:39 +0100 Subject: [PATCH 09/20] make flag 'nolegend' localfor each plot --- src/frontend/plotting/graf.c | 7 +++++-- src/include/ngspice/graph.h | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 6c427daeb..683f720b0 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -134,6 +134,8 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ graph->ticdata = NULL; } + cp_getvar("nolegend", CP_BOOL, &(graph->nolegend), 0); + if (!xlims || !ylims) { internalerror("gr_init: no range specified"); return FALSE; @@ -184,6 +186,7 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ strcpy(graph->ticchar, pgraph->ticchar); graph->ticdata = pgraph->ticdata; graph->ticmarks = pgraph->ticmarks; + graph->nolegend = pgraph->nolegend; } /* layout decisions */ @@ -434,7 +437,7 @@ static void gr_start_internal(struct dvec *dv, bool copyvec) } /* Put the legend entry on the screen. */ - if (!cp_getvar("nolegend", CP_BOOL, NULL, 0)) + if (!currentgraph->nolegend) drawlegend(currentgraph, cur.plotno++, dv); } @@ -610,7 +613,7 @@ void gr_redraw(GRAPH *graph) cur.plotno = 0; for (link = graph->plotdata; link; link = link->next) { /* redraw legend */ - if (!cp_getvar("nolegend", CP_BOOL, NULL, 0)) + if (!graph->nolegend) drawlegend(graph, cur.plotno++, link->vector); /* replot data diff --git a/src/include/ngspice/graph.h b/src/include/ngspice/graph.h index e7b64d615..22dbeb9d8 100644 --- a/src/include/ngspice/graph.h +++ b/src/include/ngspice/graph.h @@ -33,6 +33,8 @@ struct graph { int currentcolor; int linestyle; + bool nolegend; + struct { int height, width; } viewport; From 196f629d8c5716cc11b61008601bb73800714589 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Mar 2020 14:53:27 +0100 Subject: [PATCH 10/20] enable compiling wide char with MINGW --- compile_min.sh | 4 ++-- src/Makefile.am | 1 + src/winmain.c | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/compile_min.sh b/compile_min.sh index 35d1436ba..622ed7287 100755 --- a/compile_min.sh +++ b/compile_min.sh @@ -56,14 +56,14 @@ if test "$1" = "32"; then 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 --disable-utf8 prefix="C:/Spice" CFLAGS="-m32 -O2" LDFLAGS="-m32 -s" + ../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 --disable-utf8 prefix="C:/Spice64" CFLAGS="-m64 -O2" LDFLAGS="-m64 -s" + ../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 diff --git a/src/Makefile.am b/src/Makefile.am index 17a07420a..60649913a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -111,6 +111,7 @@ ngspice_SOURCES = \ ngspice_CPPFLAGS = $(AM_CPPFLAGS) -DSIMULATOR if WINGUI +ngspice_LDFLAGS = -municode $(AM_LDFLAGS) ngspice_SOURCES += winmain.c hist_info.c endif diff --git a/src/winmain.c b/src/winmain.c index 849fecdd4..cd5e3cf08 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -31,8 +31,8 @@ #include #include #include -#ifndef _MSC_VER -#include +#ifdef __MINGW32__ +#include #include #endif @@ -970,7 +970,7 @@ MakeArgcArgv(char *cmdline, int *argc, char ***argv) int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) #else -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(__MINGW32__) int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR wlpszCmdLine, _In_ int nCmdShow) #else @@ -998,7 +998,7 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR n #ifndef EXT_ASC /* convert wchar to utf-8 */ -#ifdef _MSC_VER +#if defined(_MSC_VER) || defined(__MINGW32__) char lpszCmdLine[1024]; WideCharToMultiByte(CP_UTF8, 0, wlpszCmdLine, -1, lpszCmdLine, 1023, NULL, FALSE); #else From fdcfa929b5f4066eed79fe5b8e96a890edf72e6b Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Mar 2020 14:55:32 +0100 Subject: [PATCH 11/20] clean up winmain.c --- src/winmain.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index cd5e3cf08..761d5ab96 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -970,13 +970,8 @@ MakeArgcArgv(char *cmdline, int *argc, char ***argv) int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) #else -#if defined(_MSC_VER) || defined(__MINGW32__) int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR wlpszCmdLine, _In_ int nCmdShow) -#else -int WINAPI // MINGW bug not knowing wWinMain -WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR nolpszCmdLine, _In_ int nCmdShow) -#endif #endif { int ix, iy; /* width and height of screen */ @@ -998,34 +993,8 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR n #ifndef EXT_ASC /* convert wchar to utf-8 */ -#if defined(_MSC_VER) || defined(__MINGW32__) char lpszCmdLine[1024]; WideCharToMultiByte(CP_UTF8, 0, wlpszCmdLine, -1, lpszCmdLine, 1023, NULL, FALSE); -#else - /* MINGW not knowing wWinMain - https://github.com/coderforlife/mingw-unicode-main/blob/master/mingw-unicode-gui.c - */ - NG_IGNORE(nolpszCmdLine); - char lpszCmdLine[1024]; - wchar_t *lpCmdLine = GetCommandLineW(); - if (__argc == 1) { // avoids GetCommandLineW bug that does not always quote the program name if no arguments - do { ++lpCmdLine; } while (*lpCmdLine); - } - else { - BOOL quoted = lpCmdLine[0] == L'"'; - ++lpCmdLine; // skips the " or the first letter (all paths are at least 1 letter) - while (*lpCmdLine) { - if (quoted && lpCmdLine[0] == L'"') { quoted = FALSE; } // found end quote - else if (!quoted && lpCmdLine[0] == L' ') { - // found an unquoted space, now skip all spaces - do { ++lpCmdLine; } while (lpCmdLine[0] == L' '); - break; - } - ++lpCmdLine; - } - } - WideCharToMultiByte(CP_UTF8, 0, lpCmdLine, -1, lpszCmdLine, 1023, NULL, NULL); -#endif #endif /* fill global variables */ hInst = hInstance; From 6750628c72074b13a543742792a025c7cafe6c45 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Mar 2020 14:59:02 +0100 Subject: [PATCH 12/20] enable true gmin stepping The old behavior, stepping diagmin, is re-obtained by adding flag set 'dyngmin' to .spiceinit or spinit This flag may also be set within a .control section (e.g. to compare results) --- src/spicelib/analysis/cktop.c | 205 +++++++++++++++++++++++++++++++++- 1 file changed, 200 insertions(+), 5 deletions(-) diff --git a/src/spicelib/analysis/cktop.c b/src/spicelib/analysis/cktop.c index 3f72162cf..b866b4336 100644 --- a/src/spicelib/analysis/cktop.c +++ b/src/spicelib/analysis/cktop.c @@ -9,6 +9,7 @@ Modified: 2005 Paolo Nenzi - Restructured #include "ngspice/cktdefs.h" #include "ngspice/devdefs.h" #include "ngspice/sperror.h" +#include "ngspice/cpextern.h" #ifdef XSPICE #include "ngspice/enh.h" @@ -17,6 +18,7 @@ Modified: 2005 Paolo Nenzi - Restructured static int dynamic_gmin(CKTcircuit *, long int, long int, int); static int spice3_gmin(CKTcircuit *, long int, long int, int); +static int new_gmin(CKTcircuit*, long int, long int, int); static int gillespie_src(CKTcircuit *, long int, long int, int); static int spice3_src(CKTcircuit *, long int, long int, int); @@ -51,10 +53,17 @@ CKTop (CKTcircuit *ckt, long int firstmode, long int continuemode, /* first, check if we should try gmin stepping */ if (ckt->CKTnumGminSteps >= 1) { - if (ckt->CKTnumGminSteps == 1) - converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim); - else + if (ckt->CKTnumGminSteps == 1) { + if (cp_getvar("dyngmin", CP_BOOL, NULL, 0)) { + converged = dynamic_gmin(ckt, firstmode, continuemode, iterlim); + } + else { + converged = new_gmin(ckt, firstmode, continuemode, iterlim); + } + } + else { converged = spice3_gmin(ckt, firstmode, continuemode, iterlim); + } if (converged == 0) /* If gmin-stepping worked... move out */ return converged; } @@ -304,6 +313,185 @@ spice3_gmin (CKTcircuit *ckt, long int firstmode, return converged; } +/* just step the real gmin found in every device model */ +static int +new_gmin(CKTcircuit* ckt, long int firstmode, + long int continuemode, int iterlim) +{ + double OldGmin, gtarget, factor, startgmin; + int converged; + + int NumNodes, iters, i; + double* OldRhsOld, * OldCKTstate0; + CKTnode* n; + + ckt->CKTmode = firstmode; + SPfrontEnd->IFerrorf(ERR_INFO, "Starting true gmin stepping"); + + NumNodes = 0; + for (n = ckt->CKTnodes; n; n = n->next) + NumNodes++; + + OldRhsOld = TMALLOC(double, NumNodes + 1); + OldCKTstate0 = TMALLOC(double, ckt->CKTnumStates + 1); + + for (n = ckt->CKTnodes; n; n = n->next) + ckt->CKTrhsOld[n->number] = 0; + + for (i = 0; i < ckt->CKTnumStates; i++) + ckt->CKTstate0[i] = 0; + + startgmin = ckt->CKTgmin; + factor = ckt->CKTgminFactor; + OldGmin = 1e-2; + /*ckt->CKTdiagGmin = */ckt->CKTgmin = OldGmin / factor; + gtarget = MAX(startgmin, ckt->CKTgshunt); + + for (;;) { + fprintf(stderr, "Trying gmin = %12.4E ", ckt->CKTgmin); + + ckt->CKTnoncon = 1; + iters = ckt->CKTstat->STATnumIter; + converged = NIiter(ckt, ckt->CKTdcTrcvMaxIter); + iters = ckt->CKTstat->STATnumIter - iters; + + if (converged == 0) { + ckt->CKTmode = continuemode; + SPfrontEnd->IFerrorf(ERR_INFO, "One successful gmin step"); + + if (ckt->CKTgmin <= gtarget) + break; /* successfull */ + + for (i = 0, n = ckt->CKTnodes; n; n = n->next) + OldRhsOld[i++] = ckt->CKTrhsOld[n->number]; + + memcpy(OldCKTstate0, ckt->CKTstate0, + (size_t)ckt->CKTnumStates * sizeof(double)); + + if (iters <= (ckt->CKTdcTrcvMaxIter / 4)) { + factor *= sqrt(factor); + if (factor > ckt->CKTgminFactor) + factor = ckt->CKTgminFactor; + } + + if (iters > (3 * ckt->CKTdcTrcvMaxIter / 4)) + factor = MAX(sqrt(factor), 1.00005); + + OldGmin = ckt->CKTgmin; + + if (ckt->CKTgmin < factor * gtarget) { + factor = ckt->CKTgmin / gtarget; + /*ckt->CKTdiagGmin = */ckt->CKTgmin = gtarget; + } + else { + /*ckt->CKTdiagGmin = */ckt->CKTgmin /= factor; + } + } + else { + if (factor < 1.00005) { + SPfrontEnd->IFerrorf(ERR_WARNING, "Last gmin step failed"); + break; /* failed */ + } + SPfrontEnd->IFerrorf(ERR_WARNING, "Further gmin increment"); + factor = sqrt(sqrt(factor)); + /*ckt->CKTdiagGmin = */ckt->CKTgmin = OldGmin / factor; + + for (i = 0, n = ckt->CKTnodes; n; n = n->next) + ckt->CKTrhsOld[n->number] = OldRhsOld[i++]; + + memcpy(ckt->CKTstate0, OldCKTstate0, + (size_t)ckt->CKTnumStates * sizeof(double)); + } + } + + /*ckt->CKTdiagGmin = */ckt->CKTgmin = MAX(startgmin, ckt->CKTgshunt); + FREE(OldRhsOld); + FREE(OldCKTstate0); + +#ifdef XSPICE + /* gtri - wbk - add convergence problem reporting flags */ + ckt->enh->conv_debug.last_NIiter_call = (ckt->CKTnumSrcSteps <= 0); +#endif + + converged = NIiter(ckt, iterlim); + + if (converged != 0) { + SPfrontEnd->IFerrorf(ERR_WARNING, "True gmin stepping failed"); + } + else { + SPfrontEnd->IFerrorf(ERR_INFO, "True gmin stepping completed"); +#ifdef XSPICE + /* gtri - wbk - add convergence problem reporting flags */ + ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; +#endif + } + + return converged; +} + + + + + +static int +no_new_gmin(CKTcircuit* ckt, long int firstmode, + long int continuemode, int iterlim) +{ + int converged, i; + + ckt->CKTmode = firstmode; + SPfrontEnd->IFerrorf(ERR_INFO, "Starting new gmin stepping"); + + ckt->CKTgmin = 0.01; +// (ckt->CKTgshunt == 0) ? ckt->CKTgmin : ckt->CKTgshunt; + + for (i = 0; i < ckt->CKTnumGminSteps; i++) + ckt->CKTgmin *= ckt->CKTgminFactor; + + for (i = 0; i <= ckt->CKTnumGminSteps; i++) { + fprintf(stderr, "Trying gmin = %12.4E ", ckt->CKTgmin); + + ckt->CKTnoncon = 1; + converged = NIiter(ckt, ckt->CKTdcTrcvMaxIter); + + if (converged != 0) { + ckt->CKTgmin = ckt->CKTgshunt; + SPfrontEnd->IFerrorf(ERR_WARNING, "gmin step failed"); + break; + } + + ckt->CKTgmin /= ckt->CKTgminFactor; + ckt->CKTmode = continuemode; + + SPfrontEnd->IFerrorf(ERR_INFO, "One successful gmin step"); + } + + ckt->CKTgmin = ckt->CKTgshunt; + +#ifdef XSPICE + /* gtri - wbk - add convergence problem reporting flags */ + ckt->enh->conv_debug.last_NIiter_call = (ckt->CKTnumSrcSteps <= 0); +#endif + + converged = NIiter(ckt, iterlim); + + if (converged == 0) { + SPfrontEnd->IFerrorf(ERR_INFO, "gmin stepping completed"); + +#ifdef XSPICE + /* gtri - wbk - add convergence problem reporting flags */ + ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; +#endif + + } + else { + SPfrontEnd->IFerrorf(ERR_WARNING, "gmin stepping failed"); + } + + return converged; +} + + /* Gillespie's Source stepping * Modified 2005 - Paolo Nenzi (extracted from CKTop.c code) @@ -323,6 +511,7 @@ gillespie_src (CKTcircuit *ckt, long int firstmode, int converged, i, iters; double ConvFact; CKTnode *n; + double gminstart = ckt->CKTgmin; NG_IGNORE(iterlim); @@ -442,7 +631,13 @@ gillespie_src (CKTcircuit *ckt, long int firstmode, * raise = 0.01; */ - } else { + } +/* else if (ckt->CKTgmin < 1e-3){ + ckt->CKTdiagGmin = ckt->CKTgmin *= 10; + fprintf(stderr, + "gmin raised to %8.4e\n", ckt->CKTgmin); + }*/ + else { if (ckt->CKTsrcFact - ConvFact < 1e-8) break; @@ -459,7 +654,6 @@ gillespie_src (CKTcircuit *ckt, long int firstmode, memcpy(ckt->CKTstate0, OldCKTstate0, (size_t) ckt->CKTnumStates * sizeof(double)); - } if (ckt->CKTsrcFact > 1) @@ -467,6 +661,7 @@ gillespie_src (CKTcircuit *ckt, long int firstmode, } while ((raise >= 1e-7) && (ConvFact < 1)); + ckt->CKTdiagGmin = ckt->CKTgmin = gminstart; FREE (OldRhsOld); FREE (OldCKTstate0); } From 48b00980ef02d36952179afa3d9744ede86cce14 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Mar 2020 20:41:26 +0100 Subject: [PATCH 13/20] Add compile flag -D__USE_MINGW_ANSI_STDIO=1 to enable C99 compatibility (e.g. for vsnprintf() ) --- compile_min.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compile_min.sh b/compile_min.sh index 622ed7287..bc43041e7 100755 --- a/compile_min.sh +++ b/compile_min.sh @@ -56,14 +56,14 @@ if test "$1" = "32"; then 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" + ../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --disable-debug prefix="C:/Spice" CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 -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" + ../configure --with-wingui --enable-xspice --enable-cider --enable-openmp --disable-debug prefix="C:/Spice64" CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 -m64 -O2" LDFLAGS="-m64 -s" fi if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi From b6aeaf914ba30c962cfd478f9cc39246de25a370 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Mar 2020 20:43:18 +0100 Subject: [PATCH 14/20] Replace swprintf by MultiByteToWideChar to correctly translate from utf-8 to wchar_t --- src/winmain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/winmain.c b/src/winmain.c index 761d5ab96..97779a73d 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -273,8 +273,8 @@ SetAnalyse(char *Analyse, /* in: analysis type */ #else wchar_t sw[256]; wchar_t tw[256]; - swprintf(sw, 256, L"%S", s); - swprintf(tw, 256, L"%S", t); + MultiByteToWideChar(CP_UTF8, 0, s, -1, sw, 256); + MultiByteToWideChar(CP_UTF8, 0, t, -1, tw, 256); /* Analysis window */ SetWindowTextW(hwAnalyse, sw); /* ngspice task bar */ From 698f62fc8f12a8ddb8968269e1549b06afada41e Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Mar 2020 20:49:00 +0100 Subject: [PATCH 15/20] compatibility to old vsnprintf() in MINGW is no longer needed. Compiling with -D__USE_MINGW_ANSI_STDIO=1 enables C99 compatibility. --- src/misc/string.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/misc/string.c b/src/misc/string.c index a3d1dfe12..b498308f2 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -107,22 +107,6 @@ char *tvprintf(const char *fmt, va_list args) * encoding error, which would lead to an infinte loop (until * memory was exhausted) with the old behavior */ -#ifdef __MINGW32__ - /* mingw still shows the 'old behavior' */ - if (nchars == -1) { // compatibility to old implementations - size *= 2; - } - else if (size < nchars + 1) { - size = nchars + 1; - } - else { - break; - } - /* limit memory usage */ - if (size > 100000) { - controlled_exit(-1); - } -#else if (nchars < 0) { controlled_exit(-1); } @@ -135,7 +119,7 @@ char *tvprintf(const char *fmt, va_list args) * that would have been written if the buffer were large enough * excluding the terminiating null. */ size = nchars + 1; /* min required allocation size */ -#endif + /* Allocate a larger buffer */ if (p == buf) { p = TMALLOC(char, size); From a129f863ca9cf9911417b4f2c392862be00f70d5 Mon Sep 17 00:00:00 2001 From: dwarning Date: Sat, 7 Mar 2020 14:22:20 +0100 Subject: [PATCH 16/20] omit wanted fallthrough warnings with gcc --- src/spicelib/devices/bjt/bjtparam.c | 1 + src/spicelib/devices/bsim1/b1par.c | 2 ++ src/spicelib/devices/bsim2/b2par.c | 2 ++ src/spicelib/devices/bsim3/b3par.c | 2 ++ src/spicelib/devices/bsim3soi_dd/b3soiddpar.c | 4 ++++ src/spicelib/devices/bsim3soi_fd/b3soifdpar.c | 4 ++++ src/spicelib/devices/bsim3soi_pd/b3soipdpar.c | 4 ++++ src/spicelib/devices/bsim3v0/b3v0par.c | 2 ++ src/spicelib/devices/bsim3v1/b3v1par.c | 2 ++ src/spicelib/devices/bsim3v32/b3v32par.c | 2 ++ src/spicelib/devices/bsim4/b4par.c | 2 ++ src/spicelib/devices/bsim4v5/b4v5par.c | 2 ++ src/spicelib/devices/bsim4v6/b4v6par.c | 2 ++ src/spicelib/devices/bsim4v7/b4v7par.c | 2 ++ src/spicelib/devices/hfet1/hfetparam.c | 1 + src/spicelib/devices/hfet2/hfet2param.c | 1 + src/spicelib/devices/hisim2/hsm2par.c | 2 ++ src/spicelib/devices/hisimhv1/hsmhvpar.c | 2 ++ src/spicelib/devices/hisimhv2/hsmhv2par.c | 2 ++ src/spicelib/devices/isrc/isrcpar.c | 2 ++ src/spicelib/devices/jfet/jfetpar.c | 1 + src/spicelib/devices/jfet2/jfet2par.c | 1 + src/spicelib/devices/ltra/ltrapar.c | 3 +++ src/spicelib/devices/mes/mesparam.c | 1 + src/spicelib/devices/mesa/mesaparam.c | 1 + src/spicelib/devices/mos1/mos1par.c | 2 ++ src/spicelib/devices/mos2/mos2par.c | 2 ++ src/spicelib/devices/mos3/mos3par.c | 2 ++ src/spicelib/devices/mos6/mos6par.c | 2 ++ src/spicelib/devices/mos9/mos9par.c | 2 ++ src/spicelib/devices/soi3/soi3par.c | 3 +++ src/spicelib/devices/tra/traparam.c | 3 +++ src/spicelib/devices/vbic/vbicparam.c | 1 + src/spicelib/devices/vdmos/vdmospar.c | 1 + src/spicelib/devices/vsrc/vsrcpar.c | 2 ++ 35 files changed, 70 insertions(+) diff --git a/src/spicelib/devices/bjt/bjtparam.c b/src/spicelib/devices/bjt/bjtparam.c index 1187dab06..6649c96e1 100644 --- a/src/spicelib/devices/bjt/bjtparam.c +++ b/src/spicelib/devices/bjt/bjtparam.c @@ -70,6 +70,7 @@ BJTparam(int param, IFvalue *value, GENinstance *instPtr, IFvalue *select) case 2: here->BJTicVCE = *(value->v.vec.rVec+1); here->BJTicVCEGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BJTicVBE = *(value->v.vec.rVec); here->BJTicVBEGiven = TRUE; diff --git a/src/spicelib/devices/bsim1/b1par.c b/src/spicelib/devices/bsim1/b1par.c index e097b73e3..7b6887d93 100644 --- a/src/spicelib/devices/bsim1/b1par.c +++ b/src/spicelib/devices/bsim1/b1par.c @@ -78,9 +78,11 @@ B1param(int param, IFvalue *value, GENinstance *inst, case 3: here->B1icVBS = *(value->v.vec.rVec+2); here->B1icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->B1icVGS = *(value->v.vec.rVec+1); here->B1icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->B1icVDS = *(value->v.vec.rVec); here->B1icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim2/b2par.c b/src/spicelib/devices/bsim2/b2par.c index 29e7ed06d..974b51041 100644 --- a/src/spicelib/devices/bsim2/b2par.c +++ b/src/spicelib/devices/bsim2/b2par.c @@ -77,9 +77,11 @@ B2param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 3: here->B2icVBS = *(value->v.vec.rVec+2); here->B2icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->B2icVGS = *(value->v.vec.rVec+1); here->B2icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->B2icVDS = *(value->v.vec.rVec); here->B2icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim3/b3par.c b/src/spicelib/devices/bsim3/b3par.c index 35aae2535..74599ea1e 100644 --- a/src/spicelib/devices/bsim3/b3par.c +++ b/src/spicelib/devices/bsim3/b3par.c @@ -108,9 +108,11 @@ IFvalue *select) case 3: here->BSIM3icVBS = *(value->v.vec.rVec+2); here->BSIM3icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->BSIM3icVGS = *(value->v.vec.rVec+1); here->BSIM3icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BSIM3icVDS = *(value->v.vec.rVec); here->BSIM3icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c b/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c index 5749df170..fb2ad5702 100644 --- a/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c @@ -108,15 +108,19 @@ B3SOIDDparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 5: here->B3SOIDDicVPS = *(value->v.vec.rVec+4); here->B3SOIDDicVPSGiven = TRUE; + /* FALLTHROUGH */ case 4: here->B3SOIDDicVES = *(value->v.vec.rVec+3); here->B3SOIDDicVESGiven = TRUE; + /* FALLTHROUGH */ case 3: here->B3SOIDDicVBS = *(value->v.vec.rVec+2); here->B3SOIDDicVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->B3SOIDDicVGS = *(value->v.vec.rVec+1); here->B3SOIDDicVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->B3SOIDDicVDS = *(value->v.vec.rVec); here->B3SOIDDicVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdpar.c b/src/spicelib/devices/bsim3soi_fd/b3soifdpar.c index a1351b946..6fbe77f0c 100644 --- a/src/spicelib/devices/bsim3soi_fd/b3soifdpar.c +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdpar.c @@ -109,15 +109,19 @@ B3SOIFDparam(int param, IFvalue *value, GENinstance *inst, case 5: here->B3SOIFDicVPS = *(value->v.vec.rVec+4); here->B3SOIFDicVPSGiven = TRUE; + /* FALLTHROUGH */ case 4: here->B3SOIFDicVES = *(value->v.vec.rVec+3); here->B3SOIFDicVESGiven = TRUE; + /* FALLTHROUGH */ case 3: here->B3SOIFDicVBS = *(value->v.vec.rVec+2); here->B3SOIFDicVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->B3SOIFDicVGS = *(value->v.vec.rVec+1); here->B3SOIFDicVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->B3SOIFDicVDS = *(value->v.vec.rVec); here->B3SOIFDicVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdpar.c b/src/spicelib/devices/bsim3soi_pd/b3soipdpar.c index 84cdc6df5..dafba04cb 100644 --- a/src/spicelib/devices/bsim3soi_pd/b3soipdpar.c +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdpar.c @@ -152,15 +152,19 @@ B3SOIPDparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 5: here->B3SOIPDicVPS = *(value->v.vec.rVec+4); here->B3SOIPDicVPSGiven = TRUE; + /* FALLTHROUGH */ case 4: here->B3SOIPDicVES = *(value->v.vec.rVec+3); here->B3SOIPDicVESGiven = TRUE; + /* FALLTHROUGH */ case 3: here->B3SOIPDicVBS = *(value->v.vec.rVec+2); here->B3SOIPDicVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->B3SOIPDicVGS = *(value->v.vec.rVec+1); here->B3SOIPDicVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->B3SOIPDicVDS = *(value->v.vec.rVec); here->B3SOIPDicVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim3v0/b3v0par.c b/src/spicelib/devices/bsim3v0/b3v0par.c index 8fe314af7..6e86fcc97 100644 --- a/src/spicelib/devices/bsim3v0/b3v0par.c +++ b/src/spicelib/devices/bsim3v0/b3v0par.c @@ -84,9 +84,11 @@ BSIM3v0param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 3: here->BSIM3v0icVBS = *(value->v.vec.rVec+2); here->BSIM3v0icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->BSIM3v0icVGS = *(value->v.vec.rVec+1); here->BSIM3v0icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BSIM3v0icVDS = *(value->v.vec.rVec); here->BSIM3v0icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim3v1/b3v1par.c b/src/spicelib/devices/bsim3v1/b3v1par.c index 2c58743ef..440744015 100644 --- a/src/spicelib/devices/bsim3v1/b3v1par.c +++ b/src/spicelib/devices/bsim3v1/b3v1par.c @@ -90,9 +90,11 @@ BSIM3v1param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 3: here->BSIM3v1icVBS = *(value->v.vec.rVec+2); here->BSIM3v1icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->BSIM3v1icVGS = *(value->v.vec.rVec+1); here->BSIM3v1icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BSIM3v1icVDS = *(value->v.vec.rVec); here->BSIM3v1icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim3v32/b3v32par.c b/src/spicelib/devices/bsim3v32/b3v32par.c index 83f1b4a61..485ab3642 100644 --- a/src/spicelib/devices/bsim3v32/b3v32par.c +++ b/src/spicelib/devices/bsim3v32/b3v32par.c @@ -101,9 +101,11 @@ BSIM3v32param (int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 3: here->BSIM3v32icVBS = *(value->v.vec.rVec+2); here->BSIM3v32icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->BSIM3v32icVGS = *(value->v.vec.rVec+1); here->BSIM3v32icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BSIM3v32icVDS = *(value->v.vec.rVec); here->BSIM3v32icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim4/b4par.c b/src/spicelib/devices/bsim4/b4par.c index 702e81c7b..fa5654b4a 100644 --- a/src/spicelib/devices/bsim4/b4par.c +++ b/src/spicelib/devices/bsim4/b4par.c @@ -234,9 +234,11 @@ IFvalue *select) { case 3: here->BSIM4icVBS = *(value->v.vec.rVec+2); here->BSIM4icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->BSIM4icVGS = *(value->v.vec.rVec+1); here->BSIM4icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BSIM4icVDS = *(value->v.vec.rVec); here->BSIM4icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim4v5/b4v5par.c b/src/spicelib/devices/bsim4v5/b4v5par.c index a75f7217e..2a49a0ad8 100644 --- a/src/spicelib/devices/bsim4v5/b4v5par.c +++ b/src/spicelib/devices/bsim4v5/b4v5par.c @@ -184,9 +184,11 @@ IFvalue *select) { case 3: here->BSIM4v5icVBS = *(value->v.vec.rVec+2); here->BSIM4v5icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->BSIM4v5icVGS = *(value->v.vec.rVec+1); here->BSIM4v5icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BSIM4v5icVDS = *(value->v.vec.rVec); here->BSIM4v5icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim4v6/b4v6par.c b/src/spicelib/devices/bsim4v6/b4v6par.c index a3ff5023d..2debab48c 100644 --- a/src/spicelib/devices/bsim4v6/b4v6par.c +++ b/src/spicelib/devices/bsim4v6/b4v6par.c @@ -186,9 +186,11 @@ IFvalue *select) { case 3: here->BSIM4v6icVBS = *(value->v.vec.rVec+2); here->BSIM4v6icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->BSIM4v6icVGS = *(value->v.vec.rVec+1); here->BSIM4v6icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BSIM4v6icVDS = *(value->v.vec.rVec); here->BSIM4v6icVDSGiven = TRUE; diff --git a/src/spicelib/devices/bsim4v7/b4v7par.c b/src/spicelib/devices/bsim4v7/b4v7par.c index f152f8df6..776d494bc 100644 --- a/src/spicelib/devices/bsim4v7/b4v7par.c +++ b/src/spicelib/devices/bsim4v7/b4v7par.c @@ -190,9 +190,11 @@ IFvalue *select) { case 3: here->BSIM4v7icVBS = *(value->v.vec.rVec+2); here->BSIM4v7icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->BSIM4v7icVGS = *(value->v.vec.rVec+1); here->BSIM4v7icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->BSIM4v7icVDS = *(value->v.vec.rVec); here->BSIM4v7icVDSGiven = TRUE; diff --git a/src/spicelib/devices/hfet1/hfetparam.c b/src/spicelib/devices/hfet1/hfetparam.c index 766fba189..0641a32ee 100644 --- a/src/spicelib/devices/hfet1/hfetparam.c +++ b/src/spicelib/devices/hfet1/hfetparam.c @@ -47,6 +47,7 @@ HFETAparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->HFETAicVGS = *(value->v.vec.rVec+1); here->HFETAicVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->HFETAicVDS = *(value->v.vec.rVec); here->HFETAicVDSGiven = TRUE; diff --git a/src/spicelib/devices/hfet2/hfet2param.c b/src/spicelib/devices/hfet2/hfet2param.c index b43eb0738..4d4e34169 100644 --- a/src/spicelib/devices/hfet2/hfet2param.c +++ b/src/spicelib/devices/hfet2/hfet2param.c @@ -38,6 +38,7 @@ int HFET2param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->HFET2icVGS = *(value->v.vec.rVec+1); here->HFET2icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->HFET2icVDS = *(value->v.vec.rVec); here->HFET2icVDSGiven = TRUE; diff --git a/src/spicelib/devices/hisim2/hsm2par.c b/src/spicelib/devices/hisim2/hsm2par.c index 6e84d115d..feee32092 100644 --- a/src/spicelib/devices/hisim2/hsm2par.c +++ b/src/spicelib/devices/hisim2/hsm2par.c @@ -137,9 +137,11 @@ int HSM2param( case 3: here->HSM2_icVBS = *(value->v.vec.rVec + 2); here->HSM2_icVBS_Given = TRUE; + /* FALLTHROUGH */ case 2: here->HSM2_icVGS = *(value->v.vec.rVec + 1); here->HSM2_icVGS_Given = TRUE; + /* FALLTHROUGH */ case 1: here->HSM2_icVDS = *(value->v.vec.rVec); here->HSM2_icVDS_Given = TRUE; diff --git a/src/spicelib/devices/hisimhv1/hsmhvpar.c b/src/spicelib/devices/hisimhv1/hsmhvpar.c index 3ace52ccc..35dd1d3b7 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvpar.c +++ b/src/spicelib/devices/hisimhv1/hsmhvpar.c @@ -102,9 +102,11 @@ int HSMHVparam( case 3: here->HSMHV_icVBS = *(value->v.vec.rVec + 2); here->HSMHV_icVBS_Given = TRUE; + /* FALLTHROUGH */ case 2: here->HSMHV_icVGS = *(value->v.vec.rVec + 1); here->HSMHV_icVGS_Given = TRUE; + /* FALLTHROUGH */ case 1: here->HSMHV_icVDS = *(value->v.vec.rVec); here->HSMHV_icVDS_Given = TRUE; diff --git a/src/spicelib/devices/hisimhv2/hsmhv2par.c b/src/spicelib/devices/hisimhv2/hsmhv2par.c index be803e1e5..eb608d0ed 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2par.c +++ b/src/spicelib/devices/hisimhv2/hsmhv2par.c @@ -144,9 +144,11 @@ int HSMHV2param( case 3: here->HSMHV2_icVBS = *(value->v.vec.rVec + 2); here->HSMHV2_icVBS_Given = TRUE; + /* FALLTHROUGH */ case 2: here->HSMHV2_icVGS = *(value->v.vec.rVec + 1); here->HSMHV2_icVGS_Given = TRUE; + /* FALLTHROUGH */ case 1: here->HSMHV2_icVDS = *(value->v.vec.rVec); here->HSMHV2_icVDS_Given = TRUE; diff --git a/src/spicelib/devices/isrc/isrcpar.c b/src/spicelib/devices/isrc/isrcpar.c index cecf2e199..a80c08e23 100644 --- a/src/spicelib/devices/isrc/isrcpar.c +++ b/src/spicelib/devices/isrc/isrcpar.c @@ -67,9 +67,11 @@ ISRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->ISRCacPhase = *(value->v.vec.rVec+1); here->ISRCacPGiven = TRUE; + /* FALLTHROUGH */ case 1: here->ISRCacMag = *(value->v.vec.rVec); here->ISRCacMGiven = TRUE; + /* FALLTHROUGH */ case 0: here->ISRCacGiven = TRUE; break; diff --git a/src/spicelib/devices/jfet/jfetpar.c b/src/spicelib/devices/jfet/jfetpar.c index a45d5cc61..eefb0021e 100644 --- a/src/spicelib/devices/jfet/jfetpar.c +++ b/src/spicelib/devices/jfet/jfetpar.c @@ -54,6 +54,7 @@ JFETparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->JFETicVGS = *(value->v.vec.rVec+1); here->JFETicVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->JFETicVDS = *(value->v.vec.rVec); here->JFETicVDSGiven = TRUE; diff --git a/src/spicelib/devices/jfet2/jfet2par.c b/src/spicelib/devices/jfet2/jfet2par.c index 84acdfe07..e6191083a 100644 --- a/src/spicelib/devices/jfet2/jfet2par.c +++ b/src/spicelib/devices/jfet2/jfet2par.c @@ -58,6 +58,7 @@ JFET2param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->JFET2icVGS = *(value->v.vec.rVec+1); here->JFET2icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->JFET2icVDS = *(value->v.vec.rVec); here->JFET2icVDSGiven = TRUE; diff --git a/src/spicelib/devices/ltra/ltrapar.c b/src/spicelib/devices/ltra/ltrapar.c index fea03737f..9cfeb5d52 100644 --- a/src/spicelib/devices/ltra/ltrapar.c +++ b/src/spicelib/devices/ltra/ltrapar.c @@ -39,10 +39,13 @@ LTRAparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) switch (value->v.numValue) { case 4: here->LTRAinitCur2 = *(value->v.vec.rVec + 3); + /* FALLTHROUGH */ case 3: here->LTRAinitVolt2 = *(value->v.vec.rVec + 2); + /* FALLTHROUGH */ case 2: here->LTRAinitCur1 = *(value->v.vec.rVec + 1); + /* FALLTHROUGH */ case 1: here->LTRAinitVolt1 = *(value->v.vec.rVec); break; diff --git a/src/spicelib/devices/mes/mesparam.c b/src/spicelib/devices/mes/mesparam.c index ce635757a..009e7a47a 100644 --- a/src/spicelib/devices/mes/mesparam.c +++ b/src/spicelib/devices/mes/mesparam.c @@ -45,6 +45,7 @@ MESparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->MESicVGS = *(value->v.vec.rVec+1); here->MESicVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->MESicVDS = *(value->v.vec.rVec); here->MESicVDSGiven = TRUE; diff --git a/src/spicelib/devices/mesa/mesaparam.c b/src/spicelib/devices/mesa/mesaparam.c index 5399eef71..9fd593310 100644 --- a/src/spicelib/devices/mesa/mesaparam.c +++ b/src/spicelib/devices/mesa/mesaparam.c @@ -49,6 +49,7 @@ MESAparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->MESAicVGS = *(value->v.vec.rVec+1); here->MESAicVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->MESAicVDS = *(value->v.vec.rVec); here->MESAicVDSGiven = TRUE; diff --git a/src/spicelib/devices/mos1/mos1par.c b/src/spicelib/devices/mos1/mos1par.c index 3ae4681fd..70c479560 100644 --- a/src/spicelib/devices/mos1/mos1par.c +++ b/src/spicelib/devices/mos1/mos1par.c @@ -93,9 +93,11 @@ MOS1param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 3: here->MOS1icVBS = *(value->v.vec.rVec+2); here->MOS1icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->MOS1icVGS = *(value->v.vec.rVec+1); here->MOS1icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->MOS1icVDS = *(value->v.vec.rVec); here->MOS1icVDSGiven = TRUE; diff --git a/src/spicelib/devices/mos2/mos2par.c b/src/spicelib/devices/mos2/mos2par.c index a818f7602..c7d594eb2 100644 --- a/src/spicelib/devices/mos2/mos2par.c +++ b/src/spicelib/devices/mos2/mos2par.c @@ -94,9 +94,11 @@ MOS2param(int param, IFvalue *value, GENinstance *inst, case 3: here->MOS2icVBS = *(value->v.vec.rVec+2); here->MOS2icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->MOS2icVGS = *(value->v.vec.rVec+1); here->MOS2icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->MOS2icVDS = *(value->v.vec.rVec); here->MOS2icVDSGiven = TRUE; diff --git a/src/spicelib/devices/mos3/mos3par.c b/src/spicelib/devices/mos3/mos3par.c index dea7b2421..20fed040d 100644 --- a/src/spicelib/devices/mos3/mos3par.c +++ b/src/spicelib/devices/mos3/mos3par.c @@ -94,9 +94,11 @@ MOS3param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 3: here->MOS3icVBS = *(value->v.vec.rVec+2); here->MOS3icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->MOS3icVGS = *(value->v.vec.rVec+1); here->MOS3icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->MOS3icVDS = *(value->v.vec.rVec); here->MOS3icVDSGiven = TRUE; diff --git a/src/spicelib/devices/mos6/mos6par.c b/src/spicelib/devices/mos6/mos6par.c index a3f526f99..22a56351e 100644 --- a/src/spicelib/devices/mos6/mos6par.c +++ b/src/spicelib/devices/mos6/mos6par.c @@ -86,9 +86,11 @@ MOS6param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 3: here->MOS6icVBS = *(value->v.vec.rVec+2); here->MOS6icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->MOS6icVGS = *(value->v.vec.rVec+1); here->MOS6icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->MOS6icVDS = *(value->v.vec.rVec); here->MOS6icVDSGiven = TRUE; diff --git a/src/spicelib/devices/mos9/mos9par.c b/src/spicelib/devices/mos9/mos9par.c index c8f3c9fdb..3deb06626 100644 --- a/src/spicelib/devices/mos9/mos9par.c +++ b/src/spicelib/devices/mos9/mos9par.c @@ -89,9 +89,11 @@ MOS9param(int param, IFvalue *value, GENinstance *inst, case 3: here->MOS9icVBS = *(value->v.vec.rVec+2); here->MOS9icVBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->MOS9icVGS = *(value->v.vec.rVec+1); here->MOS9icVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->MOS9icVDS = *(value->v.vec.rVec); here->MOS9icVDSGiven = TRUE; diff --git a/src/spicelib/devices/soi3/soi3par.c b/src/spicelib/devices/soi3/soi3par.c index e621c891d..5b087c8bd 100644 --- a/src/spicelib/devices/soi3/soi3par.c +++ b/src/spicelib/devices/soi3/soi3par.c @@ -137,12 +137,15 @@ SOI3param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 4: here->SOI3icVBS = *(value->v.vec.rVec+3); here->SOI3icVBSGiven = TRUE; + /* FALLTHROUGH */ case 3: here->SOI3icVGBS = *(value->v.vec.rVec+2); here->SOI3icVGBSGiven = TRUE; + /* FALLTHROUGH */ case 2: here->SOI3icVGFS = *(value->v.vec.rVec+1); here->SOI3icVGFSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->SOI3icVDS = *(value->v.vec.rVec); here->SOI3icVDSGiven = TRUE; diff --git a/src/spicelib/devices/tra/traparam.c b/src/spicelib/devices/tra/traparam.c index 21606607e..88fe0bec8 100644 --- a/src/spicelib/devices/tra/traparam.c +++ b/src/spicelib/devices/tra/traparam.c @@ -65,10 +65,13 @@ TRAparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) switch(value->v.numValue){ case 4: here->TRAinitCur2 = *(value->v.vec.rVec+3); + /* FALLTHROUGH */ case 3: here->TRAinitVolt2 = *(value->v.vec.rVec+2); + /* FALLTHROUGH */ case 2: here->TRAinitCur1 = *(value->v.vec.rVec+1); + /* FALLTHROUGH */ case 1: here->TRAinitVolt1 = *(value->v.vec.rVec); break; diff --git a/src/spicelib/devices/vbic/vbicparam.c b/src/spicelib/devices/vbic/vbicparam.c index 34e14bbc3..20523c92d 100644 --- a/src/spicelib/devices/vbic/vbicparam.c +++ b/src/spicelib/devices/vbic/vbicparam.c @@ -59,6 +59,7 @@ VBICparam(int param, IFvalue *value, GENinstance *instPtr, IFvalue *select) case 2: here->VBICicVCE = *(value->v.vec.rVec+1); here->VBICicVCEGiven = TRUE; + /* FALLTHROUGH */ case 1: here->VBICicVBE = *(value->v.vec.rVec); here->VBICicVBEGiven = TRUE; diff --git a/src/spicelib/devices/vdmos/vdmospar.c b/src/spicelib/devices/vdmos/vdmospar.c index fef9de1bf..5b6fb1554 100644 --- a/src/spicelib/devices/vdmos/vdmospar.c +++ b/src/spicelib/devices/vdmos/vdmospar.c @@ -70,6 +70,7 @@ VDMOSparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->VDMOSicVGS = *(value->v.vec.rVec+1); here->VDMOSicVGSGiven = TRUE; + /* FALLTHROUGH */ case 1: here->VDMOSicVDS = *(value->v.vec.rVec); here->VDMOSicVDSGiven = TRUE; diff --git a/src/spicelib/devices/vsrc/vsrcpar.c b/src/spicelib/devices/vsrc/vsrcpar.c index c14e39f8d..e30c45925 100644 --- a/src/spicelib/devices/vsrc/vsrcpar.c +++ b/src/spicelib/devices/vsrc/vsrcpar.c @@ -62,9 +62,11 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case 2: here->VSRCacPhase = *(value->v.vec.rVec+1); here->VSRCacPGiven = TRUE; + /* FALLTHROUGH */ case 1: here->VSRCacMag = *(value->v.vec.rVec); here->VSRCacMGiven = TRUE; + /* FALLTHROUGH */ case 0: here->VSRCacGiven = TRUE; break; From 13d8a7f515a78d12ae3ac7fbc3879b1363fa37d9 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Mar 2020 19:46:54 +0100 Subject: [PATCH 17/20] correct the return values --- src/misc/string.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/misc/string.c b/src/misc/string.c index b498308f2..afbcd80c9 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -755,8 +755,8 @@ gettok_node(char **s) /*-------------------------------------------------------------------------* * get_l_paren iterates the pointer forward in a string until it hits * the position after the next left paren "(". It returns 0 if it found a left - * paren, and 1 if no left paren is found. It is called from 'translate' - * (subckt.c). + * paren, 1 if no left paren is found, -1 if left paren is the last character. + * It is called from 'translate' (subckt.c). *-------------------------------------------------------------------------*/ int @@ -770,15 +770,18 @@ get_l_paren(char **s) (*s)++; - return **s == '\0'; + if (**s == '\0') + return -1; + + return 0; } /*-------------------------------------------------------------------------* * get_r_paren iterates the pointer forward in a string until it hits * the position after the next right paren ")". It returns 0 if it found a right - * paren, and 1 if no right paren is found. It is called from 'translate' - * (subckt.c). + * paren, 1 if no right paren is found, and -1 if right paren is te last + * character. It is called from 'translate' (subckt.c). *-------------------------------------------------------------------------*/ int @@ -792,7 +795,10 @@ get_r_paren(char **s) (*s)++; - return **s == '\0'; + if (**s == '\0') + return -1; + + return 0; } /*-------------------------------------------------------------------------* From 88e6ec2f709e476cb26ddbfdf73ea280f565864f Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Mar 2020 19:49:36 +0100 Subject: [PATCH 18/20] Add afuction to transform i(vxx) to vxx#branch in .control sections. This is to avoid memory leaks (see bug 478). A better fix may be probably available by adapting parse-bison.y. --- src/frontend/inpcom.c | 58 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 31b5a4f6e..4b2a992d9 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -180,6 +180,7 @@ static struct card *pspice_compat(struct card *newcard); static void pspice_compat_a(struct card *oldcard); static struct card *ltspice_compat(struct card *oldcard); static void ltspice_compat_a(struct card *oldcard); +static void inp_rep_ixx(struct card *deck); #if defined(__MINGW32__) || defined(_MSC_VER) #ifndef EXT_ASC @@ -705,6 +706,8 @@ struct card *inp_readall(FILE *fp, const char *dir_name, inp_bsource_compat(working); inp_dot_if(working); expr_w_temper = inp_temper_compat(working); + /* i(vxx) to vxx#branch within .control section */ + inp_rep_ixx(working); } if (expr_w_temper_p) *expr_w_temper_p = expr_w_temper; @@ -1735,6 +1738,61 @@ static void inp_chk_for_multi_in_vcvs(struct card *c, int *line_number) } } +/* replace i(vxx) by vxx#branch */ +static void inp_rep_ixx(struct card* deck) { + struct card* c; + int only_control = 0; + + for (c = deck; c; c = c->nextcard) { + + char* line, * beg; + line = beg = c->line; + + /* there is no e source inside .control ... .endc */ + if (ciprefix(".control", line)) { + only_control++; + continue; + } + else if (ciprefix(".endc", line)) { + only_control--; + continue; + } + else if (only_control <= 0) { + continue; + } + + char* new_str = NULL; + while (line) { + char* s = strstr(line, " i(v"); + if (s) { + char* beg_str, *end_str, *t; + /* replace i(vxx) by vxx#branch */ + if (get_r_paren(&line) == 1) { + fprintf(stderr, "Error: missing ')' in line\n %s\n", c->line); + break; + } + /* token containing name of voltage source to be measured */ + t = copy_substring(s + 3, line - 1); + /* change line, convert i(XXX) to XXX#branch */ + beg_str = copy_substring(beg, s); + end_str = copy(line); + tfree(new_str); + new_str = tprintf("%s %s%s %s", beg_str, t, "#branch", end_str); + beg = line = new_str; + tfree(beg_str); + tfree(end_str); + tfree(t); + } + else { + break; + } + } + if (new_str) { + tfree(c->line); + c->line = new_str; + } + } +} /* If ngspice is started with option -a, then variable 'autorun' * will be set and the following function scans the deck. From 4c4424444412b469d9748b522623c23390e67e6e Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Mar 2020 19:51:17 +0100 Subject: [PATCH 19/20] Imrove an error message: End-of-line delimiter $ is not allowed when PSPICE compatibility is set. $ is a standard character in PSPICE. --- src/spicelib/parser/inpdpar.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/spicelib/parser/inpdpar.c b/src/spicelib/parser/inpdpar.c index a7ae4f59c..5aea6509f 100644 --- a/src/spicelib/parser/inpdpar.c +++ b/src/spicelib/parser/inpdpar.c @@ -68,7 +68,12 @@ INPdevParse(char **line, CKTcircuit *ckt, int dev, GENinstance *fast, IFparm *p = find_instance_parameter(parameter, device); if (!p) { - errbuf = tprintf(" unknown parameter (%s) \n", parameter); + if (cieq(parameter, "$")) { + errbuf = copy(" unknown parameter ($). Check the compatibility flag!\n"); + } + else { + errbuf = tprintf(" unknown parameter (%s) \n", parameter); + } rtn = errbuf; goto quit; } @@ -112,7 +117,12 @@ INPdevParse(char **line, CKTcircuit *ckt, int dev, GENinstance *fast, IFparm *p = find_instance_parameter(parm, device); if (!p) { - errbuf = tprintf(" unknown parameter (%s) \n", parm); + if (eq(parm, "$")) { + errbuf = copy(" unknown parameter ($). Check the compatibility flag!\n"); + } + else { + errbuf = tprintf(" unknown parameter (%s) \n", parm); + } rtn = errbuf; goto quit; } From 55c4f161349ac40267ae8546b2711c043a4351f3 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 7 Mar 2020 23:31:47 +0100 Subject: [PATCH 20/20] re-write inp_rep_ixx(), catch all known cases, paranoia examples are o.k. --- src/frontend/inpcom.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 4b2a992d9..dc99badc1 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -1762,22 +1762,26 @@ static void inp_rep_ixx(struct card* deck) { } char* new_str = NULL; + bool strsave = FALSE; while (line) { - char* s = strstr(line, " i(v"); - if (s) { + char* s = strstr(line, "i(v"); + if (s && (s > line) && (isspace_c(s[-1]) || is_arith_char(s[-1]) + || isquote(s[-1]) || (s[-1] == '=') || (s[-1] == '.'))) { char* beg_str, *end_str, *t; + line = s; /* replace i(vxx) by vxx#branch */ if (get_r_paren(&line) == 1) { fprintf(stderr, "Error: missing ')' in line\n %s\n", c->line); break; } /* token containing name of voltage source to be measured */ - t = copy_substring(s + 3, line - 1); + t = copy_substring(s + 2, line - 1); /* change line, convert i(XXX) to XXX#branch */ beg_str = copy_substring(beg, s); end_str = copy(line); tfree(new_str); - new_str = tprintf("%s %s%s %s", beg_str, t, "#branch", end_str); + new_str = tprintf("%s%s%s%s", beg_str, t, "#branch", end_str); + strsave = TRUE; beg = line = new_str; tfree(beg_str); tfree(end_str); @@ -1787,9 +1791,10 @@ static void inp_rep_ixx(struct card* deck) { break; } } - if (new_str) { + if (strsave) { tfree(c->line); c->line = new_str; + strsave = FALSE; } } }