1 /*
2 * Copyright (c) 2016, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /**
30 * @file
31 * This file includes macros for validating runtime conditions.
32 */
33
34 #ifndef CODE_UTILS_HPP_
35 #define CODE_UTILS_HPP_
36
37 #include <stdbool.h>
38
39 #include <openthread/error.h>
40
41 #include "common/arg_macros.hpp"
42
43 /**
44 * Calculates the number of elements in an array.
45 *
46 * @param[in] aArray Name of the array variable.
47 *
48 * @returns Number of elements in the array.
49 *
50 */
51 #define OT_ARRAY_LENGTH(aArray) (sizeof(aArray) / sizeof(aArray[0]))
52
53 /**
54 * Returns a pointer to end of a given array (pointing to the past-the-end element).
55 *
56 * Note that the past-the-end element is a theoretical element that would follow the last element in the array. It does
57 * not point to an actual element in array, and thus should not be dereferenced.
58 *
59 * @param[in] Name of the array variable
60 *
61 * @returns Pointer to the past-the-end element.
62 *
63 */
64 #define OT_ARRAY_END(aArray) (&aArray[OT_ARRAY_LENGTH(aArray)])
65
66 /**
67 * Returns a pointer aligned by @p aAlignment.
68 *
69 * @param[in] aPointer A pointer to contiguous space.
70 * @param[in] aAlignment The desired alignment.
71 *
72 * @returns The aligned pointer.
73 *
74 */
75 #define OT_ALIGN(aPointer, aAlignment) \
76 ((void *)(((uintptr_t)(aPointer) + (aAlignment)-1UL) & ~((uintptr_t)(aAlignment)-1UL)))
77
78 // Calculates the aligned variable size.
79 #define OT_ALIGNED_VAR_SIZE(size, align_type) (((size) + (sizeof(align_type) - 1)) / sizeof(align_type))
80
81 // Allocate the structure using "raw" storage.
82 #define OT_DEFINE_ALIGNED_VAR(name, size, align_type) \
83 align_type name[(((size) + (sizeof(align_type) - 1)) / sizeof(align_type))]
84
85 /**
86 * Returns the smaller of @p a and @p b.
87 *
88 */
89 #define OT_MIN(a, b) ((b) < (a) ? (b) : (a))
90
91 /**
92 * Returns the greater of @p a and @p b.
93 *
94 */
95 #define OT_MAX(a, b) ((a) < (b) ? (b) : (a))
96
97 /**
98 * Checks for the specified status, which is expected to commonly be successful, and branches to the local
99 * label 'exit' if the status is unsuccessful.
100 *
101 * @param[in] aStatus A scalar status to be evaluated against zero (0).
102 *
103 */
104 #define SuccessOrExit(aStatus) \
105 do \
106 { \
107 if ((aStatus) != 0) \
108 { \
109 goto exit; \
110 } \
111 } while (false)
112
113 /**
114 * Checks for the specified condition, which is expected to commonly be true, and both executes @a ... and
115 * branches to the local label 'exit' if the condition is false.
116 *
117 * @param[in] aCondition A Boolean expression to be evaluated.
118 * @param[in] aAction An optional expression or block to execute when the assertion fails.
119 *
120 */
121 #define VerifyOrExit(...) \
122 do \
123 { \
124 if (!(OT_FIRST_ARG(__VA_ARGS__))) \
125 { \
126 OT_SECOND_ARG(__VA_ARGS__); \
127 goto exit; \
128 } \
129 } while (false)
130
131 /**
132 * Unconditionally executes @a ... and branches to the local label 'exit'.
133 *
134 * @note The use of this interface implies neither success nor failure for the overall exit status of the enclosing
135 * function body.
136 *
137 * @param[in] ... An optional expression or block to execute when the assertion fails.
138 *
139 */
140 #define ExitNow(...) \
141 do \
142 { \
143 __VA_ARGS__; \
144 goto exit; \
145 } while (false)
146
147 /*
148 * Executes the `statement` and ignores the return value.
149 *
150 * This is primarily used to indicate the intention of developer that the return value of a function/method can be
151 * safely ignored.
152 *
153 * @param[in] aStatement The function/method to execute.
154 *
155 */
156 #define IgnoreReturnValue(aStatement) \
157 do \
158 { \
159 if (aStatement) \
160 { \
161 } \
162 } while (false)
163
164 /**
165 * Ignores an error explicitly.
166 *
167 * This is primarily used to indicate the intention of developer that
168 * the error can be safely ignored or there is guaranteed to be no error.
169 *
170 * @param[in] aError The error to be ignored.
171 *
172 */
IgnoreError(otError aError)173 static inline void IgnoreError(otError aError) { OT_UNUSED_VARIABLE(aError); }
174
175 #endif // CODE_UTILS_HPP_
176