* [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse
@ 2024-07-01 10:35 Ahmad Fatoum
2024-07-01 10:35 ` [PATCH v2 2/3] lib: strtox: implement new simple_strtofract Ahmad Fatoum
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2024-07-01 10:35 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
This function is currently only used by the sedit command, but can be
useful for other "full-screen" commands as well.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
- no change
---
commands/edit.c | 85 +++++++------------------------------------------
include/term.h | 8 +++++
lib/Makefile | 1 +
lib/term.c | 69 +++++++++++++++++++++++++++++++++++++++
4 files changed, 90 insertions(+), 73 deletions(-)
create mode 100644 include/term.h
create mode 100644 lib/term.c
diff --git a/commands/edit.c b/commands/edit.c
index dea383aae7a6..893fa0271d83 100644
--- a/commands/edit.c
+++ b/commands/edit.c
@@ -13,6 +13,7 @@
#include <xfuncs.h>
#include <linux/stat.h>
#include <console.h>
+#include <term.h>
#define TABSPACE 8
@@ -40,11 +41,6 @@ static struct line *curline; /* line where the cursor is */
static struct line *scrline; /* the first line on screen */
static int scrcol = 0; /* the first column on screen */
-static void pos(int x, int y)
-{
- printf("\x1b[%d;%dH", y + 2, x + 1);
-}
-
static char *screenline(char *line, int *pos)
{
int i, outpos = 0;
@@ -95,10 +91,10 @@ static int setpos(char *line, int position)
static void refresh_line(struct line *line, int ypos)
{
char *str = screenline(line->data, NULL) + scrcol;
- pos(0, ypos);
+ term_setpos(0, ypos);
str[screenwidth] = 0;
printf("%s\x1b[K", str);
- pos(cursx, cursy);
+ term_setpos(cursx, cursy);
}
/*
@@ -119,7 +115,7 @@ static void refresh(int full)
if (scrline->next == lastscrline) {
printf("\x1b[1T");
refresh_line(scrline, 0);
- pos(0, screenheight);
+ term_setpos(0, screenheight);
printf("%*s", screenwidth, "");
return;
}
@@ -149,7 +145,7 @@ static void refresh(int full)
i++;
while (i < screenheight) {
- pos(0, i++);
+ term_setpos(0, i++);
printf("~");
}
}
@@ -346,68 +342,11 @@ static void merge_line(struct line *line)
#define ESC "\033"
-static void getwinsize(void)
-{
- int n;
- char *endp;
- struct console_device *cdev;
- const char esc[] = ESC "7" ESC "[r" ESC "[999;999H" ESC "[6n";
- char buf[64];
-
- screenwidth = screenheight = 256;
-
- for_each_console(cdev) {
- int width, height;
- uint64_t start;
-
- if (!(cdev->f_active & CONSOLE_STDIN))
- continue;
- if (!(cdev->f_active & CONSOLE_STDOUT))
- continue;
-
- memset(buf, 0, sizeof(buf));
-
- cdev->puts(cdev, esc, sizeof(esc));
-
- n = 0;
-
- start = get_time_ns();
-
- while (1) {
- if (is_timeout(start, 100 * MSECOND))
- break;
-
- if (!cdev->tstc(cdev))
- continue;
-
- buf[n] = cdev->getc(cdev);
-
- if (buf[n] == 'R')
- break;
-
- n++;
- }
-
- if (buf[0] != 27)
- continue;
- if (buf[1] != '[')
- continue;
-
- height = simple_strtoul(buf + 2, &endp, 10);
- width = simple_strtoul(endp + 1, NULL, 10);
-
- screenwidth = min(screenwidth, width);
- screenheight = min(screenheight, height);
- }
-
- pos(0, 0);
-}
-
static void statusbar(const char *str)
{
- pos(0, screenheight+1);
+ term_setpos(0, screenheight+1);
printf("%*c\r%s", screenwidth, ' ', str);
- pos(cursx, cursy);
+ term_setpos(cursx, cursy);
}
static int read_modal_key(bool is_modal)
@@ -563,7 +502,7 @@ static int do_edit(int argc, char *argv[])
/* check if we are not called as "edit" */
if (*argv[0] != 'e') {
smartscroll = 1;
- getwinsize();
+ term_getsize(&screenwidth, &screenheight);
/* check if we are called as "vi" */
if (*argv[0] == 'v')
@@ -597,12 +536,12 @@ static int do_edit(int argc, char *argv[])
printf("\x1b[2J");
- pos(0, -1);
+ term_setpos(0, -1);
if (is_vi) {
screenheight -= 2;
printf("\x1b[7m%*c\x1b[0m", screenwidth , ' ');
- pos(0, screenheight-1);
+ term_setpos(0, screenheight-1);
printf("\x1b[7m%*c\x1b[0m", screenwidth , ' ');
printf("\r\x1b[7m%-25s\x1b[0m", argv[1]);
} else {
@@ -613,7 +552,7 @@ static int do_edit(int argc, char *argv[])
if (smartscroll)
printf("\x1b[2;%dr", screenheight);
- pos(0, 0);
+ term_setpos(0, 0);
screenheight--; /* status line */
@@ -652,7 +591,7 @@ static int do_edit(int argc, char *argv[])
lastscrcol = scrcol;
lastscrline = scrline;
- pos(cursx, cursy);
+ term_setpos(cursx, cursy);
again:
c = read_modal_key(is_vi);
diff --git a/include/term.h b/include/term.h
new file mode 100644
index 000000000000..097f84681d49
--- /dev/null
+++ b/include/term.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __TERM_H
+#define __TERM_H
+
+void term_setpos(int x, int y);
+void term_getsize(int *screenwidth, int *screenheight);
+
+#endif /* __LIBBB_H */
diff --git a/lib/Makefile b/lib/Makefile
index 54866f59cc05..0dde52527f41 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-y += bcd.o
+obj-y += term.o
obj-$(CONFIG_BOOTSTRAP) += bootstrap/
obj-pbl-y += ctype.o
obj-y += rbtree.o
diff --git a/lib/term.c b/lib/term.c
new file mode 100644
index 000000000000..64dd5e430478
--- /dev/null
+++ b/lib/term.c
@@ -0,0 +1,69 @@
+#include <console.h>
+#include <term.h>
+
+void term_setpos(int x, int y)
+{
+ printf("\x1b[%d;%dH", y + 2, x + 1);
+}
+
+void term_getsize(int *screenwidth, int *screenheight)
+{
+ int n;
+ char *endp;
+ struct console_device *cdev;
+ const char esc[] = "\e7" "\e[r" "\e[999;999H" "\e[6n";
+ char buf[64];
+
+ if (screenwidth)
+ *screenwidth = 256;
+ if (screenheight)
+ *screenheight = 256;
+
+ for_each_console(cdev) {
+ int width, height;
+ uint64_t start;
+
+ if (!(cdev->f_active & CONSOLE_STDIN))
+ continue;
+ if (!(cdev->f_active & CONSOLE_STDOUT))
+ continue;
+
+ memset(buf, 0, sizeof(buf));
+
+ cdev->puts(cdev, esc, sizeof(esc));
+
+ n = 0;
+
+ start = get_time_ns();
+
+ while (1) {
+ if (is_timeout(start, 100 * MSECOND))
+ break;
+
+ if (!cdev->tstc(cdev))
+ continue;
+
+ buf[n] = cdev->getc(cdev);
+
+ if (buf[n] == 'R')
+ break;
+
+ n++;
+ }
+
+ if (buf[0] != 27)
+ continue;
+ if (buf[1] != '[')
+ continue;
+
+ height = simple_strtoul(buf + 2, &endp, 10);
+ width = simple_strtoul(endp + 1, NULL, 10);
+
+ if (screenwidth)
+ *screenwidth = min(*screenwidth, width);
+ if (screenheight)
+ *screenheight = min(*screenheight, height);
+ }
+
+ term_setpos(0, 0);
+}
--
2.39.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 2/3] lib: strtox: implement new simple_strtofract
2024-07-01 10:35 [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse Ahmad Fatoum
@ 2024-07-01 10:35 ` Ahmad Fatoum
2024-07-01 10:35 ` [PATCH v2 3/3] commands: watch: add new command Ahmad Fatoum
2024-07-01 13:26 ` [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2024-07-01 10:35 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
We have no floating point support in barebox and no strtod. Still some
user interaction could benefit from being able to supply command
arguments or device parameters in a format with decimal points.
This new simple_strtofract() function parses a fixed point format consisting
of a 32 bit integer and 32 bit fractional part and returns it multiplied
by a division argument. e.g.
simple_strtofract("1.02", NULL, 1000) == 1020
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
- no change
---
include/linux/kernel.h | 1 +
lib/strtox.c | 57 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index cd7dac73f93a..dd108ba0abf7 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -92,6 +92,7 @@ extern unsigned long simple_strtoul(const char *,char **,unsigned int);
extern long simple_strtol(const char *,char **,unsigned int);
extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
extern long long simple_strtoll(const char *,char **,unsigned int);
+extern s64 simple_strtofract(const char *cp, char **endp, u32 division);
/* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */
#define roundup(x, y) ( \
diff --git a/lib/strtox.c b/lib/strtox.c
index 76927743a72c..5ef0f0923a9e 100644
--- a/lib/strtox.c
+++ b/lib/strtox.c
@@ -78,3 +78,60 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base)
return simple_strtoull(cp, endp, base);
}
EXPORT_SYMBOL(simple_strtoll);
+
+static unsigned int simple_strtouint(const char *cp, char **endp, unsigned int base)
+{
+ unsigned int ret;
+
+ ret = simple_strtoull(cp, endp, base);
+ if (ret != (unsigned int)ret) {
+ if (endp)
+ *endp = (char *)cp;
+ return 0;
+ }
+
+ return ret;
+}
+
+s64 simple_strtofract(const char *cp, char **endp, u32 division)
+{
+ char *end = (char *)cp;
+ s64 integer, fract, scale, result = 0;
+ int fract_len = 0, sign = 1;
+
+ switch (*cp) {
+ case '-':
+ sign = -1;
+ fallthrough;
+ case '+':
+ cp++;
+ }
+
+ if (!isdigit(*cp))
+ goto out;
+
+ integer = simple_strtouint(cp, &end, 10);
+ if (end == cp)
+ goto out;
+
+ if (*end == '.' || *end == ',') {
+ cp = end + 1;
+ fract = simple_strtouint(cp, &end, 10);
+ fract_len = end - cp;
+ }
+
+ result = integer * division;
+
+ scale = 1;
+ for (int i = 0; i < fract_len; i++)
+ scale *= 10;
+ if (fract_len > 0)
+ result += (fract * division) / scale;
+
+out:
+ if (endp)
+ *endp = end;
+
+ return sign * result;
+}
+EXPORT_SYMBOL(simple_strtofract);
--
2.39.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 3/3] commands: watch: add new command
2024-07-01 10:35 [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse Ahmad Fatoum
2024-07-01 10:35 ` [PATCH v2 2/3] lib: strtox: implement new simple_strtofract Ahmad Fatoum
@ 2024-07-01 10:35 ` Ahmad Fatoum
2024-07-01 13:26 ` [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Ahmad Fatoum @ 2024-07-01 10:35 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
For testing proper operation of IIO devices, it can be useful to monitor
changes in the reading reported by the hwmon command. This is now
possible by using `watch -n 0.5 hwmon`.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v1 -> v2:
- return success when command is interrupted (Sascha)
- free all allocated buffers on exit (Sascha)
- Print title by default (Sascha)
- Remove useless duplicate ctrlc() in outer loop condition
---
commands/Kconfig | 6 +++
commands/Makefile | 1 +
commands/watch.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 106 insertions(+)
create mode 100644 commands/watch.c
diff --git a/commands/Kconfig b/commands/Kconfig
index c9c4be67e098..5b512f1bbac7 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -2417,6 +2417,12 @@ config CMD_TIME
Note: This command depends on COMMAND being interruptible,
otherwise the timer may overrun resulting in incorrect results
+config CMD_WATCH
+ bool "watch"
+ help
+ watch is used to execute a command periodically, showing
+ output to the screen.
+
config CMD_UPTIME
bool "uptime"
help
diff --git a/commands/Makefile b/commands/Makefile
index f3e8e944a931..4ca7ba7eb609 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_CMD_WD) += wd.o
obj-$(CONFIG_CMD_LED_TRIGGER) += trigger.o
obj-$(CONFIG_CMD_USB) += usb.o
obj-$(CONFIG_CMD_TIME) += time.o
+obj-$(CONFIG_CMD_WATCH) += watch.o
obj-$(CONFIG_CMD_UPTIME) += uptime.o
obj-$(CONFIG_CMD_OFTREE) += oftree.o
obj-$(CONFIG_CMD_OF_COMPATIBLE) += of_compatible.o
diff --git a/commands/watch.c b/commands/watch.c
new file mode 100644
index 000000000000..64b59abb107d
--- /dev/null
+++ b/commands/watch.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Port of Mini watch implementation from busybox
+ *
+ * Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de>
+ * Copyrigjt (C) Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <clock.h>
+#include <linux/math64.h>
+#include <malloc.h>
+#include <getopt.h>
+#include <term.h>
+#include <rtc.h>
+
+static int do_watch(int argc , char *argv[])
+{
+ const char *period_str = "2.0";
+ u64 period_ns, start;
+ bool print_header = true;
+ int opt;
+ unsigned width, new_width;
+ char *end, *header, *cmd;
+
+ while ((opt = getopt(argc, argv, "+n:t")) > 0) {
+ switch (opt) {
+ case 'n':
+ period_str = optarg;
+ break;
+ case 't':
+ print_header = false;
+ break;
+ default:
+ return COMMAND_ERROR_USAGE;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1)
+ return COMMAND_ERROR_USAGE;
+
+ period_ns = simple_strtofract(period_str, &end, NSEC_PER_SEC);
+ if (*end)
+ return -EINVAL;
+
+ cmd = strjoin(" ", argv, argc);
+
+ width = (unsigned)-1; // make sure first time new_width != width
+ header = NULL;
+
+ while (true) {
+ /* home; clear to the end of screen */
+ printf("\e[H\e[J");
+
+ if (print_header) {
+ term_getsize(&new_width, NULL);
+ if (new_width != width) {
+ width = new_width;
+ free(header);
+ header = xasprintf("Every %ss: %-*s",
+ period_str, (int)width, cmd);
+ }
+
+ printf("%s\n\n", header);
+ }
+
+ run_command(cmd);
+
+ start = get_time_ns();
+ while (!is_timeout(start, period_ns)) {
+ if (ctrlc())
+ goto out;
+ }
+ }
+
+out:
+ free(header);
+ free(cmd);
+
+ return 0;
+}
+
+BAREBOX_CMD_HELP_START(watch)
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-n SEC", "Period (default 2)")
+BAREBOX_CMD_HELP_OPT ("-t", "Don't print header")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(watch)
+ .cmd = do_watch,
+ BAREBOX_CMD_DESC("run program periodically")
+ BAREBOX_CMD_OPTS("[-n SEC] [-t] PROG ARGS")
+ BAREBOX_CMD_GROUP(CMD_GRP_MISC)
+ BAREBOX_CMD_HELP(cmd_watch_help)
+BAREBOX_CMD_END
--
2.39.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse
2024-07-01 10:35 [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse Ahmad Fatoum
2024-07-01 10:35 ` [PATCH v2 2/3] lib: strtox: implement new simple_strtofract Ahmad Fatoum
2024-07-01 10:35 ` [PATCH v2 3/3] commands: watch: add new command Ahmad Fatoum
@ 2024-07-01 13:26 ` Sascha Hauer
2 siblings, 0 replies; 4+ messages in thread
From: Sascha Hauer @ 2024-07-01 13:26 UTC (permalink / raw)
To: barebox, Ahmad Fatoum
On Mon, 01 Jul 2024 12:35:12 +0200, Ahmad Fatoum wrote:
> This function is currently only used by the sedit command, but can be
> useful for other "full-screen" commands as well.
>
>
Applied, thanks!
[1/3] commands: edit: factor out getwinsize and export it for reuse
https://git.pengutronix.de/cgit/barebox/commit/?id=7daa9f29a85c (link may not be stable)
[2/3] lib: strtox: implement new simple_strtofract
https://git.pengutronix.de/cgit/barebox/commit/?id=8482a230cd6c (link may not be stable)
[3/3] commands: watch: add new command
https://git.pengutronix.de/cgit/barebox/commit/?id=f2598a140c00 (link may not be stable)
Best regards,
--
Sascha Hauer <s.hauer@pengutronix.de>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-07-01 13:26 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-07-01 10:35 [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse Ahmad Fatoum
2024-07-01 10:35 ` [PATCH v2 2/3] lib: strtox: implement new simple_strtofract Ahmad Fatoum
2024-07-01 10:35 ` [PATCH v2 3/3] commands: watch: add new command Ahmad Fatoum
2024-07-01 13:26 ` [PATCH v2 1/3] commands: edit: factor out getwinsize and export it for reuse Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox