Nilorea Library
C utilities for networking, threading, graphics
n_common.h
Go to the documentation of this file.
1
8#ifndef __NILOREA_COMMONS__
9#define __NILOREA_COMMONS__
10
11#ifdef __cplusplus
12extern "C"
13{
14#endif
15
21#include <sys/types.h>
22#include <unistd.h>
23#include <stdlib.h>
24#include <malloc.h>
25#include <errno.h>
26#include <string.h>
27#include <stdint.h>
28#include <nilorea/n_log.h>
29#include <nilorea/n_enum.h>
30
32#define __EXTENSIONS__
33
35#if defined( _WIN32 ) || defined( _WIN64 )
36#ifndef __windows__
37#define __windows__
38#endif
39#ifndef WEXITSTATUS
40#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
41#endif
42#ifndef WIFEXITED
43#define WIFEXITED(w) (((w) & 0xff) == 0)
44#endif
45#else
46#include <alloca.h>
47#endif
48
49#if defined(__GNUC__) && __GNUC__ >= 7
50#define FALL_THROUGH __attribute__ ((fallthrough))
51#else
52#define FALL_THROUGH /* fall through */ \
53 ((void)0)
54#endif /* __GNUC__ >= 7 */
55
56#if defined( _WIN32 ) || defined( _WIN64 )
57#if defined( _WIN64 )
58#define ENV_64BITS
59#else
60#define ENV_32BITS
61#endif
62#endif
63
64#if !defined( ENV_32BITS ) || !defined( ENV_64BITS )
65#if defined( __GNUC__ )
66#if defined( __x86_64__ ) || defined( __ppc64__ )
67#define __ENVBITS __ENV_64BITS
68#else
69#define __ENVBITS __ENV_32BITS
70#endif
71#endif
72#endif
73
75#define BYTEORDER_LITTLE_ENDIAN 0 // Little endian machine.
77#define BYTEORDER_BIG_ENDIAN 1 // Big endian machine.
78
79
80#ifndef BYTEORDER_ENDIAN
81 // Detect with GCC 4.6's macro.
82#if defined(__BYTE_ORDER__)
83#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
84#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
85#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
86#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
87#else
88#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
89#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
90#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
91#endif
92 // Detect with GLIBC's endian.h.
93#elif defined(__GLIBC__)
94#include <endian.h>
95#if (__BYTE_ORDER == __LITTLE_ENDIAN)
96#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
97#elif (__BYTE_ORDER == __BIG_ENDIAN)
98#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
99#else
100#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
101#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
102#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
103#endif
104 // Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro.
105#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
106#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
107#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
108#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
109 // Detect with architecture macros.
110#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
111#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN
112#elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
113#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
114#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
115#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
116#else
117#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN
118#warning "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN."
119#warning "Setting default to BYTEORDER_LITTLE_ENDIAN"
120#endif
121#endif
122
123#if defined( __windows__ )
124 /* typedefine for unsigned category for basic native types */
126 typedef unsigned int uint;
128 typedef unsigned long ulong;
130 typedef unsigned short ushort;
132 typedef unsigned char uchar;
133#endif
134
136#ifdef _MSVC_VER
137#define FORCE_INLINE __forceinline
138#elif defined( __linux__ ) || defined( __windows__ )
139#define FORCE_INLINE inline __attribute__((always_inline))
140#else
141#define FORCE_INLINE __attribute__((always_inline))
142#endif
143
145#ifndef true
146#define true (1==1)
147#endif
148
150#ifndef TRUE
151#define TRUE true
152#endif
153
155#ifndef false
156#define false (1==0)
157#endif
158
160#ifndef FALSE
161#define FALSE false
162#endif
163
165#ifndef EMPTY
166#define EMPTY 2
167#endif
168
169
170
172#define _str( __PTR ) ((__PTR)?(__PTR):"NULL")
174#define _strp( __PTR ) ((__PTR)?(__PTR):NULL)
176#define _strw( __PTR ) ((__PTR)?(__PTR):" ")
178#define _nstr( __PTR ) ((__PTR&&__PTR->data)?(__PTR->data):"NULL")
180#define _nstrp( __PTR ) ((__PTR&&__PTR->data)?(__PTR->data):NULL)
181
183#define Malloc( __ptr , __struct , __size ) \
184 { \
185 int __n_errno = 0 ; \
186 int64_t __byte_size = __size ; \
187 if( __byte_size <= 0 ) __byte_size = 16; \
188 errno= 0 ;\
189 __ptr = ( __struct *)calloc( __byte_size , sizeof( __struct ) ); \
190 __n_errno = errno ;\
191 if( ! __ptr ) \
192 { \
193 n_log( LOG_ERR , "( %s *)calloc( %ld , sizeof( %s ) ) %s at line %d of %s \n", #__ptr , __size , #__struct , (__n_errno==0)?"malloc error":strerror( __n_errno ) , __LINE__ , __FILE__); \
194 } \
195 }
196
198#define Alloca( __ptr , __size ) \
199 { \
200 int __n_errno = 0 ; \
201 int64_t __byte_size = __size ; \
202 if( __byte_size <= 0 ) __byte_size = 16 ; \
203 errno= 0 ;\
204 __ptr = alloca( __byte_size ); \
205 __n_errno = errno ;\
206 if( ! __ptr ) \
207 { \
208 n_log( LOG_ERR , "%s=alloca( %d ) %s at line %d of %s \n", #__ptr , __size , (__n_errno==0)?"alloca error":strerror( __n_errno ) , __LINE__ , __FILE__); \
209 } \
210 else \
211 { \
212 memset( __ptr , 0 , __byte_size ); \
213 } \
214 }
215
217#define Realloc( __ptr, __struct , __size ) \
218 { \
219 int __n_errno = 0 ; \
220 int64_t __byte_size = __size * sizeof( __struct ); \
221 if( __byte_size <= 0 ) __byte_size = 16 ; \
222 errno= 0 ;\
223 void *__new_ptr = ( __struct *)realloc( __ptr , __byte_size ); \
224 __n_errno = errno ; \
225 if( !__new_ptr ) \
226 { \
227 n_log( LOG_ERR , "( %s *)realloc( %s * sizeof( %d ) ) %s at line %d of %s \n", #__ptr , #__struct , __size , (__n_errno==0)?"realloc error":strerror( __n_errno ) , __LINE__ , __FILE__);\
228 } \
229 else \
230 { \
231 __ptr = __new_ptr ; \
232 } \
233 }
234
236#define Reallocz( __ptr, __struct , __old_size , __size ) \
237 { \
238 int __n_errno = 0 ; \
239 size_t __byte_size = __size * sizeof( __struct ); \
240 if( __byte_size <= 0 ) __byte_size = 16 ; \
241 errno= 0 ;\
242 void *__new_ptr = ( __struct *)realloc( __ptr , __byte_size ); \
243 __n_errno = errno ; \
244 if( !__new_ptr ) \
245 { \
246 n_log( LOG_ERR , "( %s *)realloc( %s * sizeof( %d ) ) %s at line %d of %s \n", #__ptr , #__struct , __size , (__n_errno==0)?"realloc error":strerror( __n_errno ) , __LINE__ , __FILE__);\
247 } \
248 else \
249 { \
250 __ptr = __new_ptr ; \
251 if( __byte_size > __old_size ) memset( ( __ptr + __old_size ) , 0 , __byte_size - __old_size ); \
252 } \
253 }
254
256#define Free( __ptr ) \
257 if ( __ptr )\
258 {\
259 free( __ptr );\
260 __ptr = NULL;\
261 }\
262 else\
263 {\
264 n_log( LOG_DEBUG , "Free( %s ) already done or NULL at line %d of %s \n", #__ptr , __LINE__ , __FILE__ );\
265 }
266
268#define FreeNoLog( __ptr )\
269 if ( __ptr )\
270 {\
271 free( __ptr );\
272 __ptr = NULL;\
273 }
274
276#define __n_assert( __ptr , __ret ) \
277 if( !(__ptr) ) \
278 { \
279 n_log( LOG_DEBUG , "if( !(%s) ) assert at line %d of %s" , #__ptr , __LINE__ , __FILE__ ); \
280 __ret ; \
281 }
282
284#define CALL_RETRY(retvar, expression) do { \
285 retvar = (expression); \
286} while (retvar == -1 && errno == EINTR);
287
289#define next_odd( __val ) ( (__val)%2 == 0 ) ? (__val) : ( __val + 1 )
290
292#define next_even( __val ) ( (__val)%2 == 0 ) ? (__val + 1) : ( __val )
293
294
296#define init_error_check() \
297 static int ___error__check_flag = FALSE ;
298
300#define ifnull if( !
301
303#define ifzero if( 0 ==
304
306#define iffalse if( FALSE ==
307
309#define iftrue if( TRUE ==
310
312#define checkerror() if( ___error__check_flag == TRUE ) \
313{ n_log( LOG_ERR , "checkerror return false at line %d of %s" , __LINE__ , __FILE__ ); \
314goto error ; \
315}
316
318#define endif ){ ___error__check_flag = TRUE ; n_log( LOG_ERR , "First err was at line %d of %s" , __LINE__ , __FILE__ );}
319
321#define get_error() \
322(___error__check_flag == TRUE)
323
325#define equal_if( __a , __cond , __b ) if( (__a) __cond (__b) ){ __a = __b ; }
326
327 //#define RWLOCK_DEBUG 1
328#ifdef RWLOCK_DEBUG
330#define RWLOCK_LOGLEVEL LOG_DEBUG
331#else
333#define RWLOCK_LOGLEVEL LOG_NULL
334#endif
335
337#define init_lock( __rwlock_mutex ) \
338 ({ \
339 pthread_rwlockattr_t __attr ; \
340 pthread_rwlockattr_init( &__attr ); \
341 int __ret = 0 ; \
342 do \
343 { \
344 n_log( RWLOCK_LOGLEVEL , "init_lock %s" , #__rwlock_mutex ); \
345 __rwlock_mutex = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER ; \
346 __ret = pthread_rwlock_init( &(__rwlock_mutex) , &__attr ); \
347 if( __ret != 0 ) \
348 { \
349 n_log( LOG_ERR , "Error %s while initializing %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
350 } \
351 pthread_rwlockattr_destroy( &__attr ); \
352 } while( 0 ); \
353 __ret ; \
354 })
355
357#define read_lock( __rwlock_mutex ) \
358 ({ \
359 int __ret = 0 ; \
360 do \
361 { \
362 n_log( RWLOCK_LOGLEVEL , "read lock %s" , #__rwlock_mutex ); \
363 __ret = pthread_rwlock_rdlock( &(__rwlock_mutex) ); \
364 if( __ret != 0 ) \
365 { \
366 n_log( LOG_ERR , "Error %s while read locking %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
367 } \
368 } while( 0 ); \
369 __ret ; \
370 })
371
373#define write_lock( __rwlock_mutex ) \
374 ({ \
375 int __ret = 0 ; \
376 do \
377 { \
378 n_log( RWLOCK_LOGLEVEL , "write lock %s" , #__rwlock_mutex ); \
379 __ret = pthread_rwlock_wrlock( &(__rwlock_mutex) ); \
380 if( __ret != 0 ) \
381 { \
382 n_log( LOG_ERR , "Error %s while write locking %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
383 } \
384 } while( 0 ); \
385 __ret ; \
386 })
387
389#define unlock( __rwlock_mutex ) \
390 ({ \
391 int __ret = 0 ; \
392 do \
393 { \
394 n_log( RWLOCK_LOGLEVEL , "unlock lock %s" , #__rwlock_mutex ); \
395 __ret = pthread_rwlock_unlock( &(__rwlock_mutex) ); \
396 if( __ret != 0 ) \
397 { \
398 n_log( LOG_ERR , "Error %s while unlocking %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
399 } \
400 } while( 0 ); \
401 __ret ; \
402 })
404#define rw_lock_destroy( __rwlock_mutex ) \
405 ({ \
406 int __ret = 0 ; \
407 do \
408 { \
409 n_log( RWLOCK_LOGLEVEL , "destroy lock %s" , #__rwlock_mutex ); \
410 __ret = pthread_rwlock_destroy( &(__rwlock_mutex) ); \
411 if( __ret != 0 ) \
412 { \
413 n_log( LOG_ERR , "Error %s while destroying %s at %s:%s:%d" , strerror( __ret ) , #__rwlock_mutex , __FILE__ , __func__ , __LINE__ ); \
414 } \
415 } while( 0 ); \
416 __ret ; \
417 })
418
420#define SET 1234
422#define GET 4321
424#define DEFAULT 1000
426#define RUNNING 1001
428#define STOPWANTED 1002
430#define STOPPED 1003
432#define PAUSED 1004
433
435#define randomize() { srand((unsigned)time(NULL)); rand(); }
436
437#ifndef MIN
439#define MIN(a,b) (((a)<(b))?(a):(b))
440#endif
441#ifndef MAX
443#define MAX(a,b) (((a)>(b))?(a):(b))
444#endif
445
446
448#define CONCAT_BUILDER(a, b) a ## b
450#define CONCAT(a, b) CONCAT_BUILDER(a, b)
451
452#if( BYTEORDER_ENDIAN == BYTEORDER_LITTLE_ENDIAN )
454# define htonll(x) (x)
456# define ntohll(x) (x)
457#else
459# define htonll(x) ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
461# define ntohll(x) ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
462#endif
463
464 /* exit and print log to stderr */
465 void n_abort( char const *format, ... );
466
467 int get_computer_name( char *computer_name , size_t len );
468
469 /* get running program name */
470 char *get_prog_name( void );
471
472 /* get running program directory */
473 char *get_prog_dir( void );
474
475 /* test file presence*/
476 int file_exist( const char *filename );
477
478 /* shortcut for popen usage */
479 int n_popen( char *cmd, int read_buf_size, void **nstr_output, int *ret );
480
481#ifndef __windows__
482 int n_daemonize( void );
483 /* non blocking system call */
484 pid_t system_nb(const char * command, int * infp, int * outfp);
485#endif
486
487 /* reconstruct hidden string */
488 void N_HIDE_STR(char *buf, ...);
489
490 char *n_get_file_extension(char path[]);
495#ifdef __cplusplus
496 }
497#endif
498
499#endif // header guard
500
char * get_prog_name(void)
get current program name
Definition: n_common.c:145
void N_HIDE_STR(char *buf,...)
store a hidden version of a string
Definition: n_common.c:371
int get_computer_name(char *computer_name, size_t len)
abort program with a text
Definition: n_common.c:58
pid_t system_nb(const char *command, int *infp, int *outfp)
Non blocking system call.
Definition: n_common.c:293
char * n_get_file_extension(char path[])
get extension of path+filename
Definition: n_common.c:394
int n_popen(char *cmd, int read_buf_size, void **nstr_output, int *ret)
launch a command abd return output and status
Definition: n_common.c:185
char * get_prog_dir(void)
get current program running directory
Definition: n_common.c:109
void n_abort(char const *format,...)
abort program with a text
Definition: n_common.c:38
int n_daemonize(void)
Daemonize program.
Definition: n_common.c:236
int file_exist(const char *filename)
test if file exist and if it's readable
Definition: n_common.c:92
Macro to build enums and their tostring counterparts, a reduced version of https://github....
Generic log system.