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