On Tue, Nov 22, 2022, 6:02 AM <chr...@rtems.org> wrote: > From: Chris Johns <chr...@rtems.org> > > Closes #4763 > --- > cpukit/libmisc/shell/main_edit.c | 17 +++++- > cpukit/libmisc/shell/main_help.c | 94 ++++++++++++++++++++------------ > cpukit/libmisc/shell/shell.c | 83 +++++++++++++++++++++++++++- > 3 files changed, 154 insertions(+), 40 deletions(-) > > diff --git a/cpukit/libmisc/shell/main_edit.c > b/cpukit/libmisc/shell/main_edit.c > index 4cc742719a..16c44f2a11 100644 > --- a/cpukit/libmisc/shell/main_edit.c > +++ b/cpukit/libmisc/shell/main_edit.c > @@ -755,8 +755,21 @@ static void get_console_size(struct env *env) { > env->cols = ws.ws_col; > env->lines = ws.ws_row - 1; > #elif defined(__rtems__) > - env->cols = 80; > - env->lines = 25; > + char* e; > + e = getenv("LINES"); > + if (e != NULL) { > + int lines = strtol(e, 0, 10); > + if (lines > 0) { > + env->lines = lines - 1; > + } > + } > + e = getenv("COLUMNS"); > + if (e != NULL) { > + int cols = strtol(e, 0, 10); > + if (cols > 0) { > + env->cols = cols - 1; > + } > + } >
Does this lose the default values if the environment variables are not set? #else > struct term *term = gettib()->proc->term; > env->cols = term->cols; > diff --git a/cpukit/libmisc/shell/main_help.c > b/cpukit/libmisc/shell/main_help.c > index 564bc30a9c..e6d939d08f 100644 > --- a/cpukit/libmisc/shell/main_help.c > +++ b/cpukit/libmisc/shell/main_help.c > @@ -22,23 +22,34 @@ > #include "internal.h" > #include <string.h> > > +static int rtems_shell_help_pause(int line, int lines) { > + if (lines && line >= lines - 1) { > + printf("\rPress any key to continue..."); > + (void) getchar(); > + printf("\r%*c\r", 29, ' '); > + line = 0; > + } > + return line; > +} > + > /* > * show the help for one command. > */ > static int rtems_shell_help_cmd( > - const rtems_shell_cmd_t *shell_cmd > + const rtems_shell_cmd_t *shell_cmd, int indent, int line, > + int cols, int lines > ) > { > const char * pc; > - int col,line; > + int col; > > if (!rtems_shell_can_see_cmd(shell_cmd)) { > return 0; > } > > - printf("%-12.12s - ",shell_cmd->name); > - col = 14; > - line = 1; > + printf("%-*s - ", indent, shell_cmd->name); > + indent += 3; > + col = indent; > if (shell_cmd->alias) { > printf("is an <alias> for command '%s'",shell_cmd->alias->name); > } else if (shell_cmd->usage) { > @@ -48,8 +59,10 @@ static int rtems_shell_help_cmd( > case '\r': > break; > case '\n': > - putchar('\n'); > - col = 0; > + if (*(pc + 1) != '\0') { > + putchar('\n'); > + col = 0; > + } > break; > default: > putchar(*pc); > @@ -57,19 +70,21 @@ static int rtems_shell_help_cmd( > break; > } > pc++; > - if (col>78) { /* What daring... 78?*/ > + if (col > (cols - 3)) { > if (*pc) { > putchar('\n'); > col = 0; > } > } > - if (!col && *pc) { > - printf(" "); > - col = 12;line++; > + if (col == 0 && *pc) { > + line = rtems_shell_help_pause(line + 1, lines); > + printf("%*c", indent, ' '); > + col = indent; > } > } > } > puts(""); > + line = rtems_shell_help_pause(line + 1, lines); > return line; > } > > @@ -83,15 +98,27 @@ static int rtems_shell_help( > char * argv[] > ) > { > - int col,line,lines,arg; > - char* lines_env; > + int col,line,cols,lines,arg,indent; > + char *lines_env, *cols_env; > rtems_shell_topic_t *topic; > + rtems_shell_cmd_t *shell_cmd; > > + lines = 16; > + cols = 80; > lines_env = getenv("SHELL_LINES"); > - if (lines_env) > + if (lines_env) { > lines = strtol(lines_env, 0, 0); > - else > - lines = 16; > + } else { > + lines_env = getenv("LINES"); > + if (lines_env) { > + lines = strtol(lines_env, 0, 0); > + } > + } > + > + cols_env = getenv("COLUMNS"); > + if (cols_env) { > + cols = strtol(cols_env, 0, 0); > + } > > if (argc<2) { > printf("help: The topics are\n"); > @@ -101,7 +128,7 @@ static int rtems_shell_help( > if (!col){ > col = printf(" %s",topic->topic); > } else { > - if ((col+strlen(topic->topic)+2)>78){ > + if ((col+strlen(topic->topic)+2)>(cols - 2)){ > printf("\n"); > col = printf(" %s",topic->topic); > } else { > @@ -113,18 +140,19 @@ static int rtems_shell_help( > printf("\n"); > return 1; > } > + indent = 0; > + shell_cmd = rtems_shell_first_cmd; > + while (shell_cmd) { > + size_t len = strlen(shell_cmd->name); > + if (len > indent) { > + indent = len; > + } > + shell_cmd = shell_cmd->next; > + } > line = 0; > for (arg = 1;arg<argc;arg++) { > const char *cur = argv[arg]; > - rtems_shell_cmd_t *shell_cmd; > - > - if (lines && (line > lines)) { > - printf("Press any key to continue..."); > - (void) getchar(); /* we only want to know a character was pressed */ > - printf("\n"); > - line = 0; > - } > - topic = rtems_shell_lookup_topic(cur); > + topic = rtems_shell_lookup_topic(cur); > if (topic == NULL) { > if ((shell_cmd = rtems_shell_lookup_cmd(cur)) == NULL) { > if (strcmp(cur, "all") != 0) { > @@ -132,11 +160,11 @@ static int rtems_shell_help( > "help: topic or cmd '%s' not found. Try <help> alone for a > list\n", > cur > ); > - line++; > + line = rtems_shell_help_pause(line + 1, lines); > continue; > } > } else { > - line+= rtems_shell_help_cmd(shell_cmd); > + line = rtems_shell_help_cmd(shell_cmd, indent, line, cols, lines); > continue; > } > } > @@ -144,18 +172,12 @@ static int rtems_shell_help( > line++; > shell_cmd = rtems_shell_first_cmd; > while (shell_cmd) { > - if (topic == NULL || !strcmp(topic->topic,shell_cmd->topic)) > - line+= rtems_shell_help_cmd(shell_cmd); > - if (lines && (line > lines)) { > - printf("Press any key to continue..."); > - (void) getchar(); > - printf("\n"); > - line = 0; > + if (topic == NULL || !strcmp(topic->topic,shell_cmd->topic)) { > + line = rtems_shell_help_cmd(shell_cmd, indent, line, cols, lines); > } > shell_cmd = shell_cmd->next; > } > } > - puts(""); > return 0; > } > > diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c > index 64f90be121..cd83aa56d1 100644 > --- a/cpukit/libmisc/shell/shell.c > +++ b/cpukit/libmisc/shell/shell.c > @@ -1,6 +1,6 @@ > /** > * @file > - * > + * > * @brief Instantatiate a new terminal shell. > */ > > @@ -805,6 +805,83 @@ void rtems_shell_print_env( > } > #endif > > +/* > + * Direct method to get the size of an XTERM window. > + * > + * If you do not use an XTERM the env variables are not define. > + */ > +static void rtems_shell_winsize( void ) > +{ > + const int fd = fileno(stdin); > + struct winsize ws; > + char buf[64]; > + bool ok = false; > + int lines = 0; > + int cols = 0; > + int r; > + r = ioctl(fd, TIOCGWINSZ, &ws); > + if (r == 0) { > + ok = true; > + lines = ws.ws_row; > + cols = ws.ws_col; > + } else if (isatty(fd)) { > + struct termios cterm; > + if (tcgetattr(fd, &cterm) >= 0) { > + struct termios term = cterm; > + term.c_cc[VMIN] = 0; > + term.c_cc[VTIME] = 0; > + if (tcsetattr (fd, TCSADRAIN, &term) >= 0) { > + int msec = 50; > + int len = 0; > + int i = 0; > + memset(&buf[0], 0, sizeof(buf)); > + /* > + * > https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Miscellaneous > + * > + * CSI 1 8 t > + */ > + fputs("\033[18t", stdout); > + fflush(stdout); > + while (msec-- > 0 && len < sizeof(buf)) { > + char ch[2]; > + if (read(fd, &ch[0], 1) == 1) { > + buf[len++] = ch[0]; > + msec = 50; > + } else { > + usleep(1000); > + } > + } > + while (i < len) { > + static const char resp[] = "\033[8;"; > + if (memcmp(resp, &buf[i], sizeof(resp) - 1) == 0) { > + i += sizeof(resp) - 1; > + while (i < len && buf[i] != ';') { > + lines *= 10; > + lines += buf[i++] - '0'; > + } > + cols = 0; > + ++i; > + while (i < len && buf[i] != 't') { > + cols *= 10; > + cols += buf[i++] - '0'; > + } > + } else { > + i++; > + } > + ok = true; > + } > + } > + tcsetattr (fd, TCSADRAIN, &cterm); > + } > + } > + if (ok) { > + snprintf(buf, sizeof(buf) - 1, "%d", lines); > + setenv("LINES", buf, 1); > + snprintf(buf, sizeof(buf) - 1, "%d", cols); > + setenv("COLUMNS", buf, 1); > + } > +} > + > static rtems_task rtems_shell_task(rtems_task_argument task_argument) > { > rtems_shell_env_t *shell_env = (rtems_shell_env_t*) task_argument; > @@ -984,7 +1061,9 @@ static bool shell_main_loop( > memcpy (cmd_argv, cmds[cmd], RTEMS_SHELL_CMD_SIZE); > if (!rtems_shell_make_args(cmd_argv, &argc, argv, > RTEMS_SHELL_MAXIMUM_ARGUMENTS)) { > - int exit_code = rtems_shell_execute_cmd(argv[0], argc, argv); > + int exit_code; > + rtems_shell_winsize(); > + exit_code = rtems_shell_execute_cmd(argv[0], argc, argv); > if (shell_env->exit_code != NULL) > *shell_env->exit_code = exit_code; > if (exit_code != 0 && shell_env->exit_on_error) > -- > 2.19.1 > > _______________________________________________ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel >
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel