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

Generated by: LCOV version 2.0-1