>-----Original Message-----
>From: Troy Kisky [mailto:troy.ki...@boundarydevices.com]
>Sent: Wednesday, November 28, 2012 9:32 AM
>To: sba...@denx.de
>Cc: dirk.be...@googlemail.com; u-boot@lists.denx.de; Liu Hui-R64343;
>feste...@gmail.com; Troy Kisky
>Subject: [PATCH V4 10/11] imximage: use parse_helper functions
>
>Use parse_helper functions to pulling tokens instead of pushing them.
>Remove need for switch statements to process commands.
>
>Signed-off-by: Troy Kisky <troy.ki...@boundarydevices.com>

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

>
>---
>v2: uses file parse_helper added in previous patch changed patch subject,
>was cleanup parsing
>---
> tools/imximage.c |  267 +++++++++++++++++++-----------------------------------
> tools/imximage.h |   17 ++--
> 2 files changed, 101 insertions(+), 183 deletions(-)
>
>diff --git a/tools/imximage.c b/tools/imximage.c index 2f5ee14..5147989
>100644
>--- a/tools/imximage.c
>+++ b/tools/imximage.c
>@@ -25,9 +25,6 @@
>  * MA 02111-1307 USA
>  */
>
>-/* Required to obtain the getline prototype from stdio.h */ -#define
>_GNU_SOURCE
>-
> #include "mkimage.h"
> #include <image.h>
> #include "imximage.h"
>@@ -70,21 +67,6 @@ static uint32_t g_flash_offset;
>
> static struct image_type_params imximage_params;
>
>-static uint32_t get_cfg_value(char *token, char *name,  int linenr) -{
>-      char *endptr;
>-      uint32_t value;
>-
>-      errno = 0;
>-      value = strtoul(token, &endptr, 16);
>-      if (errno || (token == endptr)) {
>-              fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n",
>-                      name,  linenr, token);
>-              exit(EXIT_FAILURE);
>-      }
>-      return value;
>-}
>-
> static uint32_t detect_imximage_version(struct imx_header *imx_hdr)  {
>       imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; @@ -112,53
>+94,36 @@ static void err_imximage_version(int version)
>       exit(EXIT_FAILURE);
> }
>
>-static void set_dcd_val_v1(struct data_src *ds, char *name, int lineno,
>-                                      int fld, uint32_t value)
>+static int set_dcd_val_v1(struct data_src *ds, uint32_t *data)
> {
>       dcd_v1_t *dcd_v1 = &ds->imxhdr->header.hdr_v1.dcd_table;
>+      uint32_t val = *data++;
>
>-      switch (fld) {
>-      case CFG_REG_SIZE:
>-              /* Byte, halfword, word */
>-              if ((value != 1) && (value != 2) && (value != 4)) {
>-                      fprintf(stderr, "Error: %s[%d] - "
>-                              "Invalid register size " "(%d)\n",
>-                              name, lineno, value);
>-                      exit(EXIT_FAILURE);
>-              }
>-              *ds->p_entry++ = value;
>-              break;
>-      case CFG_REG_ADDRESS:
>-              *ds->p_entry++ = value;
>-              break;
>-      case CFG_REG_VALUE:
>-              *ds->p_entry++ = value;
>-              dcd_v1->preamble.length = (char *)ds->p_entry
>-                              - (char *)&dcd_v1->addr_data[0].type;
>-              break;
>-      default:
>-              break;
>-
>+      /* Byte, halfword, word */
>+      if ((val != 1) && (val != 2) && (val != 4)) {
>+              fprintf(stderr, "Error: Invalid register size (%d)\n", val);
>+              return -1;
>       }
>+      *ds->p_entry++ = val;
>+      *ds->p_entry++ = *data++;
>+      *ds->p_entry++ = *data++;
>+      dcd_v1->preamble.length = (char *)ds->p_entry - (char *)&dcd_v1->
>+                      addr_data[0].type;
>+      return 0;
> }
>
>-static void set_dcd_val_v2(struct data_src *ds, char *name, int lineno,
>-                                      int fld, uint32_t value)
>+static int set_dcd_val_v2(struct data_src *ds, uint32_t *data)
> {
>       uint32_t len;
>       dcd_v2_t *dcd_v2 = &ds->imxhdr->header.hdr_v2.dcd_table;
>+      uint32_t val = *data++;
>
>-      switch (fld) {
>-      case CFG_REG_SIZE:
>-              /* Byte, halfword, word */
>-              if ((value != 1) && (value != 2) && (value != 4)) {
>-                      fprintf(stderr, "Error: %s[%d] - "
>-                              "Invalid register size " "(%d)\n",
>-                              name, lineno, value);
>-                      exit(EXIT_FAILURE);
>-              }
>-              if (ds->p_dcd && (ds->p_dcd->param == value))
>-                      break;
>+      /* Byte, halfword, word */
>+      if ((val != 1) && (val != 2) && (val != 4)) {
>+              fprintf(stderr, "Error: Invalid register size (%d)\n", val);
>+              return -1;
>+      }
>+      if (!(ds->p_dcd && (ds->p_dcd->param == val))) {
>               if (!ds->p_dcd) {
>                       dcd_v2->header.tag = DCD_HEADER_TAG;
>                       dcd_v2->header.version = DCD_VERSION; @@ -166,24
>+131,19 @@ static void set_dcd_val_v2(struct data_src *ds, char *name, int
>lineno,
>               } else {
>                       ds->p_dcd = (write_dcd_command_t *)ds->p_entry;
>               }
>-              ds->p_dcd->param = value;
>+              ds->p_dcd->param = val;
>               ds->p_dcd->tag = DCD_COMMAND_TAG;
>               ds->p_entry = (uint32_t *)(ds->p_dcd + 1);
>-              break;
>-      case CFG_REG_ADDRESS:
>-              *ds->p_entry++ = cpu_to_be32(value);
>-              break;
>-      case CFG_REG_VALUE:
>-              *ds->p_entry++ = cpu_to_be32(value);
>-              len = (char *)ds->p_entry - (char *)&dcd_v2->header;
>-              dcd_v2->header.length = cpu_to_be16(len);
>-              len = (char *)ds->p_entry - (char *)ds->p_dcd;
>-              ds->p_dcd->length = cpu_to_be16(len);
>-              break;
>-      default:
>-              break;
>-
>       }
>+      val = *data++;
>+      *ds->p_entry++ = cpu_to_be32(val);
>+      val = *data++;
>+      *ds->p_entry++ = cpu_to_be32(val);
>+      len = (char *)ds->p_entry - (char *)&dcd_v2->header;
>+      dcd_v2->header.length = cpu_to_be16(len);
>+      len = (char *)ds->p_entry - (char *)ds->p_dcd;
>+      ds->p_dcd->length = cpu_to_be16(len);
>+      return 0;
> }
>
> static int set_imx_hdr_v1(struct data_src *ds, @@ -323,95 +283,71 @@
>static void print_hdr_v2(struct imx_header *imx_hdr)
>       printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);  }
>
>-static void parse_cfg_cmd(struct data_src *ds, int32_t cmd, char *token,
>-                              char *name, int lineno, int fld)
>+static int parse_cmd_data(struct data_src *ds) {
>+      uint32_t data[3];
>+      int ret = ph_get_array(&ds->ph, data, 3);
>+
>+      if (ret < 0)
>+              return ret;
>+      ret = (*ds->set_dcd_val)(ds, data);
>+      if (ret)
>+              return ret;
>+      if (ds->p_entry > ds->p_max_dcd) {
>+              uint32_t size = (char *)ds->p_max_dcd - (char *)ds->imxhdr;
>+              fprintf(stderr, "Error: header exceeds maximum size(%d)\n",
>+                              size);
>+              return -1;
>+      }
>+      return 0;
>+}
>+
>+static int parse_image_version(struct data_src *ds)
> {
>-      int value;
>-      static int cmd_ver_first = ~0;
>+      int ret;
>       uint32_t imximage_version;
>
>-      switch (cmd) {
>-      case CMD_IMAGE_VERSION:
>-              imximage_version = get_cfg_value(token, name, lineno);
>-              if (cmd_ver_first == 0) {
>-                      fprintf(stderr, "Error: %s[%d] - IMAGE_VERSION "
>-                              "command need be the first before other "
>-                              "valid command in the file\n", name, lineno);
>-                      exit(EXIT_FAILURE);
>-              }
>-              cmd_ver_first = 1;
>-              set_hdr_func(ds, imximage_version);
>-              break;
>-      case CMD_BOOT_FROM:
>-              g_flash_offset = get_table_entry_id(imximage_bootops,
>-                                      "imximage boot option", token);
>-              if (g_flash_offset == -1) {
>-                      fprintf(stderr, "Error: %s[%d] -Invalid boot device"
>-                              "(%s)\n", name, lineno, token);
>-                      exit(EXIT_FAILURE);
>-              }
>-              if (unlikely(cmd_ver_first != 1))
>-                      cmd_ver_first = 0;
>-              break;
>-      case CMD_DATA:
>-              value = get_cfg_value(token, name, lineno);
>-              (*ds->set_dcd_val)(ds, name, lineno, fld, value);
>-              if (unlikely(cmd_ver_first != 1))
>-                      cmd_ver_first = 0;
>-              break;
>+      ret = ph_get_value(&ds->ph, &imximage_version);
>+      if (ret)
>+              return ret;
>+      if (ds->cmd_cnt) {
>+              fprintf(stderr, "Error: IMAGE_VERSION command needs be "
>+                              "before other valid commands in the file\n");
>+              return -1;
>       }
>+      set_hdr_func(ds, imximage_version);
>+      return 0;
> }
>
>-static void parse_cfg_fld(struct data_src *ds, int32_t *cmd,
>-              char *token, char *name, int lineno, int fld)
>+static int parse_boot_from(struct data_src *ds)
> {
>-      int value;
>-
>-      switch (fld) {
>-      case CFG_COMMAND:
>-              *cmd = get_table_entry_id(imximage_cmds,
>-                      "imximage commands", token);
>-              if (*cmd < 0) {
>-                      fprintf(stderr, "Error: %s[%d] - Invalid command"
>-                      "(%s)\n", name, lineno, token);
>-                      exit(EXIT_FAILURE);
>-              }
>-              break;
>-      case CFG_REG_SIZE:
>-              parse_cfg_cmd(ds, *cmd, token, name, lineno, fld);
>-              break;
>-      case CFG_REG_ADDRESS:
>-      case CFG_REG_VALUE:
>-              if (*cmd != CMD_DATA)
>-                      return;
>-
>-              value = get_cfg_value(token, name, lineno);
>-              (*ds->set_dcd_val)(ds, name, lineno, fld, value);
>-              if (ds->p_entry > ds->p_max_dcd) {
>-                      uint32_t size = (char *)ds->p_max_dcd -
>-                                      (char *)ds->imxhdr;
>-                      fprintf(stderr, "Error: %s[%d] -"
>-                                      "header exceeds maximum size(%d)\n",
>-                                      name, lineno, size);
>-                      exit(EXIT_FAILURE);
>-              }
>-              break;
>-      default:
>-              break;
>+      g_flash_offset = ph_get_table_entry_id(&ds->ph, imximage_bootops,
>+                      "imximage boot option");
>+      if (g_flash_offset == -1) {
>+              fprintf(stderr, "Error: Invalid boot device\n");
>+              return -1;
>       }
>+      return 0;
>+}
>+
>+static const parse_fld_t cmd_table[] = {
>+      parse_image_version, parse_boot_from, parse_cmd_data };
>+
>+static int parse_command(struct data_src *ds) {
>+      int cmd = ph_get_table_entry_id(&ds->ph, imximage_cmds,
>+                      "imximage commands");
>+      if (cmd < 0)
>+              return cmd;
>+      return cmd_table[cmd](ds);
> }
>
> static int parse_cfg_file(struct imx_header *imxhdr, char *name,
>               uint32_t entry_point)
> {
>       struct data_src ds;
>-      FILE *fd = NULL;
>-      char *line = NULL;
>-      char *token, *saveptr1, *saveptr2;
>-      int lineno = 0;
>-      int fld;
>-      size_t len;
>-      int32_t cmd;
>+      struct parse_helper *ph = &ds.ph;
>
>       /* Be able to detect if the cfg file has no BOOT_FROM tag */
>       g_flash_offset = FLASH_OFFSET_UNDEFINED; @@ -423,8 +359,7 @@
>static int parse_cfg_file(struct imx_header *imxhdr, char *name,
>        * set up function ptr group to V1 by default.
>        */
>       set_hdr_func(&ds, IMXIMAGE_V1);
>-      fd = fopen(name, "r");
>-      if (fd == 0) {
>+      if (ph_open(ph, name)) {
>               fprintf(stderr, "Error: %s - Can't open DCD file\n", name);
>               exit(EXIT_FAILURE);
>       }
>@@ -432,31 +367,19 @@ static int parse_cfg_file(struct imx_header *imxhdr,
>char *name,
>       /* Very simple parsing, line starting with # are comments
>        * and are dropped
>        */
>-      while ((getline(&line, &len, fd)) > 0) {
>-              lineno++;
>-
>-              token = strtok_r(line, "\r\n", &saveptr1);
>-              if (token == NULL)
>-                      continue;
>-
>-              /* Check inside the single line */
>-              for (fld = CFG_COMMAND, cmd = CMD_INVALID,
>-                              line = token; ; line = NULL, fld++) {
>-                      token = strtok_r(line, " \t", &saveptr2);
>-                      if (token == NULL)
>-                              break;
>-
>-                      /* Drop all text starting with '#' as comments */
>-                      if (token[0] == '#')
>-                              break;
>-
>-                      parse_cfg_fld(&ds, &cmd, token, name,
>-                                      lineno, fld);
>+      for (;;) {
>+              ph->cmd_started = 0;
>+              if (ph_skip_separators(ph))
>+                      break;
>+              ph->cmd_started = 1;
>+              if (parse_command(&ds)) {
>+                      fprintf(stderr, "Error: invalid token %s[%d](%s)\n",
>+                                      name, ph->lineno, ph->p);
>+                      exit(EXIT_FAILURE);
>               }
>-
>+              ds.cmd_cnt++;
>       }
>-      fclose(fd);
>-
>+      ph_close(ph);
>       /* Exit if there is no BOOT_FROM field specifying the flash_offset */
>       if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
>               fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name); @@
>-546,12 +469,12 @@ static void imximage_set_header(void *ptr, struct stat
>*sbuf, int ifd,  int imximage_check_params(struct mkimage_params *params)
>{
>       if (!params)
>-              return CFG_INVALID;
>+              return -1;
>       if (!strlen(params->imagename)) {
>               fprintf(stderr, "Error: %s - Configuration file not specified, "
>                       "it is needed for imximage generation\n",
>                       params->cmdname);
>-              return CFG_INVALID;
>+              return -1;
>       }
>       /*
>        * Check parameters:
>diff --git a/tools/imximage.h b/tools/imximage.h index 196bb51..6bcd082
>100644
>--- a/tools/imximage.h
>+++ b/tools/imximage.h
>@@ -23,6 +23,7 @@
>
> #ifndef _IMXIMAGE_H_
> #define _IMXIMAGE_H_
>+#include "parse_helper.h"
>
> #define MAX_HW_CFG_SIZE_V2 121 /* Max number of registers imx can set
>for v2 */  #define MAX_HW_CFG_SIZE_V1 60  /* Max number of registers imx
>can set for v1 */ @@ -49,20 +50,11 @@  #define DCD_VERSION 0x40
>
> enum imximage_cmd {
>-      CMD_INVALID,
>       CMD_IMAGE_VERSION,
>       CMD_BOOT_FROM,
>       CMD_DATA
> };
>
>-enum imximage_fld_types {
>-      CFG_INVALID = -1,
>-      CFG_COMMAND,
>-      CFG_REG_SIZE,
>-      CFG_REG_ADDRESS,
>-      CFG_REG_VALUE
>-};
>-
> enum imximage_version {
>       IMXIMAGE_VER_INVALID = -1,
>       IMXIMAGE_V1 = 1,
>@@ -159,14 +151,17 @@ struct imx_header {  };
>
> struct data_src;
>-typedef void (*set_dcd_val_t)(struct data_src *ds, char *name,
>-              int lineno, int fld, uint32_t value);
>+typedef int (*parse_fld_t)(struct data_src *ds);
>+
>+typedef int (*set_dcd_val_t)(struct data_src *ds, uint32_t *data);
>
> typedef int (*set_imx_hdr_t)(struct data_src *ds, uint32_t entry_point,
>               uint32_t flash_offset);
>
> struct data_src {
>+      struct parse_helper ph;
>       struct imx_header *imxhdr;
>+      int cmd_cnt;
>       set_imx_hdr_t set_imx_hdr;
>       set_dcd_val_t set_dcd_val;
>       uint32_t *p_max_dcd;
>--
>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