diff --git a/visualc/ng_shared_xspice_v/examples/adder_mos.cir b/visualc/ng_shared_xspice_v/examples/adder_mos.cir
new file mode 100644
index 000000000..5e1b9b02a
--- /dev/null
+++ b/visualc/ng_shared_xspice_v/examples/adder_mos.cir
@@ -0,0 +1,66 @@
+ ADDER - 4 BIT ALL-NAND-GATE BINARY ADDER
+
+*** SUBCIRCUIT DEFINITIONS
+.SUBCKT NAND in1 in2 out VDD
+* NODES: INPUT(2), OUTPUT, VCC
+M1 out in2 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p
+M2 net.1 in2 0 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p
+M3 out in1 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p
+M4 out in1 net.1 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p
+.ENDS NAND
+
+.SUBCKT ONEBIT 1 2 3 4 5 6
+* NODES: INPUT(2), CARRY-IN, OUTPUT, CARRY-OUT, VCC
+X1 1 2 7 6 NAND
+X2 1 7 8 6 NAND
+X3 2 7 9 6 NAND
+X4 8 9 10 6 NAND
+X5 3 10 11 6 NAND
+X6 3 11 12 6 NAND
+X7 10 11 13 6 NAND
+X8 12 13 4 6 NAND
+X9 11 7 5 6 NAND
+.ENDS ONEBIT
+
+.SUBCKT TWOBIT 1 2 3 4 5 6 7 8 9
+* NODES: INPUT - BIT0(2) / BIT1(2), OUTPUT - BIT0 / BIT1,
+* CARRY-IN, CARRY-OUT, VCC
+X1 1 2 7 5 10 9 ONEBIT
+X2 3 4 10 6 8 9 ONEBIT
+.ENDS TWOBIT
+
+.SUBCKT FOURBIT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+* NODES: INPUT - BIT0(2) / BIT1(2) / BIT2(2) / BIT3(2),
+* OUTPUT - BIT0 / BIT1 / BIT2 / BIT3, CARRY-IN, CARRY-OUT, VCC
+X1 1 2 3 4 9 10 13 16 15 TWOBIT
+X2 5 6 7 8 11 12 16 14 15 TWOBIT
+.ENDS FOURBIT
+
+*** POWER
+VCC 99 0 DC 3.3V
+
+*** ALL INPUTS
+VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS)
+VIN1B 2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS)
+VIN2A 3 0 DC 0 PULSE(0 3 0 5NS 5NS 50NS 200NS)
+VIN2B 4 0 DC 0 PULSE(0 3 0 5NS 5NS 90NS 400NS)
+VIN3A 5 0 DC 0 PULSE(0 3 0 5NS 5NS 170NS 800NS)
+VIN3B 6 0 DC 0 PULSE(0 3 0 5NS 5NS 330NS 1600NS)
+VIN4A 7 0 DC 0 PULSE(0 3 0 5NS 5NS 650NS 3200NS)
+VIN4B 8 0 DC 0 PULSE(0 3 0 5NS 5NS 1290NS 6400NS)
+
+*** DEFINE NOMINAL CIRCUIT
+X1 1 2 3 4 5 6 7 8 9 10 11 12 0 13 99 FOURBIT
+
+.option noinit acct
+.TRAN 500p 6400NS
+* save inputs
+.save V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8)
+
+* use BSIM3 model with default parameters
+.model n1 nmos level=49 version=3.3.0
+.model p1 pmos level=49 version=3.3.0
+*.include ./Modelcards/modelcard32.nmos
+*.include ./Modelcards/modelcard32.pmos
+
+.END
diff --git a/visualc/ng_shared_xspice_v/examples/count-latch-dac.cir b/visualc/ng_shared_xspice_v/examples/count-latch-dac.cir
new file mode 100644
index 000000000..7a8c7d90a
--- /dev/null
+++ b/visualc/ng_shared_xspice_v/examples/count-latch-dac.cir
@@ -0,0 +1,81 @@
+* counter, latch DAC
+
+* 10 bit synchronous digital counter
+* inhibit at overflow, no revolving
+.subckt count10 din dinb dclk drs dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10
+
+* j k clk set reset out nout
+ajk1 din dinb diclk ds1 drs dout1 dnout1 jkflop
+ajk2 dout1 dout1 diclk ds2 drs dout2 dnout2 jkflop
+ajk3 djk3 djk3 diclk ds3 drs dout3 dnout3 jkflop
+ajk4 djk4 djk4 diclk ds4 drs dout4 dnout4 jkflop
+ajk5 djk5 djk5 diclk ds1 drs dout5 dnout5 jkflop
+ajk6 djk6 djk6 diclk ds2 drs dout6 dnout6 jkflop
+ajk7 djk7 djk7 diclk ds3 drs dout7 dnout8 jkflop
+ajk8 djk8 djk8 diclk ds4 drs dout8 dnout8 jkflop
+ajk9 djk9 djk9 diclk ds3 drs dout9 dnout9 jkflop
+ajk10 djk10 djk10 diclk ds4 drs dout10 dnout10 jkflop
+
+aand1 [dout1 dout2] djk3 and1
+aand2 [dout1 dout2 dout3] djk4 and1
+aand3 [dout1 dout2 dout3 dout4] djk5 and1
+aand4 [dout1 dout2 dout3 dout4 dout5] djk6 and1
+aand5 [dout1 dout2 dout3 dout4 dout5 dout6] djk7 and1
+aand6 [dout1 dout2 dout3 dout4 dout5 dout6 dout7] djk8 and1
+aand7 [dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8] djk9 and1
+aand8 [dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9] djk10 and1
+
+* inhibit revolving of counter, just let it saturate
+* (footnote p. 57)
+aand_all [dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10] dinhibit nand1
+aandclk [dclk dinhibit] diclk and1
+
+
+.model nand1 d_nand(rise_delay = 1e-9 fall_delay = 1e-9
++ input_load = 0.5e-12)
+
+.model and1 d_and(rise_delay = 1e-9 fall_delay = 1e-9
++ input_load = 0.5e-12)
+
+.model jkflop d_jkff(clk_delay = 1.0e-9 set_delay = 1e-9
++ reset_delay = 1e-9 ic = 0 rise_delay = 1.0e-9
++ fall_delay = 1e-9)
+
+.ends count 10
+
+** 10 bit edge triggered latch
+.subckt latch10 din1 din2 din3 din4 din5 din6 din7 din8 din9 din10
++ dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10 dclk
+
+*data clk set reset out nout
+aff1 din1 dclk dzero dzero dout1 dnout1 flop1
+aff2 din2 dclk dzero dzero dout2 dnout2 flop1
+aff3 din3 dclk dzero dzero dout3 dnout3 flop1
+aff4 din4 dclk dzero dzero dout4 dnout4 flop1
+aff5 din5 dclk dzero dzero dout5 dnout5 flop1
+aff6 din6 dclk dzero dzero dout6 dnout6 flop1
+aff7 din7 dclk dzero dzero dout7 dnout7 flop1
+aff8 din8 dclk dzero dzero dout8 dnout8 flop1
+aff9 din9 dclk dzero dzero dout9 dnout9 flop1
+aff10 din10 dclk dzero dzero dout10 dnout10 flop1
+
+.model flop1 d_dff(clk_delay = 1e-9 set_delay = 0
++ reset_delay = 0 ic = 0 rise_delay = 1e-9
++ fall_delay = 1e-9)
+
+.ends latch10
+
+** emulation of 10 bit DAC
+.subckt dac10 din1 din2 din3 din4 din5 din6 din7 din8 din9 din10 aout
+.param vref=1
+abridge1 [din1 din2 din3 din4 din5 din6 din7 din8 din9 din10]
++ [ain1 ain2 ain3 ain4 ain5 ain6 ain7 ain8 ain9 ain10] dac1
+BVout aout 0 V = 'vref'*(v(ain10)/2 + v(ain9)/4 + v(ain8)/8 + v(ain7)/16 + v(ain6)/32 +
++ v(ain5)/64 + v(ain4)/128 + v(ain3)/256 + v(ain2)/512 + v(ain1)/1024)
+
+.model dac1 dac_bridge(out_low = 0 out_high = 1 out_undef = 0.5
++ input_load = 5.0e-12 t_rise = 1e-9
++ t_fall = 1e-9)
+
+.ends dac10
+
diff --git a/visualc/ng_shared_xspice_v/examples/counter-test.cir b/visualc/ng_shared_xspice_v/examples/counter-test.cir
new file mode 100644
index 000000000..c293c5c79
--- /dev/null
+++ b/visualc/ng_shared_xspice_v/examples/counter-test.cir
@@ -0,0 +1,45 @@
+* 10 bit synchronous digital counter
+* inhibit at overflow, no revolving
+* according to Schreier, Temes: Understanding Delta-Sigma Data Converters, 2005
+* Fig. 2.27, p. 58
+
+.options noinit noacct
+
+* clock generation
+* PULSE(V1 V2 TD TR TF PW PER)
+vclk aclk 0 dc 0 pulse(0 1 1u 2n 2n 1u 2u)
+
+* reset generation
+* single pulse, actual value stored in latch and read by DAC
+vres ars 0 dc 0 pulse(0 1 1.1m 2n 2n 1u 2.2m)
+
+vone aone 0 dc 1
+vzero azero 0 dc 0
+
+* digital one
+* digital zero
+abridge1 [aone azero] [done dzero] adc_buff
+.model adc_buff adc_bridge(in_low = 0.5 in_high = 0.5)
+
+* digital clock
+* digital reset
+abridge2 [aclk ars] [dclk dreset] adc_buff
+.model adc_buff adc_bridge(in_low = 0.5 in_high = 0.5)
+
+XCounter done done dclk dreset dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10 count10
+Xlatch dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10
++ dlout1 dlout2 dlout3 dlout4 dlout5 dlout6 dlout7 dlout8 dlout9 dlout10 dreset
++ latch10
+Xdac dlout1 dlout2 dlout3 dlout4 dlout5 dlout6 dlout7 dlout8 dlout9 dlout10 adacout dac10
+
+.include count-latch-dac.cir
+.tran 1u 2.5m
+
+* no .control section if to be started with bg_run
+*.control
+*eprint dout1 dout2 dout3 dout4 dout5 dout6 dout7 dout8 dout9 dout10 > digi4b.txt
+*eprint dlout1 dlout2 dlout3 dlout4 dlout5 dlout6 dlout7 dlout8 dlout9 dlout10 >> digi4b.txt
+*plot adacout
+*.endc
+
+.end
diff --git a/visualc/ng_shared_xspice_v/ng_shared_start.bat b/visualc/ng_shared_xspice_v/ng_shared_start.bat
new file mode 100644
index 000000000..8b3af437e
--- /dev/null
+++ b/visualc/ng_shared_xspice_v/ng_shared_start.bat
@@ -0,0 +1,2 @@
+start /B .\Debug\ng_shared_test_v.exe
+PAUSE
diff --git a/visualc/ng_shared_xspice_v/ng_shared_test_v.sln b/visualc/ng_shared_xspice_v/ng_shared_test_v.sln
new file mode 100644
index 000000000..9438370fb
--- /dev/null
+++ b/visualc/ng_shared_xspice_v/ng_shared_test_v.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25029.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ng_shared_test_v", "ng_shared_test_v\ng_shared_test_v.vcxproj", "{01B94AD4-AF8F-4173-9BF8-120638B8BC6C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {01B94AD4-AF8F-4173-9BF8-120638B8BC6C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {01B94AD4-AF8F-4173-9BF8-120638B8BC6C}.Debug|Win32.Build.0 = Debug|Win32
+ {01B94AD4-AF8F-4173-9BF8-120638B8BC6C}.Release|Win32.ActiveCfg = Release|Win32
+ {01B94AD4-AF8F-4173-9BF8-120638B8BC6C}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/visualc/ng_shared_xspice_v/ng_shared_test_v/ng_shared_test_v.vcxproj b/visualc/ng_shared_xspice_v/ng_shared_test_v/ng_shared_test_v.vcxproj
new file mode 100644
index 000000000..abe62a582
--- /dev/null
+++ b/visualc/ng_shared_xspice_v/ng_shared_test_v/ng_shared_test_v.vcxproj
@@ -0,0 +1,109 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {01B94AD4-AF8F-4173-9BF8-120638B8BC6C}
+ ng_shared_test_v
+ Win32Proj
+
+
+
+ Application
+ v140
+ NotSet
+ true
+
+
+ Application
+ v140
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>14.0.25029.0
+
+
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ true
+
+
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ false
+
+
+
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;XSPICE;%(PreprocessorDefinitions)
+ true
+
+ Default
+ MultiThreadedDebug
+ true
+
+ Level4
+ EditAndContinue
+ CompileAsC
+
+
+ true
+ Console
+ false
+
+ MachineX86
+
+
+
+
+ Full
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+ MultiThreaded
+ false
+ true
+
+ Level3
+
+ CompileAsC
+
+
+ false
+ Console
+ true
+ true
+
+ MachineX86
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/visualc/ng_shared_xspice_v/src/main_xspice.c b/visualc/ng_shared_xspice_v/src/main_xspice.c
new file mode 100644
index 000000000..55e65dfd9
--- /dev/null
+++ b/visualc/ng_shared_xspice_v/src/main_xspice.c
@@ -0,0 +1,581 @@
+/*
+Test file for shared ngspice
+Copyright Holger Vogt 2013
+
+ngspice library loaded dynamically
+
+Test 1
+Load and initialize ngspice
+Source an input file adder_mos.cir
+Run the simulation for 5 seconds in a background thread
+Stop the simulation for 3 seconds
+Resume the simulation in the background thread
+Write rawfile
+Unload ngspice
+
+*/
+
+
+
+#include
+#include
+#include
+#include
+#ifndef _MSC_VER
+#include
+#include
+#else
+#define bool int
+#define true 1
+#define false 0
+#define strdup _strdup
+#endif
+#include "../../../src/include/ngspice/sharedspice.h"
+
+#if defined(__MINGW32__) || defined(_MSC_VER)
+#undef BOOLEAN
+#include
+typedef FARPROC funptr_t;
+void *dlopen (const char *, int);
+funptr_t dlsym (void *, const char *);
+int dlclose (void *);
+char *dlerror (void);
+#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];
+#else
+#include /* to load libraries*/
+#include
+#include
+typedef void * funptr_t;
+#endif
+
+bool no_bg = true;
+bool not_yet = true;
+bool will_unload = false;
+bool error_ngspice = false;
+
+int cieq(register char *p, register char *s);
+int ciprefix(const char *p, const char *s);
+
+/* callback functions used by ngspice */
+int
+ng_getchar(char* outputreturn, int ident, void* userdata);
+
+int
+ng_getstat(char* outputreturn, int ident, void* userdata);
+
+int
+ng_thread_runs(bool noruns, int ident, void* userdata);
+
+/* callback functions used by XSPICE for event data */
+int
+ng_getevtdata(int index, double step, double dvalue, char *svalue,
+ void *pvalue, int plen, int mode, int ident, void *userdata);
+
+int
+ng_getinitevtdata(int index, int max_index, char * name, char *type, int ident, void *userdata);
+
+ControlledExit ng_exit;
+SendData ng_data;
+SendInitData ng_initdata;
+
+int vecgetnumber = 0;
+double v2dat;
+static bool has_break = false;
+int testnumber = 0;
+void alterp(int sig);
+
+/* functions exported by ngspice */
+funptr_t ngSpice_Init_handle = NULL;
+funptr_t ngSpice_Command_handle = NULL;
+funptr_t ngSpice_Circ_handle = NULL;
+funptr_t ngSpice_CurPlot_handle = NULL;
+funptr_t ngSpice_AllVecs_handle = NULL;
+funptr_t ngSpice_GVI_handle = NULL;
+funptr_t ngSpice_AllNodes_handle = NULL;
+funptr_t ngSpice_EVT_handle = NULL;
+funptr_t ngSpice_Init_Evt_handle = NULL;
+
+void * ngdllhandle = NULL;
+
+#ifndef _MSC_VER
+pthread_t mainthread;
+#endif // _MSC_VER
+
+int main()
+{
+ char *errmsg = NULL, *loadstring, *curplot, *vecname;
+ int *ret, i;
+ char **vecarray;
+
+ printf("****************************\n");
+ printf("** ngspice shared start **\n");
+ printf("****************************\n");
+
+#ifndef _MSC_VER
+ mainthread = pthread_self();
+#endif // _MSC_VER
+ printf("Load ngspice.dll\n");
+#ifdef __CYGWIN__
+ loadstring = "/cygdrive/c/cygwin/usr/local/bin/cygngspice-0.dll";
+#elif _MSC_VER
+// loadstring = "ngspice.dll";
+// loadstring = "..\\..\\..\\ngspice\\visualc\\sharedspice\\Debug.Win32\\ngspice.dll";
+// loadstring = "..\\..\\..\\ngspice\\visualc\\sharedspice\\ReleaseOMP.Win32\\ngspice.dll";
+ loadstring = "D:\\Spice_general\\ngspice\\visualc\\sharedspice\\Debug.Win32\\ngspice.dll";
+#elif __MINGW32__
+ loadstring = "D:\\Spice_general\\ngspice\\visualc-shared\\Debug\\bin\\ngspice.dll";
+#else
+ loadstring = "libngspice.so";
+#endif
+ ngdllhandle = dlopen(loadstring, RTLD_NOW);
+ errmsg = dlerror();
+ if (errmsg)
+ printf("%s\n", errmsg);
+ if (ngdllhandle)
+ printf("ngspice.dll loaded\n");
+ else {
+ printf("ngspice.dll not loaded !\n");
+// exit(1);
+ }
+
+ ngSpice_Init_handle = dlsym(ngdllhandle, "ngSpice_Init");
+ errmsg = dlerror();
+ if (errmsg)
+ printf(errmsg);
+ ngSpice_Command_handle = dlsym(ngdllhandle, "ngSpice_Command");
+ errmsg = dlerror();
+ if (errmsg)
+ printf(errmsg);
+ ngSpice_CurPlot_handle = dlsym(ngdllhandle, "ngSpice_CurPlot");
+ errmsg = dlerror();
+ if (errmsg)
+ printf(errmsg);
+ ngSpice_AllVecs_handle = dlsym(ngdllhandle, "ngSpice_AllVecs");
+ errmsg = dlerror();
+ if (errmsg)
+ printf(errmsg);
+ ngSpice_GVI_handle = dlsym(ngdllhandle, "ngGet_Vec_Info");
+ errmsg = dlerror();
+ if (errmsg)
+ printf(errmsg);
+ ngSpice_AllNodes_handle = dlsym(ngdllhandle, "ngSpice_AllEvtNodes");
+ errmsg = dlerror();
+ if (errmsg)
+ printf(errmsg);
+ ngSpice_EVT_handle = dlsym(ngdllhandle, "ngGet_Evt_NodeInfo");
+ errmsg = dlerror();
+ if (errmsg)
+ printf(errmsg);
+ ngSpice_Init_Evt_handle = dlsym(ngdllhandle, "ngSpice_Init_Evt");
+ errmsg = dlerror();
+ if (errmsg)
+ printf(errmsg);
+
+ /* general callback initialization */
+ ret = ((int * (*)(SendChar*, SendStat*, ControlledExit*, SendData*, SendInitData*,
+ BGThreadRunning*, void*)) ngSpice_Init_handle)(ng_getchar, ng_getstat,
+ ng_exit, NULL, ng_initdata, ng_thread_runs, NULL);
+
+ /* event data initialization */
+ ret = ((int * (*)(SendEvtData*, SendInitEvtData*, void*)) ngSpice_Init_Evt_handle)(ng_getevtdata,
+ ng_getinitevtdata, NULL);
+
+ testnumber = 1;
+ printf("\n** Test no. %d with sourcing input file **\n\n", testnumber);
+ error_ngspice = false;
+ will_unload = false;
+
+#if defined(__CYGWIN__)
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("source /cygdrive/d/Spice_general/ngspice_sh/examples/shared-ngspice/counter-test.cir");
+#elif __MINGW32__
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("source D:\\Spice_general\\ngspice_sh\\examples\\shared-ngspice\\counter-test.cir");
+#elif _MSC_VER
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("source ./examples/counter-test.cir");
+#else
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("source ../examples/counter-test.cir");
+ // ret = ((int * (*)(char*)) ngSpice_Command_handle)("source adder_mos.cir");
+#endif
+
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("bg_run");
+ printf("We are back again\n");
+
+ /* wait to catch error signal, if available */
+#if defined(__MINGW32__) || defined(_MSC_VER)
+ Sleep(100);
+#else
+ usleep(100000);
+#endif
+ /* Upon error: unload ngspice and skip rest of test code */
+ if (error_ngspice) {
+ printf("Error detected, let's unload\n");
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("quit");
+ dlclose(ngdllhandle);
+ printf("ngspice.dll unloaded\n\n");
+ ngdllhandle = NULL;
+ return 0;
+ }
+
+ /* simulate for 500 milli seconds or until simulation has finished */
+ for (i = 0; i < 5; i++) {
+#if defined(__MINGW32__) || defined(_MSC_VER)
+ Sleep(100);
+#else
+ usleep(100000);
+#endif
+ /* we are faster than anticipated */
+ if (no_bg)
+ goto endsim;
+ }
+
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("bg_halt");
+ for (i = 3; i > 0; i--) {
+ printf("Pause for %d seconds\n", i);
+#if defined(__MINGW32__) || defined(_MSC_VER)
+ Sleep(1000);
+#else
+ usleep(1000000);
+#endif
+ }
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("bg_resume");
+
+ /* wait for 1s while simulation continues */
+#if defined(__MINGW32__) || defined(_MSC_VER)
+ Sleep(1000);
+#else
+ usleep(1000000);
+#endif
+ /* read current plot while simulation continues */
+ curplot = ((char * (*)()) ngSpice_CurPlot_handle)();
+ printf("\nCurrent plot is %s\n\n", curplot);
+
+ vecarray = ((char ** (*)(char*)) ngSpice_AllVecs_handle)(curplot);
+ /* get length of first vector */
+ if (vecarray) {
+ char plotvec[256];
+ pvector_info myvec;
+ int veclength;
+ vecname = vecarray[0];
+ sprintf(plotvec, "%s.%s", curplot, vecname);
+ myvec = ((pvector_info(*)(char*)) ngSpice_GVI_handle)(plotvec);
+ veclength = myvec->v_length;
+ printf("\nActual length of vector %s is %d\n\n", plotvec, veclength);
+ }
+
+ /* wait until simulation finishes */
+ for (;;) {
+#if defined(__MINGW32__) || defined(_MSC_VER)
+ Sleep(100);
+#else
+ usleep(100000);
+#endif
+ if (no_bg)
+ break;
+ }
+endsim:
+ /* Print all event nodes to stdout */
+ vecarray = ((char ** (*)()) ngSpice_AllNodes_handle)();
+ i = 0;
+ if (vecarray) {
+ char* node;
+ printf("\nWe print all event node names:\n");
+ for (i = 0; ; i++) {
+ node = vecarray[i];
+ if (!vecarray[i])
+ break;
+ fprintf(stdout, "%s\n", vecarray[i]);
+ }
+ }
+ printf("We have %d event nodes\n\n", i);
+
+ /* just to select some nodes */
+ int j = (int)(i / 2);
+ char * nodename;
+ if (j > 0) {
+ nodename = vecarray[j];
+ printf("We analyse event node %s\n", nodename);
+ pevt_shared_data evtnode;
+ /* Get data from ngspice.dll */
+ evtnode = ((pevt_shared_data(*)(char*)) ngSpice_EVT_handle)(nodename);
+ pevt_data *nodevals = evtnode->evt_dect;
+ int count = evtnode->num_steps;
+ for (i = 0; i < count; i++) {
+ char *nodeval = nodevals[i]->node_value;
+ double step = nodevals[i]->step;
+ fprintf(stdout, "%e %s\n", step, nodeval);
+ }
+ /* Delete data */
+ ((pevt_shared_data(*)(char*)) ngSpice_EVT_handle)(NULL);
+ /* just watch another node */
+ nodename = vecarray[j - 1];
+ printf("We analyse event node %s\n", nodename);
+ evtnode = ((pevt_shared_data(*)(char*)) ngSpice_EVT_handle)(nodename);
+ nodevals = evtnode->evt_dect;
+ count = evtnode->num_steps;
+ for (i = 0; i < count; i++) {
+ char *nodeval = nodevals[i]->node_value;
+ double step = nodevals[i]->step;
+ fprintf(stdout, "%e %s\n", step, nodeval);
+ }
+ /* Delete data */
+ ((pevt_shared_data(*)(char*)) ngSpice_EVT_handle)(NULL);
+ }
+ else
+ printf("Not enough nodes for selection\n");
+
+ ret = ((int * (*)(char*)) ngSpice_Command_handle)("quit");
+#if 0
+ /* unload now */
+ dlclose(ngdllhandle);
+ ngdllhandle = NULL;
+ printf("Unloaded\n\n");
+#endif
+ if (will_unload) {
+ printf("Unload now\n");
+ dlclose(ngdllhandle);
+ ngdllhandle = NULL;
+ printf("Unloaded\n\n");
+ }
+
+ return 0;
+}
+
+
+/* Callback function called from bg thread in ngspice to transfer
+ any string created by printf or puts. Output to stdout in ngspice is
+ preceded by token stdout, same with stderr.*/
+int
+ng_getchar(char* outputreturn, int ident, void* userdata)
+{
+ printf("%s\n", outputreturn);
+ /* setting a flag if an error message occurred */
+ if (ciprefix("stderr Error:", outputreturn))
+ error_ngspice = true;
+ return 0;
+}
+
+/* Callback function called from bg thread in ngspice to transfer
+ simulation status (type and progress in percent. */
+int
+ng_getstat(char* outputreturn, int ident, void* userdata)
+{
+ printf("%s\n", outputreturn);
+ return 0;
+}
+
+/* Callback function called from ngspice upon starting (returns true) or
+ leaving (returns false) the bg thread. */
+int
+ng_thread_runs(bool noruns, int ident, void* userdata)
+{
+ no_bg = noruns;
+ if (noruns)
+ printf("bg not running\n");
+ else
+ printf("bg running\n");
+
+ return 0;
+}
+
+/* Callback function called from bg thread in ngspice if fcn controlled_exit()
+ is hit. Do not exit, but unload ngspice. */
+int
+ng_exit(int exitstatus, bool immediate, bool quitexit, int ident, void* userdata)
+{
+
+ if(quitexit) {
+ printf("DNote: Returned from quit with exit status %d\n", exitstatus);
+ }
+ if(immediate) {
+ printf("DNote: Unload ngspice\n");
+ ((int * (*)(char*)) ngSpice_Command_handle)("quit");
+ dlclose(ngdllhandle);
+ }
+
+ else {
+ printf("DNote: Prepare unloading ngspice\n");
+ will_unload = true;
+ }
+
+ return exitstatus;
+
+}
+
+/* Callback function called from bg thread in ngspice once per accepted data point */
+int
+ng_data(pvecvaluesall vdata, int numvecs, int ident, void* userdata)
+{
+ int *ret;
+
+ v2dat = vdata->vecsa[vecgetnumber]->creal;
+ if (!has_break && (v2dat > 0.5)) {
+ /* using signal SIGTERM by sending to main thread, alterp() then is run from the main thread,
+ (not on Windows though!) */
+#ifndef _MSC_VER
+ if (testnumber == 4)
+ pthread_kill(mainthread, SIGTERM);
+#endif
+ has_break = true;
+ /* leave bg thread for a while to allow halting it from main */
+#if defined(__MINGW32__) || defined(_MSC_VER)
+ Sleep (100);
+#else
+ usleep (100000);
+#endif
+// ret = ((int * (*)(char*)) ngSpice_Command_handle)("bg_halt");
+ }
+ return 0;
+}
+
+
+/* Callback function called from bg thread in ngspice once upon intialization
+ of the analog simulation vectors)*/
+int
+ng_initdata(pvecinfoall intdata, int ident, void* userdata)
+{
+ int i;
+ /* suppress second printing (after bg_resume) */
+ static bool printonce = TRUE;
+ int vn = intdata->veccount;
+ if (printonce) {
+ for (i = 0; i < vn; i++) {
+ printf("Vector: %s\n", intdata->vecs[i]->vecname);
+ /* find the location of a vector */
+ char *myvec = "adacout";
+ if (cieq(intdata->vecs[i]->vecname, myvec)) {
+ vecgetnumber = i;
+ printf("Vector %s has index %d\n", myvec, i);
+ }
+ }
+ printonce = FALSE;
+ }
+ return 0;
+}
+
+int mindex = -1;
+char* mynode = "dout8";
+/* callback functions used by XSPICE for event data. */
+
+/* Function is executed each time EVTdump() in ngspice is called and output
+ data for the node indexed by index have changed. */
+int
+ng_getevtdata(int index, double step, double dvalue, char *svalue,
+ void *pvalue, int plen, int mode, int ident, void *userdata)
+{
+ static bool once = TRUE;
+ if (mindex == -1) {
+ if (once) {
+ fprintf(stderr, "Error: Cannot watch node %s, not found\n", mynode);
+ once = FALSE;
+ }
+ return 1;
+ }
+ /* Select an action only for a specific node.
+ The value of mindex for node mynode has been determined in function
+ ng_getinitevtdata() given below. */
+ if (index == mindex)
+ fprintf(stdout, "Node %s, Index %d, Step %e, Value %s\n", mynode, index, step, svalue);
+ return 0;
+}
+
+char *evt_nodes[2][1000];
+/* Immediately after initialization, get the list of event nodes as a string array:
+ evt_nodes[0][x]: node name
+ evt_nodes[1][x]: node type
+ index x: node number, may be used to access node value by using
+ function ng_getevtdata(index, ...) */
+int
+ng_getinitevtdata(int index, int max_index, char * name, char *type, int ident, void *userdata)
+{
+ evt_nodes[0][index] = strdup(name);
+ evt_nodes[1][index] = strdup(type);
+ /* for a given node name, find the corresponding index */
+ if (cieq(name, mynode))
+ mindex = index;
+ return 0;
+}
+
+/* Funcion called from main thread upon receiving signal SIGTERM */
+void
+alterp(int sig) {
+ ((int * (*)(char*)) ngSpice_Command_handle)("bg_halt");
+}
+
+/* Unify LINUX and Windows dynamic library handling:
+ Add functions dlopen, dlsym, dlerror, dlclose to Windows by
+ tranlating to Windows API functions.
+*/
+#if defined(__MINGW32__) || defined(_MSC_VER)
+
+void *dlopen(const char *name,int type)
+{
+ return LoadLibrary((LPCSTR)name);
+}
+
+funptr_t dlsym(void *hDll, const char *funcname)
+{
+ return GetProcAddress(hDll, funcname);
+}
+
+char *dlerror(void)
+{
+ LPVOID lpMsgBuf;
+ char * testerr;
+ DWORD dw = GetLastError();
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ dw,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+ testerr = (char*)lpMsgBuf;
+ strcpy(errstr,lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ if (ciprefix("Der Vorgang wurde erfolgreich beendet.", errstr))
+ return NULL;
+ else
+ return errstr;
+}
+
+int dlclose (void *lhandle)
+{
+ return (int)FreeLibrary(lhandle);
+}
+#endif
+
+/* Case insensitive str eq.
+ Like strcasecmp( ) XXX */
+int
+cieq(register char *p, register char *s)
+{
+ while (*p) {
+ if ((isupper(*p) ? tolower(*p) : *p) !=
+ (isupper(*s) ? tolower(*s) : *s))
+ return(false);
+ p++;
+ s++;
+ }
+ return (*s ? false : true);
+}
+
+/* Case insensitive prefix. */
+int
+ciprefix(const char *p, const char *s)
+{
+ while (*p) {
+ if ((isupper(*p) ? tolower(*p) : *p) !=
+ (isupper(*s) ? tolower(*s) : *s))
+ return(false);
+ p++;
+ s++;
+ }
+ return (true);
+}