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

sys/shell: refactor readline function. #12099

Closed
wants to merge 13 commits into from

Conversation

jcarrano
Copy link
Contributor

@jcarrano jcarrano commented Aug 27, 2019

Contribution description

This makes the code of readline() clearer and shorter. It also fixes a minor artifact of the long line handling.

Previously it was not possible to recover from a long line. That is, if too many characters were sent, the line would be invalidated and pressing backspace would not fix it- the only option was to discard the line. It is now possible to bring the line back to size. Note that visual effects when deleting characters will still depend on the host's terminal.

The new code is written in a way that all writes to memory are guarded by bounds check, so an assertion was removed.

The main commit in this PR is b7294a6 .

Testing procedure

I added test vectors to tests/shell. The tests is not really testing a lot right now because the host is still line buffering.

Issues/PRs references

Depends on:

Related to: #12085 , #10994 . In a way I'm kind of rewriting the shell little by little.

The test for the line cancellation (ctrl-c) functionality was unable to
detect error because of the way pexpect matches output.

While working on the long line shell bug, a regression was about to be
introduced because of this. This commit fixes the test by directly reading from
the child process and expects an exact response.

To make the test more robust, the newline handling was changed in native,
where an extra empty line was being sent with each character.
Add a command to retrieve buffer size and then force an extremely long
line. This is failing right now because of a bug in the shell.

The terminal was changed to socat, as pyterm messes up the I/O and makes
testing impossible.
The numeric value for EOF is (-1). This caused the shell to return
the same code when EOF was encountered and when the line lenght was
exceeded. Additionally, if the line length is exceeded, the correct
behaviour is to consume the remaining characters until the end of
the line, to prevent the following line from containing (potentially
dangerous) garbage.
There was some code added to "prevent putchar from being inlined", which
supposedly enlarged the code size.

It does not seem to have any effect: both before and after the change the
size is the same:

$ BOARD=samr21-xpro make -c tests/shell all
  ......
   text	   data	    bss	    dec	    hex	filename
  10416	    140	   2612	  13168	   3370	/home/jcarrano/source/vanillaRIOT/tests/shell/bin/samr21-xpro/tests_shell.elf

It makes sense: the compiler is not _that_ dumb.
ifdefs in the middle of code reduce readability and debugability and
should be avoided.
This adds a persistent state to the shell that stores the echo configuration
and the prompt character. Both can be changed by the user with special built
in commmands

- @eon: turn echo on.
- @eon: turn echo off.
- @ps x: make x the prompt character. "@ps" (without any char) disables
  the prompt.

This is implemented in a way that does not consume any additional RAM- it
only adds some bytes to the code. A couple of bytes are stolen from the
user supplied buffer to store this new configurations.

The default state us given by the same compile time defines as before so
this change is backwards compatible.
handle_input_line can deal with empty lines, so "case 0:" is not needed.
This makes the code of `readline()` clearer and shorter. It also fixes a
minor artifact of the long line handling.

Previously it was not possible to recover from a long line. That is, if too
many characters were sent, the line would be invalidated and pressing backspace
would not fix it- the only option was to discard the line. It is now possible
to bring the line back to size. Note that visual effects when deleting characters
will still depend on the host's terminal.

The new code is written in a way that all writes to memory are guarded by
bounds check, so an assertion was removed.
It is not very correct that the readline fucntion prints the prompt.
Test erasing characters using backspace. The tests is not really testing
a lot right now because the host is still line buffering.
@jcarrano jcarrano added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Type: cleanup The issue proposes a clean-up / The PR cleans-up parts of the codebase / documentation Area: sys Area: System labels Aug 27, 2019
@jcarrano jcarrano added the State: waiting for other PR State: The PR requires another PR to be merged first label Aug 27, 2019
@HendrikVE
Copy link
Contributor

Can be closed due to #13196

@fjmolinas
Copy link
Contributor

Closing since #13196 is merged.

@fjmolinas fjmolinas closed this Jun 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: sys Area: System State: waiting for other PR State: The PR requires another PR to be merged first Type: cleanup The issue proposes a clean-up / The PR cleans-up parts of the codebase / documentation Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants