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