This repository has been archived by the owner on Jan 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathutils.h
196 lines (174 loc) · 6.01 KB
/
utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
* Copyright (C) 2017 - This file is part of libecc project
*
* Authors:
* Ryad BENADJILA <[email protected]>
* Arnaud EBALARD <[email protected]>
* Jean-Pierre FLORI <[email protected]>
*
* Contributors:
* Nicolas VIVET <[email protected]>
* Karim KHALFALLAH <[email protected]>
*
* This software is licensed under a dual BSD and GPL v2 license.
* See LICENSE file at the root folder of the project.
*/
#ifndef __UTILS_H__
#define __UTILS_H__
#include "../words/words.h"
/*
* At various locations in the code, we expect expect some specific
* conditions to be true for correct operation of the code after
* those locations. This is commonly the case on input parameters
* at the beginning of functions. Other conditions may be expected
* but are not necessarily impacting for correct operation of the
* code.
*
* We use the three following macros for that purpose:
*
* MUST_HAVE(): The condition is always tested, i.e. both in debug
* and non debug build. This macros is used when it's better not to
* continue if the condition does not hold. In production code,
* if the condition does not hold, a while (1) loop is currently
* executed (but this may be changed for some specific code the
* system provide (e.g. abort())). In debug mode, an assert() is
* used when the condition is false.
*
* SHOULD_HAVE(): the condition is only executed in debug mode and
* the whole macros is a nop in production code. This can be used
* to add more checks in the code to detect specific conditions
* or changes. Those checks may have performance impact which are
* acceptable in debug mode but are not in production mode.
*
* KNOWN_FACT(): the condition is only executed in debug mode and
* the whole macro is a nop in production code. This macro is used
* to add conditions that are known to be true which may help analysis
* tools to work on the code. The macro can be used in order to make
* those conditions explicit.
*/
/* Some helper for printing where we have an issue */
#if defined(USE_ASSERT_PRINT)
#include "../external_deps/print.h"
#define MUST_HAVE_EXT_PRINT do { \
ext_printf("MUST_HAVE error: %s at %d\n", __FILE__,__LINE__); \
} while (0)
#define SHOULD_HAVE_EXT_PRINT do { \
ext_printf("SHOULD_HAVE error: %s at %d\n", __FILE__,__LINE__); \
} while (0)
#define KNOWN_FACT_EXT_PRINT do { \
ext_printf("KNOWN_FACT error: %s at %d\n", __FILE__,__LINE__); \
} while (0)
#else
#define MUST_HAVE_EXT_PRINT
#define SHOULD_HAVE_EXT_PRINT
#define KNOWN_FACT_EXT_PRINT
#endif
/*
* We known it is BAD BAD BAD to define macro with goto inside them
* but this is the best way we found to avoid making the code
* unreadable with tests of error conditions when implementing
* error handling in the project.
*
* EG stands for Error Goto, which represents the purpose of the
* macro, i.e. test a condition cond, and if false goto label
* lbl.
*/
#define EG(cond,lbl) do { if (cond) { goto lbl ; } } while (0)
/****** Regular DEBUG and production modes cases ****************/
/****** DEBUG mode ***********************************************/
#if defined(DEBUG)
#include <assert.h>
/*
* In DEBUG mode, we enforce a regular assert() in MUST_HAVE,
* SHOULD_HAVE and KNOWN_FACT, i.e. they are all the same.
*/
#define MUST_HAVE(cond, ret, lbl) do { \
if(!(cond)){ \
MUST_HAVE_EXT_PRINT; \
} \
assert((cond)); \
if (0) { /* silence unused \
label warning */ \
ret = -1; \
goto lbl; \
} \
} while (0)
#define SHOULD_HAVE(cond, ret, lbl) do {\
if(!(cond)){ \
SHOULD_HAVE_EXT_PRINT; \
} \
assert((cond)); \
if (0) { /* silence unused \
label warning */ \
ret = -1; \
goto lbl; \
} \
} while (0)
#define KNOWN_FACT(cond, ret, lbl) do { \
if(!(cond)){ \
KNOWN_FACT_EXT_PRINT; \
} \
assert((cond)); \
if (0) { /* silence unused \
label warning */ \
ret = -1; \
goto lbl; \
} \
} while (0)
/****** Production mode ******************************************/
#else /* !defined(DEBUG) */
/*
* In regular production mode, SHOULD_HAVE and KNOWN_FACT are void for
* performance reasons. MUST_HAVE includes an ext_printf call for
* tracing the origin of the error when necessary (if USE_ASSERT_PRINT
* is specified by the user).
*/
#define MUST_HAVE(cond, ret, lbl) do { \
if (!(cond)) { \
MUST_HAVE_EXT_PRINT; \
ret = -1; \
goto lbl; \
} \
} while (0)
#define SHOULD_HAVE(cond, ret, lbl) do { \
if (0) { /* silence unused \
label warning */ \
ret = -1; \
goto lbl; \
} \
} while (0)
#define KNOWN_FACT(cond, ret, lbl) do { \
if (0) { /* silence unused \
label warning */ \
ret = -1; \
goto lbl; \
} \
} while (0)
/******************************************************************/
#endif /* defined(DEBUG) */
#define LOCAL_MAX(x, y) (((x) > (y)) ? (x) : (y))
#define LOCAL_MIN(x, y) (((x) < (y)) ? (x) : (y))
#define BYTECEIL(numbits) (((numbits) + 7) / 8)
ATTRIBUTE_WARN_UNUSED_RET int are_equal(const void *a, const void *b, u32 len, int *check);
ATTRIBUTE_WARN_UNUSED_RET int local_memcpy(void *dst, const void *src, u32 n);
ATTRIBUTE_WARN_UNUSED_RET int local_memset(void *v, u8 c, u32 n);
ATTRIBUTE_WARN_UNUSED_RET int are_str_equal(const char *s1, const char *s2, int *check);
ATTRIBUTE_WARN_UNUSED_RET int are_str_equal_nlen(const char *s1, const char *s2, u32 maxlen, int *check);
ATTRIBUTE_WARN_UNUSED_RET int local_strlen(const char *s, u32 *len);
ATTRIBUTE_WARN_UNUSED_RET int local_strnlen(const char *s, u32 maxlen, u32 *len);
ATTRIBUTE_WARN_UNUSED_RET int local_strncpy(char *dst, const char *src, u32 n);
ATTRIBUTE_WARN_UNUSED_RET int local_strncat(char *dest, const char *src, u32 n);
/* Return 1 if architecture is big endian, 0 otherwise. */
static inline int arch_is_big_endian(void)
{
const u16 val = 0x0102;
const u8 *buf = (const u8 *)(&val);
return buf[0] == 0x01;
}
#define VAR_ZEROIFY(x) do { \
x = 0; \
} while (0)
#define PTR_NULLIFY(x) do { \
x = NULL; \
} while (0)
#endif /* __UTILS_H__ */