compiles
This commit is contained in:
@ -37,6 +37,8 @@ devsup_SRCS_DEFAULT += devsupMain.cpp
|
|||||||
devsup_SRCS_vxWorks += -nil-
|
devsup_SRCS_vxWorks += -nil-
|
||||||
|
|
||||||
devsup_SRCS += setup.c
|
devsup_SRCS += setup.c
|
||||||
|
devsup_SRCS += dbrec.c
|
||||||
|
devsup_SRCS += dbfield.c
|
||||||
|
|
||||||
# Add support from base/src/vxWorks if needed
|
# Add support from base/src/vxWorks if needed
|
||||||
#devsup_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
#devsup_OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary
|
||||||
|
192
devsupApp/src/dbfield.c
Normal file
192
devsupApp/src/dbfield.c
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
|
||||||
|
/* python has its own ideas about which version to support */
|
||||||
|
#undef _POSIX_C_SOURCE
|
||||||
|
#undef _XOPEN_SOURCE
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#include <epicsVersion.h>
|
||||||
|
#include <dbCommon.h>
|
||||||
|
#include <dbAccess.h>
|
||||||
|
#include <dbStaticLib.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
|
||||||
|
DBADDR addr;
|
||||||
|
} pyField;
|
||||||
|
|
||||||
|
static int pyField_Init(pyField *self, PyObject *args, PyObject *kws)
|
||||||
|
{
|
||||||
|
const char *pvname;
|
||||||
|
|
||||||
|
if(PyArg_ParseTuple(args, "s", &pvname))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(dbNameToAddr(pvname, &self->addr)) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "Record field not found");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(self->addr.field_type >= DBF_ENUM) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "Access to this field type is not supported");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyField_name(pyField *self)
|
||||||
|
{
|
||||||
|
return Py_BuildValue("ss",
|
||||||
|
self->addr.precord->name,
|
||||||
|
self->addr.pfldDes->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyField_fldinfo(pyField *self)
|
||||||
|
{
|
||||||
|
short dbf=self->addr.field_type;
|
||||||
|
short fsize=self->addr.field_size;
|
||||||
|
unsigned long nelm=self->addr.no_elements;
|
||||||
|
return Py_BuildValue("hhk", dbf, fsize, nelm);
|
||||||
|
}
|
||||||
|
|
||||||
|
union dbfvalue {
|
||||||
|
char dv_sval[MAX_STRING_SIZE];
|
||||||
|
epicsUInt32 dv_uval;
|
||||||
|
epicsInt32 dv_ival;
|
||||||
|
double dv_fval;
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyObject* pyField_getval(pyField *self)
|
||||||
|
{
|
||||||
|
union dbfvalue buf;
|
||||||
|
long nReq = 1;
|
||||||
|
short reqtype;
|
||||||
|
|
||||||
|
switch(self->addr.field_type)
|
||||||
|
{
|
||||||
|
case DBF_CHAR:
|
||||||
|
case DBF_UCHAR:
|
||||||
|
case DBF_SHORT:
|
||||||
|
case DBF_USHORT:
|
||||||
|
case DBF_ENUM:
|
||||||
|
case DBF_LONG:
|
||||||
|
reqtype = DBF_LONG;
|
||||||
|
break;
|
||||||
|
case DBF_ULONG:
|
||||||
|
reqtype = DBF_ULONG;
|
||||||
|
break;
|
||||||
|
case DBF_FLOAT:
|
||||||
|
case DBF_DOUBLE:
|
||||||
|
reqtype = DBF_DOUBLE;
|
||||||
|
break;
|
||||||
|
case DBF_STRING:
|
||||||
|
reqtype = DBF_STRING;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PyErr_SetString(PyExc_ValueError, "Access to this field type is not supported");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dbGet(&self->addr, reqtype, buf.dv_sval, NULL, &nReq, NULL)) {
|
||||||
|
PyErr_SetString(PyExc_ValueError, "Error getting field value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(reqtype) {
|
||||||
|
case DBF_LONG:
|
||||||
|
return PyInt_FromLong(buf.dv_ival);
|
||||||
|
case DBF_ULONG:
|
||||||
|
return PyInt_FromLong(buf.dv_uval);
|
||||||
|
case DBF_DOUBLE:
|
||||||
|
return PyInt_FromLong(buf.dv_fval);
|
||||||
|
case DBF_STRING:
|
||||||
|
return PyString_FromString(buf.dv_sval);
|
||||||
|
default:
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject* pyField_putval(pyField *self, PyObject* args)
|
||||||
|
{
|
||||||
|
PyObject *val;
|
||||||
|
|
||||||
|
union dbfvalue buf;
|
||||||
|
short puttype;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args, "O", &val))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(PyFloat_Check(val)) {
|
||||||
|
double v = PyFloat_AsDouble(val);
|
||||||
|
buf.dv_fval = v;
|
||||||
|
puttype = DBF_DOUBLE;
|
||||||
|
|
||||||
|
} else if(PyInt_Check(val)) {
|
||||||
|
long v = PyInt_AsLong(val);
|
||||||
|
if(v>0x7fffffffL) {
|
||||||
|
buf.dv_uval = v;
|
||||||
|
puttype = DBF_ULONG;
|
||||||
|
} else {
|
||||||
|
buf.dv_ival = v;
|
||||||
|
puttype = DBF_LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if(PyString_Check(val)) {
|
||||||
|
const char *v = PyString_AsString(val);
|
||||||
|
strncpy(buf.dv_sval, v, MAX_STRING_SIZE);
|
||||||
|
buf.dv_sval[MAX_STRING_SIZE-1] = '\0';
|
||||||
|
puttype = DBF_STRING;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Unable to convert put type");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dbPut(&self->addr, puttype, buf.dv_sval, 1)){
|
||||||
|
PyErr_SetString(PyExc_ValueError, "Error putting field value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef pyField_methods[] = {
|
||||||
|
{"name", (PyCFunction)pyField_name, METH_NOARGS,
|
||||||
|
"Return Names (\"record\",\"field\")"},
|
||||||
|
{"fieldinfo", (PyCFunction)pyField_fldinfo, METH_NOARGS,
|
||||||
|
"Field type info\nReturn (type, size, #elements"},
|
||||||
|
{"getval", (PyCFunction)pyField_getval, METH_VARARGS,
|
||||||
|
"Returns scalar version of field value"},
|
||||||
|
{"putval", (PyCFunction)pyField_putval, METH_VARARGS,
|
||||||
|
"Sets field value from a scalar"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static PyTypeObject pyField_type = {
|
||||||
|
PyObject_HEAD_INIT(NULL)
|
||||||
|
0,
|
||||||
|
"_dbapi.Field",
|
||||||
|
sizeof(pyField),
|
||||||
|
};
|
||||||
|
|
||||||
|
int pyField_prepare(void)
|
||||||
|
{
|
||||||
|
pyField_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||||
|
pyField_type.tp_methods = pyField_methods;
|
||||||
|
pyField_type.tp_init = (initproc)pyField_Init;
|
||||||
|
|
||||||
|
pyField_type.tp_new = PyType_GenericNew;
|
||||||
|
if(PyType_Ready(&pyField_type)<0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pyField_setup(PyObject *module)
|
||||||
|
{
|
||||||
|
PyObject *typeobj=(PyObject*)&pyField_type;
|
||||||
|
Py_INCREF(typeobj);
|
||||||
|
PyModule_AddObject(module, "Field", (PyObject*)&pyField_type);
|
||||||
|
}
|
161
devsupApp/src/dbrec.c
Normal file
161
devsupApp/src/dbrec.c
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
|
||||||
|
/* python has its own ideas about which version to support */
|
||||||
|
#undef _POSIX_C_SOURCE
|
||||||
|
#undef _XOPEN_SOURCE
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#include <epicsVersion.h>
|
||||||
|
#include <dbCommon.h>
|
||||||
|
#include <dbAccess.h>
|
||||||
|
#include <dbStaticLib.h>
|
||||||
|
#include <dbScan.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
|
||||||
|
DBENTRY entry;
|
||||||
|
} pyRecord;
|
||||||
|
|
||||||
|
static int pyRecord_Init(pyRecord *self, PyObject *args, PyObject *kws)
|
||||||
|
{
|
||||||
|
const char *recname;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args, "s", &recname))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
dbInitEntry(pdbbase, &self->entry);
|
||||||
|
|
||||||
|
if(dbFindRecord(&self->entry, recname)){
|
||||||
|
PyErr_SetString(PyExc_ValueError, "Record not found");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyRecord_name(pyRecord *self)
|
||||||
|
{
|
||||||
|
dbCommon *prec=self->entry.precnode->precord;
|
||||||
|
return PyString_FromString(prec->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyRecord_info(pyRecord *self, PyObject *args)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
PyObject *def = Py_None;
|
||||||
|
DBENTRY entry;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTuple(args, "s|O", &name, &def))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dbCopyEntryContents(&self->entry, &entry);
|
||||||
|
|
||||||
|
if(dbFindInfo(&entry, name)) {
|
||||||
|
if(def) {
|
||||||
|
Py_INCREF(def);
|
||||||
|
return def;
|
||||||
|
} else {
|
||||||
|
PyErr_SetNone(PyExc_KeyError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyString_FromString(dbGetInfoString(&entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyRecord_infos(pyRecord *self)
|
||||||
|
{
|
||||||
|
PyObject *dict;
|
||||||
|
DBENTRY entry;
|
||||||
|
long status;
|
||||||
|
|
||||||
|
dict = PyDict_New();
|
||||||
|
if(!dict)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dbCopyEntryContents(&self->entry, &entry);
|
||||||
|
|
||||||
|
for(status = dbFirstInfo(&entry); status==0; status = dbNextInfo(&entry))
|
||||||
|
{
|
||||||
|
PyObject *val = PyString_FromString(dbGetInfoString(&entry));
|
||||||
|
if(!val)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if(PyDict_SetItemString(dict, dbGetInfoName(&entry), val)<0) {
|
||||||
|
Py_DECREF(val);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dict;
|
||||||
|
fail:
|
||||||
|
Py_DECREF(dict);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyRecord_scan(pyRecord *self, PyObject *args, PyObject *kws)
|
||||||
|
{
|
||||||
|
dbCommon *prec = self->entry.precnode->precord;
|
||||||
|
|
||||||
|
static char* names[] = {"sync", NULL};
|
||||||
|
PyObject *sync = Py_False;
|
||||||
|
|
||||||
|
if(!PyArg_ParseTupleAndKeywords(args, kws, "|O", names, &sync))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!PyObject_IsTrue(sync)) {
|
||||||
|
scanOnce(prec);
|
||||||
|
} else {
|
||||||
|
Py_BEGIN_ALLOW_THREADS {
|
||||||
|
|
||||||
|
dbScanLock(prec);
|
||||||
|
dbProcess(prec);
|
||||||
|
dbScanUnlock(prec);
|
||||||
|
|
||||||
|
} Py_END_ALLOW_THREADS
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef pyRecord_methods[] = {
|
||||||
|
{"name", (PyCFunction)pyRecord_name, METH_NOARGS,
|
||||||
|
"Return record name string"},
|
||||||
|
{"info", (PyCFunction)pyRecord_info, METH_VARARGS,
|
||||||
|
"Lookup info name\ninfo(name, def=None)"},
|
||||||
|
{"infos", (PyCFunction)pyRecord_infos, METH_NOARGS,
|
||||||
|
"Return a dictionary of all infos for this record."},
|
||||||
|
{"scan", (PyCFunction)pyRecord_scan, METH_VARARGS|METH_KEYWORDS,
|
||||||
|
"scan(sync=False)\nScan this record. If sync is False then"
|
||||||
|
"a scan request is queued. If sync is True then the record"
|
||||||
|
"is scannined immidately on the current thread."
|
||||||
|
},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyTypeObject pyRecord_type = {
|
||||||
|
PyObject_HEAD_INIT(NULL)
|
||||||
|
0,
|
||||||
|
"_dbapi.Record",
|
||||||
|
sizeof(pyRecord),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int pyRecord_prepare(void)
|
||||||
|
{
|
||||||
|
pyRecord_type.tp_flags = Py_TPFLAGS_DEFAULT;
|
||||||
|
pyRecord_type.tp_methods = pyRecord_methods;
|
||||||
|
pyRecord_type.tp_init = (initproc)pyRecord_Init;
|
||||||
|
|
||||||
|
pyRecord_type.tp_new = PyType_GenericNew;
|
||||||
|
if(PyType_Ready(&pyRecord_type)<0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pyRecord_setup(PyObject *module)
|
||||||
|
{
|
||||||
|
PyObject *typeobj=(PyObject*)&pyRecord_type;
|
||||||
|
Py_INCREF(typeobj);
|
||||||
|
PyModule_AddObject(module, "Field", (PyObject*)&pyRecord_type);
|
||||||
|
}
|
@ -1,3 +1,6 @@
|
|||||||
|
/* Global interpreter setup
|
||||||
|
*/
|
||||||
|
|
||||||
/* python has its own ideas about which version to support */
|
/* python has its own ideas about which version to support */
|
||||||
#undef _POSIX_C_SOURCE
|
#undef _POSIX_C_SOURCE
|
||||||
#undef _XOPEN_SOURCE
|
#undef _XOPEN_SOURCE
|
||||||
@ -6,49 +9,98 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <epicsVersion.h>
|
||||||
|
#include <dbCommon.h>
|
||||||
|
#include <dbAccess.h>
|
||||||
|
#include <dbStaticLib.h>
|
||||||
|
#include <dbScan.h>
|
||||||
|
#include <initHooks.h>
|
||||||
#include <epicsThread.h>
|
#include <epicsThread.h>
|
||||||
#include <epicsExit.h>
|
#include <epicsExit.h>
|
||||||
#include <initHooks.h>
|
|
||||||
|
|
||||||
static PyThreadState *main_state;
|
static PyObject *hooktable;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const initHookState state;
|
||||||
|
const char * const name;
|
||||||
|
} pystate;
|
||||||
|
|
||||||
|
#define INITST(hook) {initHook ## hook, #hook }
|
||||||
|
static pystate statenames[] = {
|
||||||
|
INITST(AtIocBuild),
|
||||||
|
|
||||||
|
INITST(AtBeginning),
|
||||||
|
INITST(AfterCallbackInit),
|
||||||
|
INITST(AfterCaLinkInit),
|
||||||
|
INITST(AfterInitDrvSup),
|
||||||
|
INITST(AfterInitRecSup),
|
||||||
|
INITST(AfterInitDevSup),
|
||||||
|
INITST(AfterInitDatabase),
|
||||||
|
INITST(AfterFinishDevSup),
|
||||||
|
INITST(AfterScanInit),
|
||||||
|
|
||||||
|
INITST(AfterInitialProcess),
|
||||||
|
INITST(AfterCaServerInit),
|
||||||
|
INITST(AfterIocBuilt),
|
||||||
|
INITST(AtIocRun),
|
||||||
|
INITST(AfterDatabaseRunning),
|
||||||
|
INITST(AfterCaServerRunning),
|
||||||
|
INITST(AfterIocRunning),
|
||||||
|
INITST(AtIocPause),
|
||||||
|
|
||||||
|
INITST(AfterCaServerPaused),
|
||||||
|
INITST(AfterDatabasePaused),
|
||||||
|
INITST(AfterIocPaused),
|
||||||
|
{(initHookState)0, NULL}
|
||||||
|
};
|
||||||
|
#undef INITST
|
||||||
|
|
||||||
static void cleanupPy(void *junk)
|
static void cleanupPy(void *junk)
|
||||||
{
|
{
|
||||||
PyEval_RestoreThread(main_state);
|
PyThreadState *state = PyGILState_GetThisThreadState();
|
||||||
|
|
||||||
|
PyEval_RestoreThread(state);
|
||||||
|
|
||||||
|
/* release extra reference for hooktable */
|
||||||
|
Py_DECREF(hooktable);
|
||||||
|
hooktable = NULL;
|
||||||
|
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the interpreter environment
|
/* Initialize the interpreter environment
|
||||||
*/
|
*/
|
||||||
|
static epicsThreadOnceId setupPyOnceId = EPICS_THREAD_ONCE_INIT;
|
||||||
static void setupPyOnce(void *junk)
|
static void setupPyOnce(void *junk)
|
||||||
{
|
{
|
||||||
Py_Initialize();
|
PyThreadState *state;
|
||||||
|
|
||||||
|
Py_Initialize();
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
|
|
||||||
|
state = PyEval_SaveThread();
|
||||||
|
|
||||||
epicsAtExit(&cleanupPy, NULL);
|
epicsAtExit(&cleanupPy, NULL);
|
||||||
|
|
||||||
main_state = PyEval_SaveThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static epicsThreadOnceId setupPyOnceId = EPICS_THREAD_ONCE_INIT;
|
|
||||||
|
|
||||||
void evalPy(const char* code)
|
void evalPy(const char* code)
|
||||||
{
|
{
|
||||||
PyEval_RestoreThread(main_state);
|
PyGILState_STATE state;
|
||||||
|
|
||||||
|
state = PyGILState_Ensure();
|
||||||
|
|
||||||
if(PyRun_SimpleStringFlags(code, NULL)!=0)
|
if(PyRun_SimpleStringFlags(code, NULL)!=0)
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
|
||||||
main_state = PyEval_SaveThread();
|
PyGILState_Release(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void evalFilePy(const char* file)
|
void evalFilePy(const char* file)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
PyGILState_STATE state;
|
||||||
|
|
||||||
PyEval_RestoreThread(main_state);
|
state = PyGILState_Ensure();
|
||||||
|
|
||||||
fp = fopen(file, "r");
|
fp = fopen(file, "r");
|
||||||
if(!fp) {
|
if(!fp) {
|
||||||
@ -60,7 +112,97 @@ void evalFilePy(const char* file)
|
|||||||
}
|
}
|
||||||
/* fp closed by python */
|
/* fp closed by python */
|
||||||
|
|
||||||
main_state = PyEval_SaveThread();
|
PyGILState_Release(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pyhook(initHookState state)
|
||||||
|
{
|
||||||
|
PyGILState_STATE gilstate;
|
||||||
|
|
||||||
|
gilstate = PyGILState_Ensure();
|
||||||
|
|
||||||
|
if(hooktable && PyDict_Check(hooktable)) {
|
||||||
|
PyObject *next;
|
||||||
|
PyObject *key = PyInt_FromLong((long)state);
|
||||||
|
PyObject *list = PyDict_GetItem(hooktable, key);
|
||||||
|
Py_DECREF(key);
|
||||||
|
|
||||||
|
list = PyObject_GetIter(list);
|
||||||
|
if(!list) {
|
||||||
|
fprintf(stderr, "hook sequence not iterable!");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
while((next=PyIter_Next(list))!=NULL) {
|
||||||
|
PyObject *obj;
|
||||||
|
if(!PyCallable_Check(next))
|
||||||
|
continue;
|
||||||
|
obj = PyObject_CallFunction(next, "O", key);
|
||||||
|
Py_DECREF(next);
|
||||||
|
if(obj)
|
||||||
|
Py_DECREF(obj);
|
||||||
|
else {
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!PyErr_Occurred()) {
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PyGILState_Release(gilstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char sitestr[] = EPICS_SITE_VERSION;
|
||||||
|
|
||||||
|
static PyObject *modversion(PyObject *self)
|
||||||
|
{
|
||||||
|
int ver=EPICS_VERSION, rev=EPICS_REVISION, mod=EPICS_MODIFICATION, patch=EPICS_PATCH_LEVEL;
|
||||||
|
return Py_BuildValue("iiiis", ver, rev, mod, patch, sitestr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef devsup_methods[] = {
|
||||||
|
{"verinfo", (PyCFunction)modversion, METH_NOARGS,
|
||||||
|
"EPICS Version information\nreturn (MAJOR, MINOR, MOD, PATH, \"site\""},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
int pyField_prepare(void);
|
||||||
|
void pyField_setup(PyObject *module);
|
||||||
|
|
||||||
|
int pyRecord_prepare(void);
|
||||||
|
void pyRecord_setup(PyObject *module);
|
||||||
|
|
||||||
|
/* initialize "magic" builtin module */
|
||||||
|
static void init_dbapi(void)
|
||||||
|
{
|
||||||
|
PyObject *mod;
|
||||||
|
pystate *st;
|
||||||
|
|
||||||
|
hooktable = PyDict_New();
|
||||||
|
if(!hooktable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(pyField_prepare())
|
||||||
|
return;
|
||||||
|
if(pyRecord_prepare())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mod = Py_InitModule("_dbapi", devsup_methods);
|
||||||
|
|
||||||
|
for(st = statenames; st->name; st++) {
|
||||||
|
PyModule_AddIntConstant(mod, st->name, (long)st->state);
|
||||||
|
}
|
||||||
|
Py_INCREF(hooktable); /* an extra ref */
|
||||||
|
PyModule_AddObject(mod, "_hooktable", hooktable);
|
||||||
|
|
||||||
|
pyField_setup(mod);
|
||||||
|
pyRecord_setup(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <iocsh.h>
|
#include <iocsh.h>
|
||||||
@ -82,6 +224,8 @@ static void pySetupReg(void)
|
|||||||
epicsThreadOnce(&setupPyOnceId, &setupPyOnce, NULL);
|
epicsThreadOnce(&setupPyOnceId, &setupPyOnce, NULL);
|
||||||
iocshRegister(&codeDef, &codeRun);
|
iocshRegister(&codeDef, &codeRun);
|
||||||
iocshRegister(&fileDef, &fileRun);
|
iocshRegister(&fileDef, &fileRun);
|
||||||
|
initHookRegister(&pyhook);
|
||||||
|
init_dbapi();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <epicsExport.h>
|
#include <epicsExport.h>
|
||||||
|
Reference in New Issue
Block a user