summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/romfs/tools/cfg_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/SLOF/romfs/tools/cfg_parse.c')
-rw-r--r--qemu/roms/SLOF/romfs/tools/cfg_parse.c371
1 files changed, 371 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/romfs/tools/cfg_parse.c b/qemu/roms/SLOF/romfs/tools/cfg_parse.c
new file mode 100644
index 000000000..5137fbe4f
--- /dev/null
+++ b/qemu/roms/SLOF/romfs/tools/cfg_parse.c
@@ -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);
+
+}