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