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