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

[WIP Please ignore] Add cli completion ability; implement for esp and nrf #14478

Closed
wants to merge 2 commits into from

Conversation

lmpprk
Copy link
Contributor

@lmpprk lmpprk commented Jan 28, 2022

Problem

Change overview

  • Require command prefix/path as argument at time of command registration (e.g. "dns" is prefix for "dns resolve" and "dns browse")
  • Add Engine::GetCmdCompletion to provide command completion based on command prefixes
  • Implement the tab autocompletion for nRF Connect and ESP32 platforms
    Previously add CLI tab-to-autocomplete ability and implement for nrfconnect #13630 reverted due to racing changes with other command additions.

Testing

Build and tested manually with

nRF52840dk with lighting-app example
nrf

esp32c3 with all-clusters-app example
esp

@github-actions
Copy link

github-actions bot commented Jan 28, 2022

PR #14478: Size comparison from 92f8343 to 43d19df

Increases (3 builds for cyw30739, telink)
platform target config section 92f8343 43d19df change % change
cyw30739 light cyw930739m2evb_01 .app_xip_area 484224 484364 140 0.0
lock-app CYW30739 .app_xip_area 443780 443868 88 0.0
telink lighting-app tlsr9518adk80d (read/write) 845770 846446 676 0.1
text 592508 593628 1120 0.2
Decreases (4 builds for cyw30739, linux, telink)
platform target config section 92f8343 43d19df change % change
cyw30739 light cyw930739m2evb_01 (read/write) 578130 577246 -884 -0.2
.bss 76652 75628 -1024 -1.3
lock-app CYW30739 (read/write) 536142 535974 -168 -0.0
.bss 75148 74892 -256 -0.3
linux thermostat-no-ble arm64 (read/write) 149537 148641 -896 -0.6
.bss 67169 66273 -896 -1.3
telink lighting-app tlsr9518adk80d bss 86440 85964 -476 -0.6
Full report (16 builds for cyw30739, efr32, k32w, linux, p6, qpg, telink)
platform target config section 92f8343 43d19df change % change
cyw30739 light cyw930739m2evb_01 (read/write) 578130 577246 -884 -0.2
.app_xip_area 484224 484364 140 0.0
.bss 76652 75628 -1024 -1.3
.data 596 596 0 0.0
.rodata 0 0 0 0.0
.text 0 0 0 0.0
lock-app CYW30739 (read/write) 536142 535974 -168 -0.0
.app_xip_area 443780 443868 88 0.0
.bss 75148 74892 -256 -0.3
.data 560 560 0 0.0
.rodata 0 0 0 0.0
.text 0 0 0 0.0
efr32 lighting-app BRD4161A (read only) 842984 842984 0 0.0
(read/write) 126200 126200 0 0.0
.bss 124296 124296 0 0.0
.data 1900 1900 0 0.0
.text 842976 842976 0 0.0
BRD4161A+rpc (read only) 830336 830336 0 0.0
(read/write) 142856 142856 0 0.0
.bss 140856 140856 0 0.0
.data 2000 2000 0 0.0
.text 830328 830328 0 0.0
window-app BRD4161A (read only) 815560 815560 0 0.0
(read/write) 124852 124852 0 0.0
.bss 122996 122996 0 0.0
.data 1856 1856 0 0.0
.text 815552 815552 0 0.0
k32w light k32w061+release (read/write) 662940 662940 0 0.0
.bss 76428 76428 0 0.0
.data 1868 1868 0 0.0
.text 578844 578844 0 0.0
lock k32w061+release (read/write) 663844 663844 0 0.0
.bss 76692 76692 0 0.0
.data 1892 1892 0 0.0
.text 579460 579460 0 0.0
linux chip-tool-ipv6only arm64 (read only) 6765620 6765620 0 0.0
(read/write) 279201 279201 0 0.0
.bss 55537 55537 0 0.0
.data 1128 1128 0 0.0
.data.rel.ro 175984 175984 0 0.0
.dynamic 560 560 0 0.0
.got 42784 42784 0 0.0
.init 24 24 0 0.0
.init_array 200 200 0 0.0
.rodata 386892 386892 0 0.0
.text 5806628 5806628 0 0.0
thermostat-no-ble arm64 (read only) 2080620 2080620 0 0.0
(read/write) 149537 148641 -896 -0.6
.bss 67169 66273 -896 -1.3
.data 960 960 0 0.0
.data.rel.ro 74288 74288 0 0.0
.dynamic 560 560 0 0.0
.got 4144 4144 0 0.0
.init 24 24 0 0.0
.init_array 336 336 0 0.0
.rodata 129932 129932 0 0.0
.text 1733344 1733344 0 0.0
p6 all-clusters-app default (read/write) 2441656 2441656 0 0.0
.bss 116740 116740 0 0.0
.data 2584 2584 0 0.0
.text 1399920 1399920 0 0.0
light-app default (read/write) 2338568 2338568 0 0.0
.bss 104484 104484 0 0.0
.data 2408 2408 0 0.0
.text 1296832 1296832 0 0.0
lock-app default (read/write) 2304080 2304080 0 0.0
.bss 104228 104228 0 0.0
.data 2360 2360 0 0.0
.text 1262344 1262344 0 0.0
qpg lighting-app qpg6105+debug (read only) 570884 570884 0 0.0
(read/write) 146936 146936 0 0.0
.bss 88640 88640 0 0.0
.data 1060 1060 0 0.0
.text 565564 565564 0 0.0
lock-app qpg6105+debug (read only) 517004 517004 0 0.0
(read/write) 146940 146940 0 0.0
.bss 88112 88112 0 0.0
.data 992 992 0 0.0
.text 511684 511684 0 0.0
persistent-storage-app qpg6105+debug (read only) 107140 107140 0 0.0
(read/write) 146940 146940 0 0.0
.bss 38504 38504 0 0.0
.data 288 288 0 0.0
.text 101820 101820 0 0.0
telink lighting-app tlsr9518adk80d (read/write) 845770 846446 676 0.1
bss 86440 85964 -476 -0.6
noinit 37160 37160 0 0.0
text 592508 593628 1120 0.2

