17 #include <epicsGetopt.h> 24 #include "subRecord.h" 29 #include "osiFileName.h" 30 #include "epicsInstallDir.h" 36 # define EPICS_BASE "/" 37 # error -DEPICS_BASE required 40 #define DBD_BASE "dbd" OSI_PATH_SEPARATOR "softIoc.dbd" 41 #define EXIT_BASE "db" OSI_PATH_SEPARATOR "softIocExit.db" 42 #define DBD_FILE_REL ".." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR DBD_BASE 43 #define EXIT_FILE_REL ".." OSI_PATH_SEPARATOR ".." OSI_PATH_SEPARATOR EXIT_BASE 44 #define DBD_FILE EPICS_BASE OSI_PATH_SEPARATOR DBD_BASE 45 #define EXIT_FILE EPICS_BASE OSI_PATH_SEPARATOR EXIT_BASE 49 static void exitSubroutine(subRecord *precord) {
54 std::cout<<
"Usage: "<<arg0<<
55 " [-D softIoc.dbd] [-h] [-S] [-s] [-a ascf]\n" 56 "[-m macro=value,macro2=value2] [-d file.db]\n" 57 "[-x prefix] [st.cmd]\n" 59 " -D <dbd> If used, must come first. Specify the path to the softIoc.dbdfile." 60 " The compile-time install location is saved in the binary as a default.\n" 62 " -h Print this mesage and exit.\n" 64 " -S Prevents an interactive shell being started.\n" 66 " -s Previously caused a shell to be started. Now accepted and ignored.\n" 68 " -a <acf> Access Security configuration file. Macro substitution is\n" 71 " -m <MAC>=<value>,... Set/replace macro definitions used by subsequent -d and\n" 74 " -d <db> Load records from file (dbLoadRecords). Macro substitution is\n" 77 " -x <prefix> Load softIocExit.db. Provides a record \"<prefix>:exit\".\n" 78 " Put 0 to exit with success, or non-zero to exit with an error.\n" 80 "Any number of -m and -d arguments can be interspersed; the macros are applied\n" 81 "to the following .db files. Each later -m option causes earlier macros to be\n" 84 "A st.cmd file is optional. If any databases were loaded the st.cmd file will\n" 85 "be run *after* iocInit. To perform iocsh commands before iocInit, all database\n" 86 "loading must be performed by the script itself, or by the user from the\n" 87 "interactive IOC shell.\n" 89 "Compiled-in path to softIoc.dbd is:\n" 90 "\t"<<base_dbd.c_str()<<
"\n";
93 void errIf(
int ret,
const std::string& msg)
96 throw std::runtime_error(msg);
101 void lazy_dbd(
const std::string& dbd_file) {
102 if(lazy_dbd_loaded)
return;
103 lazy_dbd_loaded =
true;
105 errIf(dbLoadDatabase(dbd_file.c_str(),
NULL,
NULL),
106 std::string(
"Failed to load DBD file: ")+dbd_file);
107 std::cout<<
"dbLoadDatabase(\""<<dbd_file<<
"\")\n";
110 std::cout<<
"softIoc_registerRecordDeviceDriver(pdbbase)\n";
116 int main(
int argc,
char *argv[])
124 bool loadedDb =
false;
146 while ((opt =
getopt(argc, argv,
"ha:D:d:m:Ssx:")) != -1) {
149 usage(argv[0], dbd_file);
153 usage(argv[0], dbd_file);
154 std::cerr<<
"Unknown argument: -"<<char(opt)<<
"\n";
159 if (!macros.empty()) {
161 throw std::bad_alloc();
162 std::cout<<
"asSetSubstitutions(\""<<macros<<
"\")\n";
165 throw std::bad_alloc();
166 std::cout<<
"asSetFilename(\""<<
optarg<<
"\")\n";
169 if(lazy_dbd_loaded) {
170 throw std::runtime_error(
"-D specified too late. softIoc.dbd already loaded.\n");
176 errIf(dbLoadRecords(optarg, macros.c_str()),
177 std::string(
"Failed to load: ")+
optarg);
178 std::cout<<
"dbLoadRecords(\""<<optarg<<
"\"";
180 std::cout<<
", \""<<macros<<
"\"";
196 errIf(dbLoadRecords(exit_file.c_str(), xmacro.c_str()),
197 std::string(
"Failed to load: ")+exit_file);
209 std::cout<<
"# Begin "<<argv[
optind]<<
"\n";
211 std::string(
"Error in ")+argv[optind]);
212 std::cout<<
"# End "<<argv[
optind]<<
"\n";
219 std::cout<<
"iocInit()\n";
237 usage(argv[0], dbd_file);
238 std::cerr<<
"Nothing to do!\n";
247 }
catch(std::exception& e){
248 std::cerr<<
"Error: "<<e.what()<<
"\n";
int getopt(int nargc, char *const *nargv, const char *ostr)
void(* REGISTRYFUNCTION)(void)
int softIoc_registerRecordDeviceDriver(struct dbBase *pdbbase)
LIBCOM_API void epicsExitLater(int status)
Arrange to call epicsExit() later from a low priority thread.
LIBCOM_API char * epicsGetExecDir(void)
int asSetSubstitutions(const char *substitutions)
int epicsStdCall iocsh(const char *pathname)
LIBCOM_API void epicsExit(int status)
Calls epicsExitCallAtExits(), then the OS exit() routine.
Extended replacement for the Posix exit and atexit routines.
LIBCOM_API void epicsStdCall epicsThreadExitMain(void)
epicsShareFunc int registryFunctionAdd(const char *name, REGISTRYFUNCTION func)
int main(int argc, char *argv[])
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
C++ and C descriptions for a thread.
int asSetFilename(const char *acf)