Skip to content

pkg/ubasic: add support for BASIC's "shell" statement. #11349

Closed
jcarrano wants to merge 15 commits intoRIOT-OS:masterfrom
jcarrano:ubasic-with-shell-yay
Closed

pkg/ubasic: add support for BASIC's "shell" statement. #11349
jcarrano wants to merge 15 commits intoRIOT-OS:masterfrom
jcarrano:ubasic-with-shell-yay

Conversation

@jcarrano
Copy link
Contributor

@jcarrano jcarrano commented Apr 5, 2019

Contribution description

A joke can go wrong when people don't understand it, and it can wronger if they take it seriously...

This commit is based on #11319 and adds support for the "shell" statement. In BASIC, this is supposed to call a system command:

10 shell "ls $HOME"

I used "system()" to implement it. For more information regarding shell in other BASIC dialects, see:

Testing procedure

Run the test. Test case no.3 takes ages in a board (I tested samr21) so you can use the following patch to disable it (place it under pkg/ubasic/patches).
0006-remove-me-relax-test-2.patch

From 83837232900bbdd2e8827046a428ecdb0655eb3c Mon Sep 17 00:00:00 2001
From: Juan Carrano <j.carrano@fu-berlin.de>
Date: Fri, 5 Apr 2019 16:29:48 +0200
Subject: [PATCH 6/6] remove me - relax test 2

---
 tests.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests.c b/tests.c
index b4ac79a..7c0575a 100644
--- a/tests.c
+++ b/tests.c
@@ -48,8 +48,8 @@ static const char program_goto[] =
 70 end\n";
 
 static const char program_loop[] =
-"10 for i = 0 to 126\n\
-20 for j = 0 to 126\n\
+"10 for i = 0 to 1\n\
+20 for j = 0 to 1\n\
 30 for k = 0 to 10\n\
 40 let a = i * j * k\n\
 rem 45 print a, i, j, k\n\
@@ -128,7 +128,7 @@ main(void)
   assert(ubasic_get_variable(2) == 108);
 
   run(program_loop);
-  assert(ubasic_get_variable(0) == (VARIABLE_TYPE)(126 * 126 * 10));
+   /* assert(ubasic_get_variable(0) == (VARIABLE_TYPE)(126 * 126 * 10)); */
 
   run(program_shell);
 
-- 
2.21.0

Side notes.

The modifications to ubasic were unexpectedly easy. I spent most of the time figuring out how to get system() running in RIOT. One of the biggest issues I had was that at some point I added a main.c to the test application and afterwards remove it, bit the main.o was still there messing up the symbols!!!

Issues/PRs references

Depends (and extends) #11319 .

@jcarrano jcarrano added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: pkg Area: External package ports State: waiting for other PR State: The PR requires another PR to be merged first labels Apr 5, 2019
@jcarrano jcarrano requested a review from miri64 April 5, 2019 16:18
@miri64
Copy link
Member

miri64 commented Apr 5, 2019

This commit is based on #11319 and adds support for the "shell" statement. In BASIC, this is supposed to call a system command.

Can you give a ref for that? "basic shell statement" is a bit frustrating to google...

@jcarrano
Copy link
Contributor Author

jcarrano commented Apr 8, 2019

Can you give a ref for that?

Well, to be honest, I'm not very sure of what I did. There are many BASIC dialects (uBASIC being one of them), but several seem to have a shell command that takes a single string as an argument and executes it in a sub-process using the system shell.

@jcarrano
Copy link
Contributor Author

jcarrano commented Apr 8, 2019

I updated the description with reference to other dialects' shell.

@miri64
Copy link
Member

miri64 commented Apr 8, 2019 via email

Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

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

There are some dependency issues in this PR, which we should rather discuss seperately.

return 0;
}

int _echo_handler(int argc, char **argv)
Copy link
Member

Choose a reason for hiding this comment

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

This belongs into its own PR.

Copy link
Member

Choose a reason for hiding this comment

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

Also, I noticed today, that this somewhat clashes with a task in our tutorials


#ifdef MODULE_SHELL_COMMANDS
/* Provide standard system() function */
int system(const char *command)
Copy link
Member

Choose a reason for hiding this comment

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