@github-actions
Copy link

github-actions bot commented Jan 28, 2022

PR #14478: Size comparison from 92f8343 to 1f9b2f2

Increases (5 builds for cyw30739, esp32, nrfconnect, telink)
platform target config section 92f8343 1f9b2f2 change % change
cyw30739 light cyw930739m2evb_01 .app_xip_area 484224 484364 140 0.0
lock-app CYW30739 .app_xip_area 443780 443868 88 0.0
esp32 all-clusters-app m5stack (read only) 980687 981667 980 0.1
.flash.rodata 221108 221180 72 0.0
.flash.text 975303 976283 980 0.1
nrfconnect shell nrf52840dk_nrf52840 (read/write) 798203 798319 116 0.0
rodata 78288 78324 36 0.0
text 533640 534588 948 0.2
telink lighting-app tlsr9518adk80d (read/write) 845770 846446 676 0.1
text 592508 593628 1120 0.2
Decreases (6 builds for cyw30739, esp32, linux, nrfconnect, telink)
platform target config section 92f8343 1f9b2f2 change % change
cyw30739 light cyw930739m2evb_01 (read/write) 578130 577246 -884 -0.2
.bss 76652 75628 -1024 -1.3
lock-app CYW30739 (read/write) 536142 535974 -168 -0.0
.bss 75148 74892 -256 -0.3
esp32 all-clusters-app m5stack (read/write) 461692 460620 -1072 -0.2
.dram0.bss 74432 73288 -1144 -1.5
linux thermostat-no-ble arm64 (read/write) 149537 148641 -896 -0.6
.bss 67169 66273 -896 -1.3
nrfconnect shell nrf52840dk_nrf52840 bss 109776 108908 -868 -0.8
telink lighting-app tlsr9518adk80d bss 86440 85964 -476 -0.6
Full report (33 builds for cyw30739, efr32, esp32, k32w, linux, mbed, nrfconnect, p6, qpg, telink)
platform target config section 92f8343 1f9b2f2 change % change
cyw30739 light cyw930739m2evb_01 (read/write) 578130 577246 -884 -0.2
.app_xip_area 484224 484364 140 0.0
.bss 76652 75628 -1024 -1.3
.data 596 596 0 0.0
.rodata 0 0 0 0.0
.text 0 0 0 0.0
lock-app CYW30739 (read/write) 536142 535974 -168 -0.0
.app_xip_area 443780 443868 88 0.0
.bss 75148 74892 -256 -0.3
.data 560 560 0 0.0
.rodata 0 0 0 0.0
.text 0 0 0 0.0
efr32 lighting-app BRD4161A (read only) 842984 842984 0 0.0
(read/write) 126200 126200 0 0.0
.bss 124296 124296 0 0.0
.data 1900 1900 0 0.0
.text 842976 842976 0 0.0
BRD4161A+rpc (read only) 830336 830336 0 0.0
(read/write) 142856 142856 0 0.0
.bss 140856 140856 0 0.0
.data 2000 2000 0 0.0
.text 830328 830328 0 0.0
window-app BRD4161A (read only) 815560 815560 0 0.0
(read/write) 124852 124852 0 0.0
.bss 122996 122996 0 0.0
.data 1856 1856 0 0.0
.text 815552 815552 0 0.0
esp32 all-clusters-app c3devkit (read only) 932734 932734 0 0.0
(read/write) 1397322 1397322 0 0.0
.dram0.bss 69688 69688 0 0.0
.dram0.data 14244 14244 0 0.0
.flash.rodata 194480 194480 0 0.0
.flash.text 932734 932734 0 0.0
.iram0.text 62056 62056 0 0.0
m5stack (read only) 980687 981667 980 0.1
(read/write) 461692 460620 -1072 -0.2
.dram0.bss 74432 73288 -1144 -1.5
.dram0.data 34024 34024 0 0.0
.flash.rodata 221108 221180 72 0.0
.flash.text 975303 976283 980 0.1
.iram0.text 123399 123399 0 0.0
k32w light k32w061+release (read/write) 662940 662940 0 0.0
.bss 76428 76428 0 0.0
.data 1868 1868 0 0.0
.text 578844 578844 0 0.0
lock k32w061+release (read/write) 663844 663844 0 0.0
.bss 76692 76692 0 0.0
.data 1892 1892 0 0.0
.text 579460 579460 0 0.0
linux chip-tool-ipv6only arm64 (read only) 6765620 6765620 0 0.0
(read/write) 279201 279201 0 0.0
.bss 55537 55537 0 0.0
.data 1128 1128 0 0.0
.data.rel.ro 175984 175984 0 0.0
.dynamic 560 560 0 0.0
.got 42784 42784 0 0.0
.init 24 24 0 0.0
.init_array 200 200 0 0.0
.rodata 386892 386892 0 0.0
.text 5806628 5806628 0 0.0
thermostat-no-ble arm64 (read only) 2080620 2080620 0 0.0
(read/write) 149537 148641 -896 -0.6
.bss 67169 66273 -896 -1.3
.data 960 960 0 0.0
.data.rel.ro 74288 74288 0 0.0
.dynamic 560 560 0 0.0
.got 4144 4144 0 0.0
.init 24 24 0 0.0
.init_array 336 336 0 0.0
.rodata 129932 129932 0 0.0
.text 1733344 1733344 0 0.0
mbed all-clusters-app CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 2382408 2382408 0 0.0
.bss 188588 188588 0 0.0
.data 5288 5288 0 0.0
.text 1345008 1345008 0 0.0
lighting-app CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 2338200 2338200 0 0.0
.bss 179304 179304 0 0.0
.data 5584 5584 0 0.0
.text 1300800 1300800 0 0.0
lock-app CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 2302240 2302240 0 0.0
.bss 179208 179208 0 0.0
.data 5552 5552 0 0.0
.text 1264840 1264840 0 0.0
pigweed-app CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 1139712 1139712 0 0.0
.bss 11756 11756 0 0.0
.data 4368 4368 0 0.0
.text 103096 103096 0 0.0
shell CY8CPROTO_062_4343W+release (read only) 6224 6224 0 0.0
(read/write) 2292980 2292980 0 0.0
.bss 176532 176532 0 0.0
.data 5384 5384 0 0.0
.text 1255552 1255552 0 0.0
nrfconnect lighting-app nrf52840dk_nrf52840 (read/write) 981375 981375 0 0.0
bss 119660 119660 0 0.0
rodata 115684 115684 0 0.0
text 668228 668228 0 0.0
nrf52840dk_nrf52840+rpc (read/write) 966923 966923 0 0.0
bss 116704 116704 0 0.0
rodata 107160 107160 0 0.0
text 664672 664672 0 0.0
nrf52840dongle_nrf52840 (read/write) 997459 997459 0 0.0
bss 120832 120832 0 0.0
rodata 114516 114516 0 0.0
text 673656 673656 0 0.0
nrf5340dk_nrf5340_cpuapp (read/write) 890546 890546 0 0.0
bss 116448 116448 0 0.0
rodata 108964 108964 0 0.0
text 584416 584416 0 0.0
lock-app nrf52840dk_nrf52840 (read/write) 913955 913955 0 0.0
bss 118040 118040 0 0.0
rodata 104320 104320 0 0.0
text 614212 614212 0 0.0
nrf5340dk_nrf5340_cpuapp (read/write) 824006 824006 0 0.0
bss 114856 114856 0 0.0
rodata 97528 97528 0 0.0
text 531172 531172 0 0.0
pigweed-app nrf52840dk_nrf52840 (read/write) 541779 541779 0 0.0
bss 52588 52588 0 0.0
rodata 50048 50048 0 0.0
text 376940 376940 0 0.0
pump-app nrf52840dk_nrf52840 (read/write) 916819 916819 0 0.0
bss 117792 117792 0 0.0
rodata 104832 104832 0 0.0
text 616748 616748 0 0.0
pump-controller-app nrf52840dk_nrf52840 (read/write) 912003 912003 0 0.0
bss 117816 117816 0 0.0
rodata 103936 103936 0 0.0
text 612788 612788 0 0.0
shell nrf52840dk_nrf52840 (read/write) 798203 798319 116 0.0
bss 109776 108908 -868 -0.8
rodata 78288 78324 36 0.0
text 533640 534588 948 0.2
p6 all-clusters-app default (read/write) 2441656 2441656 0 0.0
.bss 116740 116740 0 0.0
.data 2584 2584 0 0.0
.text 1399920 1399920 0 0.0
light-app default (read/write) 2338568 2338568 0 0.0
.bss 104484 104484 0 0.0
.data 2408 2408 0 0.0
.text 1296832 1296832 0 0.0
lock-app default (read/write) 2304080 2304080 0 0.0
.bss 104228 104228 0 0.0
.data 2360 2360 0 0.0
.text 1262344 1262344 0 0.0
qpg lighting-app qpg6105+debug (read only) 570884 570884 0 0.0
(read/write) 146936 146936 0 0.0
.bss 88640 88640 0 0.0
.data 1060 1060 0 0.0
.text 565564 565564 0 0.0
lock-app qpg6105+debug (read only) 517004 517004 0 0.0
(read/write) 146940 146940 0 0.0
.bss 88112 88112 0 0.0
.data 992 992 0 0.0
.text 511684 511684 0 0.0
persistent-storage-app qpg6105+debug (read only) 107140 107140 0 0.0
(read/write) 146940 146940 0 0.0
.bss 38504 38504 0 0.0
.data 288 288 0 0.0
.text 101820 101820 0 0.0
telink lighting-app tlsr9518adk80d (read/write) 845770 846446 676 0.1
bss 86440 85964 -476 -0.6
noinit 37160 37160 0 0.0
text 592508 593628 1120 0.2

