ISIS Logo
UTILITIES
EPICS Utilities
dbLoadRecordsFuncs.cpp
Go to the documentation of this file.
1 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <errno.h>
9 #include <math.h>
10 #include <exception>
11 #include <algorithm>
12 #include <stdexcept>
13 #include <iostream>
14 #include <map>
15 #include <list>
16 #include <string>
17 #include <time.h>
18 #include <sstream>
19 #include <fstream>
20 #ifndef _WIN32
21 #include <unistd.h>
22 #endif
23 
24 #include "epicsStdlib.h"
25 #include "epicsString.h"
26 #include "epicsStdio.h"
27 #include "dbDefs.h"
28 #include "epicsMutex.h"
29 #include "dbBase.h"
30 #include "dbStaticLib.h"
31 #include "dbFldTypes.h"
32 #include "dbCommon.h"
33 #include "dbAccessDefs.h"
34 #include <epicsTypes.h>
35 #include <epicsTime.h>
36 #include <epicsThread.h>
37 #include <epicsString.h>
38 #include <epicsTimer.h>
39 #include <epicsMutex.h>
40 #include <iocsh.h>
41 #include "envDefs.h"
42 #include "macLib.h"
43 #include "errlog.h"
44 
45 #include <string.h>
46 #include <registryFunction.h>
47 
48 #include <epicsExport.h>
49 
50 #include "utilities.h"
51 
53 static void loadMacEnviron(MAC_HANDLE* pmh)
54 {
55  for(char** cp = environ; *cp != NULL; ++cp)
56  {
57  char* str_tmp = strdup(*cp);
58  char* equals_loc = strchr(str_tmp, '='); // split name=value string
59  if (equals_loc != NULL)
60  {
61  *equals_loc = '\0';
62  macPutValue(pmh, str_tmp, equals_loc + 1);
63  }
64  free(str_tmp);
65  }
66 }
67 
69 static void subMacros(std::string& new_macros, const char* macros, const char* loopVar)
70 {
71  char loopSubFrom[32], loopSubTo[32];
72  epicsSnprintf(loopSubFrom, sizeof(loopSubFrom), "\\$(%s)", loopVar);
73  epicsSnprintf(loopSubTo, sizeof(loopSubTo), "$(%s)", loopVar);
74  new_macros = macros;
75  size_t start_pos = 0, lf = strlen(loopSubFrom), lt = strlen(loopSubTo);
76  while( (start_pos = new_macros.find(loopSubFrom, start_pos)) != std::string::npos )
77  {
78  new_macros.replace(start_pos, lf, loopSubTo);
79  start_pos += lt;
80  }
81  epicsSnprintf(loopSubFrom, sizeof(loopSubFrom), "\\${%s}", loopVar);
82  epicsSnprintf(loopSubTo, sizeof(loopSubTo), "${%s}", loopVar);
83  start_pos = 0;
84  while( (start_pos = new_macros.find(loopSubFrom, start_pos)) != std::string::npos )
85  {
86  new_macros.replace(start_pos, lf, loopSubTo);
87  start_pos += lt;
88  }
89 }
90 
112 epicsShareFunc void dbLoadRecordsLoop(const char* dbFile, const char* macros, const char* loopVar, int start, int stop, int step)
113 {
114  char loopVal[32];
115  if (loopVar == NULL)
116  {
117  dbLoadRecords(dbFile, macros);
118  return;
119  }
120  if (step <= 0)
121  {
122  step = 1;
123  }
124  std::string macros_s, dbFile_s;
125  subMacros(macros_s, macros, loopVar);
126  subMacros(dbFile_s, dbFile, loopVar);
127  MAC_HANDLE* mh = NULL;
128  char macros_exp[1024], dbFile_exp[1024];
129  macCreateHandle(&mh, NULL);
130  loadMacEnviron(mh);
131  for(int i = start; i <= stop; i += step)
132  {
133  macPushScope(mh);
134  epicsSnprintf(loopVal, sizeof(loopVal), "%d", i);
135  macPutValue(mh, loopVar, loopVal);
136  macExpandString(mh, macros_s.c_str(), macros_exp, sizeof(macros_exp));
137  macExpandString(mh, dbFile_s.c_str(), dbFile_exp, sizeof(dbFile_exp));
138  std::ostringstream new_macros;
139  new_macros << macros_exp << (strlen(macros_exp) > 0 ? "," : "") << loopVar << "=" << i;
140  std::cout << "--> (" << i << ") dbLoadRecords(\"" << dbFile_exp << "\",\"" << new_macros.str() << "\")" << std::endl;
141  dbLoadRecords(dbFile_exp, new_macros.str().c_str());
142  macPopScope(mh);
143  }
144  macDeleteHandle(mh);
145 }
146 
167 epicsShareFunc void dbLoadRecordsList(const char* dbFile, const char* macros, const char* loopVar, const char* list, const char* sep)
168 {
169  static const char* default_sep = ";";
170  if (loopVar == NULL || list == NULL)
171  {
172  dbLoadRecords(dbFile, macros);
173  return;
174  }
175  if (sep == NULL)
176  {
177  sep = default_sep;
178  }
179  std::string macros_s, dbFile_s;
180  subMacros(macros_s, macros, loopVar);
181  subMacros(dbFile_s, dbFile, loopVar);
182  MAC_HANDLE* mh = NULL;
183  char macros_exp[1024], dbFile_exp[1024];
184  macCreateHandle(&mh, NULL);
185  loadMacEnviron(mh);
186  char* saveptr = NULL;
187  char* list_tmp = strdup(list);
188  char* list_item = epicsStrtok_r(list_tmp, sep, &saveptr);
189  while(list_item != NULL)
190  {
191  macPushScope(mh);
192  macPutValue(mh, loopVar, list_item);
193  macExpandString(mh, macros_s.c_str(), macros_exp, sizeof(macros_exp));
194  macExpandString(mh, dbFile_s.c_str(), dbFile_exp, sizeof(dbFile_exp));
195  std::ostringstream new_macros;
196  new_macros << macros_exp << (strlen(macros_exp) > 0 ? "," : "") << loopVar << "=" << list_item;
197  std::cout << "--> (" << list_item << ") dbLoadRecords(\"" << dbFile_exp << "\",\"" << new_macros.str() << "\")" << std::endl;
198  dbLoadRecords(dbFile_exp, new_macros.str().c_str());
199  list_item = epicsStrtok_r(NULL, sep, &saveptr);
200  macPopScope(mh);
201  }
202  free(list_tmp);
203  macDeleteHandle(mh);
204 }
205 
206 extern "C" {
207 
208 // EPICS iocsh shell commands
209 
210 static const iocshArg dbLoadRecordsLoopInitArg0 = { "dbFile", iocshArgString };
211 static const iocshArg dbLoadRecordsLoopInitArg1 = { "macros", iocshArgString };
212 static const iocshArg dbLoadRecordsLoopInitArg2 = { "loopVar", iocshArgString };
213 static const iocshArg dbLoadRecordsLoopInitArg3 = { "start", iocshArgInt };
214 static const iocshArg dbLoadRecordsLoopInitArg4 = { "stop", iocshArgInt };
215 static const iocshArg dbLoadRecordsLoopInitArg5 = { "step", iocshArgInt };
218 
219 static const iocshArg dbLoadRecordsListInitArg0 = { "dbFile", iocshArgString };
220 static const iocshArg dbLoadRecordsListInitArg1 = { "macros", iocshArgString };
221 static const iocshArg dbLoadRecordsListInitArg2 = { "loopVar", iocshArgString };
222 static const iocshArg dbLoadRecordsListInitArg3 = { "list", iocshArgString };
223 static const iocshArg dbLoadRecordsListInitArg4 = { "sep", iocshArgString };
225  &dbLoadRecordsListInitArg2, &dbLoadRecordsListInitArg3, &dbLoadRecordsListInitArg4 };
226 
227 static const iocshFuncDef dbLoadRecordsLoopDef = {"dbLoadRecordsLoop", sizeof(dbLoadRecordsLoopInitArgs) / sizeof(iocshArg*), dbLoadRecordsLoopInitArgs};
228 
229 static const iocshFuncDef dbLoadRecordsListDef = {"dbLoadRecordsList", sizeof(dbLoadRecordsListInitArgs) / sizeof(iocshArg*), dbLoadRecordsListInitArgs};
230 
231 static void dbLoadRecordsLoopInitCallFunc(const iocshArgBuf *args)
232 {
233  dbLoadRecordsLoop(args[0].sval, args[1].sval, args[2].sval, args[3].ival, args[4].ival, args[5].ival);
234 }
235 
236 static void dbLoadRecordsListInitCallFunc(const iocshArgBuf *args)
237 {
238  dbLoadRecordsList(args[0].sval, args[1].sval, args[2].sval, args[3].sval, args[4].sval);
239 }
240 
241 static void dbLoadRecordsFuncsRegister(void)
242 {
243  iocshRegister(&dbLoadRecordsLoopDef, dbLoadRecordsLoopInitCallFunc);
244  iocshRegister(&dbLoadRecordsListDef, dbLoadRecordsListInitCallFunc);
245 }
246 
247 epicsExportRegistrar(dbLoadRecordsFuncsRegister); // need to be declared via registrar() in utilities.dbd too
248 
249 }
static const iocshFuncDef dbLoadRecordsLoopDef
static const iocshArg dbLoadRecordsLoopInitArg3
start loop value
static void subMacros(std::string &new_macros, const char *macros, const char *loopVar)
look for e.g. $(I) and replace with so we can substitute later with macEnvExpand() ...
static const iocshArg *const dbLoadRecordsLoopInitArgs[]
static const iocshArg dbLoadRecordsListInitArg1
macros to pass to dbFile
static const iocshArg *const dbLoadRecordsListInitArgs[]
epicsShareFunc void dbLoadRecordsList(const char *dbFile, const char *macros, const char *loopVar, const char *list, const char *sep)
Load a db file multiple times according to a list of items separated by known separator(s).
static const iocshArg dbLoadRecordsLoopInitArg0
DB filename.
static const iocshArg dbLoadRecordsLoopInitArg2
loop macro variable name
static const iocshArg dbLoadRecordsLoopInitArg1
macros to pass to dbFile
static const iocshArg dbLoadRecordsListInitArg2
list macro variable name
static const iocshArg dbLoadRecordsListInitArg4
list value separator character
static const iocshFuncDef dbLoadRecordsListDef
static const iocshArg dbLoadRecordsLoopInitArg5
loop step (default: 1)
static void dbLoadRecordsLoopInitCallFunc(const iocshArgBuf *args)
static const iocshArg dbLoadRecordsListInitArg3
list of values to substitute
static const iocshArg dbLoadRecordsListInitArg0
DB filename.
static void dbLoadRecordsListInitCallFunc(const iocshArgBuf *args)
static const iocshArg dbLoadRecordsLoopInitArg4
end loop value
static void dbLoadRecordsFuncsRegister(void)
epicsExportRegistrar(dbLoadRecordsFuncsRegister)
static void loadMacEnviron(MAC_HANDLE *pmh)
load current environment into mac handle
epicsShareFunc void dbLoadRecordsLoop(const char *dbFile, const char *macros, const char *loopVar, int start, int stop, int step)
Load a db file multiple times substituting a specified macro according to a number range...
Copyright © 2013 Science and Technology Facilities Council | Generated by   doxygen 1.8.5