ARB
ut_valgrinded.h
Go to the documentation of this file.
1 // ================================================================ //
2 // //
3 // File : ut_valgrinded.h //
4 // Purpose : wrapper to call subprocesses inside valgrind //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in February 2011 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // ================================================================ //
11 
12 #ifndef UT_VALGRINDED_H
13 #define UT_VALGRINDED_H
14 
15 inline const char *find_pipe_symbol(const char *str) {
16  const char *found = strchr(str, '|');
17  while (found && found>str && found[-1] == '\\') { // skip over escaped pipe-symbols
18  found = strchr(found+1, '|');
19  }
20  return found;
21 }
22 
23 
24 #ifdef UNIT_TESTS
25 
26 #ifndef ARB_MSG_H
27 #include <arb_msg.h>
28 #endif
29 #ifndef ARB_STRING_H
30 #include <arb_string.h>
31 #endif
32 #ifndef _SYS_STAT_H
33 #include <sys/stat.h>
34 #endif
35 
36 #define UTVG_CALL_SEEN "flag.valgrind.callseen"
37 
38 namespace utvg {
39 
40  inline const char *flag_name(const char *name) {
41  const char *ARBHOME = getenv("ARBHOME");
42  const int BUFSIZE = 200;
43  static char buf[BUFSIZE];
44 
45  IF_ASSERTION_USED(int printed =)
46  snprintf(buf, BUFSIZE, "%s/UNIT_TESTER/valgrind/%s", ARBHOME, name);
47  arb_assert(printed<BUFSIZE);
48 
49  return buf;
50  }
51  inline bool flag_exists(const char *name) {
52  const char *path = flag_name(name);
53  struct stat stt;
54 
55  return stat(path, &stt) == 0 && S_ISREG(stt.st_mode);
56  }
57  inline void raise_flag(const char *name) {
58  const char *path = flag_name(name);
59  FILE *fp = fopen(path, "w");
60  arb_assert(fp);
61  fclose(fp);
62  }
63 
64  struct valgrind_info {
65  bool wanted;
66  bool leaks;
67  bool reachable;
68 
69  valgrind_info() {
70  // The following flag files are generated by ../UNIT_TESTER/Makefile.suite
71  // which reads the settings from ../UNIT_TESTER/Makefile.setup.local
72  wanted = flag_exists("flag.valgrind");
73  leaks = flag_exists("flag.valgrind.leaks");
74  reachable = flag_exists("flag.valgrind.reachable");
75  }
76  };
77 
78  inline const valgrind_info& get_valgrind_info() {
79  static valgrind_info vinfo;
80  return vinfo;
81  }
82 };
83 
84 inline void make_valgrinded_call(char *&command) { // @@@ eliminate valgrind support (too many hacks)
85  using namespace utvg;
86 
87  arb_assert(!find_pipe_symbol(command));
88 
89  const valgrind_info& valgrind = get_valgrind_info();
90  if (valgrind.wanted) {
91  const char *switches = valgrind.leaks ? (valgrind.reachable ? "-l -r" : "-l") : "";
92  char *valgrinded_command = GBS_global_string_copy("$ARBHOME/UNIT_TESTER/valgrind/arb_valgrind_logged CALL %s -c 15 %s", switches, command);
93  freeset(command, valgrinded_command);
94 
95  utvg::raise_flag(UTVG_CALL_SEEN);
96  }
97 }
98 
99 inline bool will_valgrind_calls() { return utvg::get_valgrind_info().wanted; }
100 inline bool seen_valgrinded_call() { return utvg::flag_exists(UTVG_CALL_SEEN); }
101 
102 #else // !UNIT_TESTS
103 
104 #define make_valgrinded_call(command) arb_assert(!find_pipe_symbol(command))
105 inline bool will_valgrind_calls() { return false; }
106 inline bool seen_valgrinded_call() { return false; }
107 
108 #endif // UNIT_TESTS
109 
110 
111 #else
112 #error ut_valgrinded.h included twice
113 #endif // UT_VALGRINDED_H
#define arb_assert(cond)
Definition: arb_assert.h:245
const char * find_pipe_symbol(const char *str)
Definition: ut_valgrinded.h:15
bool seen_valgrinded_call()
#define make_valgrinded_call(command)
#define IF_ASSERTION_USED(x)
Definition: arb_assert.h:308
bool will_valgrind_calls()
static char * command
Definition: arb_a2ps.c:319
#define BUFSIZE
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
GB_write_int const char s
Definition: AW_awar.cxx:154