This as well.

Also I think this rather belongs into the POSIX module and shell_commands shouldn't be a dependency.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should have its own PR. I would not put it under POSIX, since system() is C99/C89 and placing it is the easiest way to make sure system() is tied to shell_commands.

Copy link
Member

Choose a reason for hiding this comment

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

since system() is C99/C89 and placing it is the easiest way to make sure system() is tied to shell_commands.

You can have shell commands without having the module shell_commands (which provides a number of default shell commands), so I don't understand the requirement for shell_commands.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I you don't have shell_commands, then you don't have access to any command from within system(), Because you have no way for your application to communicate a custom command list:

RIOT/sys/shell/shell.c

Lines 54 to 62 in 200c465

static shell_command_handler_t find_handler(const shell_command_t *command_list, char *command)
{
const shell_command_t *command_lists[] = {
command_list,
#ifdef MODULE_SHELL_COMMANDS
_shell_command_list,
#endif
};

Nothing will break, but no commands will be available.

In 2038, when we finally get XFAs, this won't be an issue (if we survive the UNIX timestamp overflow)

Copy link
Member

Choose a reason for hiding this comment

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

I you don't have shell_commands, then you don't have access to any command from within system()

Well, that seems to be more of an issue of the current implementation. So I see it as premature to establish a dependency that in reality should not be there (I would expect e.g. system("udp …") to work if I call it with gnrc_networking.

In 2038, when we finally get XFAs, this won't be an issue (if we survive the UNIX timestamp overflow)

ztimer will handle the latter. ;-)


strncpy(tmpstring, command, len+1);

handle_input_line(_shell_command_list, tmpstring);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I should have used NULL here, since the _shell_command_list is going to be searched anyways.

Suggested change
handle_input_line(_shell_command_list, tmpstring);
handle_input_line(NULL, tmpstring);


#ifdef MODULE_SHELL_COMMANDS
/* Provide standard system() function */
int system(const char *command)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I you don't have shell_commands, then you don't have access to any command from within system(), Because you have no way for your application to communicate a custom command list:

RIOT/sys/shell/shell.c

Lines 54 to 62 in 200c465

static shell_command_handler_t find_handler(const shell_command_t *command_list, char *command)
{
const shell_command_t *command_lists[] = {
command_list,
#ifdef MODULE_SHELL_COMMANDS
_shell_command_list,
#endif
};

Nothing will break, but no commands will be available.

In 2038, when we finally get XFAs, this won't be an issue (if we survive the UNIX timestamp overflow)

@miri64
Copy link
Member

miri64 commented Apr 9, 2019

Needs rebase and split-up.

@jcarrano
Copy link
Contributor Author

@miri64 Maybe we can leave the echo commit out (i.e. not even PR it). The only reason I put it there was to be able to have at least one command to test (otherwise the only command available by default is "reboot").

The thing is, because of the way the shell works it not easy or practical to make the application specific commands available to system(). And because of how the shell is compiled, there is no [easy] way to add custom system commands without going into the shell module.

The result of all this is that it makes testing this feature harder.

@miri64
Copy link
Member

miri64 commented Jul 30, 2019

Couldn't the echo command be included via a pseudo-module? This way it is a "system" command, but still optional.

@miri64 miri64 self-assigned this Jul 30, 2019
@jcarrano
Copy link
Contributor Author

@miri64 yes, that goes along the lines of what I was proposing in #9258, which is to allow choosing which system functionality (I will try to avoid calling them "system calls" because in RIOT they are not) are provided and to allow choosing an implementation.

The first question, then, is: do we want 'system()'. I think yes because it is in the standard and because it is useful.

@miri64
Copy link
Member

miri64 commented Jul 30, 2019

The first question, then, is: do we want 'system()'. I think yes because it is in the standard and because it is useful.

I'm not against it.

@jcarrano
Copy link
Contributor Author

I'm not against it.

Then I'll make a PR just for that.

@stale
Copy link

stale bot commented Jan 31, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Jan 31, 2020
@stale stale bot closed this Mar 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: pkg Area: External package ports State: stale State: The issue / PR has no activity for >185 days State: waiting for other PR State: The PR requires another PR to be merged first 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.

2 participants