gu_util
gu_util.cpp
Go to the documentation of this file.
1/*
2 * $Id$
3 *
4 * gu_util.cpp
5 * gucdlmodule
6 *
7 * Created by Rene Hexel on 24/04/10.
8 * Copyright 2010-2015 Rene Hexel. All rights reserved.
9 *
10 */
11#pragma clang diagnostic push
12#pragma clang diagnostic ignored "-Wunused-macros"
13#pragma clang diagnostic ignored "-Wreserved-id-macro"
14#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
15#pragma clang diagnostic ignored "-Wold-style-cast"
16#pragma clang diagnostic ignored "-Wdeprecated"
17#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
18
19#ifndef _POSIX_SOURCE
20#define _POSIX_SOURCE 200112L
21#endif
22#ifndef _XOPEN_SOURCE
23#define _XOPEN_SOURCE
24#endif
25#ifdef __APPLE__
26#ifndef _DARWIN_C_SOURCE
27#define _DARWIN_C_SOURCE 200112L
28#ifndef __DARWIN_C_LEVEL
29#define __DARWIN_C_LEVEL 200112L
30#endif
31#endif
32#endif
33
34#include <cstdio>
35#include <cstdlib>
36#include <cstdarg>
37
38#undef __block
39#define __block _xblock
40#include <unistd.h>
41#undef __block
42#define __block __attribute__((__blocks__(byref)))
43
44#include <libgen.h>
45#include <fcntl.h>
46#include <time.h>
47#include <sys/stat.h>
48#include <sys/time.h>
49#include <stdio.h> //snprintf
50#include "gu_util.h"
51
52extern "C"
53{
54 bool file_exists(const char *fileName)
55 {
56 struct stat buf;
57 return stat(fileName, &buf) >= 0;
58 }
59
60 char *new_string_from_file(const char *fileName)
61 {
62 char *content;
63 int file = open(fileName, O_RDONLY);
64 if (file < 0) return NULL;
65
66 size_t len = (size_t) lseek(file, 0, SEEK_END);
67 if ((content = (char *) malloc(len+1)))
68 {
69 lseek(file, 0, SEEK_SET);
70 if (read(file, content, len) == (int)len)
71 content[len] = '\0';
72 else
73 {
74 free(content);
75 content = NULL;
76 }
77 }
78 close(file);
79
80 return content;
81 }
82
83
84 int int_from_file(const char *fileName)
85 {
86 char *s = new_string_from_file(fileName);
87
88 if (!s) return -1;
89
90 int i = atoi(s);
91
92 free(s);
93
94 return i;
95 }
96
97
98 double double_from_file(const char *fileName)
99 {
100 char *s = new_string_from_file(fileName);
101
102 if (!s) return -1;
103
104 double d = atof(s);
105
106 free(s);
107
108 return d;
109 }
110
111 char *gu_strdup(const char *s)
112 {
113 unsigned n = 1;
114
115 if (s) n = unsigned(strlen(s))+1;
116
117 char *dest = static_cast<char *>(calloc(1, n));
118
119 if (s && dest) strcpy(dest, s);
120
121 return dest;
122 }
123
124
125 char *concatenate_path(const char *head, const char *tail)
126 {
127 return gu_strdup(string_by_concatenating_path_components(head, tail).c_str());
128 }
129
130 long long get_utime(void)
131 {
132 struct timeval tv;
133 if (gettimeofday(&tv, NULL) == -1) return -1LL;
134
135 long long t = (long long) tv.tv_usec +
136 (long long) tv.tv_sec * 1000000LL;
137 return t;
138 }
139
140 void protected_usleep(long long us)
141 {
142 long long deadline = get_utime() + us;
143 while (us > 0)
144 {
145 usleep(unsigned(us));
146 us = deadline - get_utime();
147 }
148 }
149
150 char *gu_strtrim(const char *s)
151 {
152 std::string str(s);
153 return gu_strdup(gu_trim(str).c_str());
154 }
155
156 static FILE *warn_file;
157
158 int mipal_err_file(const char *filename)
159 {
160 if (warn_file) fclose(warn_file);
161
162 if (strchr(filename, '/')) do
163 {
164 /*
165 * copy filename because some implementations of
166 * dirname() may overwrite the string contents
167 */
168 char *f_copy = gu_strdup(filename);
169
170 if (!f_copy) break;
171
172 char *dir = dirname(f_copy);
173
174 mkdir(dir, 01777);
175
176 free(f_copy);
177 } while (0);
178
179 warn_file = fopen(filename, "a");
180
181 return warn_file ? 0 : -1;
182 }
183
184#pragma clang diagnostic push
185#pragma clang diagnostic ignored "-Wformat-nonliteral"
186
187 void mipal_warn(const char *fmt, ...)
188 {
189 va_list ap;
190 FILE *file = warn_file ? warn_file : stderr;
191 char buf[256];
192
193 time_t t = time(NULL);
194 const struct tm *btm = localtime(&t);
195
196 va_start(ap, fmt);
197 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", btm);
198 fprintf(file, "%s: %s - ", gu_getprogname(), buf);
199 vfprintf(file, fmt, ap);
200 fputc('\n', file);
201 fflush(file);
202 va_end(ap);
203 }
204
205#pragma clang diagnostic pop
206
207#ifndef BSD
208 static char *prog_name;
209#endif
210 const char *gu_getprogname()
211 {
212#ifdef BSD
213 return getprogname();
214#else
215// if (!prog_name)
216// prog_name = new_string_from_file("/proc/self/cmdline");
217
218 if (!prog_name)
219 {
220 const int len = 30;
221 prog_name = (char *) calloc(len, 1);
222 snprintf(prog_name, len, "pid %d", getpid());
223 }
224 return basename(prog_name);
225#endif
226 }
227
229 {
230 char path[30] = "/home/nao/data/player";
231
232 int fd = open(path, O_RDONLY);
233 if (fd < 0)
234 {
235 return -1;
236 }
237 char num[10];
238 ssize_t t = read(fd, &num, 1);
239 if (t <= 0) return 0;
240 return atoi(&num[0]);
241 }
242
243
244#if !defined(BSD) || (BSD < 199506)
245 size_t gu_strlcpy(char *dst, const char *src, size_t size)
246 {
247 strncpy(dst, src, size--);
248 dst[size] = 0;
249 return strlen(dst);
250 }
251
252 size_t gu_strlcat(char *dst, const char *src, size_t size)
253 {
254 strncat(dst, src, size--);
255 dst[size] = 0;
256 return strlen(dst);
257 }
258#endif
259}
260
261#include <sstream>
262#include <map>
263#include <fstream>
264
265using namespace std;
266
267string string_from_file(const char *fileName)
268{
269 char *s = new_string_from_file(fileName);
270
271 if (!s) return "";
272
273 string t(s);
274 free(s);
275
276 return t;
277}
278
279
280string string_by_concatenating_path_components(const string &h, const string &t)
281{
282 const char *head = h.c_str();
283 const char *tail = t.c_str();
284 std::string path(head);
285 size_t len = path.length();
286
287 if (len)
288 {
289 if (head[len-1] == '/')
290 {
291 if (tail[0] == '/') tail++;
292 }
293 else
294 {
295 if (tail[0] != '/') path += "/";
296 }
297 }
298
299 return path + tail;
300}
301
302
303#define WHITESPACE " \t\v\r\n"
304
305string &gu_trim(string &s)
306{
307 string::size_type pos = s.find_last_not_of(WHITESPACE);
308 if (pos != string::npos)
309 {
310 s.erase(pos+1);
311 pos = s.find_first_not_of(WHITESPACE);
312 if (pos != string::npos)
313 s.erase(0, pos);
314 }
315 else s.erase(s.begin(), s.end());
316
317 return s;
318}
319
320
321string gu_ltos(long val)
322{
323 char buf[80];
324 snprintf(buf, sizeof(buf), "%ld", val);
325
326 return buf;
327}
328
329
330string gu_ultos(unsigned long val)
331{
332 char buf[80];
333 snprintf(buf, sizeof(buf), "%lu", val);
334
335 return buf;
336}
337
338
339string gu_dtos(double val)
340{
341 char buf[120];
342 snprintf(buf, sizeof(buf), "%lg", val);
343
344 return buf;
345}
346
347
348vector<string> components_of_string_separated(const string &str, char sep, bool trim)
349{
350 vector<string> array;
351 istringstream iss(str);
352 std::string token;
353 while (getline(iss, token, sep))
354 {
355 if (trim) gu_trim(token);
356 array.push_back(token);
357 }
358
359 return array;
360}
361
362
363map<string,string> read_configuration(const string &filename)
364{
365 map<string,string> cfg;
366 ifstream ifs(filename.c_str(), ifstream::in);
367 if (!ifs) {
368 mipal_warn("Configuration file not found: %s\n", filename.c_str());
369 return cfg;
370 }
371
372 string line;
373 vector<string> tokens;
374 while (getline(ifs, line)) {
375 tokens = components_of_string_separated(line, '=', true);
376
377 // make sure the line is a valid `key = value` pair
378 if (tokens.size()==2 && tokens[0].size()>0 && tokens[1].size()>0) {
379 // ignore commented lines
380 if (!(tokens[0][0]=='#')) {
381 cfg.insert(pair<string, string>(tokens[0], tokens[1]));
382 }
383 }
384 }
385 return cfg;
386}
387
388
389int inc(void *num) {
390 int* a = (int*)num;
391 (*a) = (*a) + 1;
392 return *a;
393}
394
395int dec(void *num) {
396 int* a = (int*)num;
397 (*a) -= 1;
398 return *a;
399}
400#pragma clang diagnostic pop
char * gu_strdup(const char *s)
Duplicate a string.
Definition: gu_util.cpp:111
const char * gu_getprogname()
get the basename of the current program
Definition: gu_util.cpp:210
string gu_ltos(long val)
Convert a long value to a string.
Definition: gu_util.cpp:321
long long get_utime(void)
Get the current time of day in microseconds.
Definition: gu_util.cpp:130
string & gu_trim(string &s)
Trim whitespace characters from both ends of a string.
Definition: gu_util.cpp:305
int int_from_file(const char *fileName)
Load the contents of a given file into an int.
Definition: gu_util.cpp:84
double double_from_file(const char *fileName)
Load the contents of a given file into a double.
Definition: gu_util.cpp:98
int dec(void *num)
Decrement a number Used to decrement a enum value without warnings.
Definition: gu_util.cpp:395
string string_from_file(const char *fileName)
Load the contents of a given file into a string.
Definition: gu_util.cpp:267
char * new_string_from_file(const char *fileName)
Load the contents of a given file into a string.
Definition: gu_util.cpp:60
string gu_ultos(unsigned long val)
Convert an unsigned long value to a string.
Definition: gu_util.cpp:330
size_t gu_strlcat(char *dst, const char *src, size_t size)
Definition: gu_util.cpp:252
char * gu_strtrim(const char *s)
Return a trimmed copy of the current string by removing all leading and trailing whitespace character...
Definition: gu_util.cpp:150
char * concatenate_path(const char *head, const char *tail)
Create a new string by concatenating two path components.
Definition: gu_util.cpp:125
bool file_exists(const char *fileName)
Return whether a file exists.
Definition: gu_util.cpp:54
int mipal_err_file(const char *filename)
Set the log file for the current module.
Definition: gu_util.cpp:158
#define WHITESPACE
Definition: gu_util.cpp:303
void protected_usleep(long long us)
Protected usleep() – guaranteed to sleep for the given time! param us number of microseconds to sleep...
Definition: gu_util.cpp:140
vector< string > components_of_string_separated(const string &str, char sep, bool trim)
Split a string based on the token.
Definition: gu_util.cpp:348
string string_by_concatenating_path_components(const string &h, const string &t)
Concatenate two path components into a new string.
Definition: gu_util.cpp:280
void mipal_warn(const char *fmt,...)
Print a warning to the file mipal_err_file() has been set for (or stderr if none has been set)
Definition: gu_util.cpp:187
string gu_dtos(double val)
Convert a double value to a string.
Definition: gu_util.cpp:339
size_t gu_strlcpy(char *dst, const char *src, size_t size)
Definition: gu_util.cpp:245
map< string, string > read_configuration(const string &filename)
Read simple key = value pairs into a c++ map.
Definition: gu_util.cpp:363
int getplayernumber()
get player number
Definition: gu_util.cpp:228
int inc(void *num)
Increment a number Used to increment an enum value without warnings.
Definition: gu_util.cpp:389