This file can help you parse
configuration files.

Signed-off-by: Troy Kisky <troy.ki...@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

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.ki...@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.ki...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to