diff --git a/devsupApp/src/Makefile b/devsupApp/src/Makefile index a7f07cb..53af864 100644 --- a/devsupApp/src/Makefile +++ b/devsupApp/src/Makefile @@ -23,6 +23,8 @@ setup_CPPFLAGS += -DXPYDEV_BASE=\"$(abspath $(INSTALL_LOCATION))\" setup_CPPFLAGS += -DXEPICS_BASE=\"$(EPICS_BASE)\" setup_CPPFLAGS += -DPYDIR=\"python$(PY_VER)\" +devsupMain_CPPFLAGS += -DXPYDEV_BASE=\"$(abspath $(INSTALL_LOCATION))\" + pyDevSup$(PY_LD_VER)_SRCS += setup.c pyDevSup$(PY_LD_VER)_SRCS += dbbase.c pyDevSup$(PY_LD_VER)_SRCS += dbrec.c diff --git a/devsupApp/src/devsupMain.cpp b/devsupApp/src/devsupMain.cpp index a7a4234..17a2384 100644 --- a/devsupApp/src/devsupMain.cpp +++ b/devsupApp/src/devsupMain.cpp @@ -1,5 +1,59 @@ -/* devsupMain.cpp */ -/* Author: Marty Kraimer Date: 17MAR2000 */ +/*************************************************************************\ +* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2003 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE is distributed subject to the Software License Agreement +* found in the file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* $Revision-Id$ */ + +/* Author: Andrew Johnson Date: 2003-04-08 */ +/* adapted for pyDevSup */ + +/* Usage: + * softIoc [-D softIoc.dbd] [-h] [-S] [-s] [-a ascf] + * [-m macro=value,macro2=value2] [-d file.db] + * [-x prefix] [st.cmd] + * + * If used the -D option must come first, and specify the + * path to the softIoc.dbd file. The compile-time install + * location is saved in the binary as a default. + * + * Usage information will be printed if -h is given, then + * the program will exit normally. + * + * The -S option prevents an interactive shell being started + * after all arguments have been processed. + * + * Previous versions accepted a -s option to cause a shell + * to be started; this option is still accepted but ignored + * since a command shell is now started by default. + * + * Access Security can be enabled with the -a option giving + * the name of the configuration file; if any macros were + * set with -m before the -a option was given, they will be + * used as access security substitution macros. + * + * Any number of -m and -d arguments can be interspersed; + * the macros are applied to the following .db files. Each + * later -m option causes earlier macros to be discarded. + * + * The -x option loads the softIocExit.db with the macro + * IOC set to the string provided. This database contains + * a subroutine record named $(IOC):exit which has its field + * SNAM set to "exit". When this record is processed, the + * subroutine that runs will call epicsExit() with the value + * of the field A determining whether the exit status is + * EXIT_SUCCESS if (A == 0.0) or EXIT_FAILURE (A != 0.0). + * + * A st.cmd file is optional. If any databases were loaded + * the st.cmd file will be run *after* iocInit. To perform + * iocsh commands before iocInit, all database loading must + * be performed by the script itself, or by the user from + * the interactive IOC shell. + */ #include #include @@ -7,17 +61,157 @@ #include #include -#include "epicsExit.h" +#include "registryFunction.h" #include "epicsThread.h" +#include "epicsExit.h" +#include "epicsStdio.h" +#include "dbStaticLib.h" +#include "subRecord.h" +#include "dbAccess.h" +#include "asDbLib.h" +#include "iocInit.h" #include "iocsh.h" -int main(int argc,char *argv[]) -{ - if(argc>=2) { - iocsh(argv[1]); - epicsThreadSleep(.2); - } - iocsh(NULL); - epicsExit(0); - return(0); +extern "C" int softIocPy_registerRecordDeviceDriver(struct dbBase *pdbbase); + +#define DBD_FILE XPYDEV_BASE "/dbd/softIocPy.dbd" + +const char *arg0; +const char *base_dbd = DBD_FILE; + + +static void usage(int status) { + printf("Usage: %s [-D softIocPy.dbd] [-h] [-S] [-a ascf]\n", arg0); + puts("\t[-m macro=value,macro2=value2] [-d file.db]"); + puts("\t[-x prefix] [st.cmd]"); + puts("Compiled-in path to softIocPy.dbd is:"); + printf("\t%s\n", base_dbd); + epicsExit(status); +} + + +int main(int argc, char *argv[]) +{ + char *dbd_file = const_cast(base_dbd); + char *macros = NULL; + int startIocsh = 1; /* default = start shell */ + int loadedDb = 0; + + arg0 = strrchr(*argv, '/'); + if (!arg0) { + arg0 = *argv; + } else { + ++arg0; /* skip the '/' */ + } + + --argc, ++argv; + + /* Do this here in case the dbd file not available */ + if (argc>0 && **argv=='-' && (*argv)[1]=='h') { + usage(EXIT_SUCCESS); + } + + if (argc>1 && **argv=='-' && (*argv)[1]=='D') { + dbd_file = *++argv; + argc -= 2; + ++argv; + } + + if (dbLoadDatabase(dbd_file, NULL, NULL)) { + epicsExit(EXIT_FAILURE); + } + + softIocPy_registerRecordDeviceDriver(pdbbase); + + while (argc>1 && **argv == '-') { + switch ((*argv)[1]) { + case 'a': + if (macros) asSetSubstitutions(macros); + asSetFilename(*++argv); + --argc; + break; + + case 'd': + if (dbLoadRecords(*++argv, macros)) { + epicsExit(EXIT_FAILURE); + } + loadedDb = 1; + --argc; + break; + + case 'h': + usage(EXIT_SUCCESS); + + case 'm': + macros = *++argv; + --argc; + break; + + case 'S': + startIocsh = 0; + break; + + case 's': + break; + + default: + printf("%s: option '%s' not recognized\n", arg0, *argv); + usage(EXIT_FAILURE); + } + --argc; + ++argv; + } + + if (argc>0 && **argv=='-') { + switch((*argv)[1]) { + case 'a': + case 'd': + case 'm': + printf("%s: missing argument to option '%s'\n", arg0, *argv); + usage(EXIT_FAILURE); + + case 'h': + usage(EXIT_SUCCESS); + + case 'S': + startIocsh = 0; + break; + + case 's': + break; + + default: + printf("%s: option '%s' not recognized\n", arg0, *argv); + usage(EXIT_FAILURE); + } + --argc; + ++argv; + } + + if (loadedDb) { + iocInit(); + epicsThreadSleep(0.2); + } + + /* run user's startup script */ + if (argc>0) { + if (iocsh(*argv)) epicsExit(EXIT_FAILURE); + epicsThreadSleep(0.2); + loadedDb = 1; /* Give it the benefit of the doubt... */ + } + + /* start an interactive shell if it was requested */ + if (startIocsh) { + iocsh(NULL); + } else { + if (loadedDb) { + epicsThreadExitMain(); + } else { + printf("%s: Nothing to do!\n", arg0); + usage(EXIT_FAILURE); + } + } + epicsExit(EXIT_SUCCESS); + /*Note that the following statement will never be executed*/ + return 0; } diff --git a/iocBoot/iocarchivemon/st.cmd b/iocBoot/iocarchivemon/st.cmd index 1452d30..20fef52 100755 --- a/iocBoot/iocarchivemon/st.cmd +++ b/iocBoot/iocarchivemon/st.cmd @@ -2,9 +2,6 @@ < envPaths -dbLoadDatabase("../../dbd/softIocPy.dbd",0,0) -softIocPy_registerRecordDeviceDriver(pdbbase) - py "import logging" py "logging.basicConfig(level=logging.INFO)" diff --git a/iocBoot/ioccaputlog/st.cmd b/iocBoot/ioccaputlog/st.cmd index 9936853..dd9250a 100755 --- a/iocBoot/ioccaputlog/st.cmd +++ b/iocBoot/ioccaputlog/st.cmd @@ -2,9 +2,6 @@ < envPaths -dbLoadDatabase("../../dbd/softIocPy.dbd",0,0) -softIocPy_registerRecordDeviceDriver(pdbbase) - dbLoadRecords("../../db/logwatch.db","N=ACC-CT{}Log-I,FNAME=/var/log/epics/epics.log,FILTER=logwatch.caputlog") iocInit() diff --git a/iocBoot/iocweatherbnl/st.cmd b/iocBoot/iocweatherbnl/st.cmd index 00149f2..8756ad5 100755 --- a/iocBoot/iocweatherbnl/st.cmd +++ b/iocBoot/iocweatherbnl/st.cmd @@ -8,9 +8,6 @@ epicsEnvSet("http_proxy", "http://proxy:8888/") epicsEnvSet("PYTHONPATH", "${TOP}/python/$(ARCH)") -dbLoadDatabase("dbd/softIocPy.dbd") -softIocPy_registerRecordDeviceDriver(pdbbase) - dbLoadRecords("db/weather.db","P=CF:Ext{KISP},LOC=KISP") dbLoadRecords("db/weather.db","P=CF:Ext{KHWV},LOC=KHWV") dbLoadRecords("db/weather.db","P=CF:Ext{UNNT},LOC=UNNT") diff --git a/test.cmd b/test.cmd index 4335911..fee11f9 100644 --- a/test.cmd +++ b/test.cmd @@ -1,8 +1,5 @@ #!./bin/linux-x86/softIocPy -dbLoadDatabase("dbd/softIocPy.dbd") -softIocPy_registerRecordDeviceDriver(pdbbase) - py "import logging" py "logging.basicConfig(level=logging.DEBUG)"