mrfioc2  2.3.0
mrfCommon.cpp
Go to the documentation of this file.
1 #include <stdexcept>
2 #include <iomanip>
3 
4 #include <errno.h>
5 #include <limits.h>
6 #include <stdlib.h>
7 
8 #include <epicsStdio.h>
9 #include <epicsExport.h>
10 #include "mrfCommon.h"
11 
12 int MRFVersion::compare(const MRFVersion& o) const
13 {
14  if(m_major<o.m_major)
15  return -1;
16  else if(m_major>o.m_major)
17  return 1;
18  else if(m_minor<o.m_minor)
19  return -1;
20  else if(m_minor>o.m_minor)
21  return 1;
22  else
23  return 0;
24 }
25 
26 std::string MRFVersion::str() const
27 {
28  std::ostringstream strm;
29  strm<<(*this);
30  return strm.str();
31 }
32 
33 std::ostream& operator<<(std::ostream& strm, const MRFVersion& ver)
34 {
35  strm<<std::hex<<ver.firmware()
36  <<std::hex<<std::setfill('0')<<std::setw(2)<<ver.revision()
37  <<'.'
38  <<((ver.subrelease()<0) ? "-" : "")
39  <<abs(ver.subrelease());
40  return strm;
41 }
42 
43 epicsUInt32 roundToUInt(double val, epicsUInt32 max)
44 {
45  if(!isfinite(val))
46  throw std::range_error("Value not finite");
47 
48  else if(val<0)
49  throw std::range_error("Negative value not allowed");
50 
51  val+=0.5;
52 
53  if(val>(double)max)
54  throw std::range_error("Value too large");
55 
56  return (epicsUInt32)val;
57 }
58 
59 char *allocSNPrintf(size_t N, const char *fmt, ...)
60 {
61  char *mem = (char*)calloc(1, N);
62  if(!mem)
63  throw std::bad_alloc();
64 
65  va_list args;
66 
67  va_start(args, fmt);
68 
69  epicsVsnprintf(mem, N, fmt, args);
70 
71  va_end(args);
72 
73  mem[N-1] = '\0';
74 
75  return mem;
76 }
77 
78 #if (EPICS_VERSION_INT < VERSION_INT(3,15,0,2))
79 
80 static
81 int
82 epicsParseULong(const char *str, unsigned long *to, int base, char **units)
83 {
84  int c;
85  char *endp;
86  unsigned long value;
87 
88  while ((c = *str) && isspace(c))
89  ++str;
90 
91  errno = 0;
92  value = strtoul(str, &endp, base);
93 
94  if (endp == str)
95  return S_stdlib_noConversion;
96  if (errno == EINVAL) /* Not universally supported */
97  return S_stdlib_badBase;
98  if (errno == ERANGE)
99  return S_stdlib_overflow;
100 
101  while ((c = *endp) && isspace(c))
102  ++endp;
103  if (c && !units)
104  return S_stdlib_extraneous;
105 
106  *to = value;
107  if (units)
108  *units = endp;
109  return 0;
110 }
111 
112 int
113 epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units)
114 {
115  unsigned long value;
116  int status = epicsParseULong(str, &value, base, units);
117 
118  if (status)
119  return status;
120 
121 #if (ULONG_MAX > 0xffffffffULL)
122  if (value > 0xffffffffUL && value <= ~0xffffffffUL)
123  return S_stdlib_overflow;
124 #endif
125 
126  *to = (epicsUInt32) value;
127  return 0;
128 }
129 
130 #endif
#define S_stdlib_badBase
Definition: mrfCommon.h:379
int epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units)
Definition: mrfCommon.cpp:113
#define isfinite
Definition: mrfCommon.h:326
Definition: evrdump.c:37
std::ostream & operator<<(std::ostream &strm, const MRFVersion &ver)
Definition: mrfCommon.cpp:33
char * allocSNPrintf(size_t N, const char *fmt,...)
Definition: mrfCommon.cpp:59
#define S_stdlib_noConversion
Definition: mrfCommon.h:375
#define S_stdlib_overflow
Definition: mrfCommon.h:378
epicsUInt32 roundToUInt(double val, epicsUInt32 max)
Definition: mrfCommon.cpp:43
#define S_stdlib_extraneous
Definition: mrfCommon.h:376