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 OT_INCLUDE_COMMON_UTILS_CODE_UTILS_HPP_
35 #define OT_INCLUDE_COMMON_UTILS_CODE_UTILS_HPP_
36
37 #include <openthread/error.h>
38
39 #include "arg_macros.hpp"
40
41 /**
42 * Calculates the number of elements in an array.
43 *
44 * @param[in] aArray Name of the array variable.
45 *
46 * @returns Number of elements in the array.
47 */
48 #define OT_ARRAY_LENGTH(aArray) (sizeof(aArray) / sizeof(aArray[0]))
49
50 /**
51 * Returns a pointer to end of a given array (pointing to the past-the-end element).
52 *
53 * Note that the past-the-end element is a theoretical element that would follow the last element in the array. It does
54 * not point to an actual element in array, and thus should not be dereferenced.
55 *
56 * @param[in] Name of the array variable
57 *
58 * @returns Pointer to the past-the-end element.
59 */
60 #define OT_ARRAY_END(aArray) (&aArray[OT_ARRAY_LENGTH(aArray)])
61
62 /**
63 * Returns a pointer aligned by @p aAlignment.
64 *
65 * @param[in] aPointer A pointer to contiguous space.
66 * @param[in] aAlignment The desired alignment.
67 *
68 * @returns The aligned pointer.
69 */
70 #define OT_ALIGN(aPointer, aAlignment) \
71 ((void *)(((uintptr_t)(aPointer) + (aAlignment)-1UL) & ~((uintptr_t)(aAlignment)-1UL)))
72
73 // Calculates the aligned variable size.
74 #define OT_ALIGNED_VAR_SIZE(size, align_type) (((size) + (sizeof(align_type) - 1)) / sizeof(align_type))
75
76 // Allocate the structure using "raw" storage.
77 #define OT_DEFINE_ALIGNED_VAR(name, size, align_type) \
78 align_type name[(((size) + (sizeof(align_type) - 1)) / sizeof(align_type))]
79
80 /**
81 * Returns the smaller of @p a and @p b.
82 */
83 #define OT_MIN(a, b) ((b) < (a) ? (b) : (a))
84
85 /**
86 * Returns the greater of @p a and @p b.
87 */
88 #define OT_MAX(a, b) ((a) < (b) ? (b) : (a))
89
90 /**
91 * Checks for the specified status, which is expected to commonly be successful, and branches to the local
92 * label 'exit' if the status is unsuccessful.
93 *
94 * @param[in] aStatus A scalar status to be evaluated against zero (0).
95 */
96 #define SuccessOrExit(aStatus) \
97 do \
98 { \
99 if ((aStatus) != 0) \
100 { \
101 goto exit; \
102 } \
103 } while (false)
104
105 /**
106 * Checks for the specified condition, which is expected to commonly be true, and both executes @a ... and
107 * branches to the local label 'exit' if the condition is false.
108 *
109 * @param[in] aCondition A Boolean expression to be evaluated.
110 * @param[in] aAction An optional expression or block to execute when the assertion fails.
111 */
112 #define VerifyOrExit(...) \
113 do \
114 { \
115 if (!(OT_FIRST_ARG(__VA_ARGS__))) \
116 { \
117 OT_SECOND_ARG(__VA_ARGS__); \
118 goto exit; \
119 } \
120 } while (false)
121
122 /**
123 * Unconditionally executes @a ... and branches to the local label 'exit'.
124 *
125 * @note The use of this interface implies neither success nor failure for the overall exit status of the enclosing
126 * function body.
127 *
128 * @param[in] ... An optional expression or block to execute when the assertion fails.
129 */
130 #define ExitNow(...) \
131 do \
132 { \
133 __VA_ARGS__; \
134 goto exit; \
135 } while (false)
136
137 /*
138 * Executes the `statement` and ignores the return value.
139 *
140 * This is primarily used to indicate the intention of developer that the return value of a function/method can be
141 * safely ignored.
142 *
143 * @param[in] aStatement The function/method to execute.
144 */
145 #define IgnoreReturnValue(aStatement) \
146 do \
147 { \
148 if (aStatement) \
149 { \
150 } \
151 } while (false)
152
153 /**
154 * Ignores an error explicitly.
155 *
156 * This is primarily used to indicate the intention of developer that
157 * the error can be safely ignored or there is guaranteed to be no error.
158 *
159 * @param[in] aError The error to be ignored.
160 */
IgnoreError(otError aError)161 static inline void IgnoreError(otError aError) { OT_UNUSED_VARIABLE(aError); }
162
163 #endif // OT_INCLUDE_COMMON_UTILS_CODE_UTILS_HPP_
164