Matter SDK Coverage Report
Current view: top level - lib/support - CodeUtils.h (source / functions) Coverage Total Hit
Test: SHA:6c8f029dd2432dc900f1c9245c324e69bd79e40a Lines: 66.7 % 9 6
Test Date: 2026-08-08 07:40:09 Functions: 66.7 % 15 10

            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/Assertions.h>
      33              : #include <lib/support/ObjectDump.h>
      34              : #include <lib/support/logging/TextOnlyLogging.h>
      35              : #include <memory>
      36              : 
      37              : /**
      38              :  *  @def ReturnErrorOnFailure(expr, ...)
      39              :  *
      40              :  *  @brief
      41              :  *    Returns the error code if the expression returns an error. For a CHIP_ERROR expression, this means any value other
      42              :  *    than CHIP_NO_ERROR. For an integer expression, this means non-zero.
      43              :  *
      44              :  *  Example usage:
      45              :  *
      46              :  *  @code
      47              :  *    ReturnErrorOnFailure(channel->SendMsg(msg), mState = Uninitialized);
      48              :  *  @endcode
      49              :  *
      50              :  *  @param[in]  expr        An expression to be tested.
      51              :  *  @param[in]  ...         Statements to execute before returning. Optional.
      52              :  */
      53              : #define ReturnErrorOnFailure(expr, ...)                                                                                            \
      54              :     do                                                                                                                             \
      55              :     {                                                                                                                              \
      56              :         auto __err = (expr);                                                                                                       \
      57              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
      58              :         {                                                                                                                          \
      59              :             __VA_ARGS__;                                                                                                           \
      60              :             return __err;                                                                                                          \
      61              :         }                                                                                                                          \
      62              :     } while (false)
      63              : 
      64              : /**
      65              :  *  @def ReturnErrorVariantOnFailure(expr)
      66              :  *
      67              :  *  @brief
      68              :  *    This is for use when the calling function returns a Variant type. It returns a CHIP_ERROR variant with the corresponding error
      69              :  *    code if the expression returns an error.
      70              :  *
      71              :  *  Example usage:
      72              :  *
      73              :  *  @code
      74              :  *    ReturnErrorVariantOnFailure(NextStep, ParseSigma1(tlvReader, parsedSigma1));
      75              :  *  @endcode
      76              :  *
      77              :  *  @param[in]  variantType   The Variant type that the calling function returns.
      78              :  *  @param[in]  expr          An expression to be tested.
      79              :  *  @param[in]  ...         Statements to execute before returning. Optional.
      80              :  */
      81              : #define ReturnErrorVariantOnFailure(variantType, expr, ...)                                                                        \
      82              :     do                                                                                                                             \
      83              :     {                                                                                                                              \
      84              :         auto __err = (expr);                                                                                                       \
      85              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
      86              :         {                                                                                                                          \
      87              :             __VA_ARGS__;                                                                                                           \
      88              :             return variantType::Create<CHIP_ERROR>(__err);                                                                         \
      89              :         }                                                                                                                          \
      90              :     } while (false)
      91              : 
      92              : /**
      93              :  *  @def ReturnLogErrorOnFailure(expr)
      94              :  *
      95              :  *  @brief
      96              :  *    Returns the error code if the expression returns something different
      97              :  *    than CHIP_NO_ERROR.
      98              :  *
      99              :  *  Example usage:
     100              :  *
     101              :  *  @code
     102              :  *    ReturnLogErrorOnFailure(channel->SendMsg(msg));
     103              :  *  @endcode
     104              :  *
     105              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     106              :  */
     107              : #if CHIP_CONFIG_ERROR_SOURCE
     108              : #define ReturnLogErrorOnFailure(expr)                                                                                              \
     109              :     do                                                                                                                             \
     110              :     {                                                                                                                              \
     111              :         auto __err = (expr);                                                                                                       \
     112              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     113              :         {                                                                                                                          \
     114              :             ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(__err), __FILE__, __LINE__);                                        \
     115              :             return __err;                                                                                                          \
     116              :         }                                                                                                                          \
     117              :     } while (false)
     118              : #else
     119              : #define ReturnLogErrorOnFailure(expr)                                                                                              \
     120              :     do                                                                                                                             \
     121              :     {                                                                                                                              \
     122              :         auto __err = (expr);                                                                                                       \
     123              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     124              :         {                                                                                                                          \
     125              :             ::chip::Logging::LogFailure(::chip::Logging::kLogModule_NotSpecified, __err);                                          \
     126              :             return __err;                                                                                                          \
     127              :         }                                                                                                                          \
     128              :     } while (false)
     129              : #endif
     130              : 
     131              : /**
     132              :  *  @def SuccessOrLog(expr, MOD, MSG, ...)
     133              :  *
     134              :  *  @brief
     135              :  *    If expr returns something other than CHIP_NO_ERROR, log a message for the specified module
     136              :  *    in the 'Error' category.
     137              :  *
     138              :  *  Example usage:
     139              :  *
     140              :  *  @code
     141              :  *    SuccessOrLog(channel->SendMsg(msg), Module, "Failure message: %s", param);
     142              :  *  @endcode
     143              :  *
     144              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     145              :  *  @param[in]  MOD         The log module to use.
     146              :  *  @param[in]  MSG         The log message format string.
     147              :  *  @param[in]  ...         Optional arguments for the log message.
     148              :  */
     149              : #define SuccessOrLog(expr, MOD, MSG, ...)                                                                                          \
     150              :     do                                                                                                                             \
     151              :     {                                                                                                                              \
     152              :         CHIP_ERROR __lerr = (expr);                                                                                                \
     153              :         if (!::chip::ChipError::IsSuccess(__lerr))                                                                                 \
     154              :         {                                                                                                                          \
     155              :             ChipLogFailure(__lerr, MOD, MSG, ##__VA_ARGS__);                                                                       \
     156              :         }                                                                                                                          \
     157              :     } while (false)
     158              : 
     159              : /**
     160              :  *  @def ReturnAndLogOnFailure(expr, MOD, MSG, ...)
     161              :  *
     162              :  *  @brief
     163              :  *    If expr returns something than CHIP_NO_ERROR, log a chip message for the specified module
     164              :  *    in the 'Error' category and return.
     165              :  *
     166              :  *  Example usage:
     167              :  *
     168              :  *  @code
     169              :  *    ReturnAndLogOnFailure(channel->SendMsg(msg), Module, "Failure message: %s", param);
     170              :  *  @endcode
     171              :  *
     172              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     173              :  *  @param[in]  MOD         The log module to use.
     174              :  *  @param[in]  MSG         The log message format string.
     175              :  *  @param[in]  ...         Optional arguments for the log message.
     176              :  */
     177              : #define ReturnAndLogOnFailure(expr, MOD, MSG, ...)                                                                                 \
     178              :     do                                                                                                                             \
     179              :     {                                                                                                                              \
     180              :         CHIP_ERROR __err = (expr);                                                                                                 \
     181              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     182              :         {                                                                                                                          \
     183              :             ChipLogFailure(__err, MOD, MSG, ##__VA_ARGS__);                                                                        \
     184              :             return;                                                                                                                \
     185              :         }                                                                                                                          \
     186              :     } while (false)
     187              : 
     188              : /**
     189              :  *  @def ReturnErrorAndLogOnFailure(expr, MOD, MSG, ...)
     190              :  *
     191              :  *  @brief
     192              :  *    If expr returns something than CHIP_NO_ERROR, log a chip message for the specified module
     193              :  *    in the 'Error' category and return the error.
     194              :  *
     195              :  *  Example usage:
     196              :  *
     197              :  *  @code
     198              :  *    ReturnErrorAndLogOnFailure(channel->SendMsg(msg), Module, "Failure message: %s", param);
     199              :  *  @endcode
     200              :  *
     201              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     202              :  *  @param[in]  MOD         The log module to use.
     203              :  *  @param[in]  MSG         The log message format string.
     204              :  *  @param[in]  ...         Optional arguments for the log message.
     205              :  */
     206              : #define ReturnErrorAndLogOnFailure(expr, MOD, MSG, ...)                                                                            \
     207              :     do                                                                                                                             \
     208              :     {                                                                                                                              \
     209              :         CHIP_ERROR __err = (expr);                                                                                                 \
     210              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     211              :         {                                                                                                                          \
     212              :             ChipLogFailure(__err, MOD, MSG, ##__VA_ARGS__);                                                                        \
     213              :             return __err;                                                                                                          \
     214              :         }                                                                                                                          \
     215              :     } while (false)
     216              : 
     217              : /**
     218              :  *  @def ReturnValueAndLogOnFailure(expr, value, MOD, MSG, ...)
     219              :  *
     220              :  *  @brief
     221              :  *    If expr returns something other than CHIP_NO_ERROR, log a message for the specified module
     222              :  *    in the 'Error' category and return the error.
     223              :  *
     224              :  *  Example usage:
     225              :  *
     226              :  *  @code
     227              :  *    ReturnValueAndLogOnFailure(channel->SendMsg(msg), false, Module, "Failure message: %s", param);
     228              :  *  @endcode
     229              :  *
     230              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     231              :  *  @param[in]  value       A value to return if @a expr is an error.
     232              :  *  @param[in]  MOD         The log module to use.
     233              :  *  @param[in]  MSG         The log message format string.
     234              :  *  @param[in]  ...         Optional arguments for the log message.
     235              :  */
     236              : #define ReturnValueAndLogOnFailure(expr, value, MOD, MSG, ...)                                                                     \
     237              :     do                                                                                                                             \
     238              :     {                                                                                                                              \
     239              :         CHIP_ERROR __err = (expr);                                                                                                 \
     240              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     241              :         {                                                                                                                          \
     242              :             ChipLogFailure(__err, MOD, MSG, ##__VA_ARGS__);                                                                        \
     243              :             return value;                                                                                                          \
     244              :         }                                                                                                                          \
     245              :     } while (false)
     246              : 
     247              : /**
     248              :  *  @def ReturnOnFailure(expr, ...)
     249              :  *
     250              :  *  @brief
     251              :  *    Returns if the expression returns an error. For a CHIP_ERROR expression, this means any value other
     252              :  *    than CHIP_NO_ERROR. For an integer expression, this means non-zero.
     253              :  *
     254              :  *  Example usage:
     255              :  *
     256              :  *  @code
     257              :  *    ReturnOnFailure(channel->SendMsg(msg), mState = Uninitialized);
     258              :  *  @endcode
     259              :  *
     260              :  *  @param[in]  expr        An expression to be tested.
     261              :  *  @param[in]  ...         Statements to execute before returning. Optional.
     262              :  */
     263              : #define ReturnOnFailure(expr, ...)                                                                                                 \
     264              :     do                                                                                                                             \
     265              :     {                                                                                                                              \
     266              :         auto __err = (expr);                                                                                                       \
     267              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     268              :         {                                                                                                                          \
     269              :             __VA_ARGS__;                                                                                                           \
     270              :             return;                                                                                                                \
     271              :         }                                                                                                                          \
     272              :     } while (false)
     273              : 
     274              : /**
     275              :  *  @def ReturnValueOnFailure(expr, value, ...)
     276              :  *
     277              :  *  @brief
     278              :  *    Returns value if the expression returns an error. For a CHIP_ERROR expression, this means any value other
     279              :  *    than CHIP_NO_ERROR. For an integer expression, this means non-zero.
     280              :  *
     281              :  *  Example usage:
     282              :  *
     283              :  *  @code
     284              :  *    ReturnValueOnFailure(channel->SendMsg(msg), Status::Failure, mState = Uninitialized);
     285              :  *  @endcode
     286              :  *
     287              :  *  @param[in]  expr        An expression to be tested.
     288              :  *  @param[in]  value       A value to return if @a expr is an error.
     289              :  *  @param[in]  ...         Statements to execute before returning. Optional.
     290              :  */
     291              : #define ReturnValueOnFailure(expr, value, ...)                                                                                     \
     292              :     do                                                                                                                             \
     293              :     {                                                                                                                              \
     294              :         auto __err = (expr);                                                                                                       \
     295              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     296              :         {                                                                                                                          \
     297              :             __VA_ARGS__;                                                                                                           \
     298              :             return value;                                                                                                          \
     299              :         }                                                                                                                          \
     300              :     } while (false)
     301              : 
     302              : /**
     303              :  *  @def VerifyOrReturnLogError(expr, code)
     304              :  *
     305              :  *  @brief
     306              :  *    Returns and print a specified error code if expression evaluates to false
     307              :  *
     308              :  *  Example usage:
     309              :  *
     310              :  *  @code
     311              :  *    VerifyOrReturnLogError(param != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     312              :  *  @endcode
     313              :  *
     314              :  *  @param[in]  expr        A Boolean expression to be evaluated.
     315              :  *  @param[in]  code        A value to return if @a expr is false.
     316              :  */
     317              : #if CHIP_CONFIG_ERROR_SOURCE
     318              : #define VerifyOrReturnLogError(expr, code)                                                                                         \
     319              :     do                                                                                                                             \
     320              :     {                                                                                                                              \
     321              :         if (!(expr))                                                                                                               \
     322              :         {                                                                                                                          \
     323              :             auto __code = (code);                                                                                                  \
     324              :             ::chip::Logging::LogVerifyOrReturnErrorWithSource(__code, __FILE__, __LINE__);                                         \
     325              :             return __code;                                                                                                         \
     326              :         }                                                                                                                          \
     327              :     } while (false)
     328              : #else // CHIP_CONFIG_ERROR_SOURCE
     329              : #define VerifyOrReturnLogError(expr, code)                                                                                         \
     330              :     do                                                                                                                             \
     331              :     {                                                                                                                              \
     332              :         if (!(expr))                                                                                                               \
     333              :         {                                                                                                                          \
     334              :             auto __code = (code);                                                                                                  \
     335              :             ::chip::Logging::LogVerifyOrReturnError(#expr, __LINE__, __code);                                                      \
     336              :             return __code;                                                                                                         \
     337              :         }                                                                                                                          \
     338              :     } while (false)
     339              : #endif // CHIP_CONFIG_ERROR_SOURCE
     340              : 
     341              : /**
     342              :  *  @def SuccessOrShutdown(expr, ...)
     343              :  *
     344              :  *  @brief
     345              :  *    This is expected to be called from within a class that implements a Shutdown method.
     346              :  *    It checks for the specified error, which is expected to commonly be successful (CHIP_NO_ERROR),
     347              :  *    on failure, it calls the statements to be executed before shutdown if provided,
     348              :  *    then calls the Shutdown method of the class and returns the error.
     349              :  *
     350              :  *  @param[in]  expr  A ChipError object to be evaluated against success (CHIP_NO_ERROR).
     351              :  *  @param[in]  ...     Statements to execute before shutdown. Optional.
     352              :  *
     353              :  */
     354              : #define SuccessOrShutdown(expr, ...)                                                                                               \
     355              :     do                                                                                                                             \
     356              :     {                                                                                                                              \
     357              :         auto __err = (expr);                                                                                                       \
     358              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     359              :         {                                                                                                                          \
     360              :             __VA_ARGS__;                                                                                                           \
     361              :             this->Shutdown();                                                                                                      \
     362              :             return __err;                                                                                                          \
     363              :         }                                                                                                                          \
     364              :     } while (false)
     365              : 
     366              : /**
     367              :  *  @def SuccessOrExit(error)
     368              :  *
     369              :  *  @brief
     370              :  *    This checks for the specified error, which is expected to
     371              :  *    commonly be successful (CHIP_NO_ERROR), and branches to
     372              :  *    the local label 'exit' if the status is unsuccessful.
     373              :  *
     374              :  *  Example Usage:
     375              :  *
     376              :  *  @code
     377              :  *  CHIP_ERROR TryHard()
     378              :  *  {
     379              :  *      CHIP_ERROR err;
     380              :  *
     381              :  *      err = TrySomething();
     382              :  *      SuccessOrExit(err);
     383              :  *
     384              :  *      err = TrySomethingElse();
     385              :  *      SuccessOrExit(err);
     386              :  *
     387              :  *  exit:
     388              :  *      return err;
     389              :  *  }
     390              :  *  @endcode
     391              :  *
     392              :  *  @param[in]  error  A ChipError object to be evaluated against success (CHIP_NO_ERROR).
     393              :  *
     394              :  */
     395              : #define SuccessOrExit(error) VerifyOrExit(::chip::ChipError::IsSuccess((error)), {})
     396              : 
     397              : /**
     398              :  *  @def SuccessOrExitAction(error, anAction)
     399              :  *
     400              :  *  @brief
     401              :  *    This checks for the specified error, which is expected to
     402              :  *    commonly be successful (CHIP_NO_ERROR), and both executes
     403              :  *    @a anAction and branches to the local label 'exit' if the
     404              :  *    status is unsuccessful.
     405              :  *
     406              :  *  @param[in]  error  A ChipError object to be evaluated against success (CHIP_NO_ERROR).
     407              :  */
     408              : #define SuccessOrExitAction(error, action) VerifyOrExit(::chip::ChipError::IsSuccess((error)), action)
     409              : 
     410              : #ifndef chipDie
     411              : extern "C" void chipDie(void) __attribute((noreturn));
     412              : 
     413            0 : inline void chipDie(void)
     414              : {
     415            0 :     ChipLogError(NotSpecified, "chipDie chipDie chipDie");
     416            0 :     chipAbort();
     417              : }
     418              : #endif // chipDie
     419              : 
     420              : /**
     421              :  *  @def VerifyOrDie(aCondition)
     422              :  *
     423              :  *  @brief
     424              :  *    This checks for the specified condition, which is expected to
     425              :  *    commonly be true and forces an immediate abort if the condition
     426              :  *    is false.
     427              :  *
     428              :  *  Example Usage:
     429              :  *
     430              :  *  @code
     431              :  *  void FreeBuffer(const uint8_t *buf)
     432              :  *  {
     433              :  *      VerifyOrDie(buf != NULL);
     434              :  *      free(buf);
     435              :  *  }
     436              :  *  @endcode
     437              :  *
     438              :  *  @param[in]  aCondition  A Boolean expression to be evaluated.
     439              :  *
     440              :  *  @sa #VerifyOrDieWithMsg
     441              :  *  @sa #chipDie
     442              :  *
     443              :  */
     444              : #if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE && CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE_NO_COND
     445              : #define VerifyOrDie(aCondition) VerifyOrDo(aCondition, ::chip::Logging::LogVerifyOrDie(__FILE__, __LINE__))
     446              : #elif CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     447              : #define VerifyOrDie(aCondition) VerifyOrDo(aCondition, ::chip::Logging::LogVerifyOrDie(__FILE__, __LINE__, #aCondition))
     448              : #else // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     449              : #define VerifyOrDie(aCondition) VerifyOrDieWithoutLogging(aCondition)
     450              : #endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     451              : 
     452              : /**
     453              :  *  @def SuccessOrDie(error)
     454              :  *
     455              :  *  @brief
     456              :  *    This checks for the specified error, which is expected to
     457              :  *    commonly be successful (CHIP_NO_ERROR), forces an immediate abort if the status
     458              :  *    is unsuccessful.
     459              :  *
     460              :  *
     461              :  *  Example Usage:
     462              :  *
     463              :  *  @code
     464              :  *  uint8_t* AllocateBuffer()
     465              :  *  {
     466              :  *      uint8_t* buffer;
     467              :  *      SuccessOrDie(ChipAllocateBuffer(buffer));
     468              :  *      return buffer;
     469              :  *  }
     470              :  *  @endcode
     471              :  *
     472              :  *  @param[in]  error  A ChipError object to be evaluated against success (CHIP_NO_ERROR).
     473              :  *
     474              :  */
     475              : #if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE && CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE_NO_COND
     476              : #define SuccessOrDie(error)                                                                                                        \
     477              :     do                                                                                                                             \
     478              :     {                                                                                                                              \
     479              :         auto __err = (error);                                                                                                      \
     480              :         VerifyOrDo(::chip::ChipError::IsSuccess(__err), ::chip::Logging::LogSuccessOrDie(__FILE__, __LINE__, __err));              \
     481              :     } while (false)
     482              : #elif CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     483              : #define SuccessOrDie(error)                                                                                                        \
     484              :     do                                                                                                                             \
     485              :     {                                                                                                                              \
     486              :         auto __err = (error);                                                                                                      \
     487              :         VerifyOrDo(::chip::ChipError::IsSuccess(__err), ::chip::Logging::LogSuccessOrDie(__FILE__, __LINE__, __err, #error));      \
     488              :     } while (false)
     489              : #else // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     490              : #define SuccessOrDie(error) VerifyOrDieWithoutLogging(::chip::ChipError::IsSuccess((error)))
     491              : #endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     492              : 
     493              : /**
     494              :  * @def VerifyOrDieWithObject(aCondition, aObject)
     495              :  *
     496              :  * Like VerifyOrDie(), but calls DumpObjectToLog()
     497              :  * on the provided object on failure before aborting
     498              :  * if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE is enabled.
     499              :  */
     500              : #if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     501              : #define VerifyOrDieWithObject(aCondition, aObject)                                                                                 \
     502              :     VerifyOrDo(aCondition, ::chip::DumpObjectToLog(aObject); ::chip::Logging::LogVerifyOrDie(__FILE__, __LINE__, #aCondition))
     503              : #else // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     504              : #define VerifyOrDieWithObject(aCondition, aObject) VerifyOrDieWithoutLogging(aCondition)
     505              : #endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE
     506              : 
     507              : /**
     508              :  *  @def VerifyOrDieWithMsg(aCondition, aModule, aMessage, ...)
     509              :  *
     510              :  *  @brief
     511              :  *    This checks for the specified condition, which is expected to
     512              :  *    commonly be true and both prints @a aMessage and forces an
     513              :  *    immediate abort if the condition is false.
     514              :  *
     515              :  *  Example Usage:
     516              :  *
     517              :  *  @code
     518              :  *  void FreeBuffer(const uint8_t *buf)
     519              :  *  {
     520              :  *      VerifyOrDieWithMsg(buf != NULL, MemoryManagement, "Invalid pointer passed to FreeBuffer");
     521              :  *      free(buf);
     522              :  *  }
     523              :  *  @endcode
     524              :  *
     525              :  *  @param[in]  aCondition  A Boolean expression to be evaluated.
     526              :  *  @param[in]  aModule     A chip LogModule short-hand mnemonic identifing
     527              :  *                          the logical section of code that is a
     528              :  *                          source the logged message.
     529              :  *  @param[in]  aMessage    A pointer to a NULL-terminated C string with
     530              :  *                          C Standard Library-style format specifiers
     531              :  *                          containing the log message to be formatted
     532              :  *                          and logged.
     533              :  *  @param[in]  ...         A variadic argument list whose elements should
     534              :  *                          correspond to the format specifiers in @a
     535              :  *                          aMessage.
     536              :  *
     537              :  *  @sa #VerifyOrDie
     538              :  *  @sa #chipDie
     539              :  *
     540              :  */
     541              : #define CHIP_VERIFY_OR_DIE_WITH_MSG_SELECT(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME
     542              : 
     543              : #define VerifyOrDieWithMsg_NO_VA_ARGS(aCondition, aModule, aMessage)                                                               \
     544              :     VerifyOrDo(aCondition, ::chip::Logging::LogVerifyOrDieWithMsg(::chip::Logging::kLogModule_##aModule, aMessage))
     545              : 
     546              : #define VerifyOrDieWithMsg_VA_ARGS(aCondition, aModule, aMessage, ...)                                                             \
     547              :     VerifyOrDo(aCondition, ChipLogError(aModule, aMessage, ##__VA_ARGS__); chipAbort())
     548              : 
     549              : #define VerifyOrDieWithMsg(...)                                                                                                    \
     550              :     CHIP_VERIFY_OR_DIE_WITH_MSG_SELECT(__VA_ARGS__, VerifyOrDieWithMsg_VA_ARGS, VerifyOrDieWithMsg_VA_ARGS,                        \
     551              :                                        VerifyOrDieWithMsg_VA_ARGS, VerifyOrDieWithMsg_VA_ARGS, VerifyOrDieWithMsg_VA_ARGS,         \
     552              :                                        VerifyOrDieWithMsg_VA_ARGS, VerifyOrDieWithMsg_VA_ARGS, VerifyOrDieWithMsg_NO_VA_ARGS)      \
     553              :     (__VA_ARGS__)
     554              : 
     555              : /**
     556              :  *  @def LogErrorOnFailure(expr)
     557              :  *
     558              :  *  @brief
     559              :  *    Logs a message if the expression returns something different than CHIP_NO_ERROR.
     560              :  *
     561              :  *  Example usage:
     562              :  *
     563              :  *  @code
     564              :  *    ReturnLogErrorOnFailure(channel->SendMsg(msg));
     565              :  *  @endcode
     566              :  *
     567              :  *  @param[in]  expr        A scalar expression to be evaluated against CHIP_NO_ERROR.
     568              :  */
     569              : #if CHIP_CONFIG_ERROR_SOURCE
     570              : #define LogErrorOnFailure(expr)                                                                                                    \
     571              :     do                                                                                                                             \
     572              :     {                                                                                                                              \
     573              :         auto __err = (expr);                                                                                                       \
     574              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     575              :         {                                                                                                                          \
     576              :             ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(__err), __FILE__, __LINE__);                                        \
     577              :         }                                                                                                                          \
     578              :     } while (false)
     579              : #else
     580              : #define LogErrorOnFailure(expr)                                                                                                    \
     581              :     do                                                                                                                             \
     582              :     {                                                                                                                              \
     583              :         auto __err = (expr);                                                                                                       \
     584              :         if (!::chip::ChipError::IsSuccess(__err))                                                                                  \
     585              :         {                                                                                                                          \
     586              :             ::chip::Logging::LogFailure(::chip::Logging::kLogModule_NotSpecified, __err);                                          \
     587              :         }                                                                                                                          \
     588              :     } while (false)
     589              : #endif
     590              : 
     591              : #if (__cplusplus >= 201103L)
     592              : 
     593              : #ifndef __FINAL
     594              : #define __FINAL final
     595              : #endif
     596              : 
     597              : #ifndef __OVERRIDE
     598              : #define __OVERRIDE override
     599              : #endif
     600              : 
     601              : #ifndef __CONSTEXPR
     602              : #define __CONSTEXPR constexpr
     603              : #endif
     604              : 
     605              : #else
     606              : 
     607              : #ifndef __FINAL
     608              : #define __FINAL
     609              : #endif
     610              : 
     611              : #ifndef __OVERRIDE
     612              : #define __OVERRIDE
     613              : #endif
     614              : 
     615              : #ifndef __CONSTEXPR
     616              : #define __CONSTEXPR constexpr
     617              : #endif
     618              : 
     619              : #endif // (__cplusplus >= 201103L)
     620              : 
     621              : #if ((__cplusplus >= 201703L) || (defined(__GNUC__) && (__GNUC__ >= 7)) || (defined(__clang__)) && (__clang_major__ >= 4))
     622              : #define CHECK_RETURN_VALUE [[nodiscard]]
     623              : #elif defined(__GNUC__) && (__GNUC__ >= 4)
     624              : #define CHECK_RETURN_VALUE __attribute__((warn_unused_result))
     625              : #elif defined(_MSC_VER) && (_MSC_VER >= 1700)
     626              : #define CHECK_RETURN_VALUE _Check_return_
     627              : #else
     628              : #define CHECK_RETURN_VALUE
     629              : #endif
     630              : 
     631              : #if defined(__clang__)
     632              : #define FALLTHROUGH [[clang::fallthrough]]
     633              : #elif defined(__GNUC__)
     634              : #define FALLTHROUGH __attribute__((fallthrough))
     635              : #else
     636              : #define FALLTHROUGH (void) 0
     637              : #endif
     638              : 
     639              : /**
     640              :  * @def MATTER_ARRAY_SIZE(aArray)
     641              :  *
     642              :  * @brief
     643              :  *   Returns the size of an array in number of elements.
     644              :  *
     645              :  * Example Usage:
     646              :  *
     647              :  * @code
     648              :  * int numbers[10];
     649              :  * SortNumbers(numbers, MATTER_ARRAY_SIZE(numbers));
     650              :  * @endcode
     651              :  *
     652              :  * @return      The size of an array in number of elements.
     653              :  *
     654              :  * @note Clever template-based solutions seem to fail when MATTER_ARRAY_SIZE is used
     655              :  *       with a variable-length array argument, so we just do the C-compatible
     656              :  *       thing in C++ as well.
     657              :  */
     658              : #ifndef MATTER_ARRAY_SIZE
     659              : #define MATTER_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
     660              : #endif
     661              : 
     662              : /**
     663              :  * @brief Ensures that if `str` is NULL, a non-null `default_str_value` is provided
     664              :  *
     665              :  * @param str - null-terminated string pointer or nullptr
     666              :  * @param default_str_value - replacement value if `str` is nullptr
     667              :  * @return `str` if not null, otherwise `default_str_value`
     668              :  */
     669           40 : inline const char * DefaultStringWhenNull(const char * str, const char * default_str_value)
     670              : {
     671           40 :     return (str != nullptr) ? str : default_str_value;
     672              : }
     673              : 
     674              : /**
     675              :  * @brief Ensure that a string for a %s specifier is shown as "(null)" if null
     676              :  *
     677              :  * @param str - null-terminated string pointer or nullptr
     678              :  * @return `str` if not null, otherwise literal "(null)"
     679              :  */
     680           40 : inline const char * StringOrNullMarker(const char * str)
     681              : {
     682           40 :     return DefaultStringWhenNull(str, "(null)");
     683              : }
     684              : 
     685              : namespace chip {
     686              : 
     687              : /**
     688              :  * Utility for checking, at compile time if the array is constexpr, whether an
     689              :  * array is sorted.  Can be used for static_asserts.
     690              :  */
     691              : template <typename T>
     692              : constexpr bool ArrayIsSorted(const T * aArray, size_t aLength)
     693              : {
     694              :     if (aLength == 0 || aLength == 1)
     695              :     {
     696              :         return true;
     697              :     }
     698              : 
     699              :     if (aArray[0] > aArray[1])
     700              :     {
     701              :         return false;
     702              :     }
     703              : 
     704              :     return ArrayIsSorted(aArray + 1, aLength - 1);
     705              : }
     706              : 
     707              : template <typename T, size_t N>
     708              : constexpr bool ArrayIsSorted(const T (&aArray)[N])
     709              : {
     710              :     return ArrayIsSorted(aArray, N);
     711              : }
     712              : 
     713              : /**
     714              :  *  @def ScopeExit(fn)
     715              :  *
     716              :  *  @brief
     717              :  *    RAII to automatically release resources on scope exit (instead of depending on goto exit)
     718              :  *    See https://en.cppreference.com/w/cpp/experimental/scope_exit.html
     719              :  *    Use with ReturnOnFailure, ReturnLogErrorOnFailure, ReturnAndLogOnFailure and other such methods
     720              :  *    to return an error code result from a method call without needing to store in a local var
     721              :  *
     722              :  *  Example usage:
     723              :  *
     724              :  *  @code
     725              :  *  Resource * resource = GetResource();
     726              :  *  auto resourceHolder = ScopeExit([&] { resource->Release() });
     727              :  *  // If the call below fails, logs, returns the error code, and calls resourceHolder
     728              :  *  ReturnAndLogOnFailure(ProcessAndSaveResource(resource), Module, "Failure message: %s", param);
     729              :  *  resourceHolder->release(); // Cancel clean-up at end of successful method
     730              :  *  @endcode
     731              :  */
     732              : template <class F>
     733              : __attribute__((always_inline)) inline auto ScopeExit(F && fn)
     734              : {
     735        30360 :     auto deleter = [f = std::forward<F>(fn)](void *) mutable { f(); };
     736        15283 :     return std::unique_ptr<void, decltype(deleter)>(reinterpret_cast<void *>(1), std::move(deleter));
     737              : }
     738              : 
     739              : } // namespace chip
        

Generated by: LCOV version 2.0-1