Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "add CLI tab-to-autocomplete ability and implement for nrfconnect" #14384

Merged
merged 1 commit into from
Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static CHIP_ERROR SwitchCommandHandler(int argc, char ** argv)
static void RegisterSwitchCommands()
{
static const shell_command_t sSwitchCommand = { SwitchCommandHandler, "switch", "Switch commands. Usage: switch [on|off]" };
Engine::Root().RegisterCommands(&sSwitchCommand, 1, nullptr);
Engine::Root().RegisterCommands(&sSwitchCommand, 1);
return;
}
#endif // defined(ENABLE_CHIP_SHELL)
Expand Down
4 changes: 2 additions & 2 deletions examples/all-clusters-app/esp32/main/OnOffCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ void OnOffCommands::Register()
static const shell_command_t subCommands[] = { { &OnLightHandler, "on", "Usage: OnOff on endpoint-id" },
{ &OffLightHandler, "off", "Usage: OnOff off endpoint-id" },
{ &ToggleLightHandler, "toggle", "Usage: OnOff toggle endpoint-id" } };
sSubShell.RegisterCommands(subCommands, ArraySize(subCommands), "OnOff");
sSubShell.RegisterCommands(subCommands, ArraySize(subCommands));

// Register the root `OnOff` command in the top-level shell.
static const shell_command_t onOffCommand = { &OnOffHandler, "OnOff", "OnOff commands" };

Engine::Root().RegisterCommands(&onOffCommand, 1, nullptr);
Engine::Root().RegisterCommands(&onOffCommand, 1);
}

} // namespace Shell
Expand Down
4 changes: 2 additions & 2 deletions examples/lighting-app/cyw30739/src/AppShellCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ void RegisterAppShellCommands(void)
.cmd_help = "App commands",
};

sAppSubcommands.RegisterCommands(sAppSubCommands, ArraySize(sAppSubCommands), "app");
sAppSubcommands.RegisterCommands(sAppSubCommands, ArraySize(sAppSubCommands));

Engine::Root().RegisterCommands(&sAppCommand, 1, nullptr);
Engine::Root().RegisterCommands(&sAppCommand, 1);
}

CHIP_ERROR AppCommandHelpHandler(int argc, char * argv[])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ void OTAProviderCommands::Register()
"Usage: OTAProvider delay <delay in seconds>" },
};

sSubShell.RegisterCommands(subCommands, ArraySize(subCommands), "OTAProvider");
sSubShell.RegisterCommands(subCommands, ArraySize(subCommands));

// Register the root `OTA Provider` command in the top-level shell.
static const shell_command_t otaProviderCommand = { &OTAProviderHandler, "OTAProvider", "OTA Provider commands" };

Engine::Root().RegisterCommands(&otaProviderCommand, 1, nullptr);
Engine::Root().RegisterCommands(&otaProviderCommand, 1);
}

// Set Example OTA provider
Expand Down
4 changes: 2 additions & 2 deletions examples/platform/esp32/shell_extension/heap_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,15 @@ void RegisterHeapTraceCommands()
{ &HeapTraceTaskHandler, "task", "Dump heap usage of each task" },
#endif // CONFIG_HEAP_TASK_TRACKING
};
sShellHeapSubCommands.RegisterCommands(sHeapSubCommands, ArraySize(sHeapSubCommands), "heap-trace");
sShellHeapSubCommands.RegisterCommands(sHeapSubCommands, ArraySize(sHeapSubCommands));

#if CONFIG_HEAP_TRACING_STANDALONE
ESP_ERROR_CHECK(heap_trace_init_standalone(sTraceRecords, kNumHeapTraceRecords));
ESP_ERROR_CHECK(heap_trace_start(HEAP_TRACE_LEAKS));
#endif // CONFIG_HEAP_TRACING_STANDALONE

static const shell_command_t sHeapCommand = { &HeapTraceDispatch, "heap-trace", "Heap debug tracing" };
Engine::Root().RegisterCommands(&sHeapCommand, 1, nullptr);
Engine::Root().RegisterCommands(&sHeapCommand, 1);
}

} // namespace chip
Expand Down
2 changes: 1 addition & 1 deletion examples/platform/linux/CommissioneeShellCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void RegisterCommissioneeCommands()
"Commissionee commands. Usage: commissionee [command_name]" };

// Register the root `device` command with the top-level shell.
Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr);
Engine::Root().RegisterCommands(&sDeviceComand, 1);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion examples/platform/linux/ControllerShellCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ void RegisterControllerCommands()
"Controller commands. Usage: controller [command_name]" };

