le_basics.h

Go to the documentation of this file.
1 /**
2  * @page c_basics Basic Type and Constant Definitions
3  *
4  * Cardinal types and commonly-used constants form the basic
5  * foundation on which everything else is built. These include
6  * error codes, portable integer types, and helpful macros that make things easier to use.
7  *
8  * See @ref le_basics.h for basic cardinal types and commonly-used constants info.
9  *
10  * <HR>
11  *
12  * Copyright (C) Sierra Wireless Inc.
13  */
14 
15 
16 /** @file le_basics.h
17  *
18  * Legato @ref c_basics include file.
19  *
20  * Copyright (C) Sierra Wireless Inc.
21  */
22 
23 #ifndef LEGATO_BASICS_INCLUDE_GUARD
24 #define LEGATO_BASICS_INCLUDE_GUARD
25 
26 //--------------------------------------------------------------------------------------------------
27 /**
28  * If the compiler is armcc, allow anonymous unions, as these are useful and used
29  * quite a bit in Legato
30  */
31 //--------------------------------------------------------------------------------------------------
32 #ifdef __ARMCC_VERSION
33 #pragma anon_unions
34 #endif
35 
36 //--------------------------------------------------------------------------------------------------
37 /**
38  * Standard result codes.
39  *
40  * @note All error codes are negative integers. They allow functions with signed
41  * integers to return non-negative values when successful or standard error codes on failure.
42  * @deprecated the result code LE_NOT_POSSIBLE is scheduled to be removed.
43  */
44 //--------------------------------------------------------------------------------------------------
45 typedef enum
46 {
47  LE_OK = 0, ///< Successful.
48  LE_NOT_FOUND = -1, ///< Referenced item does not exist or could not be found.
49  LE_NOT_POSSIBLE = -2, ///< @deprecated It is not possible to perform the requested action.
50  LE_OUT_OF_RANGE = -3, ///< An index or other value is out of range.
51  LE_NO_MEMORY = -4, ///< Insufficient memory is available.
52  LE_NOT_PERMITTED = -5, ///< Current user does not have permission to perform requested action.
53  LE_FAULT = -6, ///< Unspecified internal error.
54  LE_COMM_ERROR = -7, ///< Communications error.
55  LE_TIMEOUT = -8, ///< A time-out occurred.
56  LE_OVERFLOW = -9, ///< An overflow occurred or would have occurred.
57  LE_UNDERFLOW = -10, ///< An underflow occurred or would have occurred.
58  LE_WOULD_BLOCK = -11, ///< Would have blocked if non-blocking behaviour was not requested.
59  LE_DEADLOCK = -12, ///< Would have caused a deadlock.
60  LE_FORMAT_ERROR = -13, ///< Format error.
61  LE_DUPLICATE = -14, ///< Duplicate entry found or operation already performed.
62  LE_BAD_PARAMETER = -15, ///< Parameter is invalid.
63  LE_CLOSED = -16, ///< The resource is closed.
64  LE_BUSY = -17, ///< The resource is busy.
65  LE_UNSUPPORTED = -18, ///< The underlying resource does not support this operation.
66  LE_IO_ERROR = -19, ///< An IO operation failed.
67  LE_NOT_IMPLEMENTED = -20, ///< Unimplemented functionality.
68  LE_UNAVAILABLE = -21, ///< A transient or temporary loss of a service or resource.
69  LE_TERMINATED = -22, ///< The process, operation, data stream, session, etc. has stopped.
70  LE_IN_PROGRESS = -23, ///< The operation is in progress.
71  LE_SUSPENDED = -24, ///< The operation is suspended.
72 }
74 
75 
76 //--------------------------------------------------------------------------------------------------
77 /**
78  * Standard exit codes.
79  *
80  * @note The value follow standardize exit codes of BSD(Berkeley software distribution),
81  * detail in file <sysexits.h>.
82  *
83  * Present exit status of process that is stopped by loss of a service or resource.
84  */
85 //--------------------------------------------------------------------------------------------------
86 #define EXIT_UNAVAILABLE 69
87 
88 
89 //--------------------------------------------------------------------------------------------------
90 /**
91  * ON/OFF type.
92  *
93  */
94 //--------------------------------------------------------------------------------------------------
95 typedef enum
96 {
97  LE_OFF = 0,
98  LE_ON = 1,
99 }
100 le_onoff_t;
101 
102 
103 //--------------------------------------------------------------------------------------------------
104 /** @name Bit Masks
105  *
106  * Single byte bit definitions that can be used for bit masking.
107  * @{
108  */
109 //--------------------------------------------------------------------------------------------------
110 #define BIT0 0x01
111 #define BIT1 0x02
112 #define BIT2 0x04
113 #define BIT3 0x08
114 #define BIT4 0x10
115 #define BIT5 0x20
116 #define BIT6 0x40
117 #define BIT7 0x80
118 // @}
119 
120 //--------------------------------------------------------------------------------------------------
121 /**
122  * Find the address of a containing structure or union, based on the address of one of its members.
123  *
124  * If @c countPtr points to the @c count member of an object type
125  * @c my_class_t, then a pointer to that object should use this:
126  *
127  * @code
128  * my_class_t* myObjPtr = CONTAINER_OF(countPtr, my_class_t, count);
129  * @endcode
130  */
131 //--------------------------------------------------------------------------------------------------
132 #define CONTAINER_OF(memberPtr, type, member) \
133  ((type*)(((uint8_t*)(memberPtr))-((size_t)(&(((type*)0)->member)))))
134 
135 
136 //--------------------------------------------------------------------------------------------------
137 /**
138  * Computes number of members in an array at compile time.
139  *
140  * @warning Does NOT work for pointers to arrays.
141  *
142  * Here's a code sample:
143  *
144  * @code
145  * const char message[] = "Hello world!";
146  *
147  * size_t x = NUM_ARRAY_MEMBERS(message);
148  *
149  * printf("%lu\n", x);
150  * @endcode
151  *
152  * Will print @c 13 on a 32-bit target.
153  *
154  * But this example is @b incorrect:
155  *
156  * @code
157  * const char message[] = "Hello world!";
158  * const char* messagePtr = &message;
159  *
160  * size_t x = NUM_ARRAY_MEMBERS(messagePtr); // NO! BAD PROGRAMMER! BAD!
161  *
162  * printf("%lu\n", x);
163  * @endcode
164  */
165 //--------------------------------------------------------------------------------------------------
166 #define NUM_ARRAY_MEMBERS(array) \
167  (sizeof(array) / sizeof((array)[0]))
168 
169 
170 //--------------------------------------------------------------------------------------------------
171 /**
172  * Computes the index of a member within an array.
173  *
174  * This code sample prints out "The 'w' is at index 6.":
175  *
176  * @code
177  * const char message[] = "Hello world!";
178  * const char* charPtr;
179  * int i;
180  *
181  * for (i = 0; i < sizeof(message); i++)
182  * {
183  * if (message[i] == 'w')
184  * {
185  * charPtr = &message[i];
186  * }
187  * }
188  *
189  * printf("The 'w' is at index %zu.\n", INDEX_OF_ARRAY_MEMBER(message, charPtr));
190  * @endcode
191  **/
192 //--------------------------------------------------------------------------------------------------
193 #define INDEX_OF_ARRAY_MEMBER(array, memberPtr) \
194  ((((size_t)memberPtr) - ((size_t)array)) / sizeof(*(memberPtr)))
195 
196 
197 //--------------------------------------------------------------------------------------------------
198 /**
199  * This function takes the characters as an argument and puts quotes around them.
200  *
201  * Code sample:
202  *
203  * @code
204  * const char name[] = STRINGIZE(foo);
205  * @endcode
206  *
207  * Is seen by the compiler as
208  *
209  * @code
210  * const char name[] = "foo";
211  * @endcode
212  *
213  * The STRINGIZE() macro function passes names like macro definitions
214  * on the compiler's command-line. If the above code were changed to:
215  *
216  * @code
217  * const char name[] = STRINGIZE(NAME);
218  * @endcode
219  *
220  * then compiling it using the following command line makes it equivalent to the
221  * example above:
222  *
223  * @code
224  * $ gcc -c -DNAME=foo file.c
225  * @endcode
226  *
227  * The <c>-DNAME=foo</c> defines a macro called <c>NAME</c> with a value <c>foo</c>.
228  * The C preprocessor then replaces <c>STRINGIZE(NAME)</c> with <c>"foo"</c>.
229  */
230 //--------------------------------------------------------------------------------------------------
231 #define STRINGIZE(x) STRINGIZE_EXPAND(x)
232 
233 //--------------------------------------------------------------------------------------------------
234 /**
235  * Helper macro for @ref STRINGIZE(x).
236  */
237 //--------------------------------------------------------------------------------------------------
238 #define STRINGIZE_EXPAND(x) #x // Needed to expand macros.
239 
240 //--------------------------------------------------------------------------------------------------
241 /**
242  * Macro to help concatenate preprocessor tokens while first allowing macro expansion of those
243  * tokens.
244  *
245  * Original source: https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
246  */
247 //--------------------------------------------------------------------------------------------------
248 #define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
249 
250 //--------------------------------------------------------------------------------------------------
251 /**
252  * Helper macro for @ref STRINGIZE(x).
253  */
254 //--------------------------------------------------------------------------------------------------
255 #define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
256 
257 //--------------------------------------------------------------------------------------------------
258 /**
259  * Helper macro for @ref SECOND(...). Always select the second parameter.
260  */
261 //--------------------------------------------------------------------------------------------------
262 #define SECOND(a, b, ...) b
263 
264 //--------------------------------------------------------------------------------------------------
265 /**
266  * If the macro passed as the first parameter is defined in the form ,<value> (note the leading
267  * comma) this evaluates to <value>. If the macro is not defined in this format (or not defined at
268  * all, this evaluates to the second, default parameter.
269  */
270 //--------------------------------------------------------------------------------------------------
271 #define LE_DEFAULT(...) SECOND(__VA_ARGS__)
272 
273 //--------------------------------------------------------------------------------------------------
274 /**
275  * Macro used to declare that a symbol should be shared outside the dynamic shared object in
276  * which it is defined.
277  *
278  * This can be used with either a declaration or a definition.
279  *
280  * E.g., with a declaration (perhaps in a header file):
281  *
282  * @code
283  * LE_SHARED void my_Function();
284  * @endcode
285  *
286  * E.g., with a definition (in a .c file):
287  *
288  * @code
289  * LE_SHARED void my_OtherFunction()
290  * {
291  * LE_INFO("Hello world.");
292  * }
293  * @endcode
294  *
295  **/
296 //--------------------------------------------------------------------------------------------------
297 #define LE_SHARED __attribute__((visibility ("default")))
298 
299 //--------------------------------------------------------------------------------------------------
300 /**
301  * @macro LE_DECLARE_INLINE
302  *
303  * Declare an inline function in a header.
304  *
305  * GNU by default uses a non-standard method of declaring inline functions with the
306  * exact *opposite* meaning of the C99 standard.
307  *
308  * So use LE_DECLARE_INLINE with the function body in a header. Then use LE_DEFINE_INLINE with
309  * just the function prototype in a .c file to tell the compiler to emit the function definition
310  * for cases where the function is not inlined.
311  *
312  * This is preferred over using "static inline" since if a static inline function is not inlined
313  * by gcc, there may be multiple copies of the function included in the output.
314  */
315 /**
316  * @macro LE_DEFINE_INLINE
317  *
318  * Cause a function definition to be emitted for an inline function, in case the compiler
319  * decides not to use the inline definition.
320  *
321  * @see @c LE_DECLARE_INLINE
322  */
323 //--------------------------------------------------------------------------------------------------
324 #ifdef __GNUC_GNU_INLINE__
325 // Using gcc inline semantics
326 # define LE_DECLARE_INLINE extern inline
327 # define LE_DEFINE_INLINE inline
328 #else
329 // Use C99 inline semantics
330 # define LE_DECLARE_INLINE inline
331 # define LE_DEFINE_INLINE extern inline
332 #endif
333 
334 // Clang feature check macros -- define to return sensible defaults if macro is not available.
335 #ifndef __is_identifier
336 # define __is_identifier(x) 1
337 #endif
338 
339 #ifndef __has_warning
340 # define __has_warning(x) 0
341 #endif
342 
343 #ifndef __has_attribute
344 # define __has_attribute(x) 0
345 #endif
346 
347 #if !__is_identifier(_Nonnull)
348 
349 // Nullability information is not complete. Normally clang will warn in that case.
350 # if __has_warning("-Wnullability-completeness")
351 # pragma clang diagnostic ignored "-Wnullability-completeness"
352 # endif
353 
354 //--------------------------------------------------------------------------------------------------
355 /**
356  * Mark a parameter or return value as never NULL.
357  */
358 //--------------------------------------------------------------------------------------------------
359 # define LE_NONNULL _Nonnull
360 
361 //--------------------------------------------------------------------------------------------------
362 /**
363  * Mark a parameter or return value as potentially NULL.
364  */
365 //--------------------------------------------------------------------------------------------------
366 # define LE_NULLABLE _Nullable
367 #else
368 # define LE_NONNULL
369 # define LE_NULLABLE
370 #endif
371 
372 //--------------------------------------------------------------------------------------------------
373 /**
374  * Mark a variable as unused.
375  *
376  * @param v Variable to mark as unused.
377  */
378 //--------------------------------------------------------------------------------------------------
379 #define LE_UNUSED(v) ((void) (v))
380 
381 //--------------------------------------------------------------------------------------------------
382 /**
383  * Format specifiers for size_t
384  */
385 //--------------------------------------------------------------------------------------------------
386 #if (__STDC_VERSION__ >= 199901L) || LE_CONFIG_LINUX
387 # define __PRIS_PREFIX "z"
388 #elif defined(__LP64__) || defined(_LP64)
389 # define __PRIS_PREFIX "ll"
390 #else
391 # define __PRIS_PREFIX "l"
392 #endif
393 
394 #define PRIdS __PRIS_PREFIX "d"
395 #define PRIxS __PRIS_PREFIX "x"
396 #define PRIuS __PRIS_PREFIX "u"
397 #define PRIXS __PRIS_PREFIX "X"
398 #define PRIoS __PRIS_PREFIX "o"
399 
400 
401 #if !defined(static_assert) && !defined(__cplusplus)
402 //--------------------------------------------------------------------------------------------------
403 /**
404  * Provide static_assert if not available.
405  */
406 //--------------------------------------------------------------------------------------------------
407 # if __GNUC__ || __STDC_VERSION__ >= 201112L
408 # define static_assert(cond, msg) _Static_assert((cond), #cond ": " msg)
409 # else
410 # define static_assert(cond, msg) ((void)sizeof(char[1 - 2*!(cond)]))
411 # endif
412 #endif
413 
414 #if __GNUC__
415 // ({ }) is a GNU extension, so only use it if compiler is GCC-compatible
416 # define inline_static_assert(cond, msg) ({ static_assert(cond, msg); })
417 #else
418 # define inline_static_assert(cond, msg) ((void)(0))
419 #endif
420 
421 //--------------------------------------------------------------------------------------------------
422 /**
423  * Test if a KConfig feature is enabled.
424  */
425 //--------------------------------------------------------------------------------------------------
426 #define LE_CONFIG_IS_ENABLED(option) (("" STRINGIZE(option))[0] == '1')
427 
428 #endif // LEGATO_BASICS_INCLUDE_GUARD
Format error.
Definition: le_basics.h:60
The underlying resource does not support this operation.
Definition: le_basics.h:65
Current user does not have permission to perform requested action.
Definition: le_basics.h:52
Unspecified internal error.
Definition: le_basics.h:53
Duplicate entry found or operation already performed.
Definition: le_basics.h:61
Insufficient memory is available.
Definition: le_basics.h:51
le_result_t
Definition: le_basics.h:45
An IO operation failed.
Definition: le_basics.h:66
Would have caused a deadlock.
Definition: le_basics.h:59
Successful.
Definition: le_basics.h:47
Unimplemented functionality.
Definition: le_basics.h:67
An overflow occurred or would have occurred.
Definition: le_basics.h:56
A time-out occurred.
Definition: le_basics.h:55
An underflow occurred or would have occurred.
Definition: le_basics.h:57
Referenced item does not exist or could not be found.
Definition: le_basics.h:48
The resource is closed.
Definition: le_basics.h:63
A transient or temporary loss of a service or resource.
Definition: le_basics.h:68
Definition: le_basics.h:49
The resource is busy.
Definition: le_basics.h:64
The operation is in progress.
Definition: le_basics.h:70
An index or other value is out of range.
Definition: le_basics.h:50
Parameter is invalid.
Definition: le_basics.h:62
Would have blocked if non-blocking behaviour was not requested.
Definition: le_basics.h:58
The process, operation, data stream, session, etc. has stopped.
Definition: le_basics.h:69
The operation is suspended.
Definition: le_basics.h:71
Communications error.
Definition: le_basics.h:54
le_onoff_t
Definition: le_basics.h:95