Matter SDK Coverage Report
Current view: top level - lib/support - CodeUtils.h (source / functions) Coverage Total Hit
Test: SHA:f468d4e0557730acf75c7d4f0d8966932c0745d0 Lines: 44.4 % 9 4
Test Date: 2025-10-08 07:10:10 Functions: 50.0 % 4 2

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *    Copyright (c) 2013-2017 Nest Labs, Inc.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *      This file defines and implements a number of miscellaneous
      22              :  *      templates for finding object minima and maxima and interface
      23              :  *      macros for assertion checking.
      24              :  *
      25              :  */
      26              : 
      27              : #pragma once
      28              : 
      29              : #include <lib/core/CHIPConfig.h>
      30              : #include <lib/core/CHIPError.h>
      31              : #include <lib/core/ErrorStr.h>
      32              : #include <lib/support/ObjectDump.h>
      33              : #include <lib/support/VerificationMacrosNoLogging.h>
      34              : #include <lib/support/logging/TextOnlyLogging.h>
      35              : 
      36              : /**
      37              :  * Base-level abnormal termination.
      38              :  *
      39              :  * Terminate the program immediately, without invoking destructors, atexit callbacks, etc.
      40              :  * Used to implement the default `chipDie()`.
      41              :  *
      42              :  * @note
      43              :  *  This should never be invoked directly by code outside this file.
      44              :  */
      45              : #if !defined(CHIP_CONFIG_ABORT)
      46              : #define CHIP_CONFIG_ABORT() abort()
      47              : #endif
      48              : 
      49              : /**
      50              :  *  @name chip-specific nlassert.h Overrides
      51              :  *
      52              :  *  @{
      53              :  *
      54              :  */
      55              : 
      56              : /**
      57              :  *  @def NL_ASSERT_ABORT()
      58              :  *
      59              :  *  @brief
      60              :  *    This implements a chip-specific override for #NL_ASSERT_ABORT *
      61              :  *    from nlassert.h.
      62              :  *
      63              :  */
      64              : #if !defined(NL_ASSERT_ABORT)
      65              : #define NL_ASSERT_ABORT() chipAbort()
      66              : #endif
      67              : 
      68              : /**
      69              :  *  @def NL_ASSERT_LOG(aPrefix, aName, aCondition, aLabel, aFile, aLine, aMessage)
      70              :  *
      71              :  *  @brief
      72              :  *    This implements a chip-specific override for \c NL_ASSERT_LOG
      73              :  *    from nlassert.h.
      74              :  *
      75              :  *  @param[in]  aPrefix     A pointer to a NULL-terminated C string printed
      76              :  *                          at the beginning of the logged assertion
      77              :  *                          message. Typically this is and should be
      78              :  *                          \c NL_ASSERT_PREFIX_STRING.
      79              :  *  @param[in]  aName       A pointer to a NULL-terminated C string printed
      80              :  *                          following @a aPrefix that indicates what
      81              :  *                          module, program, application or subsystem
      82              :  *                          the assertion occurred in Typically this
      83              :  *                          is and should be
      84              :  *                          \c NL_ASSERT_COMPONENT_STRING.
      85              :  *  @param[in]  aCondition  A pointer to a NULL-terminated C string indicating
      86              :  *                          the expression that evaluated to false in
      87              :  *                          the assertion. Typically this is a
      88              :  *                          stringified version of the actual
      89              :  *                          assertion expression.
      90              :  *  @param[in]  aLabel      An optional pointer to a NULL-terminated C string
      91              :  *                          indicating, for exception-style
      92              :  *                          assertions, the label that will be
      93              :  *                          branched to when the assertion expression
      94              :  *                          evaluates to false.
      95              :  *  @param[in]  aFile       A pointer to a NULL-terminated C string indicating
      96              :  *                          the file in which the exception
      97              :  *                          occurred. Typically this is and should be
      98              :  *                          \_\_FILE\_\_ from the C preprocessor.
      99              :  *  @param[in]  aLine       The line number in @a aFile on which the assertion
     100              :  *                          expression evaluated to false. Typically
     101              :  *                          this is and should be \_\_LINE\_\_ from the C
     102              :  *                          preprocessor.
     103              :  *  @param[in]  aMessage    An optional pointer to a NULL-terminated C string
     104              :  *                          containing a caller-specified message
     105              :  *                          further describing the assertion failure.
     106              :  *
     107              :  */
     108              : // clang-format off
     109              : #if !defined(NL_ASSERT_LOG)
     110              : #define NL_ASSERT_LOG(aPrefix, aName, aCondition, aLabel, aFile, aLine, aMessage)         \
     111              :     do                                                                                    \
     112              :     {                                                                                     \
     113              :         ChipLogError(NotSpecified,                                                       \
     114              :                       NL_ASSERT_LOG_FORMAT_DEFAULT,                                       \
     115              :                       aPrefix,                                                            \
     116              :                       (((aName) == 0) || (*(aName) == '\0')) ? "" : aName,                \
     117              :                       (((aName) == 0) || (*(aName) == '\0')) ? "" : ": ",                 \
     118              :                       aCondition,                                                         \
     119              :                       (((aMessage) == 0) ? "" : aMessage),                                \
     120              :                       (((aMessage) == 0) ? "" : ", "),                                    \
     121              :                       aFile,                                                              \
     122              :                       aLine);                                                             \
     123              :     } while (0)
     124              : #endif
     125              : // clang-format on
     126              : 
     127              : /**
     128              :  *  @} chip-specific nlassert.h Overrides
     129              :  *
     130              :  */
     131              : 
     132              : #include <nlassert.h>
     133              : 
     134              : /**
     135              :  *  @def ReturnErrorOnFailure(expr)
     136              :  *
     137              :  *  @brief
     138              :  *    Returns the error code if the expression returns an error. For a CHIP_ERROR expression, this means any value other
     139              :  *    than CHIP_NO_ERROR. For an integer expression, this means non-zero.
     140              :  *
     141              :  *  Example usage:
     142              :  *
     143              :  *  @code
     144              :  *    ReturnErrorOnFailure(channel->SendMsg(msg));
     145              :  *  @endcode
     146              :  *
     147              :  *  @param[in]  expr        An expression to be tested.
     148              :  */
     149              : #define ReturnErrorOnFailure(expr)                                                                                                 \
     150              :     do                                                                                                                             \
     151              :     {                                                                                                                              \
     152              :         auto __err = (expr);                                                                                                       \
     153              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     154              :         {                                                                                                                          \
     155              :             return __err;                                                                                                          \
     156              :         }                                                                                                                          \
     157              :     } while (false)
     158              : 
     159              : /**
     160              :  *  @def ReturnErrorVariantOnFailure(expr)
     161              :  *
     162              :  *  @brief
     163              :  *    This is for use when the calling function returns a Variant type. It returns a CHIP_ERROR variant with the corresponding error
     164              :  *    code if the expression returns an error.
     165              :  *
     166              :  *  Example usage:
     167              :  *
     168              :  *  @code
     169              :  *    ReturnErrorVariantOnFailure(NextStep, ParseSigma1(tlvReader, parsedSigma1));
     170              :  *  @endcode
     171              :  *
     172              :  *  @param[in]  variantType   The Variant type that the calling function returns.
     173              :  *  @param[in]  expr          An expression to be tested.
     174              : 
     175              :  */
     176              : #define ReturnErrorVariantOnFailure(variantType, expr)                                                                             \
     177              :     do                                                                                                                             \
     178              :     {                                                                                                                              \
     179              :         auto __err = (expr);                                                                                                       \
     180              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     181              :         {                                                                                                                          \
     182              :             return variantType::Create<CHIP_ERROR>(__err);                                                                         \
     183              :         }                                                                                                                          \
     184              :     } while (false)
     185              : 
     186              : /**
     187              :  *  @def ReturnLogErrorOnFailure(expr)
     188              :  *
     189              :  *  @brief
     190              :  *    Returns the error code if the expression returns something different
     191              :  *    than CHIP_NO_ERROR.
     192              :  *
     193              :  *  Example usage:
     194              :  *
     195              :  *  @code
     196              :  *    ReturnLogErrorOnFailure(channel->SendMsg(msg));
     197              :  *  @endcode
     198              :  *
     199              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     200              :  */
     201              : #define ReturnLogErrorOnFailure(expr)                                                                                              \
     202              :     do                                                                                                                             \
     203              :     {                                                                                                                              \
     204              :         CHIP_ERROR __err = (expr);                                                                                                 \
     205              :         if (__err != CHIP_NO_ERROR)                                                                                                \
     206              :         {                                                                                                                          \
     207              :             ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(__err), __FILE__, __LINE__);                                        \
     208              :             return __err;                                                                                                          \
     209              :         }                                                                                                                          \
     210              :     } while (false)
     211              : 
     212              : /**
     213              :  *  @def LogAndReturnOnFailure(expr)
     214              :  *
     215              :  *  @brief
     216              :  *    If expr returns something than CHIP_NO_ERROR, log a chip message for the specified module
     217              :  *    in the 'Error' category and return.
     218              :  *
     219              :  *  Example usage:
     220              :  *
     221              :  *  @code
     222              :  *    LogAndReturnOnFailure(channel->SendMsg(msg), Module, "Failure message: %s", param);
     223              :  *  @endcode
     224              :  *
     225              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     226              :  */
     227              : #define LogAndReturnOnFailure(expr, MOD, MSG, ...)                                                                                 \
     228              :     do                                                                                                                             \
     229              :     {                                                                                                                              \
     230              :         CHIP_ERROR __err = (expr);                                                                                                 \
     231              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     232              :         {                                                                                                                          \
     233              :             ChipLogError(MOD, MSG ": %" CHIP_ERROR_FORMAT, ##__VA_ARGS__, __err.Format());                                         \
     234              :             return;                                                                                                                \
     235              :         }                                                                                                                          \
     236              :     } while (false)
     237              : 
     238              : /**
     239              :  *  @def LogAndReturnErrorOnFailure(expr)
     240              :  *
     241              :  *  @brief
     242              :  *    If expr returns something than CHIP_NO_ERROR, lg a chip message for the specified module
     243              :  *    in the 'Error' category and return the error.
     244              :  *
     245              :  *  Example usage:
     246              :  *
     247              :  *  @code
     248              :  *    LogAndReturnErrorOnFailure(channel->SendMsg(msg), Module, "Failure message: %s", param);
     249              :  *  @endcode
     250              :  *
     251              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     252              :  */
     253              : #define LogAndReturnErrorOnFailure(expr, MOD, MSG, ...)                                                                            \
     254              :     do                                                                                                                             \
     255              :     {                                                                                                                              \
     256              :         CHIP_ERROR __err = (expr);                                                                                                 \
     257              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     258              :         {                                                                                                                          \
     259              :             ChipLogError(MOD, MSG ": %" CHIP_ERROR_FORMAT, ##__VA_ARGS__, __err.Format());                                         \
     260              :             return _err;                                                                                                           \
     261              :         }                                                                                                                          \
     262              :     } while (false)
     263              : 
     264              : /**
     265              :  *  @def ReturnOnFailure(expr)
     266              :  *
     267              :  *  @brief
     268              :  *    Returns if the expression returns an error. For a CHIP_ERROR expression, this means any value other
     269              :  *    than CHIP_NO_ERROR. For an integer expression, this means non-zero.
     270              :  *
     271              :  *  Example usage:
     272              :  *
     273              :  *  @code
     274              :  *    ReturnOnFailure(channel->SendMsg(msg));
     275              :  *  @endcode
     276              :  *
     277              :  *  @param[in]  expr        An expression to be tested.
     278              :  *  @param[in]  ...         Statements to execute before returning. Optional.
     279              :  */
     280              : #define ReturnOnFailure(expr, ...)                                                                                                 \
     281              :     do                                                                                                                             \
     282              :     {                                                                                                                              \
     283              :         auto __err = (expr);                                                                                                       \
     284              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     285              :         {                                                                                                                          \
     286              :             __VA_ARGS__;                                                                                                           \
     287              :             return;                                                                                                                \
     288              :         }                                                                                                                          \
     289              :     } while (false)
     290              : 
     291              : /**
     292              :  *  @def ReturnValueOnFailure(expr)
     293              :  *
     294              :  *  @brief
     295              :  *    Returns value if the expression returns an error. For a CHIP_ERROR expression, this means any value other
     296              :  *    than CHIP_NO_ERROR. For an integer expression, this means non-zero.
     297              :  *
     298              :  *  Example usage:
     299              :  *
     300              :  *  @code
     301              :  *    ReturnValueOnFailure(channel->SendMsg(msg), Status::Failure);
     302              :  *  @endcode
     303              :  *
     304              :  *  @param[in]  expr        An expression to be tested.
     305              :  *  @param[in]  value       A value to return if @a expr is an error.
     306              :  *  @param[in]  ...         Statements to execute before returning. Optional.
     307              :  */
     308              : #define ReturnValueOnFailure(expr, value, ...)                                                                                     \
     309              :     do                                                                                                                             \
     310              :     {                                                                                                                              \
     311              :         auto __err = (expr);                                                                                                       \
     312              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     313              :         {                                                                                                                          \
     314              :             __VA_ARGS__;                                                                                                           \
     315              :             return value;                                                                                                          \
     316              :         }                                                                                                                          \
     317              :     } while (false)
     318              : 
     319              : /**
     320              :  *  @def VerifyOrReturn(expr, ...)
     321              :  *
     322              :  *  @brief
     323              :  *    Returns from the void function if expression evaluates to false
     324              :  *
     325              :  *  Example usage:
     326              :  *
     327              :  *  @code
     328              :  *    VerifyOrReturn(param != nullptr, LogError("param is nullptr"));
     329              :  *  @endcode
     330              :  *
     331              :  *  @param[in]  expr        A Boolean expression to be evaluated.
     332              :  *  @param[in]  ...         Statements to execute before returning. Optional.
     333              :  */
     334              : #define VerifyOrReturn(expr, ...)                                                                                                  \
     335              :     do                                                                                                                             \
     336              :     {                                                                                                                              \
     337              :         if (!(expr))                                                                                                               \
     338              :         {                                                                                                                          \
     339              :             __VA_ARGS__;                                                                                                           \
     340              :             return;                                                                                                                \
     341              :         }                                                                                                                          \
     342              :     } while (false)
     343              : 
     344              : /**
     345              :  *  @def VerifyOrReturnError(expr, code, ...)
     346              :  *
     347              :  *  @brief
     348              :  *    Returns a specified error code if expression evaluates to false
     349              :  *
     350              :  *  Example usage:
     351              :  *
     352              :  *  @code
     353              :  *    VerifyOrReturnError(param != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     354              :  *  @endcode
     355              :  *
     356              :  *  @param[in]  expr        A Boolean expression to be evaluated.
     357              :  *  @param[in]  code        A value to return if @a expr is false.
     358              :  *  @param[in]  ...         Statements to execute before returning. Optional.
     359              :  */
     360              : #define VerifyOrReturnError(expr, code, ...) VerifyOrReturnValue(expr, code, ##__VA_ARGS__)
     361              : 
     362              : /**
     363              :  *  @def VerifyOrReturnValue(expr, value, ...)
     364              :  *
     365              :  *  @brief
     366              :  *    Returns a specified value if expression evaluates to false
     367              :  *
     368              :  *  Example usage:
     369              :  *
     370              :  *  @code
     371              :  *    VerifyOrReturnError(param != nullptr, Foo());
     372              :  *  @endcode
     373              :  *
     374              :  *  @param[in]  expr        A Boolean expression to be evaluated.
     375              :  *  @param[in]  value       A value to return if @a expr is false.
     376              :  *  @param[in]  ...         Statements to execute before returning. Optional.
     377              :  */
     378              : #define VerifyOrReturnValue(expr, value, ...)                                                                                      \
     379              :     do                                                                                                                             \
     380              :     {                                                                                                                              \
     381              :         if (!(expr))                                                                                                               \
     382              :         {                                                                                                                          \
     383              :             __VA_ARGS__;                                                                                                           \
     384              :             return (value);                                                                                                        \
     385              :         }                                                                                                                          \
     386              :     } while (false)
     387              : 
     388              : /**
     389              :  *  @def VerifyOrReturnLogError(expr, code)
     390              :  *
     391              :  *  @brief
     392              :  *    Returns and print a specified error code if expression evaluates to false
     393              :  *
     394              :  *  Example usage:
     395              :  *
     396              :  *  @code
     397              :  *    VerifyOrReturnLogError(param != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     398              :  *  @endcode
     399              :  *
     400              :  *  @param[in]  expr        A Boolean expression to be evaluated.
     401              :  *  @param[in]  code        A value to return if @a expr is false.
     402              :  */
     403              : #if CHIP_CONFIG_ERROR_SOURCE
     404              : #define VerifyOrReturnLogError(expr, code)                                                                                         \
     405              :     do                                                                                                                             \
     406              :     {                                                                                                                              \
     407              :         if (!(expr))                                                                                                               \
     408              :         {                                                                                                                          \
     409              :             ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(code), __FILE__, __LINE__);                                         \
     410              :             return code;                                                                                                           \
     411              :         }                                                                                                                          \
     412              :     } while (false)
     413              : #else // CHIP_CONFIG_ERROR_SOURCE
     414              : #define VerifyOrReturnLogError(expr, code)                                                                                         \
     415              :     do                                                                                                                             \
     416              :     {                                                                                                                              \
     417              :         if (!(expr))                                                                                                               \
     418              :         {                                                                                                                          \
     419              :             ChipLogError(NotSpecified, "%s:%d false: %" CHIP_ERROR_FORMAT, #expr, __LINE__, code.Format());                        \
     420              :             return code;                                                                                                           \
     421              :         }                                                                                                                          \
     422              :     } while (false)
     423              : #endif // CHIP_CONFIG_ERROR_SOURCE
     424              : 
     425              : /**
     426              :  *  @def SuccessOrExit(error)
     427              :  *
     428              :  *  @brief
     429              :  *    This checks for the specified error, which is expected to
     430              :  *    commonly be successful (CHIP_NO_ERROR), and branches to
     431              :  *    the local label 'exit' if the status is unsuccessful.
     432              :  *
     433              :  *  Example Usage:
     434              :  *
     435              :  *  @code
     436              :  *  CHIP_ERROR TryHard()
     437              :  *  {
     438              :  *      CHIP_ERROR err;
     439              :  *
     440              :  *      err = TrySomething();
     441              :  *      SuccessOrExit(err);
     442              :  *
     443              :  *      err = TrySomethingElse();
     444              :  *      SuccessOrExit(err);
     445              :  *
     446              :  *  exit:
     447              :  *      return err;
     448              :  *  }
     449              :  *  @endcode
     450              :  *
     451              :  *  @param[in]  error  A ChipError object to be evaluated against success (CHIP_NO_ERROR).
     452              :  *
     453              :  */
     454              : #define SuccessOrExit(error) nlEXPECT(::chip::ChipError::IsSuccess((error)), exit)
     455              : 
     456              : /**
     457              :  *  @def SuccessOrExitAction(error, anAction)
     458              :  *
     459              :  *  @brief
     460              :  *    This checks for the specified error, which is expected to
     461              :  *    commonly be successful (CHIP_NO_ERROR), and both executes
     462              :  *    @a anAction and branches to the local label 'exit' if the
     463              :  *    status is unsuccessful.
     464              :  *
     465              :  *  @param[in]  error  A ChipError object to be evaluated against success (CHIP_NO_ERROR).
     466              :  */
     467              : #define SuccessOrExitAction(error, action) nlEXPECT_ACTION(::chip::ChipError::IsSuccess((error)), exit, action)
     468              : 
     469              : /**
     470              :  *  @def VerifyOrExit(aCondition, anAction)
     471              :  *
     472              :  *  @brief
     473              :  *    This checks for the specified condition, which is expected to
     474              :  *    commonly be true, and both executes @a anAction and branches to
     475              :  *    the local label 'exit' if the condition is false.
     476              :  *
     477              :  *  Example Usage:
     478              :  *
     479              :  *  @code
     480              :  *  CHIP_ERROR MakeBuffer(const uint8_t *& buf)
     481              :  *  {
     482              :  *      CHIP_ERROR err = CHIP_NO_ERROR;
     483              :  *
     484              :  *      buf = (uint8_t *)malloc(1024);
     485              :  *      VerifyOrExit(buf != NULL, err = CHIP_ERROR_NO_MEMORY);
     486              :  *
     487              :  *      memset(buf, 0, 1024);
     488              :  *
     489              :  *  exit:
     490              :  *      return err;
     491              :  *  }
     492              :  *  @endcode
     493              :  *
     494              :  *  @param[in]  aCondition  A Boolean expression to be evaluated.
     495              :  *  @param[in]  anAction    An expression or block to execute when the
     496              :  *                          assertion fails.
     497              :  *
     498              :  */
     499              : #define VerifyOrExit(aCondition, anAction) nlEXPECT_ACTION(aCondition, exit, anAction)
     500              : 
     501              : /**
     502              :  *  @def ExitNow(...)
     503              :  *
     504              :  *  @brief
     505              :  *    This unconditionally executes @a ... and branches to the local
     506              :  *    label 'exit'.
     507              :  *
     508              :  *  @note The use of this interface implies neither success nor
     509              :  *        failure for the overall exit status of the enclosing function
     510              :  *        body.
     511              :  *
     512              :  *  Example Usage:
     513              :  *
     514              :  *  @code
     515              :  *  CHIP_ERROR ReadAll(Reader& reader)
     516              :  *  {
     517              :  *      CHIP_ERROR err;
     518              :  *
     519              :  *      while (true)
     520              :  *      {
     521              :  *          err = reader.ReadNext();
     522              :  *          if (err == CHIP_ERROR_AT_END)
     523              :  *              ExitNow(err = CHIP_NO_ERROR);
     524              :  *          SuccessOrExit(err);
     525              :  *          DoSomething();
     526              :  *      }
     527              :  *
     528              :  *  exit:
     529              :  *      return err;
     530              :  *  }
     531              :  *  @endcode
     532              :  *
     533              :  *  @param[in]  ...         Statements to execute. Optional.
     534              :  */
     535              : // clang-format off
     536              : #define ExitNow(...)                                                   \
     537              :     do {                                                               \
     538              :         __VA_ARGS__;                                                   \
     539              :         goto exit;                                                     \
     540              :     } while (0)
     541              : // clang-format on
     542              : 
     543              : /**
     544              :  *  @brief
     545              :  *    This is invoked when a #VerifyOrDie or #VerifyOrDieWithMsg
     546              :  *    assertion expression evaluates to false.
     547              :  *
     548              :  *    Developers may override and customize this by defining #chipDie
     549              :  *    before CodeUtils.h is included by the preprocessor.
     550              :  *
     551              :  *  Example Usage:
     552              :  *
     553              :  *  @code
     554              :  *  chipDie();
     555              :  *  @endcode
     556              :  *
     557              :  */
     558              : #ifndef chipAbort
     559              : extern "C" void chipAbort(void) __attribute((noreturn));
     560              : 
     561            0 : inline void chipAbort(void)
     562              : {
     563              :     while (true)
     564              :     {
     565              :         // NL_ASSERT_ABORT is redefined to be chipAbort, so not useful here.
     566            0 :         CHIP_CONFIG_ABORT();
     567              :     }
     568              : }
     569              : #endif // chipAbort
     570              : #ifndef chipDie
     571              : extern "C" void chipDie(void) __attribute((noreturn));
     572              : 
     573            0 : inline void chipDie(void)
     574              : {
     575            0 :     ChipLogError(NotSpecified, "chipDie chipDie chipDie");
     576            0 :     chipAbort();
     577              : }
     578              : #endif // chipDie
     579              : 
     580              : /**
     581              :  *  @def VerifyOrDie(aCondition)
     582              :  *
     583              :  *  @brief
     584              :  *    This checks for the specified condition, which is expected to
     585              :  *    commonly be true and forces an immediate abort if the condition
     586              :  *    is false.
     587              :  *
     588              :  *  Example Usage:
     589              :  *
     590              :  *  @code
     591              :  *  void FreeBuffer(const uint8_t *buf)
     592              :  *  {
     593              :  *      VerifyOrDie(buf != NULL);
     594              :  *      free(buf);
     595              :  *  }
     596              :  *  @endcode
     597              :  *
     598              :  *  @param[in]  aCondition  A Boolean expression to be evaluated.
     599              :  *
     600              :  *  @sa #VerifyOrDieWithMsg
     601              :  *  @sa #chipDie
     602              :  *
     603              :  */
     604              : #if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE && CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE_NO_COND
     605              : #define VerifyOrDie(aCondition)                                                                                                    \
     606              :     nlABORT_ACTION(aCondition, ChipLogError(Support, "VerifyOrDie failure at %s:%d", __FILE__, __LINE__))
     607              : #elif CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     608              : #define VerifyOrDie(aCondition)                                                                                                    \
     609              :     nlABORT_ACTION(aCondition, ChipLogError(Support, "VerifyOrDie failure at %s:%d: %s", __FILE__, __LINE__, #aCondition))
     610              : #else // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     611              : #define VerifyOrDie(aCondition) VerifyOrDieWithoutLogging(aCondition)
     612              : #endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     613              : 
     614              : /**
     615              :  *  @def SuccessOrDie(error)
     616              :  *
     617              :  *  @brief
     618              :  *    This checks for the specified error, which is expected to
     619              :  *    commonly be successful (CHIP_NO_ERROR), forces an immediate abort if the status
     620              :  *    is unsuccessful.
     621              :  *
     622              :  *
     623              :  *  Example Usage:
     624              :  *
     625              :  *  @code
     626              :  *  uint8_t* AllocateBuffer()
     627              :  *  {
     628              :  *      uint8_t* buffer;
     629              :  *      SuccessOrDie(ChipAllocateBuffer(buffer));
     630              :  *      return buffer;
     631              :  *  }
     632              :  *  @endcode
     633              :  *
     634              :  *  @param[in]  error  A ChipError object to be evaluated against success (CHIP_NO_ERROR).
     635              :  *
     636              :  */
     637              : #if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE && CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE_NO_COND
     638              : #define SuccessOrDie(error)                                                                                                        \
     639              :     nlABORT_ACTION(::chip::ChipError::IsSuccess((error)),                                                                          \
     640              :                    ChipLogError(Support, "SuccessOrDie failure %s at %s:%d", ErrorStr((error)), __FILE__, __LINE__))
     641              : #elif CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     642              : #define SuccessOrDie(error)                                                                                                        \
     643              :     nlABORT_ACTION(::chip::ChipError::IsSuccess((error)),                                                                          \
     644              :                    ChipLogError(Support, "SuccessOrDie failure %s at %s:%d: %s", ErrorStr((error)), __FILE__, __LINE__, #error))
     645              : #else // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     646              : #define SuccessOrDie(error) VerifyOrDieWithoutLogging(::chip::ChipError::IsSuccess((error)))
     647              : #endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     648              : 
     649              : /**
     650              :  * @def VerifyOrDieWithObject(aCondition, aObject)
     651              :  *
     652              :  * Like VerifyOrDie(), but calls DumpObjectToLog()
     653              :  * on the provided object on failure before aborting
     654              :  * if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE is enabled.
     655              :  */
     656              : #if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     657              : #define VerifyOrDieWithObject(aCondition, aObject)                                                                                 \
     658              :     nlABORT_ACTION(aCondition, ::chip::DumpObjectToLog(aObject);                                                                   \
     659              :                    ChipLogError(Support, "VerifyOrDie failure at %s:%d: %s", __FILE__, __LINE__, #aCondition))
     660              : #else // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     661              : #define VerifyOrDieWithObject(aCondition, aObject) VerifyOrDieWithoutLogging(aCondition)
     662              : #endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     663              : 
     664              : /**
     665              :  *  @def VerifyOrDieWithMsg(aCondition, aModule, aMessage, ...)
     666              :  *
     667              :  *  @brief
     668              :  *    This checks for the specified condition, which is expected to
     669              :  *    commonly be true and both prints @a aMessage and forces an
     670              :  *    immediate abort if the condition is false.
     671              :  *
     672              :  *  Example Usage:
     673              :  *
     674              :  *  @code
     675              :  *  void FreeBuffer(const uint8_t *buf)
     676              :  *  {
     677              :  *      VerifyOrDieWithMsg(buf != NULL, MemoryManagement, "Invalid pointer passed to FreeBuffer");
     678              :  *      free(buf);
     679              :  *  }
     680              :  *  @endcode
     681              :  *
     682              :  *  @param[in]  aCondition  A Boolean expression to be evaluated.
     683              :  *  @param[in]  aModule     A chip LogModule short-hand mnemonic identifing
     684              :  *                          the logical section of code that is a
     685              :  *                          source the logged message.
     686              :  *  @param[in]  aMessage    A pointer to a NULL-terminated C string with
     687              :  *                          C Standard Library-style format specifiers
     688              :  *                          containing the log message to be formatted
     689              :  *                          and logged.
     690              :  *  @param[in]  ...         A variadic argument list whose elements should
     691              :  *                          correspond to the format specifiers in @a
     692              :  *                          aMessage.
     693              :  *
     694              :  *  @sa #VerifyOrDie
     695              :  *  @sa #chipDie
     696              :  *
     697              :  */
     698              : #define VerifyOrDieWithMsg(aCondition, aModule, aMessage, ...)                                                                     \
     699              :     nlABORT_ACTION(aCondition, ChipLogError(aModule, aMessage, ##__VA_ARGS__))
     700              : 
     701              : /**
     702              :  *  @def LogErrorOnFailure(expr)
     703              :  *
     704              :  *  @brief
     705              :  *    Logs a message if the expression returns something different than CHIP_NO_ERROR.
     706              :  *
     707              :  *  Example usage:
     708              :  *
     709              :  *  @code
     710              :  *    ReturnLogErrorOnFailure(channel->SendMsg(msg));
     711              :  *  @endcode
     712              :  *
     713              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     714              :  */
     715              : #define LogErrorOnFailure(expr)                                                                                                    \
     716              :     do                                                                                                                             \
     717              :     {                                                                                                                              \
     718              :         CHIP_ERROR __err = (expr);                                                                                                 \
     719              :         if (__err != CHIP_NO_ERROR)                                                                                                \
     720              :         {                                                                                                                          \
     721              :             ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(__err), __FILE__, __LINE__);                                        \
     722              :         }                                                                                                                          \
     723              :     } while (false)
     724              : 
     725              : /**
     726              :  *  @def VerifyOrDo(expr, ...)
     727              :  *
     728              :  *  @brief
     729              :  *    do something if expression evaluates to false
     730              :  *
     731              :  *  Example usage:
     732              :  *
     733              :  * @code
     734              :  *    VerifyOrDo(param != nullptr, LogError("param is nullptr"));
     735              :  *  @endcode
     736              :  *
     737              :  *  @param[in]  expr        A Boolean expression to be evaluated.
     738              :  *  @param[in]  ...         Statements to execute.
     739              :  */
     740              : #define VerifyOrDo(expr, ...)                                                                                                      \
     741              :     do                                                                                                                             \
     742              :     {                                                                                                                              \
     743              :         if (!(expr))                                                                                                               \
     744              :         {                                                                                                                          \
     745              :             __VA_ARGS__;                                                                                                           \
     746              :         }                                                                                                                          \
     747              :     } while (false)
     748              : 
     749              : #if (__cplusplus >= 201103L)
     750              : 
     751              : #ifndef __FINAL
     752              : #define __FINAL final
     753              : #endif
     754              : 
     755              : #ifndef __OVERRIDE
     756              : #define __OVERRIDE override
     757              : #endif
     758              : 
     759              : #ifndef __CONSTEXPR
     760              : #define __CONSTEXPR constexpr
     761              : #endif
     762              : 
     763              : #else
     764              : 
     765              : #ifndef __FINAL
     766              : #define __FINAL
     767              : #endif
     768              : 
     769              : #ifndef __OVERRIDE
     770              : #define __OVERRIDE
     771              : #endif
     772              : 
     773              : #ifndef __CONSTEXPR
     774              : #define __CONSTEXPR constexpr
     775              : #endif
     776              : 
     777              : #endif // (__cplusplus >= 201103L)
     778              : 
     779              : #if ((__cplusplus >= 201703L) || (defined(__GNUC__) && (__GNUC__ >= 7)) || (defined(__clang__)) && (__clang_major__ >= 4))
     780              : #define CHECK_RETURN_VALUE [[nodiscard]]
     781              : #elif defined(__GNUC__) && (__GNUC__ >= 4)
     782              : #define CHECK_RETURN_VALUE __attribute__((warn_unused_result))
     783              : #elif defined(_MSC_VER) && (_MSC_VER >= 1700)
     784              : #define CHECK_RETURN_VALUE _Check_return_
     785              : #else
     786              : #define CHECK_RETURN_VALUE
     787              : #endif
     788              : 
     789              : #if defined(__clang__)
     790              : #define FALLTHROUGH [[clang::fallthrough]]
     791              : #elif defined(__GNUC__)
     792              : #define FALLTHROUGH __attribute__((fallthrough))
     793              : #else
     794              : #define FALLTHROUGH (void) 0
     795              : #endif
     796              : 
     797              : /**
     798              :  * @def MATTER_ARRAY_SIZE(aArray)
     799              :  *
     800              :  * @brief
     801              :  *   Returns the size of an array in number of elements.
     802              :  *
     803              :  * Example Usage:
     804              :  *
     805              :  * @code
     806              :  * int numbers[10];
     807              :  * SortNumbers(numbers, MATTER_ARRAY_SIZE(numbers));
     808              :  * @endcode
     809              :  *
     810              :  * @return      The size of an array in number of elements.
     811              :  *
     812              :  * @note Clever template-based solutions seem to fail when MATTER_ARRAY_SIZE is used
     813              :  *       with a variable-length array argument, so we just do the C-compatible
     814              :  *       thing in C++ as well.
     815              :  */
     816              : #ifndef MATTER_ARRAY_SIZE
     817              : #define MATTER_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
     818              : #endif
     819              : 
     820              : /**
     821              :  * @brief Ensures that if `str` is NULL, a non-null `default_str_value` is provided
     822              :  *
     823              :  * @param str - null-terminated string pointer or nullptr
     824              :  * @param default_str_value - replacement value if `str` is nullptr
     825              :  * @return `str` if not null, otherwise `default_str_value`
     826              :  */
     827         4412 : inline const char * DefaultStringWhenNull(const char * str, const char * default_str_value)
     828              : {
     829         4412 :     return (str != nullptr) ? str : default_str_value;
     830              : }
     831              : 
     832              : /**
     833              :  * @brief Ensure that a string for a %s specifier is shown as "(null)" if null
     834              :  *
     835              :  * @param str - null-terminated string pointer or nullptr
     836              :  * @return `str` if not null, otherwise literal "(null)"
     837              :  */
     838         4412 : inline const char * StringOrNullMarker(const char * str)
     839              : {
     840         4412 :     return DefaultStringWhenNull(str, "(null)");
     841              : }
     842              : 
     843              : namespace chip {
     844              : 
     845              : /**
     846              :  * Utility for checking, at compile time if the array is constexpr, whether an
     847              :  * array is sorted.  Can be used for static_asserts.
     848              :  */
     849              : 
     850              : template <typename T>
     851              : constexpr bool ArrayIsSorted(const T * aArray, size_t aLength)
     852              : {
     853              :     if (aLength == 0 || aLength == 1)
     854              :     {
     855              :         return true;
     856              :     }
     857              : 
     858              :     if (aArray[0] > aArray[1])
     859              :     {
     860              :         return false;
     861              :     }
     862              : 
     863              :     return ArrayIsSorted(aArray + 1, aLength - 1);
     864              : }
     865              : 
     866              : template <typename T, size_t N>
     867              : constexpr bool ArrayIsSorted(const T (&aArray)[N])
     868              : {
     869              :     return ArrayIsSorted(aArray, N);
     870              : }
     871              : 
     872              : } // namespace chip
        

Generated by: LCOV version 2.0-1