// Register the root `device` command with the top-level shell.
Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr);
Engine::Root().RegisterCommands(&sDeviceComand, 1);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion examples/shell/shell_common/cmd_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,5 @@ static shell_command_t cmds_misc[] = {

void cmd_misc_init()
{
Engine::Root().RegisterCommands(cmds_misc, ArraySize(cmds_misc), nullptr);
Engine::Root().RegisterCommands(cmds_misc, ArraySize(cmds_misc));
}
2 changes: 1 addition & 1 deletion examples/shell/shell_common/cmd_otcli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,6 @@ void cmd_otcli_init()
#endif

// Register the root otcli command with the top-level shell.
Engine::Root().RegisterCommands(&cmds_otcli_root, 1, nullptr);
Engine::Root().RegisterCommands(&cmds_otcli_root, 1);
#endif // CHIP_ENABLE_OPENTHREAD
}
2 changes: 1 addition & 1 deletion examples/shell/shell_common/cmd_ping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,5 +483,5 @@ static shell_command_t cmds_ping[] = {

void cmd_ping_init()
{
Engine::Root().RegisterCommands(cmds_ping, ArraySize(cmds_ping), nullptr);
Engine::Root().RegisterCommands(cmds_ping, ArraySize(cmds_ping));
}
2 changes: 1 addition & 1 deletion examples/shell/shell_common/cmd_send.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,5 +406,5 @@ static shell_command_t cmds_send[] = {

void cmd_send_init()
{
Engine::Root().RegisterCommands(cmds_send, ArraySize(cmds_send), nullptr);
Engine::Root().RegisterCommands(cmds_send, ArraySize(cmds_send));
}
4 changes: 2 additions & 2 deletions examples/shell/shell_common/cmd_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ void cmd_app_server_init()
std::atexit(CmdAppServerAtExit);

// Register `server` subcommands with the local shell dispatcher.
sShellServerSubcommands.RegisterCommands(sServerSubCommands, ArraySize(sServerSubCommands), "server");
sShellServerSubcommands.RegisterCommands(sServerSubCommands, ArraySize(sServerSubCommands));

// Register the root `server` command with the top-level shell.
Engine::Root().RegisterCommands(&sServerComand, 1, nullptr);
Engine::Root().RegisterCommands(&sServerComand, 1);
}
2 changes: 1 addition & 1 deletion examples/tv-app/linux/AppPlatformShellCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ void RegisterAppPlatformCommands()
static const shell_command_t sDeviceComand = { &AppPlatformHandler, "app", "App commands. Usage: app [command_name]" };

// Register the root `device` command with the top-level shell.
Engine::Root().RegisterCommands(&sDeviceComand, 1, nullptr);
Engine::Root().RegisterCommands(&sDeviceComand, 1);
return;
}

Expand Down
187 changes: 23 additions & 164 deletions src/lib/shell/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
* Source implementation for a generic shell API for CHIP examples.
*/

#include <lib/shell/Engine.h>

#include <lib/core/CHIPError.h>
#include <lib/shell/Commands.h>
#include <lib/shell/Engine.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
Expand All @@ -34,14 +35,14 @@
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>

using namespace chip::Logging;

