EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_functions.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ functions
5 # Copyright (C) 2015 National Research Council Canada
6 #
7 # This file is part of EGSnrc.
8 #
9 # EGSnrc is free software: you can redistribute it and/or modify it under
10 # the terms of the GNU Affero General Public License as published by the
11 # Free Software Foundation, either version 3 of the License, or (at your
12 # option) any later version.
13 #
14 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU Affero General Public License
20 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21 #
22 ###############################################################################
23 #
24 # Author: Iwan Kawrakow, 2005
25 #
26 # Contributors: Ernesto Mainegra-Hing
27 #
28 ###############################################################################
29 */
30 
31 
37 #include "egs_functions.h"
38 #include "egs_application.h"
39 
40 #include <cstdio>
41 #include <cstdarg>
42 #include <cstdlib>
43 #include <cctype>
44 
45 #ifdef WIN32
46  const char __egs_fs = 92;
47 #else
48  const char __egs_fs = '/';
49 #endif
50 
51 /*
52 extern "C" void __attribute__((destructor)) finish_egspp_library() {
53  egsInformation("In finish_egspp_library()\n");
54 }
55 */
56 
57 bool EGS_EXPORT egsStoreI64(ostream &data, EGS_I64 n) {
58  EGS_I64 i1 = n;
59  i1 /= 1000000000;
60  EGS_I64 i2 = n % 1000000000;
61  data << " " << (int) i1 << " " << (int) i2;
62  if (data.fail()) {
63  return false;
64  }
65  return true;
66 }
67 
68 bool EGS_EXPORT egsGetI64(istream &data, EGS_I64 &n) {
69  int i1, i2;
70  data >> i1 >> i2;
71  if (data.eof() || !data.good()) {
72  return false;
73  }
74  n = i1;
75  n *= 1000000000;
76  n += i2;
77  return true;
78 }
79 
80 static FILE *egs_info_fp = stdout;
81 static FILE *egs_warning_fp = stderr;
82 static FILE *egs_error_fp = stderr;
83 
84 static EGS_LOCAL char __egsf_write_buf[8192];
85 
86 static void EGS_LOCAL __egs_default_information(const char *msg, ...) {
87  va_list ap;
88  va_start(ap, msg);
90  if (a) {
91  vsprintf(__egsf_write_buf,msg,ap);
92  a->appInformation(__egsf_write_buf);
93  }
94  else {
95  vfprintf(egs_info_fp, msg, ap);
96  fflush(egs_info_fp);
97  }
98  va_end(ap);
99 }
100 
101 static void EGS_LOCAL __egs_default_warning(const char *msg, ...) {
102  va_list ap;
103  va_start(ap, msg);
105  if (a) {
106  vsprintf(__egsf_write_buf,msg,ap);
107  a->appWarning(__egsf_write_buf);
108  }
109  else {
110 
111  vfprintf(egs_warning_fp, msg, ap);
112  fflush(egs_warning_fp);
113  }
114  va_end(ap);
115 }
116 
117 static void EGS_LOCAL __egs_default_error(const char *msg, ...) {
118  va_list ap;
119  va_start(ap, msg);
121  if (a) {
122  vsprintf(__egsf_write_buf,msg,ap);
123  va_end(ap);
124  a->appFatal(__egsf_write_buf);
125  }
126  else {
127  vfprintf(egs_error_fp, msg, ap);
128  fflush(stderr);
129  va_end(ap);
130  exit(1);
131  }
132 }
133 
134 EGS_InfoFunction EGS_EXPORT egsInformation = __egs_default_information;
135 EGS_InfoFunction EGS_EXPORT egsWarning = __egs_default_warning;
136 EGS_InfoFunction EGS_EXPORT egsFatal = __egs_default_error;
137 
139  if (!func) {
140  egsWarning("egsSetInfoFunction: info function can not be NULL!\n");
141  return 0;
142  }
143  EGS_InfoFunction res;
144  switch (t) {
145  case Information:
146  res = egsInformation;
147  egsInformation = func;
148  break;
149  case Warning:
150  res = egsWarning;
151  egsWarning = func;
152  break;
153  case Fatal:
154  res = egsFatal;
155  egsFatal = func;
156  break;
157  default:
158  egsWarning("Unknown info function type\n");
159  res = 0;
160  }
161  return res;
162 }
163 
165  egsInformation = __egs_default_information;
166  egsWarning = __egs_default_warning;
167  egsFatal = __egs_default_error;
168 }
169 
170 template <class T> void __egs_swap_bytes(T *v) {
171  char *c = (char *) v;
172  char tmp = c[0];
173  c[0]=c[3];
174  c[3]=tmp;
175  tmp = c[1];
176  c[1]=c[2];
177  c[2]=tmp;
178 }
179 
180 void egsSwapBytes(int *n) {
181  __egs_swap_bytes<int>(n);
182 }
183 void egsSwapBytes(float *n) {
184  __egs_swap_bytes<float>(n);
185 }
186 
187 void egsSwapBytes(short *n) {
188  char *c = (char *) n;
189  char tmp=c[0];
190  c[0]=c[1];
191  c[1]=tmp;
192 }
193 
194 string egsJoinPath(const string &first, const string &second) {
195  int n = first.size()-1;
196  char c = first[n];
197  string result(first);
198  if (c == '/' && c != __egs_fs) {
199  result[n] = __egs_fs;
200  }
201  if (result[n] != __egs_fs) {
202  result += __egs_fs;
203  }
204  result += second;
205  return result;
206 }
207 
208 /* Expand first environment variable found anywhere in string aname
209 
210  - Checks for Unix or Windows style environment variable
211  - Expands environment variable in aname appending folder
212  separator if missing
213  - Replaces backslashes with slashes
214  - Checks for duplicate slashes in aname
215 */
216 string egsExpandPath(const string &aname) {
217  string str = aname;
218  string c = "%$";
219  // Check for FIRST environment variable anywhere in aname
220  size_t p1= str.npos;
221  int i = 0;
222  while (i < c.size()) {
223  p1= str.find_first_of(c[i++]);
224  if (p1 != str.npos) {
225  break;
226  }
227  }
228  string fs = "%/\\";
229  i = 0;
230  size_t p2 = str.npos;
231  while (p1 != str.npos && i < fs.size()) {
232  p2 = str.find_first_of(fs[i++],p1+1);
233  if (p2 != str.npos) {
234  break;
235  }
236  }
237  // Did we find an environment variable?
238  if (p1 != str.npos && p2 != str.npos) {
239  string envvar = str.substr(p1+1, p2-(p1+1));
240  char *envval = getenv(envvar.c_str());
241  // Check that env var is defined
242  string envloc = envval ? string(envval) : string();
243  if (!envloc.empty()) {
244  // Append missing separator
245  size_t last = envloc.find_last_of("/\\");
246  if (last != envloc.size()-1) {
247  if (envloc[last] == __egs_fs) {
248  envloc.append("\\");
249  }
250  else {
251  envloc.append("/");
252  }
253  }
254  str.replace(p1, p2-p1+1,envloc);
255  }
256  else {
257  if (str[p1] == '$') {
258  egsWarning("\n\n *** egs++ egsExpandPath: Undefined environment variable $%s \n\n", envvar.c_str());
259  }
260  else {
261  egsWarning("\n\n *** egs++ egsExpandPath: Undefined environment variable %%%s%% \n\n", envvar.c_str());
262  }
263  }
264  }
265  // Replace back slashes with slashes
266  size_t found = str.find("\\");
267  while (found != str.npos) {
268  str.replace(found,1,"/");
269  found = str.find("\\");
270  }
271  // Remove duplicated slashes
272  found = str.find("//");
273  while (found != str.npos) {
274  str.replace(found,2,"/");
275  found = str.find("//");
276  }
277 
278  return str;
279 }
280 
281 string egsStripPath(const string &aname) {
282  int j;
283  for (j=aname.size()-1; j>=0; j--) {
284  if (aname[j] == '/' || aname[j] == __egs_fs) {
285  j++;
286  break;
287  }
288  }
289  if (j < 0) {
290  return aname;
291  }
292  string result;
293  if (j >= 0) {
294  while (j < aname.size()) {
295  result += aname[j++];
296  }
297  }
298  return result;
299 }
300 
301 #ifdef WIN32
302  #include <process.h>
303 #else
304  #include <sys/types.h>
305  #include <unistd.h>
306 #endif
307 
308 string egsHostName() {
309 #ifdef WIN32
310  // Windows has the gethostname() function but it only works after
311  // calling WSAStartup and in addition we have to link against the
312  // ws2_32 DLL. This is pretty stupid as we just want to get the host name =>
313  // we try to get the host name from environment variables.
314  char *var = getenv("COMPUTERNAME");
315  if (!var) {
316  var = getenv("HOSTNAME");
317  if (!var) {
318  var = getenv("HOST");
319  }
320  }
321  if (!var) {
322  return "unknown";
323  }
324  return var;
325 #else
326  char buf[1024];
327  int err = gethostname(buf,1023);
328  if (err) {
329  return "unknown";
330  }
331  return buf;
332 #endif
333 }
334 
335 int egsGetPid() {
336 #ifdef WIN32
337  return _getpid();
338 #else
339  return getpid();
340 #endif
341 }
342 
343 string egsSimplifyCVSKey(const string &key) {
344  if (key.size() < 2) {
345  return key;
346  }
347  int js;
348  for (js=0; js<key.size(); js++) if (key[js] == '$') {
349  break;
350  }
351  if (js >= key.size()) {
352  return key;
353  }
354  int je;
355  for (je=key.size()-1; je>=0; je--) if (key[je] == '$') {
356  break;
357  }
358  if (je <= js) {
359  return key;
360  }
361  string result;
362  for (int j=js+1; j<je; j++) {
363  result += key[j];
364  }
365  return result;
366 }
367 
369  int nl = 0x12345678;
370  unsigned char *p = (unsigned char *)(&nl);
371  if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78) {
372  return 0;
373  }
374  if (p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12) {
375  return 1;
376  }
377  return -1;
378 }
379 
380 bool egsIsAbsolutePath(const string &path) {
381 #ifdef WIN32
382  if (path.size() < 2) {
383  return false;
384  }
385  if ((path[0] == '/' || path[0] == __egs_fs) &&
386  (path[1] == '/' || path[1] == __egs_fs)) {
387  return true;
388  }
389  if (path.size() < 3) {
390  return false;
391  }
392  if (!isalpha(path[0])) {
393  return false;
394  }
395  if (path[1] != ':') {
396  return false;
397  }
398  if (path[2] != '/' && path[2] != __egs_fs) {
399  return false;
400  }
401  return true;
402 #else
403  return (path[0] == '/');
404 #endif
405 }
406 
407 bool egsEquivStr(const string &a, const string &b) {
408  unsigned int sz = a.size();
409  if (b.size() != sz) {
410  return false;
411  }
412  for (unsigned int i = 0; i < sz; ++i)
413  if (tolower(a[i]) != tolower(b[i])) {
414  return false;
415  }
416  return true;
417 }
#define EGS_EXPORT
Export symbols from the egspp library.
Definition: egs_libconfig.h:90
string egsStripPath(const string &aname)
Strip the path from a file name and return the result.
bool EGS_EXPORT egsGetI64(istream &data, EGS_I64 &n)
Reads a 64 bit integer from the stream data and assigns it to n. Returns true on success, false on failure.
int egsGetPid()
Get the process id.
bool egsIsAbsolutePath(const string &path)
Does the string path represent an absolute path name?
bool EGS_EXPORT egsStoreI64(ostream &data, EGS_I64 n)
Writes the 64 bit integer n to the output stream data and returns true on success, false on failure.
string egsJoinPath(const string &first, const string &second)
Join two path variables (or a path and a file name) using the platform specific directory separator a...
EGS_InfoFunction egsSetInfoFunction(EGS_InfoType t, EGS_InfoFunction func)
Set a function to be used for outputing information, warning messages or reporting fatal errors...
void egsSetDefaultIOFunctions()
Reset I/O functions to their defaults.
Global egspp functions header file.
virtual void appInformation(const char *)
Write an information message.
void egsSwapBytes(int *n)
Swap the bytes of 32 bit integers.
virtual void appFatal(const char *)
Write a warning message and exit.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
string egsExpandPath(const string &aname)
Expands first environment variable found in a file name.
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
int egsGetEndian()
Get the endianess of the machine.
static EGS_Application * activeApplication()
Get the active application.
string egsSimplifyCVSKey(const string &key)
Remove the $&#39;s from a CVS key.
virtual void appWarning(const char *)
Write a warning message.
void(* EGS_InfoFunction)(const char *,...)
Defines a function printf-like prototype for functions to be used to report info, warnings...
EGS_Application class header file.
Base class for advanced EGSnrc C++ applications.
string egsHostName()
Get the name of the host the program is running on.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.