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 /**
219  * Macro used to declare that a symbol should be shared outside the dynamic shared object in
220  * which it is defined.
221  *
222  * This can be used with either a declaration or a definition.
223  *
224  * E.g., with a declaration (perhaps in a header file):
225  *
226  * @code
227  * LE_SHARED void my_Function();
228  * @endcode
229  *
230  * E.g., with a definition (in a .c file):
231  *
232  * @code
233  * LE_SHARED void my_OtherFunction()
234  * {
235  * LE_INFO("Hello world.");
236  * }
237  * @endcode
238  *
239  **/
240 //--------------------------------------------------------------------------------------------------
241 #define LE_SHARED __attribute__((visibility ("default")))
242 
243 //--------------------------------------------------------------------------------------------------
244 /**
245  * @macro LE_DECLARE_INLINE
246  *
247  * Declare an inline function in a header.
248  *
249  * GNU by default uses a non-standard method of declaring inline functions with the
250  * exact *opposite* meaning of the C99 standard.
251  *
252  * So use LE_DECLARE_INLINE with the function body in a header. Then use LE_DEFINE_INLINE with
253  * just the function prototype in a .c file to tell the compiler to emit the function definition
254  * for cases where the function is not inlined.
255  *
256  * This is preferred over using "static inline" since if a static inline function is not inlined
257  * by gcc, there may be multiple copies of the function included in the output.
258  */
259 /**
260  * @macro LE_DEFINE_INLINE
261  *
262  * Cause a function definition to be emitted for an inline function, in case the compiler
263  * decides not to use the inline definition.
264  *
265  * @see @c LE_DECLARE_INLINE
266  */
267 //--------------------------------------------------------------------------------------------------
268 #ifdef __GNUC_GNU_INLINE__
269 // Using gcc inline semantics
270 # define LE_DECLARE_INLINE extern inline
271 # define LE_DEFINE_INLINE inline
272 #else
273 // Use C99 inline semantics
274 # define LE_DECLARE_INLINE inline
275 # define LE_DEFINE_INLINE extern inline
276 #endif
277 
278 //--------------------------------------------------------------------------------------------------
279 /**
280  * Macro used to declare that a symbol is part of the "full" Legato API.
281  *
282  * There are two APIs for Legato: "full" and "limited". Linux uses the "full" API and all
283  * functions are available. On other platforms only the "limited" API is supported, and
284  * any attempt to use a "full" api function will lead to a compile error.
285  */
286 //--------------------------------------------------------------------------------------------------
287 #ifdef LE_CONFIG_LINUX
288 # define LE_FULL_API
289 #else
290 # define LE_FULL_API __attribute__((error ("Function not available on this platform")))
291 #endif
292 
293 // CLang feature check macros -- define to return sensible defaults if macro is not available.
294 #ifndef __is_identifier
295 # define __is_identifier(x) 1
296 #endif
297 
298 #ifndef __has_warning
299 # define __has_warning(x) 0
300 #endif
301 
302 #if !__is_identifier(_Nonnull)
303 
304 // Nullability information is not complete. Normally clang will warn in that case.
305 # if __has_warning("-Wnullability-completeness")
306 # pragma clang diagnostic ignored "-Wnullability-completeness"
307 # endif
308 
309 //--------------------------------------------------------------------------------------------------
310 /**
311  * Mark a parameter or return value as never NULL.
312  */
313 //--------------------------------------------------------------------------------------------------
314 # define LE_NONNULL _Nonnull
315 
316 //--------------------------------------------------------------------------------------------------
317 /**
318  * Mark a parameter or return value as potentially NULL.
319  */
320 //--------------------------------------------------------------------------------------------------
321 # define LE_NULLABLE _Nullable
322 #else
323 # define LE_NONNULL
324 # define LE_NULLABLE
325 #endif
326 
327 //--------------------------------------------------------------------------------------------------
328 /**
329  * Format specifiers for size_t
330  */
331 //--------------------------------------------------------------------------------------------------
332 #if (__STDC_VERSION__ >= 199901L) || LE_CONFIG_LINUX
333 # define __PRIS_PREFIX "z"
334 #elif defined(__LP64__) || defined(_LP64)
335 # define __PRIS_PREFIX "ll"
336 #else
337 # define __PRIS_PREFIX "l"
338 #endif
339 
340 #define PRIdS __PRIS_PREFIX "d"
341 #define PRIxS __PRIS_PREFIX "x"
342 #define PRIuS __PRIS_PREFIX "u"
343 #define PRIXS __PRIS_PREFIX "X"
344 #define PRIoS __PRIS_PREFIX "o"
345 
346 
347 #if !defined(static_assert) && !defined(__cplusplus)
348 //--------------------------------------------------------------------------------------------------
349 /**
350  * Provide static_assert if not available.
351  */
352 //--------------------------------------------------------------------------------------------------
353 # define static_assert(cond, msg) _Static_assert((cond), #cond ": " msg)
354 #endif
355 #define inline_static_assert(cond, msg) ({ static_assert(cond, msg); })
356 
357 //--------------------------------------------------------------------------------------------------
358 /**
359  * Test if a KConfig feature is enabled.
360  */
361 //--------------------------------------------------------------------------------------------------
362 #define LE_CONFIG_IS_ENABLED(option) (("" #option)[0] == '1')
363 
364 #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