namespace chip {
namespace Shell {

Engine Engine::theEngineRoot;
shell_map * Engine::theShellMapListHead = NULL;

int Engine::Init()
{
Expand All @@ -55,189 +56,47 @@ int Engine::Init()

void Engine::ForEachCommand(shell_command_iterator_t * on_command, void * arg)
{
for (unsigned i = 0; i < _commandCount; i++)
for (unsigned i = 0; i < _commandSetCount; i++)
{
if (on_command(_commands[i], arg) != CHIP_NO_ERROR)
for (unsigned j = 0; j < _commandSetSize[i]; j++)
{
return;
}
}
}

void Engine::RegisterCommands(shell_command_t * command_set, unsigned count, const char * prefix)
{
if (this == &Engine::Root() || prefix == nullptr)
{
prefix = "";
}

if (_commandCount + count > CHIP_SHELL_MAX_MODULES)
{
ChipLogError(Shell, "Max number of commands registered to this shell");
assert(0);
}

for (unsigned i = 0; i < count; i++)
{
_commands[_commandCount + i] = &command_set[i];
}
_commandCount += count;

Engine::InsertShellMap(prefix, this);
}

void Engine::InsertShellMap(char const * prefix, Engine * shell)
{
shell_map_t * map = Engine::theShellMapListHead;
while (map != NULL)
{
if (strcmp(prefix, map->prefix) == 0)
{
for (size_t i = 0; i < map->enginec; i++)
if (on_command(&_commandSet[i][j], arg) != CHIP_NO_ERROR)
{
if (map->enginev[i] == shell)
{
return;
}
return;
}
if (map->enginec == sizeof(map->enginev))
{
ChipLogError(Shell, "Max number of shells registered under this prefix");
assert(0);
}
map->enginev[map->enginec] = shell;
map->enginec++;
return;
}
map = map->next;
}
shell_map_t * new_map = new shell_map_t;
new_map->prefix = prefix;
new_map->enginev[0] = shell;
new_map->enginec = 1;
new_map->next = Engine::theShellMapListHead;
Engine::theShellMapListHead = new_map;
}

CHIP_ERROR Engine::GetCommandCompletions(cmd_completion_context * context)
void Engine::RegisterCommands(shell_command_t * command_set, unsigned count)
{

if (Engine::theShellMapListHead == NULL)
{
ChipLogDetail(Shell, "There isn't any command registered yet.");
return CHIP_NO_ERROR;
}
const char * buf = context->line_buf;
if (buf == nullptr)
if (_commandSetCount >= CHIP_SHELL_MAX_MODULES)
{
buf = "";
}

int last_space_idx = -1;
int buf_len = strlen(buf);

// find space in buf
for (int i = buf_len - 1; i > -1; i--)
{
if (buf[i] == ' ')
{
last_space_idx = i;
break;
}
}

// check whether the buf perfectly matches a prefix
bool perfect_match = false;
shell_map_t * map = Engine::theShellMapListHead;

while (map != NULL)
{

if (strcmp(buf, map->prefix) == 0)
{
perfect_match = true;
break;
}
map = map->next;
}

char * prefix;
char * incomplete_cmd;

if (perfect_match)
{
// If it's a perfect match
// - use the whole buf as the prefix
// - there is no "incomplete command" so set it to empty
prefix = new char[buf_len + 1];
incomplete_cmd = new char[1];
strncpy(prefix, buf, buf_len + 1);
strncpy(incomplete_cmd, "", 1);
}
else
{
// If it's not a perfect match:
// - prefix is up to the last space
// - incomplete_cmd is what's after the last space
bool no_space = (last_space_idx == -1) ? true : false;
prefix = new char[last_space_idx + 1 + no_space];
incomplete_cmd = new char[buf_len - last_space_idx];
strncpy(prefix, buf, last_space_idx + 1 + no_space);
strncpy(incomplete_cmd, &buf[last_space_idx + 1], buf_len - last_space_idx);
}

// Array to pass arguments into the ForEachCommand call
void * lambda_args[] = { context, incomplete_cmd };
map = Engine::theShellMapListHead;

while (map != NULL && context->cmdc < CHIP_SHELL_MAX_CMD_COMPLETIONS)
{
if (strcmp(prefix, map->prefix) == 0)
{
context->ret_prefix = map->prefix;
for (unsigned i = 0; i < map->enginec; i++)
{
map->enginev[i]->ForEachCommand(
[](shell_command_t * cmd, void * arg) -> CHIP_ERROR {
cmd_completion_context * ctx = (cmd_completion_context *) ((void **) arg)[0];
char * _incomplete_cmd = (char *) ((void **) arg)[1];
// For end nodes like "ble adv", need to avoid duplicate returns.
// Return for prefix="ble adv" cmd=""; reject for prefix="ble" cmd="adv"
if ((strcmp(cmd->cmd_name, _incomplete_cmd) != 0 &&
strncmp(cmd->cmd_name, _incomplete_cmd, strlen(_incomplete_cmd)) == 0) ||
strcmp(_incomplete_cmd, "") == 0)
{
ctx->cmdc++;
ctx->cmdv[ctx->cmdc - 1] = cmd;
}
return CHIP_NO_ERROR;
},
lambda_args);
}
break;
}

map = map->next;
ChipLogError(Shell, "Max number of modules reached\n");
assert(0);
}

delete[] prefix;
delete[] incomplete_cmd;

return CHIP_NO_ERROR;
_commandSet[_commandSetCount] = command_set;
_commandSetSize[_commandSetCount] = count;
++_commandSetCount;
}

CHIP_ERROR Engine::ExecCommand(int argc, char * argv[])
{
CHIP_ERROR retval = CHIP_ERROR_INVALID_ARGUMENT;

VerifyOrReturnError(argc > 0, retval);
// Find the command
for (unsigned i = 0; i < _commandCount; i++)
for (unsigned i = 0; i < _commandSetCount; i++)
{
if (strcmp(argv[0], _commands[i]->cmd_name) == 0)
for (unsigned j = 0; j < _commandSetSize[i]; j++)
{
// Execute the command!
retval = _commands[i]->cmd_func(argc - 1, argv + 1);
break;
if (strcmp(argv[0], _commandSet[i][j].cmd_name) == 0)
{
// Execute the command!
retval = _commandSet[i][j].cmd_func(argc - 1, argv + 1);
break;
}
}
}

Expand Down
Loading