ISIS Logo
UTILITIES
EPICS Utilities
iocdcalc.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 double in resultVar
53 // 0x1: verbose
54 static void iocdcalc(const char* resultvar, const char* expression, int options, int precision)
55 {
56  if (resultvar == NULL || expression == NULL)
57  {
58  errlogPrintf("iocdcalc: ERROR: NULL args");
59  return;
60  }
61  bool verbose = (options & 0x1);
62  char* expr_expand = macEnvExpand(expression);
63  if (expr_expand == NULL)
64  {
65  errlogPrintf("iocdcalc: ERROR: NULL expanded expression arg");
66  return;
67  }
68  if (verbose)
69  {
70  printf("iocdcalc: expanded expression=\"%s\"\n", expr_expand);
71  }
72  short calc_error;
73  static const int CALC_NARGS = 12; // named A to L
74  std::vector<double> parg(CALC_NARGS);
75  for(int i=0; i<CALC_NARGS; ++i)
76  {
77  parg[i] = 0.0;
78  }
79  double result;
80  // need at add extra space to INFIX_TO_POSTFIX_SIZE - bug?
81  boost::scoped_array<char> ppostfix(new char[INFIX_TO_POSTFIX_SIZE(strlen(expr_expand)) + 100]); // cannot use std::unique_ptr<char[]> yet
82  if ( postfix(expr_expand, ppostfix.get(), &calc_error) != 0 )
83  {
84  errlogPrintf("iocdcalc: ERROR: postfix: %s\n", calcErrorStr(calc_error));
85  return;
86  }
87  if ( calcPerform(&(parg[0]), &result, ppostfix.get()) != 0 )
88  {
89  errlogPrintf("iocdcalc: ERROR: calcPerform: %s\n", "");
90  return;
91  }
92  char result_str[32];
93  double dsmall = 1.0E-20;
94  std::ostringstream format_str;
95 
96  format_str << "%";
97  if (precision > 0)
98  {
99  format_str << "." << precision;
100  }
101  format_str << "f";
102  if ( sprintf(result_str, format_str.str().c_str(), result) < 0 )
103  {
104  errlogPrintf("iocdcalc: ERROR: sprintf: %s\n", format_str.str().c_str());
105  return;
106  }
107 
108  epicsEnvSet(resultvar, result_str);
109  free(expr_expand);
110 }
111 
112 extern "C" {
113 
114 // EPICS iocsh shell commands
115 
116 // calc "result" "expression"
117 static const iocshArg dcalcInitArg0 = { "resultvar", iocshArgString };
118 static const iocshArg dcalcInitArg1 = { "expression", iocshArgString };
119 static const iocshArg dcalcInitArg2 = { "options", iocshArgInt };
120 static const iocshArg dcalcInitArg3 = { "precision", iocshArgInt };
121 static const iocshArg * const dcalcInitArgs[] = { &dcalcInitArg0, &dcalcInitArg1, &dcalcInitArg2, &dcalcInitArg3 };
122 
123 static const iocshFuncDef dcalcInitFuncDef = {"dcalc", sizeof(dcalcInitArgs) / sizeof(iocshArg*), dcalcInitArgs};
124 
125 static void dcalcInitCallFunc(const iocshArgBuf *args)
126 {
127  iocdcalc(args[0].sval, args[1].sval, args[2].ival, args[3].ival);
128 }
129 
130 static void iocdcalcRegister(void)
131 {
132  iocshRegister(&dcalcInitFuncDef, dcalcInitCallFunc);
133 }
134 
135 epicsExportRegistrar(iocdcalcRegister); // need to be declared via registrar() in utilities.dbd too
136 
137 // asub callable functions - need to be in utilities.dbd as function()
138 
139 //epicsRegisterFunction(setIOCName);
140 //epicsRegisterFunction(getIOCName);
141 //epicsRegisterFunction(getIOCGroup);
142 
143 }
144 
static void iocdcalc(const char *resultvar, const char *expression, int options, int precision)
Definition: iocdcalc.cpp:54
static void iocdcalcRegister(void)
Definition: iocdcalc.cpp:130
static const iocshFuncDef dcalcInitFuncDef
Definition: iocdcalc.cpp:123
static const iocshArg *const dcalcInitArgs[]
Definition: iocdcalc.cpp:121
static const iocshArg dcalcInitArg3
Definition: iocdcalc.cpp:120
static const iocshArg dcalcInitArg2
Definition: iocdcalc.cpp:119
static const iocshArg dcalcInitArg0
Definition: iocdcalc.cpp:117
static void dcalcInitCallFunc(const iocshArgBuf *args)
Definition: iocdcalc.cpp:125
epicsExportRegistrar(dbLoadRecordsFuncsRegister)
static const iocshArg dcalcInitArg1
Definition: iocdcalc.cpp:118
Copyright © 2013 Science and Technology Facilities Council | Generated by   doxygen 1.8.5