Copy link
Contributor

@andy31415 andy31415 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strncpy code is hard to ensure correctness and maintain, memory allocation and lifetime is not as clear.

please use src/lib/support/StringBuilder.h and scoped memory buffers.


public:
Engine() {}
Engine(){};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

supernit: remove the ; change here and below. There should be no ; after method implementations

if (strcmp(prefix, "") != 0)
{
strncpy(&sub_prefix[pos], prefix, strlen(prefix));
pos += strlen(prefix);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just use strcpy:

  • strncpy is not using the sub_prefix pos at all and sub_prefix size is preallocated
  • using strncpy but then advancing by strlen(prefix) will not make use of strncpy guarantees (we move up to length of prefix anyway)

{
strncpy(&sub_prefix[pos], prefix, strlen(prefix));
pos += strlen(prefix);
strncpy(&sub_prefix[pos], " ", 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strncpy with size 1 is the same like sub_prefix[pos] = ' '; right? And the assignment makes it clear that the string is no longer guaranteed to be null terminated (which strncpy above does not guarantee either). Does this need fix?

strncpy(&sub_prefix[pos], " ", 1);
pos += 1;
}
strncpy(&sub_prefix[pos], syntax, strlen(syntax) + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using strlen of the 2nd argument in strncpy negates the usefulness of strncpy. Just use strcpy to make it clear what it does and that we do not validate sizes at all.

const struct shell_static_entry * build_command_tree(const char * prefix, const char * syntax, const char * help)
{

char * sub_prefix = new char[strlen(prefix) + strlen(syntax) + 2];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ScopedMemoryBuffer here. Otherwise tracking if sub_prefix is allocated and freed correctly is hard.
Also add a guard to see if memory allocation succeeded.

memcpy((shell_static_entry *) &sub_static_entry[i], &leaf_entry, sizeof(struct shell_static_entry));
continue;
}
memcpy((shell_static_entry *) &sub_static_entry[i], sub_entry, sizeof(struct shell_static_entry));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the cast required here/above/below?

// Zephyr's shell_cmd_entry.u.entry needs an additional NULL element to terminate the array.
memset((shell_static_entry *) &sub_static_entry[context.cmdc], 0, sizeof(struct shell_static_entry));

const struct shell_cmd_entry * sub_cmd_entry =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lifetime comments for these and below.
Also explanation of why this does not use PlatformAlloc but direct new

if (buf[len - 1] == ' ')
{
trailing_space = true;
memset((char *) &buf[len - 1], 0, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a very complex way of saying buf[len-1] = 0. Please replace with simple assignment

{
// remove "matter " prefix for completion lookup as the command
// registeration in general are done without "matter" prefix
char * line = new char[len - strlen(matter_prefix) + trailing_space + 1];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use bools in integer arithmentic. Feels like "tricky code" even if it works.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use scoped buffers for line, check allocation.


// Write "matter "
size_t pos = 0;
strncpy(&cmd_completion[pos], matter_prefix, strlen(matter_prefix) + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strncpy should take the target destination as size or not take any size at all. Use strcpy if you cannot use the size of destination, since strcpy is supposed to protect against destination overflow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In hindsight after seeing all this code: you should probably be using src/lib/support/StringBuilder.h to have these append logic work and then you do not need to worry as much about pos and sizes and such.
StringBuilderBase with a ScopedBuffer for memory allocation should work well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you very much for taking time to review and the guidance, really appreciate it. Let me work on the changes to address them and will send this again later.

@lmpprk lmpprk changed the title Add cli completion ability; implement for esp and nrf [WIP Please ignore] Add cli completion ability; implement for esp and nrf Feb 1, 2022
@stale
Copy link

stale bot commented Feb 9, 2022

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale Stale issue or PR label Feb 9, 2022
@stale
Copy link

stale bot commented Feb 17, 2022

This stale pull request has been automatically closed. Thank you for your contributions.

@stale stale bot closed this Feb 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tab key doesn't trigger autocomplete for Matter-specific Zephyr CLI commands
2 participants