2004-06-02 Adrian Dawe <adrian.dawe@multigig.com>
* src/frontend/com_dl.c src/frontend/com_dl.c src/frontend/commands.c: Add function xaltermod 2004-06-02 Stefan Jones <stefan.jones@multigig.com> * configure.in: Change to version 16 Disable GnuReadline in tclspice * src/tclspice.c: Added trigger and step callbacks Fix redef of sighandler_t * src/pkgIndex.tcl.in: set a global variable spice_version
This commit is contained in:
parent
3b794a57d1
commit
8bb830eff2
18
ChangeLog
18
ChangeLog
|
|
@ -1,3 +1,21 @@
|
|||
2004-06-02 Adrian Dawe <adrian.dawe@multigig.com>
|
||||
|
||||
* src/frontend/com_dl.c src/frontend/com_dl.c src/frontend/commands.c:
|
||||
Add function xaltermod
|
||||
|
||||
2004-06-02 Stefan Jones <stefan.jones@multigig.com>
|
||||
|
||||
* configure.in:
|
||||
Change to version 16
|
||||
Disable GnuReadline in tclspice
|
||||
|
||||
* src/tclspice.c:
|
||||
Added trigger and step callbacks
|
||||
Fix redef of sighandler_t
|
||||
|
||||
* src/pkgIndex.tcl.in:
|
||||
set a global variable spice_version
|
||||
|
||||
2004-05-26 Stefan Jones <stefan.jones@multigig.com>
|
||||
|
||||
* src/tclspice.c src/include/ngspice.h src/misc/tilde.c
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ dnl Create a configuration header
|
|||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Initialize automake stuff
|
||||
AM_INIT_AUTOMAKE(tclspice,0.2.15)
|
||||
AM_INIT_AUTOMAKE(tclspice,0.2.16)
|
||||
|
||||
dnl --enable-ftedebug : enable frontend debug macros
|
||||
AC_ARG_ENABLE(ftedebug,
|
||||
|
|
@ -435,9 +435,9 @@ if test "$enable_cluster" = "yes"; then
|
|||
LIBS="$LIBS -lpthread"
|
||||
fi
|
||||
|
||||
|
||||
dnl ---- Option to include GNU readline support in ngspice CLI ----
|
||||
if test "$with_readline" != "no"; then
|
||||
if test "$with_readline" != "no" -a \
|
||||
\( "x$with_tcl" == "x" -o "$with_tcl" == "no" \) ; then
|
||||
AC_MSG_RESULT(Checking for readline:)
|
||||
AC_CHECK_HEADERS([readline/readline.h readline/history.h],
|
||||
[AC_DEFINE(HAVE_GNUREADLINE)],
|
||||
|
|
|
|||
|
|
@ -4,6 +4,18 @@
|
|||
#include <../spicelib/devices/dev.h> /*for load library commands*/
|
||||
|
||||
#ifdef XSPICE
|
||||
|
||||
#include "mifproto.h"
|
||||
#include "inpdefs.h"
|
||||
#include "fteext.h"
|
||||
#include "ifsim.h"
|
||||
#include "dllitf.h"
|
||||
#include "iferrmsg.h"
|
||||
#include <iferrmsg.h>
|
||||
|
||||
|
||||
|
||||
|
||||
void com_codemodel(wordlist *wl){
|
||||
wordlist *ww;
|
||||
for(ww = wl;ww;ww = ww->wl_next)
|
||||
|
|
@ -11,6 +23,138 @@ void com_codemodel(wordlist *wl){
|
|||
fprintf(cp_err,"Error: Library %s couldn't be loaded!\n",ww->wl_word);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void com_xaltermod(wordlist *wl){
|
||||
wordlist *ww, *eqword, *words;
|
||||
int i, err, typecode=-1;
|
||||
GENinstance *devptr=(GENinstance *)NULL;
|
||||
GENmodel *modptr=(GENmodel *)NULL;
|
||||
IFdevice *device;
|
||||
IFparm *opt;
|
||||
IFvalue nval;
|
||||
bool found;
|
||||
char *dev, *p;
|
||||
char *param;
|
||||
|
||||
if (!ft_curckt) {
|
||||
fprintf(cp_err, "Error: no circuit loaded\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!wl) {
|
||||
fprintf(cp_err, "usage: xaltermod dev param = expression\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
words = wl;
|
||||
while (words) {
|
||||
p = words->wl_word;
|
||||
eqword = words;
|
||||
words = words->wl_next;
|
||||
if (eq(p, "=")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!words) {
|
||||
fprintf(cp_err, "usage: xaltermod dev param = expression\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dev = NULL;
|
||||
param = NULL;
|
||||
words = wl;
|
||||
while (words != eqword) {
|
||||
p = words->wl_word;
|
||||
if (param) {
|
||||
fprintf(cp_err, "Error: excess parameter name \"%s\" ignored.\n",p);
|
||||
} else if (dev) {
|
||||
param = words->wl_word;
|
||||
} else {
|
||||
dev = p;
|
||||
}
|
||||
words = words->wl_next;
|
||||
}
|
||||
if (!dev) {
|
||||
fprintf(cp_err, "Error: no model name provided.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
words = eqword->wl_next;
|
||||
|
||||
INPretrieve(&dev,(INPtables *)ft_curckt->ci_symtab);
|
||||
|
||||
err = (*(ft_sim->findInstance))(ft_curckt->ci_ckt,&typecode,(void **)&devptr,dev,NULL,NULL);
|
||||
|
||||
if (err != OK) {
|
||||
typecode = -1;
|
||||
devptr = (void *)NULL;
|
||||
err = (*(ft_sim->findModel))(ft_curckt->ci_ckt,&typecode,(void **)&modptr,dev);
|
||||
}
|
||||
|
||||
if (err != OK) {
|
||||
printf("Error: no such model '%s'.\n",dev);
|
||||
printf(" use spice::showmod all, to display all models\n");
|
||||
return;
|
||||
}
|
||||
|
||||
device = ft_sim->devices[typecode];
|
||||
found = FALSE;
|
||||
|
||||
int id;
|
||||
int numParams =0;
|
||||
|
||||
for(ww = words;ww;ww = ww->wl_next)
|
||||
numParams ++;
|
||||
|
||||
for (i = 0; i < *(device->numModelParms); i++) {
|
||||
opt = &device->modelParms[i];
|
||||
|
||||
if (strcmp(opt->keyword,param) == 0) {
|
||||
id = opt->id;
|
||||
nval.v.numValue = 0;
|
||||
|
||||
if (opt->dataType & IF_VECTOR) {
|
||||
switch (opt->dataType & (IF_VARTYPES & ~IF_VECTOR))
|
||||
{
|
||||
case IF_STRING:
|
||||
found = TRUE;
|
||||
nval.v.vec.sVec = malloc((numParams +1) * sizeof(char *));
|
||||
for(ww = words;ww;ww = ww->wl_next) {
|
||||
nval.v.vec.sVec[nval.v.numValue] = ww->wl_word;
|
||||
nval.v.numValue++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Error: xaltermod only supports vectors of strings.\n");
|
||||
printf(" use spice::altermod\n");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printf("Error: xaltermod only supports vectors of strings.\n");
|
||||
printf(" use spice::altermod\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found == FALSE) {
|
||||
printf("Error: no parameter '%s' in model '%s'.\n", param, dev);
|
||||
printf(" use spice::showmod all, to list all model parameters\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = (*(ft_sim->setModelParm))((void *)ft_curckt->ci_ckt, (void *)modptr,
|
||||
id, &nval, (IFvalue *)NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef DEVLIB
|
||||
void com_use(wordlist *wl){
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#ifdef XSPICE
|
||||
void com_codemodel(wordlist *wl);
|
||||
void com_xaltermod(wordlist *wl);
|
||||
#endif
|
||||
|
||||
#ifdef DEVLIB
|
||||
|
|
|
|||
|
|
@ -184,6 +184,11 @@ struct comm spcp_coms[] = {
|
|||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
(void (*)()) NULL,
|
||||
"library library ... : Loads the opus librarys." } ,
|
||||
{ "xaltermod", com_xaltermod, FALSE, FALSE, TRUE,
|
||||
{ 040000, 040000, 040000, 040000 }, E_BEGINNING, 1, LOTS,
|
||||
(void (*)()) NULL,
|
||||
"library library ... : Loads the opus librarys." } ,
|
||||
|
||||
#endif
|
||||
#ifdef DEVLIB
|
||||
{ "use", com_use, FALSE, FALSE, TRUE,
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ proc Loadspice { version dir } {
|
|||
spicewish::init_gui $spicefile
|
||||
}
|
||||
|
||||
set ::spice_version $version
|
||||
}
|
||||
|
||||
proc q { } { exit }
|
||||
|
|
|
|||
296
src/tclspice.c
296
src/tclspice.c
|
|
@ -53,9 +53,8 @@
|
|||
|
||||
/* To interupt a spice run */
|
||||
#include <signal.h>
|
||||
#ifndef sighandler_t
|
||||
typedef void (*sighandler_t)(int);
|
||||
#endif
|
||||
typedef void (*sighandler)(int);
|
||||
|
||||
#include <setjmp.h>
|
||||
extern sigjmp_buf jbuf;
|
||||
|
||||
|
|
@ -109,14 +108,14 @@ typedef struct {
|
|||
} vector;
|
||||
|
||||
/*The current run (to get variable names, etc)*/
|
||||
static runDesc *cur_run = NULL;
|
||||
static runDesc *cur_run;
|
||||
|
||||
static vector *vectors = NULL;
|
||||
static vector *vectors;
|
||||
|
||||
static int ownVectors = 0;
|
||||
static int ownVectors;
|
||||
|
||||
/* save this each time called */
|
||||
static Tcl_Interp *spice_interp=NULL;
|
||||
static Tcl_Interp *spice_interp;
|
||||
#define save_interp() \
|
||||
do {\
|
||||
spice_interp = interp;\
|
||||
|
|
@ -127,9 +126,9 @@ do {\
|
|||
/****************************************************************************/
|
||||
|
||||
/*this holds the number of time points done (altered by spice)*/
|
||||
int steps_completed = 0;
|
||||
int steps_completed;
|
||||
/* number of bltvectors*/
|
||||
static int blt_vnum = 0;
|
||||
static int blt_vnum;
|
||||
|
||||
|
||||
/*Native Tcl functions */
|
||||
|
|
@ -303,6 +302,55 @@ static int lastVector TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
|||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*agr1: spice variable name
|
||||
*arg2: index
|
||||
*/
|
||||
static int get_value TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
char *var;
|
||||
int i, vindex, j;
|
||||
double val=0;
|
||||
if(argc != 3) {
|
||||
Tcl_SetResult(interp,
|
||||
"Wrong # args. spice::get_value spice_variable index",
|
||||
TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
var = (char *)argv[1];
|
||||
|
||||
for(i=0;i < blt_vnum && strcmp(var,vectors[i].name);i++);
|
||||
|
||||
if(i == blt_vnum) {
|
||||
Tcl_SetResult(interp, "Bad spice variable ",TCL_STATIC);
|
||||
Tcl_AppendResult(interp, (char *)var, TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
} else vindex = i;
|
||||
|
||||
j = atoi(argv[2]);
|
||||
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_lock(&vectors[vindex].mutex);
|
||||
#endif
|
||||
|
||||
if(j < 0 || j >= vectors[vindex].length) {
|
||||
i = 1;
|
||||
} else {
|
||||
i = 0;
|
||||
val = vectors[vindex].data[j];
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&vectors[vindex].mutex);
|
||||
#endif
|
||||
|
||||
if(i) {
|
||||
Tcl_SetResult(interp, "Index out of range",TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
} else {
|
||||
Tcl_SetObjResult(interp,Tcl_NewDoubleObj(val));
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*agr1: spice variable name
|
||||
*arg2: blt_vector
|
||||
*arg3: start copy index, optional
|
||||
|
|
@ -310,7 +358,7 @@ static int lastVector TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
|||
*/
|
||||
static int spicetoblt TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
||||
Blt_Vector *vec;
|
||||
int index, i;
|
||||
int j, i;
|
||||
char *blt, *var;
|
||||
int start=0,end=-1,len;
|
||||
|
||||
|
|
@ -328,7 +376,7 @@ static int spicetoblt TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
|||
Tcl_SetResult(interp, "Bad spice variable ",TCL_STATIC);
|
||||
Tcl_AppendResult(interp, (char *)var, TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
} else index = i;
|
||||
} else j = i;
|
||||
|
||||
if(Blt_GetVector(interp,blt,&vec)){
|
||||
Tcl_SetResult(interp, "Bad blt vector ",TCL_STATIC);
|
||||
|
|
@ -341,12 +389,12 @@ static int spicetoblt TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
|||
start = atoi(argv[3]);
|
||||
if(argc == 5)
|
||||
end = atoi(argv[4]);
|
||||
if(vectors[index].length) {
|
||||
if(vectors[j].length) {
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_lock(&vectors[index].mutex);
|
||||
pthread_mutex_lock(&vectors[j].mutex);
|
||||
#endif
|
||||
|
||||
len = vectors[index].length;
|
||||
len = vectors[j].length;
|
||||
|
||||
if(start){
|
||||
start = start % len;
|
||||
|
|
@ -360,11 +408,11 @@ static int spicetoblt TCL_CMDPROCARGS(clientData,interp,argc,argv) {
|
|||
|
||||
len = abs(end - start + 1);
|
||||
|
||||
Blt_ResetVector(vec,(vectors[index].data + start),len,
|
||||
Blt_ResetVector(vec,(vectors[j].data + start),len,
|
||||
len,TCL_VOLATILE);
|
||||
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&vectors[index].mutex);
|
||||
pthread_mutex_unlock(&vectors[j].mutex);
|
||||
#endif
|
||||
}
|
||||
return TCL_OK;
|
||||
|
|
@ -422,7 +470,7 @@ static int _thread_stop(){
|
|||
static int _run(int argc,char **argv){
|
||||
char buf[1024] = "";
|
||||
int i;
|
||||
sighandler_t oldHandler;
|
||||
sighandler oldHandler;
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
char *string;
|
||||
bool fl_bg = FALSE;
|
||||
|
|
@ -1146,8 +1194,8 @@ struct triggerEvent {
|
|||
};
|
||||
|
||||
|
||||
struct triggerEvent *eventQueue=NULL;
|
||||
struct triggerEvent *eventQueueEnd=NULL;
|
||||
struct triggerEvent *eventQueue;
|
||||
struct triggerEvent *eventQueueEnd;
|
||||
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_t triggerMutex;
|
||||
|
|
@ -1166,7 +1214,103 @@ struct watch {
|
|||
double oV;
|
||||
};
|
||||
|
||||
struct watch *watches=NULL;
|
||||
struct watch *watches;
|
||||
|
||||
char *triggerCallback;
|
||||
unsigned int triggerPollTime=1;
|
||||
|
||||
char *stepCallback;
|
||||
unsigned int stepPollTime=1;
|
||||
unsigned int stepCount=1;
|
||||
int stepCallbackPending;
|
||||
|
||||
void stepEventSetup(ClientData clientData,int flags) {
|
||||
Tcl_Time t;
|
||||
if(stepCallbackPending) {
|
||||
t.sec = 0;
|
||||
t.usec = 0;
|
||||
} else {
|
||||
t.sec = stepPollTime / 1000;
|
||||
t.usec = (stepPollTime % 1000) * 1000;
|
||||
}
|
||||
Tcl_SetMaxBlockTime(&t);
|
||||
}
|
||||
|
||||
int stepEventHandler(Tcl_Event *evPtr, int flags) {
|
||||
if(stepCallbackPending) {
|
||||
stepCallbackPending = 0;
|
||||
Tcl_Preserve((ClientData)spice_interp);
|
||||
Tcl_Eval(spice_interp,stepCallback);
|
||||
Tcl_ResetResult(spice_interp);
|
||||
Tcl_Release((ClientData)spice_interp);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
void stepEventCheck(ClientData clientData,int flags) {
|
||||
if(stepCallbackPending) {
|
||||
Tcl_Event *tclEvent;
|
||||
tclEvent = (Tcl_Event *) ckalloc(sizeof(Tcl_Event));
|
||||
tclEvent->proc = stepEventHandler;
|
||||
Tcl_QueueEvent(tclEvent,TCL_QUEUE_TAIL);
|
||||
}
|
||||
}
|
||||
|
||||
int triggerEventHandler(Tcl_Event *evPtr, int flags) {
|
||||
static char buf[512];
|
||||
int rtn=TCL_OK;
|
||||
Tcl_Preserve((ClientData)spice_interp);
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_lock(&triggerMutex);
|
||||
#endif
|
||||
while(eventQueue) {
|
||||
struct triggerEvent *event = eventQueue;
|
||||
eventQueue = eventQueue->next;
|
||||
|
||||
snprintf(buf,512,"%s %s %g %d %d",triggerCallback,vectors[event->vector].name,
|
||||
event->time,event->stepNumber,event->type);
|
||||
rtn = Tcl_Eval(spice_interp,buf);
|
||||
FREE(event);
|
||||
if(rtn) {
|
||||
goto quit;
|
||||
}
|
||||
}
|
||||
eventQueueEnd = NULL;
|
||||
quit:
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&triggerMutex);
|
||||
#endif
|
||||
Tcl_ResetResult(spice_interp);
|
||||
Tcl_Release((ClientData)spice_interp);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
void triggerEventSetup(ClientData clientData,int flags) {
|
||||
Tcl_Time t;
|
||||
if(eventQueue) {
|
||||
t.sec = 0;
|
||||
t.usec = 0;
|
||||
} else {
|
||||
t.sec = triggerPollTime / 1000;
|
||||
t.usec = (triggerPollTime % 1000) * 1000;
|
||||
}
|
||||
Tcl_SetMaxBlockTime(&t);
|
||||
}
|
||||
|
||||
void triggerEventCheck(ClientData clientData,int flags) {
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_lock(&triggerMutex);
|
||||
#endif
|
||||
if(eventQueue) {
|
||||
Tcl_Event *tclEvent;
|
||||
tclEvent = (Tcl_Event *) ckalloc(sizeof(Tcl_Event));
|
||||
tclEvent->proc = triggerEventHandler;
|
||||
Tcl_QueueEvent(tclEvent,TCL_QUEUE_TAIL);
|
||||
}
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&triggerMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Tcl_ExecutePerLoop() {
|
||||
|
||||
|
|
@ -1225,12 +1369,32 @@ int Tcl_ExecutePerLoop() {
|
|||
pthread_mutex_unlock(&v->mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(stepCallback && vectors[0].length % stepCount == 0) {
|
||||
stepCallbackPending=1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
pthread_mutex_unlock(&triggerMutex);
|
||||
|
||||
pthread_mutex_unlock(&vectors[0].mutex);
|
||||
|
||||
if(triggerCallback && eventQueue && bgtid != pthread_self()) {
|
||||
triggerEventHandler(NULL,0);
|
||||
}
|
||||
|
||||
if(stepCallback && stepCallbackPending && bgtid != pthread_self()) {
|
||||
stepEventHandler(NULL,0);
|
||||
}
|
||||
#else
|
||||
if(triggerCallback && eventQueue) {
|
||||
triggerEventHandler(NULL,0);
|
||||
}
|
||||
if(stepCallback && stepCallbackPending) {
|
||||
triggerEventHandler(NULL,0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1261,6 +1425,83 @@ static int resetTriggers() {
|
|||
}
|
||||
|
||||
|
||||
/* Registers a watch for a trigger
|
||||
*arg0: Callback function (optional - none removes callback)
|
||||
*arg1: Poll interval usec (optional - defaults to 500000 )
|
||||
*/
|
||||
static int registerTriggerCallback TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
||||
|
||||
if (argc > 3) {
|
||||
Tcl_SetResult(interp,
|
||||
"Wrong # args. spice::registerTriggerCallback ?proc? ?ms?",
|
||||
TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if(triggerCallback) {
|
||||
Tcl_DeleteEventSource(triggerEventSetup,triggerEventCheck,NULL);
|
||||
free(triggerCallback);
|
||||
triggerCallback = NULL;
|
||||
}
|
||||
|
||||
if(argc == 1) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
triggerCallback = strdup(argv[1]);
|
||||
Tcl_CreateEventSource(triggerEventSetup,triggerEventCheck,NULL);
|
||||
|
||||
if(argc == 3) {
|
||||
triggerPollTime = atoi(argv[2]);
|
||||
if(triggerPollTime == 0)
|
||||
triggerPollTime = 500;
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* Registers step counter callback
|
||||
*arg0: Callback function (optional - none removes callback)
|
||||
*arg1: Number of steps per Callback
|
||||
*arg2: Poll interval usec (optional - defaults to 500000 )
|
||||
*/
|
||||
static int registerStepCallback TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
||||
|
||||
if (argc > 4) {
|
||||
Tcl_SetResult(interp,
|
||||
"Wrong # args. spice::registerStepCallback ?proc? ?steps? ?ms?",
|
||||
TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if(stepCallback) {
|
||||
Tcl_DeleteEventSource(stepEventSetup,stepEventCheck,NULL);
|
||||
free(stepCallback);
|
||||
stepCallback = NULL;
|
||||
}
|
||||
|
||||
if(argc == 1) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
stepCallback = strdup(argv[1]);
|
||||
Tcl_CreateEventSource(stepEventSetup,stepEventCheck,NULL);
|
||||
|
||||
if(argc >= 3) {
|
||||
stepCount = atoi(argv[2]);
|
||||
if(stepCount == 0)
|
||||
stepCount = 1;
|
||||
}
|
||||
|
||||
if(argc == 4) {
|
||||
stepPollTime = atoi(argv[3]);
|
||||
if(stepPollTime == 0)
|
||||
stepPollTime = 50;
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* Registers a watch for a trigger
|
||||
*arg0: Vector Name to watch
|
||||
*arg1: Vmin
|
||||
|
|
@ -1390,7 +1631,8 @@ static int popTriggerEvent TCL_CMDPROCARGS(clientData,interp,argc,argv){
|
|||
popedEvent = eventQueue;
|
||||
|
||||
eventQueue = popedEvent->next;
|
||||
|
||||
if(eventQueue == NULL)
|
||||
eventQueueEnd = NULL;
|
||||
|
||||
list = Tcl_NewListObj(0,NULL);
|
||||
|
||||
|
|
@ -1470,7 +1712,7 @@ int Spice_Init(Tcl_Interp *interp) {
|
|||
char *key;
|
||||
Tcl_CmdInfo infoPtr;
|
||||
char buf[256];
|
||||
sighandler_t old_sigint;
|
||||
sighandler old_sigint;
|
||||
|
||||
ft_rawfile = NULL;
|
||||
ivars( );
|
||||
|
|
@ -1563,6 +1805,7 @@ bot:
|
|||
Tcl_CreateCommand(interp, TCLSPICE_prefix "spice_data", spice_data, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "spicetoblt", spicetoblt, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "lastVector", lastVector, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "get_value", get_value, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "spice", _spice_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "get_output", get_output, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "get_param", get_param, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
|
|
@ -1576,16 +1819,21 @@ bot:
|
|||
Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_date", plot_date, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_name", plot_name, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "plot_nvars", plot_nvars, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "registerTrigger", registerTrigger, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "popTriggerEvent", popTriggerEvent, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "registerTrigger", registerTrigger, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "registerTriggerCallback", registerTriggerCallback, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "popTriggerEvent", popTriggerEvent, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "unregisterTrigger", unregisterTrigger, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "listTriggers", listTriggers, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "registerStepCallback", registerTriggerCallback, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
#ifdef HAVE_LIBPTHREAD
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "bg", _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "halt", _tcl_dispatch, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "running", running, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
#endif
|
||||
|
||||
Tcl_CreateCommand(interp, TCLSPICE_prefix "registerStepCallback", registerStepCallback, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||||
|
||||
Tcl_LinkVar(interp, TCLSPICE_prefix "steps_completed", (char *)&steps_completed, TCL_LINK_READ_ONLY|TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, TCLSPICE_prefix "blt_vnum", (char *)&blt_vnum, TCL_LINK_READ_ONLY|TCL_LINK_INT);
|
||||
|
|
|
|||
Loading…
Reference in New Issue