From 266a378563a80f0d4bc0eaec924885e182ebac35 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Tue, 27 Oct 2020 15:19:05 +0100 Subject: [PATCH] thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) (#3339) --- .../chip-tool/commands/common/Command.cpp | 70 ++++++++++++++++++- examples/chip-tool/commands/common/Command.h | 37 ++++++++-- 2 files changed, 98 insertions(+), 9 deletions(-) diff --git a/examples/chip-tool/commands/common/Command.cpp b/examples/chip-tool/commands/common/Command.cpp index 3398905500f799..97aad235df9afb 100644 --- a/examples/chip-tool/commands/common/Command.cpp +++ b/examples/chip-tool/commands/common/Command.cpp @@ -23,6 +23,7 @@ #include #include +#include #include bool Command::InitArguments(int argc, char ** argv) @@ -97,9 +98,59 @@ bool Command::InitArgument(size_t argIndex, const char * argValue) break; } - case ArgumentType::Number: { - uint32_t * value = reinterpret_cast(arg.value); + case ArgumentType::Number_uint8: { + uint8_t * value = reinterpret_cast(arg.value); + // stringstream treats uint8_t as char, which is not what we want here. + uint16_t tmpValue; + std::stringstream ss(argValue); + ss >> tmpValue; + if (chip::CanCastTo(tmpValue)) + { + *value = static_cast(tmpValue); + isValidArgument = (!ss.fail() && ss.eof() && *value >= arg.min && *value <= arg.max); + } + else + { + isValidArgument = false; + } + break; + } + + case ArgumentType::Number_uint16: { + uint16_t * value = reinterpret_cast(arg.value); + std::stringstream ss(argValue); + ss >> *value; + isValidArgument = (!ss.fail() && ss.eof() && *value >= arg.min && *value <= arg.max); + break; + } + + case ArgumentType::Number_uint32: { + uint32_t * value = reinterpret_cast(arg.value); + std::stringstream ss(argValue); + ss >> *value; + isValidArgument = (!ss.fail() && ss.eof() && *value >= arg.min && *value <= arg.max); + break; + } + + case ArgumentType::Number_int8: { + int8_t * value = reinterpret_cast(arg.value); + std::stringstream ss(argValue); + ss >> *value; + isValidArgument = (!ss.fail() && ss.eof() && *value >= arg.min && *value <= arg.max); + break; + } + + case ArgumentType::Number_int16: { + int16_t * value = reinterpret_cast(arg.value); + std::stringstream ss(argValue); + ss >> *value; + isValidArgument = (!ss.fail() && ss.eof() && *value >= arg.min && *value <= arg.max); + break; + } + + case ArgumentType::Number_int32: { + int32_t * value = reinterpret_cast(arg.value); std::stringstream ss(argValue); ss >> *value; isValidArgument = (!ss.fail() && ss.eof() && *value >= arg.min && *value <= arg.max); @@ -154,10 +205,23 @@ size_t Command::AddArgument(const char * name, AddressWithInterface * out) return mArgs.size(); } +size_t Command::AddArgument(const char * name, int64_t min, int64_t max, void * out, ArgumentType type) +{ + Argument arg; + arg.type = type; + arg.name = name; + arg.value = out; + arg.min = min; + arg.max = max; + + mArgs.emplace(mArgs.begin(), arg); + return mArgs.size(); +} + size_t Command::AddArgument(const char * name, int64_t min, int64_t max, void * out) { Argument arg; - arg.type = ArgumentType::Number; + arg.type = ArgumentType::Number_uint8; arg.name = name; arg.value = out; arg.min = min; diff --git a/examples/chip-tool/commands/common/Command.h b/examples/chip-tool/commands/common/Command.h index d08ea5cac4f0e6..5fdad7431df639 100644 --- a/examples/chip-tool/commands/common/Command.h +++ b/examples/chip-tool/commands/common/Command.h @@ -44,7 +44,12 @@ typedef std::initializer_list commands_list; enum ArgumentType { - Number, + Number_uint8, + Number_uint16, + Number_uint32, + Number_int8, + Number_int16, + Number_int32, String, Attribute, Address @@ -82,11 +87,6 @@ class Command size_t GetArgumentsCount(void) const { return mArgs.size(); } bool InitArguments(int argc, char ** argv); - template - size_t AddArgument(const char * name, int64_t min, int64_t max, T * out) - { - return AddArgument(name, min, max, reinterpret_cast(out)); - } size_t AddArgument(const char * name, const char * value); /** * @brief @@ -98,6 +98,30 @@ class Command */ size_t AddArgument(const char * name, char ** value); size_t AddArgument(const char * name, AddressWithInterface * out); + size_t AddArgument(const char * name, int64_t min, int64_t max, int8_t * out) + { + return AddArgument(name, min, max, reinterpret_cast(out), Number_int8); + } + size_t AddArgument(const char * name, int64_t min, int64_t max, int16_t * out) + { + return AddArgument(name, min, max, reinterpret_cast(out), Number_int16); + } + size_t AddArgument(const char * name, int64_t min, int64_t max, int32_t * out) + { + return AddArgument(name, min, max, reinterpret_cast(out), Number_int32); + } + size_t AddArgument(const char * name, int64_t min, int64_t max, uint8_t * out) + { + return AddArgument(name, min, max, reinterpret_cast(out), Number_uint8); + } + size_t AddArgument(const char * name, int64_t min, int64_t max, uint16_t * out) + { + return AddArgument(name, min, max, reinterpret_cast(out), Number_uint16); + } + size_t AddArgument(const char * name, int64_t min, int64_t max, uint32_t * out) + { + return AddArgument(name, min, max, reinterpret_cast(out), Number_uint32); + } size_t AddArgument(const char * name, const void * value) { return 0; }; virtual CHIP_ERROR Run(ChipDeviceController * dc, NodeId remoteId) = 0; @@ -107,6 +131,7 @@ class Command private: bool InitArgument(size_t argIndex, const char * argValue); + size_t AddArgument(const char * name, int64_t min, int64_t max, void * out, ArgumentType type); size_t AddArgument(const char * name, int64_t min, int64_t max, void * out); bool mCommandExitStatus = false;