Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / romfs / tools / cfg_parse.c
diff --git a/qemu/roms/SLOF/romfs/tools/cfg_parse.c b/qemu/roms/SLOF/romfs/tools/cfg_parse.c
new file mode 100644 (file)
index 0000000..5137fbe
--- /dev/null
@@ -0,0 +1,371 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <cfgparse.h>
+
+static int inbetween_white(char *s, int max, char **start, char **end,
+                          char **next);
+static int add_header(struct ffs_chain_t *, struct ffs_header_t *);
+
+static int glob_come_from_cr = 0;
+
+static int
+find_next_entry(int file, struct ffs_chain_t *chain)
+{
+#define MAX_LINE_SIZE 1024
+       char lnbuf[MAX_LINE_SIZE], b0 = 0, b1 = 0;
+       char *start, *end, *next;
+       struct ffs_header_t *hdr;       //, *hdr2;
+       int lc, rc;
+       char c;
+
+       /* search for new config line */
+       if (0 == glob_come_from_cr) {
+               while (1 == (rc = read(file, &c, 1))) {
+                       //printf("b0=%c b1=%c c=%c\n",
+                       //              b0, b1, c);
+                       b0 = b1;
+                       b1 = c;
+                       /* this looks for starting sign "<CR>[^#]" */
+                       if (((0x0a == b0) || (0x0d == b0)) &&
+                           (('#' != b1) && (0x0a != b1) && (0x0d != b1))) {
+                               break;
+                       }
+               }
+       } else {
+               /* normalize */
+               while (1 == (rc = read(file, &c, 1))) {
+                       //printf("read c=%c\n", c);
+                       if ((0x0a != c) && (0x0d != c)) {
+                               break;
+                       }
+               }
+               glob_come_from_cr = 0;
+               //printf("debug: glob_come_from_cr = 0\n");
+       }
+       if (1 != rc) {
+               return 1;
+       }
+
+       /* now buffer it until end of line */
+       memset((void *) lnbuf, 0, MAX_LINE_SIZE);
+       lnbuf[0] = c;
+       lc = 1;
+       while ((1 == read(file, &(lnbuf[lc]), 1)) && (lc < MAX_LINE_SIZE)) {
+               //printf("read lnbuf=%c\n", lnbuf[lc]);
+               if ((0x0a == lnbuf[lc]) || (0x0d == lnbuf[lc])) {
+                       glob_come_from_cr = 1;
+                       //printf("debug: glob_come_from_cr = 1\n");
+                       break;
+               }
+               lc++;
+       }
+
+       /* allocate header */
+       hdr = malloc(sizeof(struct ffs_header_t));
+       if (NULL == hdr) {
+               perror("alloc memory");
+               return 2;
+       }
+       memset((void *) hdr, 0, sizeof(struct ffs_header_t));
+
+       /* attach header to chain */
+       if (0 != add_header(chain, hdr)) {
+               return 2;
+       }
+
+       /**********************************************************/
+       /* extract token name *********************************** */
+       start = NULL;
+       if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
+               printf("parsing error 1");
+               return 2;
+       }
+       /* get memory for it */
+       hdr->token = malloc(end - start + 1);
+       if (NULL == hdr->token) {
+               return 2;
+       }
+       /* set string */
+       strncpy(hdr->token, start, end - start + 1);
+       hdr->token[end - start] = 0;
+
+       /**********************************************************/
+       /* extract file name *********************************** */
+       if (NULL == next) {
+               return 2;
+       }
+       start = next;
+       if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
+               printf("parsing error 1");
+               return 2;
+       }
+
+       /* get memory for it */
+       hdr->imagefile = malloc(end - start + 1);
+       if (NULL == hdr->imagefile) {
+               return 2;
+       }
+
+       /* check if file is existing */
+
+       /* set string */
+       strncpy(hdr->imagefile, start, end - start + 1);
+       hdr->imagefile[end - start] = 0;
+
+       /* check if entry is linked to another header */
+       if (':' == *start) {
+               printf
+                   ("\nERROR: links are removed as feature in this version\n");
+               return 2;
+
+               /*
+                  start++;
+                  if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) {
+                  printf("[%s]: link to [%s] not found\n", 
+                  hdr->token, hdr->imagefile+1);
+                  dump_fs_contents(chain);
+                  return 2;
+                  }
+                  hdr->linked_to = hdr2;
+                */
+       }
+
+       /**********************************************************/
+       /* extract flags name *********************************** */
+       if (NULL == next) {
+               return 2;
+       }
+       start = next;
+       if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
+               printf("parsing error 1");
+               return 2;
+       }
+       hdr->flags = strtoul(start, NULL, 16);
+
+       /**********************************************************/
+       /* extract rom start name *********************************** */
+       if (NULL == next) {
+               return 2;
+       }
+       start = next;
+       if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
+               printf("parsing error 1");
+               return 2;
+       }
+       if ('-' == *start) {
+               /* this means not specific address request for data */
+               hdr->romaddr = 0;
+       } else {
+               /* data has to begin at specific address */
+               hdr->romaddr = strtoul(start, NULL, 16);
+       }
+
+       return 0;
+}
+
+int
+read_config(int conf_file, struct ffs_chain_t *ffs_chain)
+{
+       int rc;
+
+       while (1) {
+               rc = find_next_entry(conf_file, ffs_chain);
+               if (rc != 0)
+                       break;
+       }
+       return rc;
+}
+
+static int
+inbetween_white(char *s, int max, char **start, char **end, char **next)
+{
+       int pos = 0, posalt;
+
+       if (NULL != *start) {
+               pos = *start - s;
+               s = *start;
+       }
+
+       /* wind to first non white */
+       while (pos < max) {
+               if ((' ' == *s) || ('   ' == *s)) {
+                       s++;
+                       pos++;
+                       continue;
+               }
+               break;
+       }
+       if (pos >= max) {
+               /* no non-white found */
+               return 1;
+       }
+
+       /* assign start */
+       *start = s;
+
+       /* wind to end of non white or end of buffer */
+       posalt = pos;
+       while (pos < max) {
+               if ((' ' == *s) || ('   ' == *s) ||
+                   (0x0a == *s) || (0x0d == *s)) {
+                       break;
+               }
+               s++;
+               pos++;
+       }
+
+       if (pos == posalt) {
+               return 1;
+       }
+
+       *end = s;
+
+       if ((pos + 1) >= max) {
+               *next = NULL;
+       } else {
+               *next = s;
+       }
+
+       return 0;
+}
+
+int
+add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr)
+{
+       struct ffs_header_t *next;
+
+       if (NULL == chain->first) {
+               chain->count = 1;
+               chain->first = hdr;
+               return 0;
+       }
+       next = chain->first;
+
+       /* find last */
+       while (NULL != next->next) {
+               next = next->next;
+       }
+       next->next = hdr;
+       chain->count++;
+
+       return 0;
+}
+
+void
+dump_fs_contents(struct ffs_chain_t *chain)
+{
+       struct ffs_header_t *next;
+
+       if (NULL == chain->first) {
+               printf("no contents in fs\n");
+               return;
+       }
+       next = chain->first;
+
+       while (1) {
+               if (NULL != next->token) {
+                       printf("Token [%s] ", next->token);
+               } else {
+                       printf(" [not-set], ");
+               }
+
+               if (NULL != next->imagefile) {
+                       printf(" <%s>, ", next->imagefile);
+               } else {
+                       printf(" file<not-set>, ");
+               }
+
+               printf("flags<%llx>, ", next->flags);
+               printf("romaddr<%llx>, ", next->romaddr);
+
+               if (NULL != next->linked_to) {
+                       printf("linked to [%s]", next->linked_to->token);
+               }
+
+               printf("\n");
+               if (NULL == next->next) {
+                       break;
+               }
+
+               next = next->next;
+       }
+
+}
+
+void
+free_chain_memory(struct ffs_chain_t *chain)
+{
+       struct ffs_header_t *hdr, *next_hdr;
+
+       if (NULL != chain->first) {
+               hdr = chain->first;
+               chain->first = NULL;
+       } else {
+               return;
+       }
+
+       while (NULL != hdr) {
+               //printf("%p  ", hdr);
+               if (NULL != hdr->token) {
+                       //printf("free up %s\n", hdr->token);
+                       free(hdr->token);
+               }
+               if (NULL != hdr->imagefile) {
+                       free(hdr->imagefile);
+               }
+               next_hdr = hdr->next;
+               free(hdr);
+               hdr = next_hdr;
+       }
+}
+
+
+/*
+ * Detect duplicate entries in the romfs list
+ */
+void
+find_duplicates(struct ffs_chain_t *chain)
+{
+       struct ffs_header_t *act, *sub;
+
+       if (NULL == chain->first) {
+               printf("no contents in fs\n");
+               return;
+       }
+       act = chain->first;
+
+       do {
+               sub = act->next;
+               while (sub != NULL) {
+
+                       if (act->token == NULL || sub->token == NULL) {
+                               printf("find_duplicates: token not set!\n");
+                       } else if (strcmp(act->token, sub->token) == 0) {
+                               printf("*** NOTE: duplicate romfs file '%s'.\n",
+                                      act->token);
+                       }
+                       sub = sub->next;
+               }
+
+               act = act->next;
+
+       } while (act != NULL);
+
+}