Patchwork [U-Boot,V4,09/11] tools: add parse_helper file

login
register
mail settings
Submitter Troy Kisky
Date Nov. 28, 2012, 1:31 a.m.
Message ID <1354066303-29762-10-git-send-email-troy.kisky@boundarydevices.com>
Download mbox | patch
Permalink /patch/202343/
State Changes Requested
Delegated to: Stefano Babic
Headers show

Comments

Troy Kisky - Nov. 28, 2012, 1:31 a.m.
This file can help you parse
configuration files.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
 tools/Makefile       |    2 +
 tools/parse_helper.c |  173 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/parse_helper.h |   28 ++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 tools/parse_helper.c
 create mode 100644 tools/parse_helper.h
Wolfgang Denk - Nov. 28, 2012, 9:41 a.m.
Dear Troy Kisky,

In message <1354066303-29762-10-git-send-email-troy.kisky@boundarydevices.com> you wrote:
> This file can help you parse
> configuration files.

If this is intended to be useful, you need to add documentation, for
example what your definition of "configuration files" is, and which
data format[s] is/are supported, etc.

As is, this cannot be reused.

Best regards,

Wolfgang Denk
Liu Hui-R64343 - Nov. 28, 2012, 10:48 a.m.
>-----Original Message-----
>From: Troy Kisky [mailto:troy.kisky@boundarydevices.com]
>Sent: Wednesday, November 28, 2012 9:32 AM
>To: sbabic@denx.de
>Cc: dirk.behme@googlemail.com; u-boot@lists.denx.de; Liu Hui-R64343;
>festevam@gmail.com; Troy Kisky
>Subject: [PATCH V4 09/11] tools: add parse_helper file
>
>This file can help you parse
>configuration files.

One line is enough. :)

>
>Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>

Acked-by: Jason Liu <r64343@freescale.com>

