ISIS Logo
UTILITIES
EPICS Utilities
ioccalc.cpp
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <errno.h>
5 #include <math.h>
6 #include <exception>
7 #include <algorithm>
8 #include <stdexcept>
9 #include <iostream>
10 #include <map>
11 #include <list>
12 #include <string>
13 #include <time.h>
14 #include <sstream>
15 #include <fstream>
16 #include <vector>
17 #include <memory>
18 
19 #include "epicsStdlib.h"
20 #include "epicsString.h"
21 #include "dbDefs.h"
22 #include "epicsMutex.h"
23 #include "dbBase.h"
24 #include "dbStaticLib.h"
25 #include "dbFldTypes.h"
26 #include "dbCommon.h"
27 #include "dbAccessDefs.h"
28 #include <epicsTypes.h>
29 #include <epicsTime.h>
30 #include <epicsThread.h>
31 #include <epicsString.h>
32 #include <epicsTimer.h>
33 #include <epicsMutex.h>
34 #include <iocsh.h>
35 #include "envDefs.h"
36 #include "macLib.h"
37 #include "errlog.h"
38 
39 #include "postfix.h"
40 #include "cvtFast.h"
41 
42 #include <boost/scoped_array.hpp>
43 
44 #include <string.h>
45 #include <registryFunction.h>
46 
47 #include <epicsExport.h>
48 
49 #include "utilities.h"
50 
51 // options
52 // default: perform calc and return integer in resultVar
53 // 0x1: verbose
54 // 0x2: zero pad to specified length
55 // 0x4: if true ( !=0 ) then return ' ', if false ( ==0 ) return '#'
56 static void ioccalc(const char* resultvar, const char* expression, int options, int length)
57 {
58  if (resultvar == NULL || expression == NULL)
59  {
60  errlogPrintf("ioccalc: ERROR: NULL args");
61  return;
62  }
63  bool verbose = (options & 0x1);
64  bool zero_pad = (options & 0x2);
65  bool hash_mode = (options & 0x4);
66  char* expr_expand = macEnvExpand(expression);
67  if (expr_expand == NULL)
68  {
69  errlogPrintf("ioccalc: ERROR: NULL expanded expression arg");
70  return;
71  }
72  if (verbose)
73  {
74  printf("ioccalc: expanded expression=\"%s\"\n", expr_expand);
75  }
76  short calc_error;
77  static const int CALC_NARGS = 12; // named A to L
78  std::vector<double> parg(CALC_NARGS);
79  for(int i=0; i<CALC_NARGS; ++i)
80  {
81  parg[i] = 0.0;
82  }
83  double result;
84  // need at add extra space to INFIX_TO_POSTFIX_SIZE - bug?
85  boost::scoped_array<char> ppostfix(new char[INFIX_TO_POSTFIX_SIZE(strlen(expr_expand)) + 100]); // cannot use std::unique_ptr<char[]> yet
86  if ( postfix(expr_expand, ppostfix.get(), &calc_error) != 0 )
87  {
88  errlogPrintf("ioccalc: ERROR: postfix: %s\n", calcErrorStr(calc_error));
89  return;
90  }
91  if ( calcPerform(&(parg[0]), &result, ppostfix.get()) != 0 )
92  {
93  errlogPrintf("ioccalc: ERROR: calcPerform: %s\n", "");
94  return;
95  }
96  long long_result = static_cast<long>(floor(result + 0.5));
97  char result_str[32];
98  std::ostringstream format_str;
99  if (hash_mode)
100  {
101  if ( sprintf(result_str, "%s", (long_result != 0 ? " " : "#")) < 0 )
102  {
103  errlogPrintf("ioccalc: ERROR: sprintf (hash mode)\n");
104  return;
105  }
106  }
107  else
108  {
109  format_str << "%";
110  if (zero_pad)
111  {
112  format_str << "0";
113  }
114  if (length > 0)
115  {
116  format_str << length;
117  }
118  format_str << "ld";
119  if ( sprintf(result_str, format_str.str().c_str(), long_result) < 0 )
120  {
121  errlogPrintf("ioccalc: ERROR: sprintf: %s\n", format_str.str().c_str());
122  return;
123  }
124  }
125  if (verbose)
126  {
127  printf("ioccalc: setting %s=\"%s\" (%g)\n", resultvar, result_str, result);
128  // print out parg array too for info? (values assigned to A, B, C parameters in exporession)
129  }
130  epicsEnvSet(resultvar, result_str);
131  free(expr_expand);
132 }
133 
134 extern "C" {
135 
136 // EPICS iocsh shell commands
137 
138 // calc "result" "expression"
139 static const iocshArg calcInitArg0 = { "resultvar", iocshArgString };
140 static const iocshArg calcInitArg1 = { "expression", iocshArgString };
141 static const iocshArg calcInitArg2 = { "options", iocshArgInt };
142 static const iocshArg calcInitArg3 = { "length", iocshArgInt };
143 static const iocshArg * const calcInitArgs[] = { &calcInitArg0, &calcInitArg1, &calcInitArg2, &calcInitArg3 };
144 
145 static const iocshFuncDef calcInitFuncDef = {"calc", sizeof(calcInitArgs) / sizeof(iocshArg*), calcInitArgs};
146 
147 static void calcInitCallFunc(const iocshArgBuf *args)
148 {
149  ioccalc(args[0].sval, args[1].sval, args[2].ival, args[3].ival);
150 }
151 
152 static void ioccalcRegister(void)
153 {
154  iocshRegister(&calcInitFuncDef, calcInitCallFunc);
155 }
156 
157 epicsExportRegistrar(ioccalcRegister); // need to be declared via registrar() in utilities.dbd too
158 
159 // asub callable functions - need to be in utilities.dbd as function()
160 
161 //epicsRegisterFunction(setIOCName);
162 //epicsRegisterFunction(getIOCName);
163 //epicsRegisterFunction(getIOCGroup);
164 
165 }
166 
static void ioccalcRegister(void)
Definition: ioccalc.cpp:152
static const iocshFuncDef calcInitFuncDef
Definition: ioccalc.cpp:145
static const iocshArg *const calcInitArgs[]
Definition: ioccalc.cpp:143
static const iocshArg calcInitArg0
Definition: ioccalc.cpp:139
static void ioccalc(const char *resultvar, const char *expression, int options, int length)
Definition: ioccalc.cpp:56
static const iocshArg calcInitArg3
Definition: ioccalc.cpp:142
static const iocshArg calcInitArg2
Definition: ioccalc.cpp:141
static void calcInitCallFunc(const iocshArgBuf *args)
Definition: ioccalc.cpp:147
static const iocshArg calcInitArg1
Definition: ioccalc.cpp:140
epicsExportRegistrar(dbLoadRecordsFuncsRegister)
Copyright © 2013 Science and Technology Facilities Council | Generated by   doxygen 1.8.5