1 /* Utility functions definitions */
2 
3 #ifndef SYSTEM_H_
4 #define SYSTEM_H_
5 
6 #include <stddef.h>
7 #include <stdio.h>
8 #include <limits.h>
9 #include <stdint.h>
10 #include <string.h>
11 
12 #ifdef __cplusplus
13 #define SYSTEM_H_BEGIN_ extern "C" {
14 #define SYSTEM_H_END_ }
15 #else
16 #define SYSTEM_H_BEGIN_
17 #define SYSTEM_H_END_
18 #endif
19 
20 SYSTEM_H_BEGIN_
21 
22 #ifndef __MINGW32__
23 #define DGEN_BASEDIR ".dgen"
24 #define DGEN_RC "dgenrc"
25 #define DGEN_AUTORC "dgenrc.auto"
26 #define DGEN_DIRSEP "/"
27 #else
28 #define DGEN_BASEDIR "DGen"
29 #define DGEN_RC "dgen.cfg"
30 #define DGEN_AUTORC "dgen_auto.cfg"
31 #define DGEN_DIRSEP "\\/"
32 #endif
33 
34 #define elemof(a) (sizeof(a) / sizeof((a)[0]))
35 #define containerof(p, s, m) (s *)((uintptr_t)(p) - offsetof(s, m))
36 
37 #define BITS_TO_BYTES(v) ((((v) + 7u) & ~7u) >> 3)
38 
39 #define DGEN_READ 0x1
40 #define DGEN_WRITE 0x2
41 #define DGEN_APPEND 0x4
42 #define DGEN_CURRENT 0x8
43 #define DGEN_TEXT 0x10
44 
45 #define dgen_fopen_rc(mode) dgen_fopen(NULL, DGEN_RC, ((mode) | DGEN_TEXT))
46 #define dgen_fopen_autorc(mode)					\
47 	dgen_fopen(NULL, DGEN_AUTORC, ((mode) | DGEN_TEXT))
48 extern FILE *dgen_fopen(const char *relative, const char *file,
49 			unsigned int mode);
50 extern FILE *dgen_freopen(const char *relative, const char *file,
51 			  unsigned int mode, FILE *f);
52 extern const char *dgen_basename(const char *path);
53 extern char *dgen_dir(char *buf, size_t *size, const char *sub);
54 extern char *dgen_userdir(char *buf, size_t *size);
55 
56 #define le2h16(v) h2le16(v)
h2le16(uint16_t v)57 static inline uint16_t h2le16(uint16_t v)
58 {
59 #ifdef WORDS_BIGENDIAN
60 	return ((v >> 8) | (v << 8));
61 #else
62 	return v;
63 #endif
64 }
65 
66 #define be2h16(v) h2be16(v)
h2be16(uint16_t v)67 static inline uint16_t h2be16(uint16_t v)
68 {
69 #ifdef WORDS_BIGENDIAN
70 	return v;
71 #else
72 	return ((v >> 8) | (v << 8));
73 #endif
74 }
75 
76 #define le2h32(v) h2le32(v)
h2le32(uint32_t v)77 static inline uint32_t h2le32(uint32_t v)
78 {
79 #ifdef WORDS_BIGENDIAN
80 	return (((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >>  8) |
81 		((v & 0x0000ff00) <<  8) | ((v & 0x000000ff) << 24));
82 #else
83 	return v;
84 #endif
85 }
86 
87 #define be2h32(v) h2be32(v)
h2be32(uint32_t v)88 static inline uint32_t h2be32(uint32_t v)
89 {
90 #ifdef WORDS_BIGENDIAN
91 	return v;
92 #else
93 	return (((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >>  8) |
94 		((v & 0x0000ff00) <<  8) | ((v & 0x000000ff) << 24));
95 #endif
96 }
97 
98 typedef uint8_t uint24_t[3];
99 
u24cpy(uint24_t * dst,const uint24_t * src)100 static inline uint24_t *u24cpy(uint24_t *dst, const uint24_t *src)
101 {
102 	/* memcpy() is sometimes faster. */
103 #ifdef U24CPY_MEMCPY
104 	memcpy(*dst, *src, sizeof(*dst));
105 #else
106 	(*dst)[0] = (*src)[0];
107 	(*dst)[1] = (*src)[1];
108 	(*dst)[2] = (*src)[2];
109 #endif
110 	return dst;
111 }
112 
113 extern uint8_t *load(void **context,
114 		     size_t *file_size, FILE *file, size_t max_size);
115 extern void load_finish(void **context);
116 extern void unload(uint8_t *data);
117 
118 extern char **complete_path(const char *prefix, size_t len,
119 			    const char *relative);
120 extern void complete_path_free(char **cp);
121 
strcommon(const char * s1,const char * s2)122 static inline size_t strcommon(const char *s1, const char *s2)
123 {
124 	size_t i;
125 
126 	for (i = 0; ((s1[i] != '\0') && (s2[i] != '\0')); ++i)
127 		if (s1[i] != s2[i])
128 			break;
129 	return i;
130 }
131 
132 #define BACKSLASHIFY_NOQUOTES 0x0001
133 
134 extern char *backslashify(const uint8_t *src, size_t size, unsigned int flags,
135 			  size_t *pos);
136 
137 extern size_t utf8u32(uint32_t *u32, const uint8_t *u8);
138 extern size_t utf32u8(uint8_t *u8, uint32_t u32);
139 
140 extern int prefix_casematch(const char *str, const char *argv[]);
141 extern size_t prefix_getuint(const char *str, unsigned int *num);
142 
143 SYSTEM_H_END_
144 
145 #endif /* SYSTEM_H_ */
146