>---
> tools/Makefile       |    2 +
> tools/parse_helper.c |  173
>++++++++++++++++++++++++++++++++++++++++++++++++++
> tools/parse_helper.h |   28 ++++++++
> 3 files changed, 203 insertions(+)
> create mode 100644 tools/parse_helper.c  create mode 100644
>tools/parse_helper.h
>
>diff --git a/tools/Makefile b/tools/Makefile index 686840a..db3b247 100644
>--- a/tools/Makefile
>+++ b/tools/Makefile
>@@ -94,6 +94,7 @@ NOPED_OBJ_FILES-y += aisimage.o  NOPED_OBJ_FILES-y
>+= kwbimage.o  NOPED_OBJ_FILES-y += pblimage.o  NOPED_OBJ_FILES-y +=
>imximage.o
>+NOPED_OBJ_FILES-y += parse_helper.o
> NOPED_OBJ_FILES-y += omapimage.o
> NOPED_OBJ_FILES-y += mkenvimage.o
> NOPED_OBJ_FILES-y += mkimage.o
>@@ -208,6 +209,7 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \
> 			$(obj)fit_image.o \
> 			$(obj)image.o \
> 			$(obj)imximage.o \
>+			$(obj)parse_helper.o \
> 			$(obj)kwbimage.o \
> 			$(obj)pblimage.o \
> 			$(obj)md5.o \
>diff --git a/tools/parse_helper.c b/tools/parse_helper.c new file mode 100644
>index 0000000..0a5c5f6
>--- /dev/null
>+++ b/tools/parse_helper.c
>@@ -0,0 +1,173 @@
>+/*
>+ * (C) Copyright 20012  Boundary Devices Inc,
>+troy.kisky@boundarydevices.com
>+ *
>+ * Licensed under the GPL-2 or later.
>+ */
>+
>+/* Required to obtain the getline prototype from stdio.h */ #define
>+_GNU_SOURCE
>+
>+#include "mkimage.h"
>+#include <image.h>
>+#include "parse_helper.h"
>+
>+int ph_open(struct parse_helper *ph, char *filename) {
>+	ph->line = NULL;
>+	ph->len = 0;
>+	ph->fd = fopen(filename, "r");
>+	ph->lineno = 0;
>+	ph->cmd_started = 0;
>+	ph->filename = filename;
>+	ph->p = NULL;
>+	return (!ph->fd) ? -1 : 0;
>+}
>+
>+void ph_close(struct parse_helper *ph)
>+{
>+	fclose(ph->fd);
>+	ph->fd = NULL;
>+}
>+
>+int ph_skip_separators(struct parse_helper *ph) {
>+	int line_no = ph->lineno;
>+	char *p = ph->p;
>+
>+	for (;;) {
>+		char c;
>+		if (!p) {
>+			if (getline(&ph->line, &ph->len, ph->fd) <= 0)
>+				return -1;
>+			ph->lineno++;
>+			p = ph->line;
>+			if (ph->cmd_started) {
>+				fprintf(stderr, "warning: continuing command
>on"
>+						" next line, line %s[%d](%s)\n",
>+						ph->filename, ph->lineno, p);
>+			}
>+		}
>+		c = *p;
>+		if ((c == ' ') || (c == '\t')) {
>+			p++;
>+			continue;
>+		}
>+		/* Drop all text starting with '#' as comments */
>+		if ((c == '#') || (c == '\r') || (c == '\n')
>+				|| !c) {
>+			p = NULL;
>+			continue;
>+		}
>+		if (c == ';') {
>+			if (ph->cmd_started) {
>+				fprintf(stderr, "Error: command not "
>+						"finished:%s[%d](%s)\n",
>+						ph->filename, ph->lineno, p);
>+				exit(EXIT_FAILURE);
>+			}
>+			p++;
>+			continue;
>+		}
>+		if (!ph->cmd_started && line_no == ph->lineno) {
>+			fprintf(stderr, "Error: extra data at end "
>+					"of line %s[%d](%s)\n",
>+					ph->filename, ph->lineno, p);
>+			exit(EXIT_FAILURE);
>+		}
>+		ph->p = p;
>+		return 0;
>+	}
>+}
>+
>+int ph_skip_comma(struct parse_helper *ph) {
>+	char *p = ph->p;
>+
>+	for (;;) {
>+		char c = *p++;
>+		if ((c == '#') || (c == '\r') || (c == '\n') || !c)
>+			return 0;
>+		if (c == ',') {
>+			ph->p = p;
>+			ph_skip_separators(ph);
>+			return 1;
>+		}
>+		if ((c != ' ') && (c == '\t'))
>+			return 0;
>+	}
>+}
>+
>+int ph_get_value(struct parse_helper *ph, uint32_t *pval) {
>+	char *endptr;
>+	uint32_t value;
>+
>+	if (ph_skip_separators(ph))
>+		return -1;
>+	errno = 0;
>+	value = strtoul(ph->p, &endptr, 16);
>+	if (errno || (ph->p == endptr))
>+		return -1;
>+	*pval = value;
>+	ph->p = endptr;
>+	return 0;
>+}
>+
>+/*
>+ * Comma separator optional
>+ * Input:
>+ * ph - input source
>+ * data - array to fill in
>+ * cnt - exact number of elements to parse
>+ * Return: number of elements parsed, or error  */ int
>+ph_get_array(struct parse_helper *ph, uint32_t *data, int cnt) {
>+	int i = 0;
>+
>+	for (;;) {
>+		int ret = ph_get_value(ph, &data[i++]);
>+		if (ret)
>+			return ret;
>+		if (i >= cnt)
>+			break;
>+		ph_skip_comma(ph);		/* comma is optional */
>+	}
>+	return i;
>+}
>+
>+static char *grab_token(char *dest, int size, char *src) {
>+	while (size) {
>+		char c = *src;
>+		if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')
>+				|| (c == '#') || !c)
>+			break;
>+		*dest++ = c;
>+		size--;
>+		src++;
>+	}
>+	if (!size)
>+		return NULL;
>+	*dest = 0;
>+	return src;
>+}
>+
>+int ph_get_table_entry_id(struct parse_helper *ph,
>+		const table_entry_t *table, const char *table_name) {
>+	int val;
>+	char token[16];
>+	char *p;
>+
>+	if (ph_skip_separators(ph))
>+		return -1;
>+	p = grab_token(token, sizeof(token), ph->p);
>+	if (!p)
>+		return -1;
>+	val = get_table_entry_id(table, table_name, token);
>+	if (val != -1)
>+		ph->p = p;
>+	return val;
>+}
>+
>diff --git a/tools/parse_helper.h b/tools/parse_helper.h new file mode
>100644 index 0000000..1ff98a3
>--- /dev/null
>+++ b/tools/parse_helper.h
>@@ -0,0 +1,28 @@
>+/*
>+ * (C) Copyright 20012  Boundary Devices Inc,
>+troy.kisky@boundarydevices.com
>+ *
>+ * Licensed under the GPL-2 or later.
>+ */
>+
>+#ifndef _PARSE_HELPER_H_
>+#define _PARSE_HELPER_H_
>+
>+struct parse_helper {
>+	char *line;
>+	size_t len;
>+	FILE *fd;
>+	int lineno;
>+	char cmd_started;
>+	char *filename;
>+	char *p;
>+};
>+
>+int ph_open(struct parse_helper *ph, char *filename); void
>+ph_close(struct parse_helper *ph); int ph_skip_separators(struct
>+parse_helper *ph); int ph_skip_comma(struct parse_helper *ph); int
>+ph_get_value(struct parse_helper *ph, uint32_t *pval); int
>+ph_get_array(struct parse_helper *ph, uint32_t *data, int cnt); int
>+ph_get_table_entry_id(struct parse_helper *ph,
>+		const table_entry_t *table, const char *table_name); #endif
>--
>1.7.9.5
>

