Skip to content

Commit

Permalink
Make sure optional arguments come last for chip-tool. (#12064)
Browse files Browse the repository at this point in the history
The code that initializes arguments assumes the optional ones are
sorted at the end.  So make sure that's actually true.

Fixes #12063
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Dec 8, 2021
1 parent ce74f38 commit 770e35d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
46 changes: 32 additions & 14 deletions examples/chip-tool/commands/common/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,7 @@ size_t Command::AddArgument(const char * name, const char * value, bool optional
arg.value = const_cast<void *>(reinterpret_cast<const void *>(value));
arg.optional = optional;

mArgs.emplace_back(arg);
return mArgs.size();
return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, char ** value, bool optional)
Expand All @@ -394,8 +393,7 @@ size_t Command::AddArgument(const char * name, char ** value, bool optional)
arg.value = reinterpret_cast<void *>(value);
arg.optional = optional;

mArgs.emplace_back(arg);
return mArgs.size();
return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, chip::CharSpan * value, bool optional)
Expand All @@ -406,8 +404,7 @@ size_t Command::AddArgument(const char * name, chip::CharSpan * value, bool opti
arg.value = reinterpret_cast<void *>(value);
arg.optional = optional;

mArgs.emplace_back(arg);
return mArgs.size();
return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, chip::ByteSpan * value, bool optional)
Expand All @@ -418,8 +415,7 @@ size_t Command::AddArgument(const char * name, chip::ByteSpan * value, bool opti
arg.value = reinterpret_cast<void *>(value);
arg.optional = optional;

mArgs.emplace_back(arg);
return mArgs.size();
return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, AddressWithInterface * out, bool optional)
Expand All @@ -430,8 +426,7 @@ size_t Command::AddArgument(const char * name, AddressWithInterface * out, bool
arg.value = reinterpret_cast<void *>(out);
arg.optional = optional;

mArgs.emplace_back(arg);
return mArgs.size();
return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, bool optional)
Expand All @@ -444,8 +439,7 @@ size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void *
arg.max = max;
arg.optional = optional;

mArgs.emplace_back(arg);
return mArgs.size();
return AddArgumentToList(std::move(arg));
}

size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, bool optional)
Expand All @@ -458,8 +452,7 @@ size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void *
arg.max = max;
arg.optional = optional;

mArgs.emplace_back(arg);
return mArgs.size();
return AddArgumentToList(std::move(arg));
}

const char * Command::GetArgumentName(size_t index) const
Expand All @@ -486,3 +479,28 @@ const char * Command::GetAttribute(void) const

return nullptr;
}

size_t Command::AddArgumentToList(Argument && argument)
{
if (argument.optional || mArgs.empty() || !mArgs.back().optional)
{
// Safe to just append.
mArgs.emplace_back(std::move(argument));
return mArgs.size();
}

// We're inserting a non-optional arg but we already have something optional
// in the list. Insert before the first optional arg.
for (auto cur = mArgs.cbegin(), end = mArgs.cend(); cur != end; ++cur)
{
if ((*cur).optional)
{
mArgs.emplace(cur, std::move(argument));
return mArgs.size();
}
}

// Never reached.
VerifyOrDie(false);
return 0;
}
6 changes: 6 additions & 0 deletions examples/chip-tool/commands/common/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ class Command
size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, bool optional);
size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, bool optional);

/**
* Add the Argument to our list. This preserves the property that all
* optional arguments come at the end of the list.
*/
size_t AddArgumentToList(Argument && argument);

const char * mName = nullptr;
std::vector<Argument> mArgs;
};

0 comments on commit 770e35d

Please sign in to comment.