mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] commands: add 'findstr' to get string from file
@ 2014-05-20 17:27 Christoph Fritz
  2014-05-20 18:08 ` Alexander Aring
  2014-05-21 13:51 ` [PATCH] commands: add 'findstr' to get string from file Sascha Hauer
  0 siblings, 2 replies; 9+ messages in thread
From: Christoph Fritz @ 2014-05-20 17:27 UTC (permalink / raw)
  To: barebox

Command 'findstr' can be for example used to find the string
"MAC=1C:BA:8C:F3:82:BB" in file /dev/eeprom0 to set the
appropriate variable:

 $ findstr -o 4 -l 17 -t eth0.ethaddr MAC /dev/eeprom0

Usage: findstr [OPTIONS] <STRING> <FILE>
Find string in file and print it
-o <offset>     set offset of string which gets printed
-l <length>     set length of string which gets printed
-t <var>        print into variable instead of stdio

Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
 commands/Kconfig   |    7 +++
 commands/Makefile  |    1 +
 commands/findstr.c |  138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 146 insertions(+)
 create mode 100644 commands/findstr.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 3ef8860..a2f817a 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -149,6 +149,13 @@ config CMD_GLOBAL
 	help
 	  The global command allows to create global variables
 
+config CMD_FINDSTR
+	tristate
+	default n
+	prompt "findstr"
+	help
+	  Find string in file.
+
 endmenu
 
 menu "file commands"
diff --git a/commands/Makefile b/commands/Makefile
index f927d21..b7c7e31 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -97,3 +97,4 @@ obj-$(CONFIG_CMD_READF)		+= readf.o
 obj-$(CONFIG_CMD_MENUTREE)	+= menutree.o
 obj-$(CONFIG_CMD_2048)		+= 2048.o
 obj-$(CONFIG_CMD_REGULATOR)	+= regulator.o
+obj-$(CONFIG_CMD_FINDSTR)	+= findstr.o
\ No newline at end of file
diff --git a/commands/findstr.c b/commands/findstr.c
new file mode 100644
index 0000000..37cfee3
--- /dev/null
+++ b/commands/findstr.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014 Christoph Fritz <chf.fritz@googlemail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/**
+ * @file
+ * @brief Find string in file
+ */
+
+#include <common.h>
+#include <command.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <getopt.h>
+#include <environment.h>
+
+extern char *mem_rw_buf;
+
+/**
+ * @param[in] argc Argument count from command line
+ * @param[in] argv List of input arguments
+ */
+static int do_findstr(int argc, char *argv[])
+{
+	int opt, fd, r, ret = 1;
+	loff_t len = 0, offset = 0, idx = 0;
+	u_char *s, *t = NULL, *v = (u_char *)mem_rw_buf;
+	unsigned int v_idx, s_idx = 0;
+
+	if (argc < 2)
+		return COMMAND_ERROR_USAGE;
+
+	while ((opt = getopt(argc, argv, "o:l:t:")) > 0) {
+		switch (opt) {
+		case 'o':
+			offset = simple_strtoul(optarg, NULL, 0);
+			break;
+		case 'l':
+			len = simple_strtoul(optarg, NULL, 0);
+			break;
+		case 't':
+			t = optarg;
+			break;
+		}
+	}
+
+	if (argc - optind != 2)
+		return COMMAND_ERROR_USAGE;
+
+	s = argv[optind];
+
+	fd = open(argv[optind+1], O_RDONLY);
+	if (fd < 0)
+		return COMMAND_ERROR_USAGE;
+
+	while (1) {
+		r = read(fd, mem_rw_buf, RW_BUF_SIZE);
+		if (r < 0) {
+			ret = -EIO;
+			goto out;
+		}
+		if (!r)
+			break;
+
+		v_idx = 0;
+
+		while (r) {
+			if (v[v_idx] == s[s_idx])
+				s_idx++;
+			else
+				s_idx = 0;
+
+			idx++;
+			v_idx++;
+
+			if (s_idx == strlen(s)) {	/* found */
+				loff_t sz;
+				loff_t hit = idx - strlen(s);
+
+				if (lseek(fd, hit + offset, SEEK_SET) < 0) {
+					ret = -EIO;
+					goto out;
+				}
+
+				if (!len)
+					len = strlen(s);
+				sz = min_t(loff_t, len, RW_BUF_SIZE - 1);
+				r = read(fd, mem_rw_buf, sz);
+				if (r != sz) {
+					ret = -EIO;
+					goto out;
+				}
+
+				v[sz] = '\0';
+
+				if (t)
+					setenv(t, v);
+				else
+					printf("%s\n", v);
+
+				ret = 0;
+				goto out;
+			}
+			r--;
+		}
+	}
+out:
+	close(fd);
+	return ret;
+}
+
+BAREBOX_CMD_HELP_START(findstr)
+BAREBOX_CMD_HELP_USAGE("findstr [OPTIONS] <STRING> <FILE>\n")
+BAREBOX_CMD_HELP_SHORT("Find string in file and print it\n")
+BAREBOX_CMD_HELP_OPT("-o <offset>", "set offset of string which gets printed\n")
+BAREBOX_CMD_HELP_OPT("-l <length>", "set length of string which gets printed\n")
+BAREBOX_CMD_HELP_OPT("-t <var>", "print into variable instead of stdio\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(findstr)
+	.cmd		= do_findstr,
+	.usage		= "findstr [OPTIONS] <STRING> <FILE>",
+	BAREBOX_CMD_HELP(cmd_findstr_help)
+BAREBOX_CMD_END
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] commands: add 'findstr' to get string from file
  2014-05-20 17:27 [PATCH] commands: add 'findstr' to get string from file Christoph Fritz
