LCOV - code coverage report
Current view: top level - AP_Common - AP_Common.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 6 6 100.0 %
Date: 2026-09-09 11:02:08 Functions: 6 8 75.0 %

          Line data    Source code
       1             : /*
       2             :    This program is free software: you can redistribute it and/or modify
       3             :    it under the terms of the GNU General Public License as published by
       4             :    the Free Software Foundation, either version 3 of the License, or
       5             :    (at your option) any later version.
       6             : 
       7             :    This program is distributed in the hope that it will be useful,
       8             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
       9             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10             :    GNU General Public License for more details.
      11             : 
      12             :    You should have received a copy of the GNU General Public License
      13             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      14             :  */
      15             : ///
      16             : /// @file       AP_Common.h
      17             : /// @brief              Common definitions and utility routines for the ArduPilot
      18             : ///                             libraries.
      19             : ///
      20             : 
      21             : #pragma once
      22             : 
      23             : #include <stdint.h>
      24             : #include <stdlib.h>
      25             : #include <type_traits>
      26             : #include <new>
      27             : 
      28             : // used to pack structures
      29             : #define PACKED __attribute__((__packed__))
      30             : 
      31             : #if !defined(CYGWIN_BUILD)
      32             : // used to weaken symbols
      33             : #define WEAK __attribute__((__weak__))
      34             : #else
      35             : // cygwin cannot properly support weak symbols allegedly due to Windows
      36             : // executable format limitations
      37             : // (see https://www.cygwin.com/faq.html#faq.programming.linker ). fortunately
      38             : // we only use weak symbols for tests and some HAL stuff which SITL and
      39             : // therefore cygwin does not need to override. in the event that overriding is
      40             : // attempted the link will fail with a symbol redefinition error hopefully
      41             : // suggesting that an alternate approach is needed.
      42             : #define WEAK
      43             : #endif
      44             : 
      45             : // used to mark a function that may be unused in some builds
      46             : #define UNUSED_FUNCTION __attribute__((unused))
      47             : 
      48             : // used to mark an attribute that may be unused in some builds
      49             : #ifdef __clang__
      50             : #define UNUSED_PRIVATE_MEMBER __attribute__((unused))
      51             : #else
      52             : #define UNUSED_PRIVATE_MEMBER
      53             : #endif
      54             : 
      55             : // this can be used to optimize individual functions
      56             : #define OPTIMIZE(level) __attribute__((optimize(level)))
      57             : 
      58             : // sometimes we need to prevent inlining to prevent large stack usage
      59             : #ifndef NOINLINE
      60             : #define NOINLINE __attribute__((noinline))
      61             : #endif
      62             : 
      63             : // used to ignore results for functions marked as warn unused
      64             : #define IGNORE_RETURN(x) do {if (x) {}} while(0)
      65             : 
      66             : #define FMT_PRINTF(a,b) __attribute__((format(printf, a, b)))
      67             : #define FMT_SCANF(a,b) __attribute__((format(scanf, a, b)))
      68             : 
      69             : // used to forbid copy of objects
      70             : #define CLASS_NO_COPY(c) c(const c &other) = delete; c &operator=(const c&) = delete
      71             : 
      72             : #ifdef __has_cpp_attribute
      73             : #  if __has_cpp_attribute(fallthrough)
      74             : #    define FALLTHROUGH [[fallthrough]]
      75             : #  elif __has_cpp_attribute(gnu::fallthrough)
      76             : #    define FALLTHROUGH [[gnu::fallthrough]]
      77             : #  endif
      78             : #endif
      79             : #ifndef FALLTHROUGH
      80             : #  define FALLTHROUGH
      81             : #endif
      82             : 
      83             : #ifdef __GNUC__
      84             :  #define WARN_IF_UNUSED __attribute__ ((warn_unused_result))
      85             : #else
      86             :  #define WARN_IF_UNUSED
      87             : #endif
      88             : 
      89             : #define NORETURN __attribute__ ((noreturn))
      90             : 
      91             : /* Declare and implement const and non-const versions of the array subscript
      92             :  * operator. The object is treated as an array of type_ values. */
      93             : #define DEFINE_BYTE_ARRAY_METHODS                                                                   \
      94             :     inline uint8_t &operator[](size_t i) { return reinterpret_cast<uint8_t *>(this)[i]; }           \
      95             :     inline uint8_t operator[](size_t i) const { return reinterpret_cast<const uint8_t *>(this)[i]; }
      96             : 
      97             : /*
      98             :   check if bit bitnumber is set in value, returned as a
      99             :   bool. Bitnumber starts at 0 for the first bit
     100             :  */
     101             : #define BIT_IS_SET(value, bitnumber) (((value) & (1U<<(bitnumber))) != 0)
     102             : #define BIT_IS_SET_64(value, bitnumber) (((value) & (uint64_t(1U)<<(bitnumber))) != 0)
     103             : 
     104             : // get high or low bytes from 2 byte integer
     105             : #define LOWBYTE(i) ((uint8_t)(i))
     106             : #define HIGHBYTE(i) ((uint8_t)(((uint16_t)(i))>>8))
     107             : 
     108             : #define ARRAY_SIZE(_arr) (sizeof(_arr) / sizeof(_arr[0]))
     109             : 
     110             : #define UINT16_VALUE(hbyte, lbyte) (static_cast<uint16_t>(((hbyte)<<8)|(lbyte)))
     111             : #define UINT32_VALUE(b3, b2, b1, b0) (static_cast<uint32_t>(((b3)<<24)|((b2)<<16)|((b1)<<8)|(b0)))
     112             : 
     113             : /*
     114             :  * See UNUSED_RESULT. The difference is that it receives @uniq_ as the name to
     115             :  * be used for its internal variable.
     116             :  *
     117             :  * @uniq_: a unique name to use for variable name
     118             :  * @expr_: the expression to be evaluated
     119             :  */
     120             : #define _UNUSED_RESULT(uniq_, expr_)                      \
     121             :     do {                                                  \
     122             :         decltype(expr_) uniq_ __attribute__((unused));    \
     123             :         uniq_ = expr_;                                    \
     124             :     } while (0)
     125             : 
     126             : /*
     127             :  * Allow to call a function annotated with warn_unused_result attribute
     128             :  * without getting a warning, because sometimes this is what we want to do.
     129             :  *
     130             :  * @expr_: the expression to be evaluated
     131             :  */
     132             : #define UNUSED_RESULT(expr_) _UNUSED_RESULT(__unique_name_##__COUNTER__, expr_)
     133             : 
     134             : // @}
     135             : 
     136             : // STR_VALUE returns the string equivalent for the passed cpp macro, so e.g.
     137             : // printf("%s", STR_VALUE(EINVAL)); will print "EINVAL"
     138             : #define STR_VALUE(x) #x
     139             : 
     140             : // assert_storage_size template: assert that the memory used to store an
     141             : // item is of a specific size.
     142             : // example invocation:
     143             : // assert_storage_size<class Location, 16> _assert_storage_size_Location;
     144             : // templates are used for this because the compiler's output will
     145             : // usually contain details of the template instantiation so you can
     146             : // see how the actual size differs from the expected size.
     147             : template<typename s, size_t s_size, size_t t> struct _assert_storage_size {
     148             :     static_assert(s_size == t, "wrong size");
     149             : };
     150             : template<typename s, size_t t> struct assert_storage_size {
     151             :     _assert_storage_size<s, sizeof(s), t> _member;
     152             : };
     153             : 
     154             : #define ASSERT_STORAGE_SIZE_JOIN( name, line ) ASSERT_STORAGE_SIZE_DO_JOIN( name, line )
     155             : #define ASSERT_STORAGE_SIZE_DO_JOIN( name, line )  name ## line
     156             : #define ASSERT_STORAGE_SIZE(structure, size) \
     157             :     do { assert_storage_size<structure, size> ASSERT_STORAGE_SIZE_JOIN(assert_storage_sizex, __LINE__); (void)ASSERT_STORAGE_SIZE_JOIN(assert_storage_sizex, __LINE__); } while(false)
     158             : 
     159             : ////////////////////////////////////////////////////////////////////////////////
     160             : /// @name       Conversions
     161             : ///
     162             : /// Conversion macros and factors.
     163             : ///
     164             : //@{
     165             : 
     166             : /*
     167             :   Return true if value is between lower and upper bound inclusive.
     168             :   False otherwise.
     169             : */
     170             : bool is_bounded_int32(int32_t value, int32_t lower_bound, int32_t upper_bound);
     171             : 
     172             : bool WARN_IF_UNUSED hex_char_to_nibble(uint8_t a, uint8_t &res);  // return the uint8 value of an ascii hex character
     173             : 
     174             : /*
     175             :   decode two hex characters into a byte.
     176             :   e.g. hex_twochars_to_uint8("3F", res) -> res = 0x3F
     177             :  */
     178             : bool WARN_IF_UNUSED hex_twochars_to_uint8(const char s[2], uint8_t &res);
     179             : 
     180             : /*
     181             :   decode num_pairs pairs of hex characters into bytes at out[]
     182             :  */
     183             : bool WARN_IF_UNUSED hex_charpairs_to_uint8s(const char *s, uint8_t num_pairs, uint8_t *out);
     184             : 
     185             : /*
     186             :   decode len hex characters into a uint32_t, treating each character
     187             :   as a nibble (most-significant first).
     188             :   e.g. hex_chars_to_uint32("1A2B", 4, out) -> out = 0x1A2B
     189             :  */
     190             : bool WARN_IF_UNUSED hex_chars_to_uint32(const char *s, uint8_t len, uint32_t &out);
     191             : 
     192             : /*
     193             :   strncpy without the warning for not leaving room for nul termination
     194             :  */
     195             : size_t strncpy_noterm(char *dest, const char *src, size_t n);
     196             : 
     197             : 
     198             : /*
     199             :   Bit manipulation
     200             :  */
     201             : //#define BIT_SET(value, bitnumber) ((value) |= (((typeof(value))1U) << (bitnumber)))
     202       19413 : template <typename T> void BIT_SET (T& value, uint8_t bitnumber) noexcept {
     203             :      static_assert(std::is_integral<T>::value, "Integral required.");
     204       19413 :      ((value) |= ((T)(1U) << (bitnumber)));
     205       19413 :  }
     206             : //#define BIT_CLEAR(value, bitnumber) ((value) &= ~(((typeof(value))1U) << (bitnumber)))
     207       77520 : template <typename T> void BIT_CLEAR (T& value, uint8_t bitnumber) noexcept {
     208             :      static_assert(std::is_integral<T>::value, "Integral required.");
     209       77520 :      ((value) &= ~((T)(1U) << (bitnumber)));
     210       77520 :  }
     211             : 
     212             : /*
     213             :   See the comments in libraries/AP_Common/c++.cpp
     214             :  */
     215             : #ifndef NEW_NOTHROW
     216             : #define NEW_NOTHROW new(std::nothrow)
     217             : #endif
     218             : 
     219             : void * WEAK mem_realloc(void *ptr, size_t old_size, size_t new_size);

Generated by: LCOV version 1.14