Patch

diff --git a/tools/Makefile b/tools/Makefile
index 686840a..db3b247 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -94,6 +94,7 @@  NOPED_OBJ_FILES-y += aisimage.o
 NOPED_OBJ_FILES-y += kwbimage.o
 NOPED_OBJ_FILES-y += pblimage.o
 NOPED_OBJ_FILES-y += imximage.o
+NOPED_OBJ_FILES-y += parse_helper.o
 NOPED_OBJ_FILES-y += omapimage.o
 NOPED_OBJ_FILES-y += mkenvimage.o
 NOPED_OBJ_FILES-y += mkimage.o
@@ -208,6 +209,7 @@  $(obj)mkimage$(SFX):	$(obj)aisimage.o \
 			$(obj)fit_image.o \
 			$(obj)image.o \
 			$(obj)imximage.o \
+			$(obj)parse_helper.o \
 			$(obj)kwbimage.o \
 			$(obj)pblimage.o \
 			$(obj)md5.o \
diff --git a/tools/parse_helper.c b/tools/parse_helper.c
new file mode 100644
index 0000000..0a5c5f6
--- /dev/null
+++ b/tools/parse_helper.c
@@ -0,0 +1,173 @@ 
+/*
+ * (C) Copyright 20012  Boundary Devices Inc, troy.kisky@boundarydevices.com
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+/* Required to obtain the getline prototype from stdio.h */
+#define _GNU_SOURCE
+
+#include "mkimage.h"
+#include <image.h>
+#include "parse_helper.h"
+
+int ph_open(struct parse_helper *ph, char *filename)
+{
+	ph->line = NULL;
+	ph->len = 0;
+	ph->fd = fopen(filename, "r");
+	ph->lineno = 0;
+	ph->cmd_started = 0;
+	ph->filename = filename;
+	ph->p = NULL;
+	return (!ph->fd) ? -1 : 0;
+}
+
+void ph_close(struct parse_helper *ph)
+{
+	fclose(ph->fd);
+	ph->fd = NULL;
+}
+
+int ph_skip_separators(struct parse_helper *ph)
+{
+	int line_no = ph->lineno;
+	char *p = ph->p;
+
+	for (;;) {
+		char c;
+		if (!p) {
+			if (getline(&ph->line, &ph->len, ph->fd) <= 0)
+				return -1;
+			ph->lineno++;
+			p = ph->line;
+			if (ph->cmd_started) {
+				fprintf(stderr, "warning: continuing command on"
+						" next line, line %s[%d](%s)\n",
+						ph->filename, ph->lineno, p);
+			}
+		}
+		c = *p;
+		if ((c == ' ') || (c == '\t')) {
+			p++;
+			continue;
+		}
+		/* Drop all text starting with '#' as comments */
+		if ((c == '#') || (c == '\r') || (c == '\n')
+				|| !c) {
+			p = NULL;
+			continue;
+		}
+		if (c == ';') {
+			if (ph->cmd_started) {
+				fprintf(stderr, "Error: command not "
+						"finished:%s[%d](%s)\n",
+						ph->filename, ph->lineno, p);
+				exit(EXIT_FAILURE);
+			}
+			p++;
+			continue;
+		}
+		if (!ph->cmd_started && line_no == ph->lineno) {
+			fprintf(stderr, "Error: extra data at end "
+					"of line %s[%d](%s)\n",
+					ph->filename, ph->lineno, p);
+			exit(EXIT_FAILURE);
+		}
+		ph->p = p;
+		return 0;
+	}
+}
+
+int ph_skip_comma(struct parse_helper *ph)
+{
+	char *p = ph->p;
+
+	for (;;) {
+		char c = *p++;
+		if ((c == '#') || (c == '\r') || (c == '\n') || !c)
+			return 0;
+		if (c == ',') {
+			ph->p = p;
+			ph_skip_separators(ph);
+			return 1;
+		}
+		if ((c != ' ') && (c == '\t'))
+			return 0;
+	}
+}
+
+int ph_get_value(struct parse_helper *ph, uint32_t *pval)
+{
+	char *endptr;
+	uint32_t value;
+
+	if (ph_skip_separators(ph))
+		return -1;
+	errno = 0;
+	value = strtoul(ph->p, &endptr, 16);
+	if (errno || (ph->p == endptr))
+		return -1;
+	*pval = value;
+	ph->p = endptr;
+	return 0;
+}
+
+/*
+ * Comma separator optional
+ * Input:
+ * ph - input source
+ * data - array to fill in
+ * cnt - exact number of elements to parse
+ * Return: number of elements parsed, or error
+ */
+int ph_get_array(struct parse_helper *ph, uint32_t *data, int cnt)
+{
+	int i = 0;
+
+	for (;;) {
+		int ret = ph_get_value(ph, &data[i++]);
+		if (ret)
+			return ret;
+		if (i >= cnt)
+			break;
+		ph_skip_comma(ph);		/* comma is optional */
+	}
+	return i;
+}
+
+static char *grab_token(char *dest, int size, char *src)
+{
+	while (size) {
+		char c = *src;
+		if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')
+				|| (c == '#') || !c)
+			break;
+		*dest++ = c;
+		size--;
+		src++;
+	}
+	if (!size)
+		return NULL;
+	*dest = 0;
+	return src;
+}
+
+int ph_get_table_entry_id(struct parse_helper *ph,
+		const table_entry_t *table, const char *table_name)
+{
+	int val;
+	char token[16];
+	char *p;
+
+	if (ph_skip_separators(ph))
+		return -1;
+	p = grab_token(token, sizeof(token), ph->p);
+	if (!p)
+		return -1;
+	val = get_table_entry_id(table, table_name, token);
+	if (val != -1)
+		ph->p = p;
+	return val;
+}
+
diff --git a/tools/parse_helper.h b/tools/parse_helper.h
new file mode 100644
index 0000000..1ff98a3
--- /dev/null
+++ b/tools/parse_helper.h
@@ -0,0 +1,28 @@ 
+/*
+ * (C) Copyright 20012  Boundary Devices Inc, troy.kisky@boundarydevices.com
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef _PARSE_HELPER_H_
+#define _PARSE_HELPER_H_
+
+struct parse_helper {
+	char *line;
+	size_t len;
+	FILE *fd;
+	int lineno;
+	char cmd_started;
+	char *filename;
+	char *p;
+};
+
+int ph_open(struct parse_helper *ph, char *filename);
+void ph_close(struct parse_helper *ph);
+int ph_skip_separators(struct parse_helper *ph);
+int ph_skip_comma(struct parse_helper *ph);
+int ph_get_value(struct parse_helper *ph, uint32_t *pval);
+int ph_get_array(struct parse_helper *ph, uint32_t *data, int cnt);
+int ph_get_table_entry_id(struct parse_helper *ph,
+		const table_entry_t *table, const char *table_name);
+#endif