Add two new functions to the shared library API.
ngSpice_Raw_Evt() requests a callback that returns all the XSPICE events for a specific node that occurred during the last timestep. ngSpice_Decode_Evt() provides numeric and string versions of the event data. Also fix some warnings in sharedspice.c.
This commit is contained in:
parent
44b620658e
commit
16aadef4c7
|
|
@ -148,16 +148,18 @@ void EVTcancel_value_call(const char *node,
|
||||||
Evt_New_Value_Cb_t fn,
|
Evt_New_Value_Cb_t fn,
|
||||||
void *ctx);
|
void *ctx);
|
||||||
|
|
||||||
/* Internal utility functions. */
|
/* Parse a node name with member and return the node index and type. */
|
||||||
|
|
||||||
void Evt_purge_free_outputs(void);
|
|
||||||
|
|
||||||
/* Parse a node name with member and find the node index. */
|
|
||||||
|
|
||||||
struct node_parse {
|
struct node_parse {
|
||||||
char *node;
|
char *node;
|
||||||
char *member;
|
char *member;
|
||||||
|
int udn_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
int Evt_Parse_Node(const char *node, struct node_parse *result);
|
int Evt_Parse_Node(const char *node, struct node_parse *result);
|
||||||
|
|
||||||
|
/* Internal utility functions. */
|
||||||
|
|
||||||
|
void Evt_purge_free_outputs(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -357,6 +357,18 @@ typedef int (SendInitEvtData)(int, int, char*, char*, int, void*);
|
||||||
int identification number of calling ngspice shared lib
|
int identification number of calling ngspice shared lib
|
||||||
void* return pointer received from caller
|
void* return pointer received from caller
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Upon time step finished, all events that occurred on a node.
|
||||||
|
* A non-zero return value cancels further reports for tis node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int (SendRawEvtData)(double, void *, void *, int);
|
||||||
|
/*
|
||||||
|
double event time
|
||||||
|
void* pointer to the node's value (a Digital_t for digital nodes)
|
||||||
|
void* return pointer received from caller
|
||||||
|
int zero if another event report for the same node follows
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ngspice initialization,
|
/* ngspice initialization,
|
||||||
|
|
@ -415,6 +427,32 @@ userData: pointer to user-defined data, will not be modified, but
|
||||||
handed over back to caller during Callback, e.g. address of calling object */
|
handed over back to caller during Callback, e.g. address of calling object */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
int ngSpice_Init_Evt(SendEvtData* sevtdata, SendInitEvtData* sinitevtdata, void* userData);
|
int ngSpice_Init_Evt(SendEvtData* sevtdata, SendInitEvtData* sinitevtdata, void* userData);
|
||||||
|
|
||||||
|
/* Request callback for every event on a specific XSPICE event node.
|
||||||
|
* A single callback function pointer is stored, with all calls directed
|
||||||
|
* to the function specified last.
|
||||||
|
* The return value identifies the node data type or is -1 on error.
|
||||||
|
*
|
||||||
|
* node name of an event node.
|
||||||
|
* srawevt pointer to callback function.
|
||||||
|
* userData pointer to user-defined data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IMPEXP
|
||||||
|
int ngSpice_Raw_Evt(const char* node, SendRawEvtData* srawevt, void* userData);
|
||||||
|
|
||||||
|
/* Decode raw event node data. Return 0 on success.
|
||||||
|
* evt pointer to event data (a reported node value).
|
||||||
|
* type node type index, return value from ngSpice_Raw_Evt().
|
||||||
|
* pplotval pointer to a double, the "plotting value" is returned. NULL OK.
|
||||||
|
* printval pointer to a char pointer that is updated to point to a
|
||||||
|
* readonly string describing the value. If evt is NULL, a string
|
||||||
|
* identifying the node data type is returned. NULL is OK.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IMPEXP
|
||||||
|
int ngSpice_Decode_Evt(void* evt, int type,
|
||||||
|
double *pplotval, const char **pprintval);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,8 @@ typedef void (*sighandler)(int);
|
||||||
|
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
#include "ngspice/evtshared.h"
|
#include "ngspice/evtshared.h"
|
||||||
|
#include "ngspice/evtproto.h"
|
||||||
|
#include "ngspice/evtudn.h"
|
||||||
extern bool wantevtdata;
|
extern bool wantevtdata;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -222,7 +224,7 @@ extern struct comm spcp_coms[];
|
||||||
struct comm* cp_coms = spcp_coms;
|
struct comm* cp_coms = spcp_coms;
|
||||||
|
|
||||||
/* Main options */
|
/* Main options */
|
||||||
static bool ft_servermode = FALSE;
|
|
||||||
bool ft_batchmode = FALSE;
|
bool ft_batchmode = FALSE;
|
||||||
bool ft_pipemode = FALSE;
|
bool ft_pipemode = FALSE;
|
||||||
bool rflag = FALSE; /* has rawfile */
|
bool rflag = FALSE; /* has rawfile */
|
||||||
|
|
@ -341,6 +343,8 @@ void sh_delete_myvec(void);
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
void shared_send_event(int, double, double, char *, void *, int, int);
|
void shared_send_event(int, double, double, char *, void *, int, int);
|
||||||
void shared_send_dict(int, int, char*, char*);
|
void shared_send_dict(int, int, char*, char*);
|
||||||
|
|
||||||
|
static int evt_shim(double time, Mif_Value_t *vp, void *ctx, int last);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(low_latency)
|
#if !defined(low_latency)
|
||||||
|
|
@ -397,6 +401,7 @@ static int intermj = 1;
|
||||||
#ifdef XSPICE
|
#ifdef XSPICE
|
||||||
static SendInitEvtData* sendinitevt;
|
static SendInitEvtData* sendinitevt;
|
||||||
static SendEvtData* sendevt;
|
static SendEvtData* sendevt;
|
||||||
|
static SendRawEvtData *sendrawevt;
|
||||||
#endif
|
#endif
|
||||||
static void* euserptr;
|
static void* euserptr;
|
||||||
static wordlist *shcontrols;
|
static wordlist *shcontrols;
|
||||||
|
|
@ -1387,6 +1392,41 @@ int ngSpice_Init_Evt(SendEvtData* sevtdata, SendInitEvtData* sinitevtdata, void
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set callback address for raw XSPICE events.
|
||||||
|
* The return value identifies the node data type or is -1 on error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IMPEXP
|
||||||
|
int ngSpice_Raw_Evt(const char* node, SendRawEvtData* srawevt, void* userData)
|
||||||
|
{
|
||||||
|
struct node_parse np;
|
||||||
|
|
||||||
|
if (Evt_Parse_Node(node, &np) < 0 || np.member)
|
||||||
|
return -1; // Invalid node name.
|
||||||
|
sendrawevt = srawevt;
|
||||||
|
EVTnew_value_call(node, evt_shim, Evt_Cbt_Raw, userData);
|
||||||
|
return np.udn_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPEXP
|
||||||
|
int ngSpice_Decode_Evt(void* evt, int type,
|
||||||
|
double *pplotval, const char **ppprintval)
|
||||||
|
{
|
||||||
|
if (type >= g_evt_num_udn_types)
|
||||||
|
return 1;
|
||||||
|
if (!evt) {
|
||||||
|
if (!ppprintval)
|
||||||
|
return 2;
|
||||||
|
*ppprintval = g_evt_udn_info[type]->name;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pplotval)
|
||||||
|
g_evt_udn_info[type]->plot_val(evt, "", pplotval);
|
||||||
|
if (ppprintval)
|
||||||
|
g_evt_udn_info[type]->print_val(evt, "", (char **)ppprintval);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get info about the event node vector.
|
/* Get info about the event node vector.
|
||||||
If node_name is NULL, just delete previous data */
|
If node_name is NULL, just delete previous data */
|
||||||
IMPEXP
|
IMPEXP
|
||||||
|
|
@ -1467,7 +1507,7 @@ sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char *p/*, *s*/;
|
char *p/*, *s*/;
|
||||||
int nchars, /*escapes,*/ result;
|
int nchars;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1547,7 +1587,7 @@ sh_vfprintf(FILE *f, const char *fmt, va_list args)
|
||||||
Spice_Init() from caller of ngspice.dll */
|
Spice_Init() from caller of ngspice.dll */
|
||||||
|
|
||||||
|
|
||||||
result = sh_fputs(p, f);
|
sh_fputs(p, f);
|
||||||
|
|
||||||
if (p != buf)
|
if (p != buf)
|
||||||
tfree(p);
|
tfree(p);
|
||||||
|
|
@ -1929,7 +1969,6 @@ void SetAnalyse(
|
||||||
|| defined (HAVE_FTIME)
|
|| defined (HAVE_FTIME)
|
||||||
PerfTime timenow; /* actual time stamp */
|
PerfTime timenow; /* actual time stamp */
|
||||||
int diffsec, diffmillisec; /* differences actual minus prev. time stamp */
|
int diffsec, diffmillisec; /* differences actual minus prev. time stamp */
|
||||||
int result; /* return value from callback function */
|
|
||||||
char* s; /* outputs to callback function */
|
char* s; /* outputs to callback function */
|
||||||
int OldPercent; /* Previous progress value */
|
int OldPercent; /* Previous progress value */
|
||||||
char OldAn[128]; /* Previous analysis type */
|
char OldAn[128]; /* Previous analysis type */
|
||||||
|
|
@ -1994,7 +2033,7 @@ void SetAnalyse(
|
||||||
if (!strcmp(Analyse, "tran")) {
|
if (!strcmp(Analyse, "tran")) {
|
||||||
if (ckt && (ckt->CKTtime > ckt->CKTfinalTime - ckt->CKTmaxStep)) {
|
if (ckt && (ckt->CKTtime > ckt->CKTfinalTime - ckt->CKTmaxStep)) {
|
||||||
sprintf(s, "--ready--");
|
sprintf(s, "--ready--");
|
||||||
result = statfcn(s, ng_ident, userptr);
|
statfcn(s, ng_ident, userptr);
|
||||||
tfree(s);
|
tfree(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2007,7 +2046,7 @@ void SetAnalyse(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sprintf( s, "--ready--");
|
sprintf( s, "--ready--");
|
||||||
result = statfcn(s, ng_ident, userptr);
|
statfcn(s, ng_ident, userptr);
|
||||||
tfree(s);
|
tfree(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2056,7 +2095,7 @@ void SetAnalyse(
|
||||||
}
|
}
|
||||||
/* ouput only after a change */
|
/* ouput only after a change */
|
||||||
if (strcmp(olds, s))
|
if (strcmp(olds, s))
|
||||||
result = statfcn(s, ng_ident, userptr);
|
statfcn(s, ng_ident, userptr);
|
||||||
if(thread1)
|
if(thread1)
|
||||||
strcpy(olds1, s);
|
strcpy(olds1, s);
|
||||||
else
|
else
|
||||||
|
|
@ -2065,11 +2104,10 @@ void SetAnalyse(
|
||||||
tfree(s);
|
tfree(s);
|
||||||
#else
|
#else
|
||||||
char* s;
|
char* s;
|
||||||
int result;
|
|
||||||
static bool havesent = FALSE;
|
static bool havesent = FALSE;
|
||||||
if (!havesent) {
|
if (!havesent) {
|
||||||
s = copy("No usage info available");
|
s = copy("No usage info available");
|
||||||
result = statfcn(s, ng_ident, userptr);
|
statfcn(s, ng_ident, userptr);
|
||||||
tfree(s);
|
tfree(s);
|
||||||
havesent = TRUE;
|
havesent = TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -2460,6 +2498,13 @@ void shared_send_dict(int index, int no_of_nodes, char* name, char*type)
|
||||||
if (sendinitevt)
|
if (sendinitevt)
|
||||||
sendinitevt(index, no_of_nodes, name, type, ng_ident, euserptr);
|
sendinitevt(index, no_of_nodes, name, type, ng_ident, euserptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int evt_shim(double time, Mif_Value_t *vp, void *ctx, int last)
|
||||||
|
{
|
||||||
|
if (sendrawevt)
|
||||||
|
return sendrawevt(time, vp->pvalue, ctx, last); // Strip Mif_value.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int totalreset(void)
|
static int totalreset(void)
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ int Evt_Parse_Node(const char *node, struct node_parse *result)
|
||||||
tfree(name);
|
tfree(name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
result->udn_index = node_table[i]->udn_index;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue