rewrite load_opus(), add code model access to ngspice facilities,

add error message
This commit is contained in:
Jim Monte 2020-04-25 19:58:31 +02:00 committed by Holger Vogt
parent 004b27bd92
commit 7ead3fe552
2 changed files with 144 additions and 98 deletions

View File

@ -42,20 +42,23 @@
#include <string.h> /* for strcpy, strcat*/ #include <string.h> /* for strcpy, strcat*/
#if (!defined HAS_WINGUI) && (!defined __MINGW32__) && (!defined _MSC_VER) #if (!defined HAS_WINGUI) && (!defined __MINGW32__) && (!defined _MSC_VER)
#include <dlfcn.h> /* to load libraries*/ #include <dlfcn.h> /* to load libraries*/
typedef void * funptr_t; typedef void * funptr_t;
#define FREE_DLERR_MSG(msg)
#else /* ifdef HAS_WINGUI */ #else /* ifdef HAS_WINGUI */
#undef BOOLEAN #undef BOOLEAN
#include <windows.h> #include <windows.h>
typedef FARPROC funptr_t; typedef FARPROC funptr_t;
void *dlopen (const char *, int); void *dlopen(const char *, int);
funptr_t dlsym (void *, const char *); funptr_t dlsym(void *, const char *);
int dlclose (void *); char *dlerror(void);
char *dlerror (void); #define FREE_DLERR_MSG(msg) free_dlerr_msg(msg)
#define RTLD_LAZY 1 /* lazy function call binding */ static void free_dlerr_msg(char *msg);
#define RTLD_NOW 2 /* immediate function call binding */ #define RTLD_LAZY 1 /* lazy function call binding */
#define RTLD_GLOBAL 4 /* symbols in this dlopen'ed obj are visible to other dlopen'ed objs */ #define RTLD_NOW 2 /* immediate function call binding */
static char errstr[128]; #define RTLD_GLOBAL 4 /* symbols in this dlopen'ed obj are visible to other
* dlopen'ed objs */
#endif /* ifndef HAS_WINGUI */ #endif /* ifndef HAS_WINGUI */
#include "ngspice/dllitf.h" /* the coreInfo Structure*/ #include "ngspice/dllitf.h" /* the coreInfo Structure*/
#include "ngspice/evtudn.h" /*Use defined nodes */ #include "ngspice/evtudn.h" /*Use defined nodes */
@ -66,7 +69,8 @@ int g_evt_num_udn_types = 0;
extern Evt_Udn_Info_t idn_digital_info; extern Evt_Udn_Info_t idn_digital_info;
int add_device(int n, SPICEdev **devs, int flag); int add_device(int n, SPICEdev **devs, int flag);
int add_udn(int,Evt_Udn_Info_t **); int add_udn(int,Evt_Udn_Info_t **);
/*saj*/
extern struct coreInfo_t coreInfo; /* cmexport.c */
#endif #endif
@ -369,8 +373,9 @@ static void relink(void) {
int add_device(int n, SPICEdev **devs, int flag){ int add_device(int n, SPICEdev **devs, int flag){
int i; int i;
DEVices = TREALLOC(SPICEdev *, DEVices, DEVNUM + n); int dnum = DEVNUM + n;
DEVicesfl = TREALLOC(int, DEVicesfl, DEVNUM + n); DEVices = TREALLOC(SPICEdev *, DEVices, dnum);
DEVicesfl = TREALLOC(int, DEVicesfl, dnum);
for(i = 0; i < n;i++){ for(i = 0; i < n;i++){
#ifdef TRACE #ifdef TRACE
printf("Added device: %s\n",devs[i]->DEVpublic.name); printf("Added device: %s\n",devs[i]->DEVpublic.name);
@ -389,7 +394,8 @@ int add_device(int n, SPICEdev **devs, int flag){
int add_udn(int n,Evt_Udn_Info_t **udns){ int add_udn(int n,Evt_Udn_Info_t **udns){
int i; int i;
g_evt_udn_info = TREALLOC(Evt_Udn_Info_t *, g_evt_udn_info, g_evt_num_udn_types + n); int utypes = g_evt_num_udn_types + n;
g_evt_udn_info = TREALLOC(Evt_Udn_Info_t *, g_evt_udn_info, utypes);
for(i = 0; i < n;i++){ for(i = 0; i < n;i++){
#ifdef TRACE #ifdef TRACE
printf("Added udn: %s\n",udns[i]->name); printf("Added udn: %s\n",udns[i]->name);
@ -400,115 +406,155 @@ int add_udn(int n,Evt_Udn_Info_t **udns){
return 0; return 0;
} }
extern struct coreInfo_t coreInfo;
int load_opus(char *name){ int load_opus(const char *name)
void *lib; {
const char *msg; void *lib;
int *num=NULL; char *msg;
struct coreInfo_t **core; int num;
SPICEdev **devs; SPICEdev **devs;
Evt_Udn_Info_t **udns; Evt_Udn_Info_t **udns;
funptr_t fetch; funptr_t fetch;
lib = dlopen(name, RTLD_NOW);
if (!lib) {
msg = dlerror();
printf("Error opening code model \"%s\": %s\n", name, msg);
FREE_DLERR_MSG(msg);
return 1;
}
/* Get code models defined by the library */
if ((fetch = dlsym(lib, "CMdevNum")) != (funptr_t) NULL) {
num = *(*(int * (*)(void)) fetch)();
fetch = dlsym(lib, "CMdevs");
if (fetch != (funptr_t) NULL) {
devs = (*(SPICEdev ** (*)(void)) fetch)();
}
else {
msg = dlerror();
printf("Error getting the list of devices: %s\n",
msg);
FREE_DLERR_MSG(msg);
return 1;
}
}
else {
msg = dlerror();
printf("Error finding the number of devices: %s\n", msg);
FREE_DLERR_MSG(msg);
return 1;
}
add_device(num, devs, 1);
lib = dlopen(name,RTLD_NOW);
if(!lib){
msg = dlerror();
printf("%s\n", msg);
return 1;
}
fetch = dlsym(lib,"CMdevNum");
if(fetch){
num = ((int * (*)(void)) fetch) ();
#ifdef TRACE #ifdef TRACE
printf("Got %u devices.\n",*num); printf("Got %u devices.\n", num);
#endif #endif
}else{
msg = dlerror();
printf("%s\n", msg);
return 1;
}
fetch = dlsym(lib,"CMdevs");
if(fetch){
devs = ((SPICEdev ** (*)(void)) fetch) ();
}else{
msg = dlerror();
printf("%s\n", msg);
return 1;
}
fetch = dlsym(lib,"CMgetCoreItfPtr"); /* Get user-defined ndes defined by the library */
if(fetch){ if ((fetch = dlsym(lib, "CMudnNum")) != (funptr_t) NULL) {
core = ((struct coreInfo_t ** (*)(void)) fetch) (); num = *(*(int * (*)(void)) fetch)();
*core = &coreInfo; fetch = dlsym(lib, "CMudns");
}else{ if (fetch != (funptr_t) NULL) {
msg = dlerror(); udns = (*(Evt_Udn_Info_t ** (*)(void)) fetch)();
printf("%s\n", msg); }
return 1; else {
} msg = dlerror();
add_device(*num,devs,1); printf("Error getting the list of user-defined types: %s\n",
msg);
FREE_DLERR_MSG(msg);
return 1;
}
}
else {
msg = dlerror();
printf("Error finding the number of user-defined types: %s\n", msg);
FREE_DLERR_MSG(msg);
return 1;
}
fetch = dlsym(lib,"CMudnNum"); add_udn(num, udns);
if(fetch){
num = ((int * (*)(void)) fetch) ();
#ifdef TRACE #ifdef TRACE
printf("Got %u udns.\n",*num); printf("Got %u udns.\n", num);
#endif #endif
}else{
msg = dlerror();
printf("%s\n", msg);
return 1;
}
fetch = dlsym(lib,"CMudns"); /* Give the code model access to facilities provided by ngspice. */
if(fetch){ if ((fetch = dlsym(lib,"CMgetCoreItfPtr")) != (funptr_t) NULL) {
udns = ((Evt_Udn_Info_t ** (*)(void)) fetch) (); const struct coreInfo_t ** const core =
}else{ (const struct coreInfo_t **const)
msg = dlerror(); (*(struct coreInfo_t ** (*)(void)) fetch)();
printf("%s\n", msg); *core = &coreInfo;
return 1; }
} else {
msg = dlerror();
printf("Error getting interface pointer: %s\n", msg);
FREE_DLERR_MSG(msg);
return 1;
}
return 0;
} /* end of function load_opus */
add_udn(*num,udns);
return 0;
}
#if defined(__MINGW32__) || defined(HAS_WINGUI) || defined(_MSC_VER) #if defined(__MINGW32__) || defined(HAS_WINGUI) || defined(_MSC_VER)
void *dlopen(const char *name,int type) /* For reporting error message if formatting fails */
static const char errstr_fmt[] =
"Unable to find message in dlerr(). System code = %lu";
static char errstr[sizeof errstr_fmt - 3 + 3 * sizeof(unsigned long)];
/* Emulations of POSIX dlopen(), dlsym(), and dlerror(). */
void *dlopen(const char *name, int type)
{ {
NG_IGNORE(type); NG_IGNORE(type);
return LoadLibrary(name); return LoadLibrary(name);
} }
funptr_t dlsym(void *hDll, const char *funcname) funptr_t dlsym(void *hDll, const char *funcname)
{ {
return GetProcAddress(hDll, funcname); return GetProcAddress(hDll, funcname);
} }
char *dlerror(void) char *dlerror(void)
{ {
LPVOID lpMsgBuf; LPVOID lpMsgBuf;
FormatMessage( DWORD rc = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, NULL,
GetLastError(), GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, (LPTSTR) &lpMsgBuf,
0, 0,
NULL NULL
); );
strcpy(errstr,lpMsgBuf);
LocalFree(lpMsgBuf);
return errstr;
}
#endif
if (rc == 0) { /* FormatMessage failed */
(void) sprintf(errstr, errstr_fmt, (unsigned long) GetLastError());
return errstr;
}
return lpMsgBuf; /* Return the formatted message */
} /* end of function dlerror */
/* Free message related to dynamic loading */
static void free_dlerr_msg(char *msg)
{
if (msg != errstr) { /* msg is an allocation */
LocalFree(msg);
}
} /* end of function free_dlerr_msg */
#endif /* Windows emulation of dlopen, dlsym, and dlerr */
#endif #endif
/*-------------------- end of XSPICE additions ----------------------*/ /*-------------------- end of XSPICE additions ----------------------*/

View File

@ -8,7 +8,7 @@ int num_devices(void);
IFdevice **devices_ptr(void); IFdevice **devices_ptr(void);
SPICEdev **devices(void); SPICEdev **devices(void);
#ifdef XSPICE #ifdef XSPICE
int load_opus(char *); int load_opus(const char *);
int DEVflag(int type); int DEVflag(int type);
#endif #endif
#ifdef DEVLIB #ifdef DEVLIB