@ 2014-05-20 18:08 ` Alexander Aring
  2014-05-20 20:29   ` Christoph Fritz
  2014-05-21 13:51 ` [PATCH] commands: add 'findstr' to get string from file Sascha Hauer
  1 sibling, 1 reply; 9+ messages in thread
From: Alexander Aring @ 2014-05-20 18:08 UTC (permalink / raw)
  To: Christoph Fritz; +Cc: barebox

On Tue, May 20, 2014 at 07:27:55PM +0200, Christoph Fritz wrote:
> Command 'findstr' can be for example used to find the string
> "MAC=1C:BA:8C:F3:82:BB" in file /dev/eeprom0 to set the
> appropriate variable:
> 
>  $ findstr -o 4 -l 17 -t eth0.ethaddr MAC /dev/eeprom0
> 
> Usage: findstr [OPTIONS] <STRING> <FILE>
> Find string in file and print it
> -o <offset>     set offset of string which gets printed
> -l <length>     set length of string which gets printed
> -t <var>        print into variable instead of stdio
> 
> Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
> ---
>  commands/Kconfig   |    7 +++
>  commands/Makefile  |    1 +
>  commands/findstr.c |  138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 146 insertions(+)
>  create mode 100644 commands/findstr.c
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 3ef8860..a2f817a 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -149,6 +149,13 @@ config CMD_GLOBAL
>  	help
>  	  The global command allows to create global variables
>  
> +config CMD_FINDSTR
> +	tristate
> +	default n
not needed.

> +	prompt "findstr"
> +	help
> +	  Find string in file.
> +
>  endmenu
>  
>  menu "file commands"
> diff --git a/commands/Makefile b/commands/Makefile
> index f927d21..b7c7e31 100644
> --- a/commands/Makefile
> +++ b/commands/Makefile
> @@ -97,3 +97,4 @@ obj-$(CONFIG_CMD_READF)		+= readf.o
>  obj-$(CONFIG_CMD_MENUTREE)	+= menutree.o
>  obj-$(CONFIG_CMD_2048)		+= 2048.o
>  obj-$(CONFIG_CMD_REGULATOR)	+= regulator.o
> +obj-$(CONFIG_CMD_FINDSTR)	+= findstr.o
> \ No newline at end of file
> diff --git a/commands/findstr.c b/commands/findstr.c
> new file mode 100644
> index 0000000..37cfee3
> --- /dev/null
> +++ b/commands/findstr.c
> @@ -0,0 +1,138 @@
> +/*
> + * Copyright (c) 2014 Christoph Fritz <chf.fritz@googlemail.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +/**
> + * @file
> + * @brief Find string in file
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <fs.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +#include <getopt.h>
> +#include <environment.h>
> +
> +extern char *mem_rw_buf;
> +
> +/**
> + * @param[in] argc Argument count from command line
> + * @param[in] argv List of input arguments
> + */
> +static int do_findstr(int argc, char *argv[])
> +{
> +	int opt, fd, r, ret = 1;
> +	loff_t len = 0, offset = 0, idx = 0;
> +	u_char *s, *t = NULL, *v = (u_char *)mem_rw_buf;
> +	unsigned int v_idx, s_idx = 0;
> +
> +	if (argc < 2)
> +		return COMMAND_ERROR_USAGE;
> +
> +	while ((opt = getopt(argc, argv, "o:l:t:")) > 0) {
> +		switch (opt) {
> +		case 'o':
> +			offset = simple_strtoul(optarg, NULL, 0);
> +			break;
> +		case 'l':
> +			len = simple_strtoul(optarg, NULL, 0);
> +			break;
> +		case 't':
> +			t = optarg;
> +			break;
> +		}

switch case without default branch can occur compiler warnings.

You should return COMMAND_ERROR_USAGE in the default branch if non valid
parameter is given.

> +	}
> +
> +	if (argc - optind != 2)
> +		return COMMAND_ERROR_USAGE;
> +
> +	s = argv[optind];
> +
> +	fd = open(argv[optind+1], O_RDONLY);
> +	if (fd < 0)
> +		return COMMAND_ERROR_USAGE;
> +
> +	while (1) {
> +		r = read(fd, mem_rw_buf, RW_BUF_SIZE);
> +		if (r < 0) {
> +			ret = -EIO;
> +			goto out;
> +		}
> +		if (!r)
> +			break;
> +
> +		v_idx = 0;
> +
> +		while (r) {
> +			if (v[v_idx] == s[s_idx])
> +				s_idx++;
> +			else
> +				s_idx = 0;
> +
> +			idx++;
> +			v_idx++;
> +
> +			if (s_idx == strlen(s)) {	/* found */
> +				loff_t sz;
> +				loff_t hit = idx - strlen(s);
> +
> +				if (lseek(fd, hit + offset, SEEK_SET) < 0) {
> +					ret = -EIO;
> +					goto out;
> +				}
> +
> +				if (!len)
> +					len = strlen(s);
> +				sz = min_t(loff_t, len, RW_BUF_SIZE - 1);
> +				r = read(fd, mem_rw_buf, sz);
> +				if (r != sz) {
> +					ret = -EIO;
> +					goto out;
> +				}
> +
> +				v[sz] = '\0';
> +
> +				if (t)
> +					setenv(t, v);
> +				else
> +					printf("%s\n", v);
> +
> +				ret = 0;
> +				goto out;
> +			}
> +			r--;
> +		}

Why not use read_file and the awesome string function strstr and then
write the file back.

- Alex

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] commands: add 'findstr' to get string from file
  2014-05-20 18:08 ` Alexander Aring
