Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
util.cpp
Go to the documentation of this file.
1
27#include <assert.h> /* for assert */
28#include <errno.h> /* for errno */
29#include <signal.h> /* for sigaction(), signal() */
30#include <stdio.h> /* for vfprintf */
31#include <stdlib.h> /* for exit, malloc */
32#include <stdarg.h> /* for va_* */
33#include <string.h> /* for strerror */
34
35#include <sys/stat.h> /* for stat() */
36#include <sys/types.h> /* for size_t */
37
38#ifndef _WIN32
39# include <unistd.h> /* for sleep() */
40#else
41# include <windows.h> /* for Sleep() */
42#endif /* _WIN32 */
43
44
45#include "cmdopt.h" /* for exe_name, target_name */
46
47#include "util.h"
48
49
50#ifdef _WIN32
51# define DEV_NULL "NUL:"
52#else
53# define DEV_NULL "/dev/null"
54#endif // _WIN32
55
56
57void
58warn (const char* const format, ...)
59{
60 const char* const target_name = get_target ();
61 va_list args;
62
63 assert (0 != format);
64
65 if (target_name)
66 fprintf (stderr, "%s (%s): ", exe_name, target_name);
67 else
68 fprintf (stderr, "%s: ", exe_name);
69
70 va_start (args, format);
71 vfprintf (stderr, format, args);
72 va_end (args);
73}
74
75void
76terminate (const int state, const char* const format, ...)
77{
78 const char* const target_name = get_target ();
79 va_list args;
80
81 assert (0 != format);
82 assert (0 != state);
83
84 if (target_name)
85 fprintf (stderr, "%s (%s): ", exe_name, target_name);
86 else
87 fprintf (stderr, "%s: ", exe_name);
88
89 va_start (args, format);
90 vfprintf (stderr, format, args);
91 va_end (args);
92
93 exit (state);
94}
95
96void*
97guarded_malloc (const size_t size, const char* const file, const unsigned line)
98{
99 void* alloc;
100
101 assert (0 != file);
102 assert (0 < size);
103
104 alloc = malloc (size);
105
106 if (0 == alloc)
107 terminate (1, "malloc (%lu) at line %u of %s failed: %s\n",
108 (unsigned long)size, line, file, strerror (errno));
109
110 return alloc;
111}
112
113void*
114guarded_realloc (void* source, const size_t size, const char* const file,
115 const unsigned line)
116{
117 void* alloc;
118
119 assert (0 != file);
120 assert (0 < size);
121
122 alloc = realloc (source, size);
123
124 if (0 == alloc)
125 terminate (1, "malloc(%lu) at line %u of %s failed: %s\n",
126 (unsigned long)size, line, file, strerror (errno));
127
128 return alloc;
129}
130
131char*
132reference_name (const char* data_dir, const char* subdir, const char* mode)
133{
134 size_t root_len, cmp_len, dir_len, mode_len, net_len;
135 char* ref_name;
136 char* tail;
137 const char* const target_name = get_target ();
138
139 assert (0 != target_name);
140 assert (0 != subdir);
141 assert (0 != mode);
142
143 root_len = data_dir ? strlen (data_dir) : 0;
144 cmp_len = strlen (target_name) - exe_suffix_len;
145 dir_len = strlen (subdir);
146 mode_len = strlen (mode);
147 net_len = root_len + cmp_len + dir_len + mode_len * 2 + 5;
148 /* 5 comes from 3 path seperator characters, the suffix seperator
149 character, and the trailing null */
150 tail = ref_name = (char*)RW_MALLOC (net_len);
151
152 memcpy (tail, data_dir, root_len);
153 tail += root_len;
154 *tail++ = default_path_sep;
155 memcpy (tail , subdir, dir_len);
156 tail += dir_len;
157 *tail++ = default_path_sep;
158 memcpy (tail , mode, mode_len);
159 tail += mode_len;
160 *tail++ = default_path_sep;
161 memcpy (tail , target_name, cmp_len);
162 tail += cmp_len;
163 *tail++ = suffix_sep;
164 memcpy (tail , mode, mode_len);
165 tail += mode_len;
166 *tail = '\0';
167
168 return ref_name;
169}
170
171
189char*
190input_name (const char* data_dir, const char* target)
191{
192 char* fname = 0;
193 int stat_result = 0;
194 struct stat sb;
195
196 assert (0 != target);
197
198 if (data_dir && *data_dir) {
199
200 /* Try data_dir/manual/in/target.in */
201 fname = reference_name (data_dir, "manual", "in");
202 stat_result = stat (fname, &sb);
203
204 if (0 == stat_result)
205 return fname;
206
207 free (fname);
208
209 /* Try data_dir/tutorial/in/target.in */
210 fname = reference_name (data_dir, "tutorial", "in");
211 stat_result = stat (fname, &sb);
212
213 if (0 == stat_result)
214 return fname;
215
216 free (fname);
217 }
218
219 /* If we didn't find a source file, use /dev/null */
220 fname = (char*)RW_MALLOC (sizeof DEV_NULL);
221 strcpy (fname, DEV_NULL);
222 return fname;
223}
224
225
226char*
227output_name (const char* target)
228{
229 const char* suffix = "out";
230 const size_t sfx_len = strlen (suffix);
231 const size_t exe_len = strlen (target) - exe_suffix_len;
232 char* const tmp_name = (char*)RW_MALLOC (exe_len + sfx_len + 2);
233
234 memcpy (tmp_name, target, exe_len);
235 *(tmp_name + exe_len) = suffix_sep;
236 memcpy (tmp_name + exe_len + 1, suffix, sfx_len + 1);
237 return tmp_name;
238}
239
240
241#ifndef _WIN32
242
243void
244rw_sleep (int seconds)
245{
246 sleep (seconds);
247}
248
249
250# ifndef _RWSTD_EDG_ECCP
251
252# ifdef __cplusplus
253
254extern "C" {
255
256# endif /* __cplusplus */
257
258int
259rw_signal (int signo, void (*func)(int))
260{
261 struct sigaction act;
262 memset (&act, 0, sizeof act);
263
264 /* avoid extern "C"/"C++" mismatch due to an HP aCC 6 bug
265 (see STDCXX-291) */
266 if (func)
267 memcpy (&act.sa_handler, &func, sizeof func);
268 else
269 act.sa_handler = 0;
270
271 return 0 > sigaction (signo, &act, 0);
272}
273
274# ifdef __cplusplus
275
276} /* extern "C" */
277
278# endif /* __cplusplus */
279
280# else /* if defined (_RWSTD_EDG_ECCP) */
281
282# ifdef __cplusplus
283
284extern "C" {
285
286# endif /* __cplusplus */
287
288int
289rw_signal (int signo, void (*func)(int))
290{
291 return SIG_ERR == signal (signo, func);
292}
293
294# ifdef __cplusplus
295
296} /* extern "C" */
297
298# endif /* __cplusplus */
299# endif /* _RWSTD_EDG_ECCP */
300#else /* ifdef _WIN32 */
301
302void
303rw_sleep (int seconds)
304{
305 Sleep (seconds * 1000);
306}
307
308
309int
310rw_signal (int signo, void (*func)(int))
311{
312 return SIG_ERR == signal (signo, func);
313}
314
315#endif /* _WIN32 */
#define alloc
Definition 17.names.cpp:441
#define line
Definition 17.names.cpp:490
#define sb
Definition 17.names.cpp:542
#define mode
Definition 17.names.cpp:497
void terminate()
IMPORT_C UInt32 sleep(UInt32 seconds)
#define assert(expr)
Definition _cassert.h:40
#define SIG_ERR
#define va_end(ignore)
#define va_start(va, name)
#define stderr
const char * get_target()
Definition runall.cpp:411
const char suffix_sep
Definition cmdopt.cpp:61
const char * exe_name
Definition cmdopt.cpp:55
const size_t exe_suffix_len
Definition cmdopt.cpp:62
const char default_path_sep
Definition cmdopt.cpp:60
char * input_name(const char *data_dir, const char *target)
Definition util.cpp:190
char * reference_name(const char *data_dir, const char *subdir, const char *mode)
Definition util.cpp:132
#define DEV_NULL
Definition util.cpp:53
void * guarded_realloc(void *source, const size_t size, const char *const file, const unsigned line)
Definition util.cpp:114
char * output_name(const char *target)
Definition util.cpp:227
void * guarded_malloc(const size_t size, const char *const file, const unsigned line)
Definition util.cpp:97
void warn(const char *const format,...)
Definition util.cpp:58
int rw_signal(int signo, void(*func)(int))
Definition util.cpp:259
void rw_sleep(int seconds)
Definition util.cpp:244
#define RW_MALLOC(size)
Definition util.h:51