mirror of
https://github.com/espressif/openthread.git
synced 2026-08-24 11:19:51 +00:00
[cli] simplify argument processing (#6767)
This commit changes `ParseCmd()` such that as `aArgs` array entries
are populated with parsed arguments from a command line string, the
remaining unused `aArgs` entries in the array are marked as "empty".
We also ensure that the `aArgs[]` array always end with an "empty"
`Arg` which indicates end of the list (this is similar to how C
string ends with a null '\0' character). This commit also changes
different methods of `Arg` class (`Arg::ParseAs{Type}()` or overload
of operator `==`, etc) to check and handle when `Arg` is marked
as "empty".
These changes help simplify how the arguments are processed in CLI
modules. In `Cli::Process{Command}()` methods we can just pass the
`aArgs[]` array and do not need to pass a separate args length
parameter. In many cases the args length checks can be removed since
it will be checked from `ParseAs{Type}()` call.
This commit is contained in:
+30
-36
@@ -51,9 +51,8 @@ UdpExample::UdpExample(Interpreter &aInterpreter)
|
||||
memset(&mSocket, 0, sizeof(mSocket));
|
||||
}
|
||||
|
||||
otError UdpExample::ProcessHelp(uint8_t aArgsLength, Arg aArgs[])
|
||||
otError UdpExample::ProcessHelp(Arg aArgs[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aArgsLength);
|
||||
OT_UNUSED_VARIABLE(aArgs);
|
||||
|
||||
for (const Command &command : sCommands)
|
||||
@@ -64,15 +63,14 @@ otError UdpExample::ProcessHelp(uint8_t aArgsLength, Arg aArgs[])
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError UdpExample::ProcessBind(uint8_t aArgsLength, Arg aArgs[])
|
||||
otError UdpExample::ProcessBind(Arg aArgs[])
|
||||
{
|
||||
otError error;
|
||||
otSockAddr sockaddr;
|
||||
|
||||
VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
SuccessOrExit(error = aArgs[0].ParseAsIp6Address(sockaddr.mAddress));
|
||||
SuccessOrExit(error = aArgs[1].ParseAsUint16(sockaddr.mPort));
|
||||
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
error = otUdpBind(mInterpreter.mInstance, &mSocket, &sockaddr);
|
||||
|
||||
@@ -80,15 +78,14 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError UdpExample::ProcessConnect(uint8_t aArgsLength, Arg aArgs[])
|
||||
otError UdpExample::ProcessConnect(Arg aArgs[])
|
||||
{
|
||||
otError error;
|
||||
otSockAddr sockaddr;
|
||||
|
||||
VerifyOrExit(aArgsLength == 2, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
SuccessOrExit(error = aArgs[0].ParseAsIp6Address(sockaddr.mAddress));
|
||||
SuccessOrExit(error = aArgs[1].ParseAsUint16(sockaddr.mPort));
|
||||
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
error = otUdpConnect(mInterpreter.mInstance, &mSocket, &sockaddr);
|
||||
|
||||
@@ -96,17 +93,15 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError UdpExample::ProcessClose(uint8_t aArgsLength, Arg aArgs[])
|
||||
otError UdpExample::ProcessClose(Arg aArgs[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aArgsLength);
|
||||
OT_UNUSED_VARIABLE(aArgs);
|
||||
|
||||
return otUdpClose(mInterpreter.mInstance, &mSocket);
|
||||
}
|
||||
|
||||
otError UdpExample::ProcessOpen(uint8_t aArgsLength, Arg aArgs[])
|
||||
otError UdpExample::ProcessOpen(Arg aArgs[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aArgsLength);
|
||||
OT_UNUSED_VARIABLE(aArgs);
|
||||
|
||||
otError error;
|
||||
@@ -118,12 +113,11 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError UdpExample::ProcessSend(uint8_t aArgsLength, Arg aArgs[])
|
||||
otError UdpExample::ProcessSend(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
otMessage * message = nullptr;
|
||||
otMessageInfo messageInfo;
|
||||
uint8_t argIndex = 0;
|
||||
otMessageSettings messageSettings = {mLinkSecurityEnabled, OT_MESSAGE_PRIORITY_NORMAL};
|
||||
|
||||
memset(&messageInfo, 0, sizeof(messageInfo));
|
||||
@@ -135,47 +129,43 @@ otError UdpExample::ProcessSend(uint8_t aArgsLength, Arg aArgs[])
|
||||
// send <ip> <port> <text>
|
||||
// send <ip> <port> <type> <value>
|
||||
|
||||
VerifyOrExit(aArgsLength >= 1 && aArgsLength <= 4, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (aArgsLength > 2)
|
||||
if (!aArgs[2].IsEmpty())
|
||||
{
|
||||
SuccessOrExit(error = aArgs[argIndex++].ParseAsIp6Address(messageInfo.mPeerAddr));
|
||||
SuccessOrExit(error = aArgs[argIndex++].ParseAsUint16(messageInfo.mPeerPort));
|
||||
SuccessOrExit(error = aArgs[0].ParseAsIp6Address(messageInfo.mPeerAddr));
|
||||
SuccessOrExit(error = aArgs[1].ParseAsUint16(messageInfo.mPeerPort));
|
||||
aArgs += 2;
|
||||
}
|
||||
|
||||
message = otUdpNewMessage(mInterpreter.mInstance, &messageSettings);
|
||||
VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
|
||||
|
||||
if (aArgs[argIndex] == "-s")
|
||||
if (aArgs[0] == "-s")
|
||||
{
|
||||
// Auto-generated payload with a given length
|
||||
|
||||
uint16_t payloadLength;
|
||||
|
||||
argIndex++;
|
||||
VerifyOrExit(argIndex < aArgsLength, error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = aArgs[argIndex].ParseAsUint16(payloadLength));
|
||||
SuccessOrExit(error = aArgs[1].ParseAsUint16(payloadLength));
|
||||
SuccessOrExit(error = PrepareAutoGeneratedPayload(*message, payloadLength));
|
||||
}
|
||||
else if (aArgs[argIndex] == "-x")
|
||||
else if (aArgs[0] == "-x")
|
||||
{
|
||||
// Binary hex data payload
|
||||
|
||||
argIndex++;
|
||||
VerifyOrExit(argIndex < aArgsLength, error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = PrepareHexStringPaylod(*message, aArgs[argIndex].GetCString()));
|
||||
VerifyOrExit(!aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = PrepareHexStringPaylod(*message, aArgs[1].GetCString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Text payload (same as without specifying the type)
|
||||
|
||||
if (aArgs[argIndex] == "-t")
|
||||
if (aArgs[0] == "-t")
|
||||
{
|
||||
argIndex++;
|
||||
aArgs++;
|
||||
}
|
||||
|
||||
VerifyOrExit(argIndex < aArgsLength, error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = otMessageAppend(message, aArgs[argIndex].GetCString(), aArgs[argIndex].GetLength()));
|
||||
VerifyOrExit(!aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
|
||||
SuccessOrExit(error = otMessageAppend(message, aArgs[0].GetCString(), aArgs[0].GetLength()));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otUdpSend(mInterpreter.mInstance, &mSocket, message, &messageInfo));
|
||||
@@ -191,11 +181,11 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError UdpExample::ProcessLinkSecurity(uint8_t aArgsLength, Arg aArgs[])
|
||||
otError UdpExample::ProcessLinkSecurity(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
if (aArgsLength == 0)
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
mInterpreter.OutputEnabledDisabledStatus(mLinkSecurityEnabled);
|
||||
}
|
||||
@@ -264,17 +254,21 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError UdpExample::Process(uint8_t aArgsLength, Arg aArgs[])
|
||||
otError UdpExample::Process(Arg aArgs[])
|
||||
{
|
||||
otError error = OT_ERROR_INVALID_ARGS;
|
||||
const Command *command;
|
||||
|
||||
VerifyOrExit(aArgsLength != 0, IgnoreError(ProcessHelp(0, nullptr)));
|
||||
if (aArgs[0].IsEmpty())
|
||||
{
|
||||
IgnoreError(ProcessHelp(aArgs));
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
command = Utils::LookupTable::Find(aArgs[0].GetCString(), sCommands);
|
||||
VerifyOrExit(command != nullptr, error = OT_ERROR_INVALID_COMMAND);
|
||||
|
||||
error = (this->*command->mHandler)(aArgsLength - 1, aArgs + 1);
|
||||
error = (this->*command->mHandler)(aArgs + 1);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
Reference in New Issue
Block a user