@ 2014-05-20 20:29   ` Christoph Fritz
  2014-05-21  3:44     ` Alexander Aring
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Fritz @ 2014-05-20 20:29 UTC (permalink / raw)
  To: Alexander Aring; +Cc: barebox

Hi Alexander

On Tue, 2014-05-20 at 20:08 +0200, Alexander Aring wrote:
> On Tue, May 20, 2014 at 07:27:55PM +0200, Christoph Fritz wrote:

> > +config CMD_FINDSTR
> > +	tristate
> > +	default n
> not needed.

Ok

> > +	while ((opt = getopt(argc, argv, "o:l:t:")) > 0) {
> > +		switch (opt) {
> > +		case 'o':
> > +			offset = simple_strtoul(optarg, NULL, 0);
> > +			break;
> > +		case 'l':
> > +			len = simple_strtoul(optarg, NULL, 0);
> > +			break;
> > +		case 't':
> > +			t = optarg;
> > +			break;
> > +		}
> 
> switch case without default branch can occur compiler warnings.
> 
> You should return COMMAND_ERROR_USAGE in the default branch if non valid
> parameter is given.

Ok

> > +	fd = open(argv[optind+1], O_RDONLY);
> > +	if (fd < 0)
> > +		return COMMAND_ERROR_USAGE;
> > +
> > +	while (1) {
> > +		r = read(fd, mem_rw_buf, RW_BUF_SIZE);
> > +		if (r < 0) {
> > +			ret = -EIO;
> > +			goto out;
> > +		}
> > +		if (!r)
> > +			break;
> > +
> > +		v_idx = 0;
> > +
> > +		while (r) {
> > +			if (v[v_idx] == s[s_idx])
> > +				s_idx++;
> > +			else
> > +				s_idx = 0;
> > +
> > +			idx++;
> > +			v_idx++;
> > +
> > +			if (s_idx == strlen(s)) {	/* found */
> > +				loff_t sz;
> > +				loff_t hit = idx - strlen(s);
> > +
> > +				if (lseek(fd, hit + offset, SEEK_SET) < 0) {
> > +					ret = -EIO;
> > +					goto out;
> > +				}
> > +
> > +				if (!len)
> > +					len = strlen(s);
> > +				sz = min_t(loff_t, len, RW_BUF_SIZE - 1);
> > +				r = read(fd, mem_rw_buf, sz);
> > +				if (r != sz) {
> > +					ret = -EIO;
> > +					goto out;
> > +				}
> > +
> > +				v[sz] = '\0';
> > +
> > +				if (t)
> > +					setenv(t, v);
> > +				else
> > +					printf("%s\n", v);
> > +
> > +				ret = 0;
> > +				goto out;
> > +			}
> > +			r--;
> > +		}
> 
> Why not use read_file and the awesome string function strstr and then
> write the file back.

read_file() reads the whole file which can get pretty slow over an i2c
link accessing an eeprom which mostly holds the configuration-string at
the beginning.

Why would I want to write the file back?

 Thanks
  -- Christoph


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] commands: add 'findstr' to get string from file
  2014-05-20 20:29   ` Christoph Fritz
@ 2014-05-21  3:44     ` Alexander Aring
  2014-05-21  8:02       ` [PATCH v2] commands: add 'findstr' to search file for string Christoph Fritz
  0 siblings, 1 reply; 9+ messages in thread
From: Alexander Aring @ 2014-05-21  3:44 UTC (permalink / raw)
  To: Christoph Fritz; +Cc: barebox

On Tue, May 20, 2014 at 10:29:20PM +0200, Christoph Fritz wrote:
> Hi Alexander
> 
> On Tue, 2014-05-20 at 20:08 +0200, Alexander Aring wrote:
> > On Tue, May 20, 2014 at 07:27:55PM +0200, Christoph Fritz wrote:
> 
> > > +config CMD_FINDSTR
> > > +	tristate
> > > +	default n
> > not needed.
> 
> Ok
> 
> > > +	while ((opt = getopt(argc, argv, "o:l:t:")) > 0) {
> > > +		switch (opt) {
> > > +		case 'o':
> > > +			offset = simple_strtoul(optarg, NULL, 0);
> > > +			break;
> > > +		case 'l':
> > > +			len = simple_strtoul(optarg, NULL, 0);
> > > +			break;
> > > +		case 't':
> > > +			t = optarg;
> > > +			break;
> > > +		}
> > 
> > switch case without default branch can occur compiler warnings.
> > 
> > You should return COMMAND_ERROR_USAGE in the default branch if non valid
> > parameter is given.
> 
> Ok
> 
> > > +	fd = open(argv[optind+1], O_RDONLY);
> > > +	if (fd < 0)
> > > +		return COMMAND_ERROR_USAGE;
> > > +
> > > +	while (1) {
> > > +		r = read(fd, mem_rw_buf, RW_BUF_SIZE);
> > > +		if (r < 0) {
> > > +			ret = -EIO;
> > > +			goto out;
> > > +		}
> > > +		if (!r)
> > > +			break;
> > > +
> > > +		v_idx = 0;
> > > +
> > > +		while (r) {
> > > +			if (v[v_idx] == s[s_idx])
> > > +				s_idx++;
> > > +			else
> > > +				s_idx = 0;
> > > +
> > > +			idx++;
> > > +			v_idx++;
> > > +
> > > +			if (s_idx == strlen(s)) {	/* found */
> > > +				loff_t sz;
> > > +				loff_t hit = idx - strlen(s);
> > > +
> > > +				if (lseek(fd, hit + offset, SEEK_SET) < 0) {
> > > +					ret = -EIO;
> > > +					goto out;
> > > +				}
> > > +
> > > +				if (!len)
> > > +					len = strlen(s);
> > > +				sz = min_t(loff_t, len, RW_BUF_SIZE - 1);
> > > +				r = read(fd, mem_rw_buf, sz);
> > > +				if (r != sz) {
> > > +					ret = -EIO;
> > > +					goto out;
> > > +				}
> > > +
> > > +				v[sz] = '\0';
> > > +
> > > +				if (t)
> > > +					setenv(t, v);
> > > +				else
> > > +					printf("%s\n", v);
> > > +
> > > +				ret = 0;
> > > +				goto out;
> > > +			}
> > > +			r--;
> > > +		}
> > 
> > Why not use read_file and the awesome string function strstr and then
> > write the file back.
> 
> read_file() reads the whole file which can get pretty slow over an i2c
> link accessing an eeprom which mostly holds the configuration-string at
> the beginning.
> 
> Why would I want to write the file back?
> 

Oh, thought you do that to manipulate the MAC configuration...
Yea, this could be slow and of course on big files like /dev/mem but
this would be more a pebcak related problem like somebody will do a
"edit /dev/mem", which should not work because edit use read_file.

Are you sure that the command also works if the searched string is
overlapped in two areas of RW_BUF_SIZE? I don't see that in the current
implementation.

You also assume here that the content is ascii based. Maybe you should
write that in the command description.

This handling would be much easier with a proper eeprom
configurationlayout with a static offset for each setting.

- Alex

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] commands: add 'findstr' to search file for string
  2014-05-21  3:44     ` Alexander Aring
@ 2014-05-21  8:02       ` Christoph Fritz
  2014-05-21  9:22         ` Antony Pavlov
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Fritz @ 2014-05-21  8:02 UTC (permalink / raw)
  To: barebox

Command 'findstr' can be for example used to find string
"MAC=1C:BA:8C:F3:82:BB" in file /dev/eeprom0 to set an
appropriate environment variable:

 $ findstr -o 16 -l 17 -t eth0.ethaddr pcm051_eth0_MAC= /dev/eeprom0

Usage: findstr [OPTIONS] <STRING> <FILE>
Find ASCII string in file and print it
-o <offset>     set offset of string which gets printed
-l <length>     set length of string which gets printed
-t <var>        print into variable instead of stdio

Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
---
Changes in v2:
 - fix Kconfig: 'default n' is default
 - add default branch to switch
 - fix search string read-buffer overlap
---
 commands/Kconfig   |    6 +++
 commands/Makefile  |    1 +
 commands/findstr.c |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 commands/findstr.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 3ef8860..a795da9 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -149,6 +149,12 @@ config CMD_GLOBAL
 	help
 	  The global command allows to create global variables
 
+config CMD_FINDSTR
+	tristate
+	prompt "findstr"
+	help
+	  Find ASCII string in file.
+
 endmenu
 
 menu "file commands"
diff --git a/commands/Makefile b/commands/Makefile
index f927d21..580b137 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -97,3 +97,4 @@ obj-$(CONFIG_CMD_READF)		+= readf.o
 obj-$(CONFIG_CMD_MENUTREE)	+= menutree.o
 obj-$(CONFIG_CMD_2048)		+= 2048.o
 obj-$(CONFIG_CMD_REGULATOR)	+= regulator.o
+obj-$(CONFIG_CMD_FINDSTR)	+= findstr.o
diff --git a/commands/findstr.c b/commands/findstr.c
new file mode 100644
index 0000000..934c300
--- /dev/null
+++ b/commands/findstr.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2014 Christoph Fritz <chf.fritz@googlemail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/**
+ * @file
+ * @brief Find string in file
+ */
+
+#include <common.h>
+#include <command.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <getopt.h>
+#include <environment.h>
+
+#define FINDSTR_BUF_SIZE	RW_BUF_SIZE
+
+extern char *mem_rw_buf;
+
+/**
+ * @param[in] argc Argument count from command line
+ * @param[in] argv List of input arguments
+ */
+static int do_findstr(int argc, char *argv[])
+{
+	int opt, fd, r, ret = 1;
+	loff_t len = 0, offset = 0, idx = 0;
+	u_char *s, *t = NULL, *v = (u_char *)mem_rw_buf;
+	unsigned int v_idx, s_idx = 0;
+
+	if (argc < 2)
+		return COMMAND_ERROR_USAGE;
+
+	while ((opt = getopt(argc, argv, "o:l:t:")) > 0) {
+		switch (opt) {
+		case 'o':
+			offset = simple_strtoul(optarg, NULL, 0);
+			break;
+		case 'l':
+			len = simple_strtoul(optarg, NULL, 0);
+			break;
+		case 't':
+			t = optarg;
+			break;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	if (argc - optind != 2)
+		return COMMAND_ERROR_USAGE;
+
+	s = argv[optind];
+
+	fd = open(argv[optind+1], O_RDONLY);
+	if (fd < 0)
+		return COMMAND_ERROR_USAGE;
+
+	while (1) {
+		r = read(fd, mem_rw_buf, FINDSTR_BUF_SIZE);
+		if (r < 0) {
+			ret = -EIO;
+			goto out;
+		}
+		if (!r)
+			break;
+
+		v_idx = 0;
+
+		while (r) {
+			if (v[v_idx] == s[s_idx])
+				s_idx++;
+			else
+				s_idx = 0;
+
+			idx++;
+			v_idx++;
+
+			if (s_idx == strlen(s)) {	/* found */
+				loff_t hit = idx - strlen(s);
+
+				if (lseek(fd, hit + offset, SEEK_SET) < 0) {
+					ret = -EIO;
+					goto out;
+				}
+
+				if (!len)
+					len = strlen(s);
+				r = read(fd, mem_rw_buf, len);
+				if (r != len) {
+					ret = -EIO;
+					goto out;
+				}
+
+				v[r] = '\0';
+
+				if (t)
+					setenv(t, v);
+				else
+					printf("%s\n", v);
+
+				ret = 0;
+				goto out;
+			}
+			r--;
+		}
+	}
+out:
+	close(fd);
+	return ret;
+}
+
+BAREBOX_CMD_HELP_START(findstr)
+BAREBOX_CMD_HELP_USAGE("findstr [OPTIONS] <STRING> <FILE>\n")
+BAREBOX_CMD_HELP_SHORT("Find ASCII string in file and print it\n")
+BAREBOX_CMD_HELP_OPT("-o <offset>", "set offset of string which gets printed\n")
+BAREBOX_CMD_HELP_OPT("-l <length>", "set length of string which gets printed\n")
+BAREBOX_CMD_HELP_OPT("-t <var>", "print into variable instead of stdio\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(findstr)
+	.cmd		= do_findstr,
+	.usage		= "findstr [OPTIONS] <STRING> <FILE>",
+	BAREBOX_CMD_HELP(cmd_findstr_help)
+BAREBOX_CMD_END
-- 
1.7.10.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] commands: add 'findstr' to search file for string
  2014-05-21  8:02       ` [PATCH v2] commands: add 'findstr' to search file for string Christoph Fritz
@ 2014-05-21  9:22         ` Antony Pavlov
  2014-05-21  9:49           ` Christoph Fritz
  0 siblings, 1 reply; 9+ messages in thread
From: Antony Pavlov @ 2014-05-21  9:22 UTC (permalink / raw)
  To: Christoph Fritz; +Cc: barebox

On Wed, 21 May 2014 10:02:42 +0200
Christoph Fritz <chf.fritz@googlemail.com> wrote:

> Command 'findstr' can be for example used to find string

We already have some commands with string.h style names:
  memcmp, memcpy, memset

Can we use 'strstr' name for your new command?

Another proposition:
 can we add <offset from file start> and <no more N characters to search> parameters?

Using these parameters you can speed up your search and use your command with /dev/mem.

> "MAC=1C:BA:8C:F3:82:BB" in file /dev/eeprom0 to set an
> appropriate environment variable:
> 
>  $ findstr -o 16 -l 17 -t eth0.ethaddr pcm051_eth0_MAC= /dev/eeprom0
> 
> Usage: findstr [OPTIONS] <STRING> <FILE>
> Find ASCII string in file and print it
> -o <offset>     set offset of string which gets printed
> -l <length>     set length of string which gets printed
> -t <var>        print into variable instead of stdio
> 
> Signed-off-by: Christoph Fritz <chf.fritz@googlemail.com>
> ---
> Changes in v2:
>  - fix Kconfig: 'default n' is default
>  - add default branch to switch
>  - fix search string read-buffer overlap
> ---
>  commands/Kconfig   |    6 +++
>  commands/Makefile  |    1 +
>  commands/findstr.c |  140 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 147 insertions(+)
>  create mode 100644 commands/findstr.c
> 
> diff --git a/commands/Kconfig b/commands/Kconfig
> index 3ef8860..a795da9 100644
> --- a/commands/Kconfig
> +++ b/commands/Kconfig
> @@ -149,6 +149,12 @@ config CMD_GLOBAL
>  	help
>  	  The global command allows to create global variables
>  
> +config CMD_FINDSTR
> +	tristate
> +	prompt "findstr"
> +	help
> +	  Find ASCII string in file.
> +
>  endmenu
>  
>  menu "file commands"
> diff --git a/commands/Makefile b/commands/Makefile
> index f927d21..580b137 100644
> --- a/commands/Makefile
> +++ b/commands/Makefile
> @@ -97,3 +97,4 @@ obj-$(CONFIG_CMD_READF)		+= readf.o
>  obj-$(CONFIG_CMD_MENUTREE)	+= menutree.o
>  obj-$(CONFIG_CMD_2048)		+= 2048.o
>  obj-$(CONFIG_CMD_REGULATOR)	+= regulator.o
> +obj-$(CONFIG_CMD_FINDSTR)	+= findstr.o
> diff --git a/commands/findstr.c b/commands/findstr.c
> new file mode 100644
> index 0000000..934c300
> --- /dev/null
> +++ b/commands/findstr.c
> @@ -0,0 +1,140 @@
> +/*
> + * Copyright (c) 2014 Christoph Fritz <chf.fritz@googlemail.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2
> + * as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +/**
> + * @file
> + * @brief Find string in file
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <fs.h>
> +#include <fcntl.h>
> +#include <errno.h>
> +#include <getopt.h>
> +#include <environment.h>
> +
> +#define FINDSTR_BUF_SIZE	RW_BUF_SIZE
> +
> +extern char *mem_rw_buf;
> +
> +/**
> + * @param[in] argc Argument count from command line
> + * @param[in] argv List of input arguments
> + */
> +static int do_findstr(int argc, char *argv[])
> +{
> +	int opt, fd, r, ret = 1;
> +	loff_t len = 0, offset = 0, idx = 0;
> +	u_char *s, *t = NULL, *v = (u_char *)mem_rw_buf;
> +	unsigned int v_idx, s_idx = 0;
> +
> +	if (argc < 2)
> +		return COMMAND_ERROR_USAGE;
> +
> +	while ((opt = getopt(argc, argv, "o:l:t:")) > 0) {
> +		switch (opt) {
> +		case 'o':
> +			offset = simple_strtoul(optarg, NULL, 0);
> +			break;
> +		case 'l':
> +			len = simple_strtoul(optarg, NULL, 0);
> +			break;
> +		case 't':
> +			t = optarg;
> +			break;
> +		default:
> +			return COMMAND_ERROR_USAGE;
> +		}
> +	}
> +
> +	if (argc - optind != 2)
> +		return COMMAND_ERROR_USAGE;
> +
> +	s = argv[optind];
> +
> +	fd = open(argv[optind+1], O_RDONLY);
> +	if (fd < 0)
> +		return COMMAND_ERROR_USAGE;
> +
> +	while (1) {
> +		r = read(fd, mem_rw_buf, FINDSTR_BUF_SIZE);
> +		if (r < 0) {
> +			ret = -EIO;
> +			goto out;
> +		}
> +		if (!r)
> +			break;
> +
> +		v_idx = 0;
> +
> +		while (r) {
> +			if (v[v_idx] == s[s_idx])
> +				s_idx++;
> +			else
> +				s_idx = 0;
> +
> +			idx++;
> +			v_idx++;
> +
> +			if (s_idx == strlen(s)) {	/* found */
> +				loff_t hit = idx - strlen(s);
> +
> +				if (lseek(fd, hit + offset, SEEK_SET) < 0) {
> +					ret = -EIO;
> +					goto out;
> +				}
> +
> +				if (!len)
> +					len = strlen(s);
> +				r = read(fd, mem_rw_buf, len);
> +				if (r != len) {
> +					ret = -EIO;
> +					goto out;
> +				}
> +
> +				v[r] = '\0';
> +
> +				if (t)
> +					setenv(t, v);
> +				else
> +					printf("%s\n", v);
> +
> +				ret = 0;
> +				goto out;
> +			}
> +			r--;
> +		}
> +	}
> +out:
> +	close(fd);
> +	return ret;
> +}
> +
> +BAREBOX_CMD_HELP_START(findstr)
> +BAREBOX_CMD_HELP_USAGE("findstr [OPTIONS] <STRING> <FILE>\n")
> +BAREBOX_CMD_HELP_SHORT("Find ASCII string in file and print it\n")
> +BAREBOX_CMD_HELP_OPT("-o <offset>", "set offset of string which gets printed\n")
> +BAREBOX_CMD_HELP_OPT("-l <length>", "set length of string which gets printed\n")
> +BAREBOX_CMD_HELP_OPT("-t <var>", "print into variable instead of stdio\n")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(findstr)
> +	.cmd		= do_findstr,
> +	.usage		= "findstr [OPTIONS] <STRING> <FILE>",
> +	BAREBOX_CMD_HELP(cmd_findstr_help)
> +BAREBOX_CMD_END
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox


-- 
-- 
Best regards,
  Antony Pavlov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] commands: add 'findstr' to search file for string
  2014-05-21  9:22         ` Antony Pavlov
@ 2014-05-21  9:49           ` Christoph Fritz
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Fritz @ 2014-05-21  9:49 UTC (permalink / raw)
  To: Antony Pavlov; +Cc: barebox

Hi Antony

On Wed, 2014-05-21 at 13:22 +0400, Antony Pavlov wrote:
> On Wed, 21 May 2014 10:02:42 +0200
> Christoph Fritz <chf.fritz@googlemail.com> wrote:
> 
> > Command 'findstr' can be for example used to find string
> 
> We already have some commands with string.h style names:
>   memcmp, memcpy, memset
> 
> Can we use 'strstr' name for your new command?

Sure, anyone with any objections?

> Another proposition:
>  can we add <offset from file start> and <no more N characters to
> search> parameters?
> 
> Using these parameters you can speed up your search and use your
> command with /dev/mem.

Ok, I can add this to a [PATCH v3], anyone with any objections?

> > "MAC=1C:BA:8C:F3:82:BB" in file /dev/eeprom0 to set an
> > appropriate environment variable:
> > 
> >  $ findstr -o 16 -l 17 -t eth0.ethaddr pcm051_eth0_MAC= /dev/eeprom0
> > 
> > Usage: findstr [OPTIONS] <STRING> <FILE>
> > Find ASCII string in file and print it
> > -o <offset>     set offset of string which gets printed
> > -l <length>     set length of string which gets printed
> > -t <var>        print into variable instead of stdio

 Thanks
  -- Christoph


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] commands: add 'findstr' to get string from file
  2014-05-20 17:27 [PATCH] commands: add 'findstr' to get string from file Christoph Fritz
  2014-05-20 18:08 ` Alexander Aring
@ 2014-05-21 13:51 ` Sascha Hauer
  2014-05-22  9:20   ` Christoph Fritz
  1 sibling, 1 reply; 9+ messages in thread
From: Sascha Hauer @ 2014-05-21 13:51 UTC (permalink / raw)
  To: Christoph Fritz; +Cc: barebox

Hi Christoph,

On Tue, May 20, 2014 at 07:27:55PM +0200, Christoph Fritz wrote:
> Command 'findstr' can be for example used to find the string
> "MAC=1C:BA:8C:F3:82:BB" in file /dev/eeprom0 to set the
> appropriate variable:
> 
>  $ findstr -o 4 -l 17 -t eth0.ethaddr MAC /dev/eeprom0
> 
> Usage: findstr [OPTIONS] <STRING> <FILE>
> Find string in file and print it
> -o <offset>     set offset of string which gets printed
> -l <length>     set length of string which gets printed
> -t <var>        print into variable instead of stdio

I wonder how useful such a command is. I mean normally I would
expect a MAC address to be stored in binary format and not ASCII.
Matching 'MAC' (what about the '='?) seems not very robust. What about
strings with dynamic lengths?
If the command is primarily intended for the MAC address then maybe
a more dedicated command or a piece of code called from board code
is more robust. If the command is intended as a general
eeprom-variable-store then I think it's not flexible enough.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] commands: add 'findstr' to get string from file
  2014-05-21 13:51 ` [PATCH] commands: add 'findstr' to get string from file Sascha Hauer
@ 2014-05-22  9:20   ` Christoph Fritz
  0 siblings, 0 replies; 9+ messages in thread
From: Christoph Fritz @ 2014-05-22  9:20 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: barebox

Hi Sascha

On Wed, 2014-05-21 at 15:51 +0200, Sascha Hauer wrote:
> On Tue, May 20, 2014 at 07:27:55PM +0200, Christoph Fritz wrote:
> > Command 'findstr' can be for example used to find the string
> > "MAC=1C:BA:8C:F3:82:BB" in file /dev/eeprom0 to set the
> > appropriate variable:
> > 
> >  $ findstr -o 4 -l 17 -t eth0.ethaddr MAC /dev/eeprom0
> > 
> > Usage: findstr [OPTIONS] <STRING> <FILE>
> > Find string in file and print it
> > -o <offset>     set offset of string which gets printed
> > -l <length>     set length of string which gets printed
> > -t <var>        print into variable instead of stdio
> 
> I wonder how useful such a command is. I mean normally I would
> expect a MAC address to be stored in binary format and not ASCII.

Yes, and if a user wants to set it to another value, there is variable
'ethaddr' in 'env/network/eth0' which can be changed.

The use case here I'm facing: User wants to change 'ethaddr' and store
it in eeprom instead. If the whole /dev/eeprom0 would be a
barebox-script, it could be processed, but I can't rely on.

> Matching 'MAC' (what about the '='?) seems not very robust.

From the example above, the offset is 4 and a '=' or any other char gets
bypassed.

>  What about strings with dynamic lengths?

A more robust and flexible approach I have in mind is this: Find string
xy and delimiter z in file and optionally execute what is in between as
a command. 

> If the command is primarily intended for the MAC address then maybe
> a more dedicated command or a piece of code called from board code
> is more robust.

That's what I'm already doing here, but want to get a more general
solution for all kinds of settings.

>  If the command is intended as a general
> eeprom-variable-store then I think it's not flexible enough.

What do you think about the more robust approach from above?

 Thanks
  -- Christoph


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-05-22  9:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-20 17:27 [PATCH] commands: add 'findstr' to get string from file Christoph Fritz
2014-05-20 18:08 ` Alexander Aring
2014-05-20 20:29   ` Christoph Fritz
2014-05-21  3:44     ` Alexander Aring
2014-05-21  8:02       ` [PATCH v2] commands: add 'findstr' to search file for string Christoph Fritz
2014-05-21  9:22         ` Antony Pavlov
2014-05-21  9:49           ` Christoph Fritz
2014-05-21 13:51 ` [PATCH] commands: add 'findstr' to get string from file Sascha Hauer
2014-05-22  9:20   ` Christoph Fritz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox