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