Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / romfs / tools / cfg_parse.c
1 /******************************************************************************
2  * Copyright (c) 2004, 2008 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <string.h>
18 #include <unistd.h>
19
20 #include <cfgparse.h>
21
22 static int inbetween_white(char *s, int max, char **start, char **end,
23                            char **next);
24 static int add_header(struct ffs_chain_t *, struct ffs_header_t *);
25
26 static int glob_come_from_cr = 0;
27
28 static int
29 find_next_entry(int file, struct ffs_chain_t *chain)
30 {
31 #define MAX_LINE_SIZE 1024
32         char lnbuf[MAX_LINE_SIZE], b0 = 0, b1 = 0;
33         char *start, *end, *next;
34         struct ffs_header_t *hdr;       //, *hdr2;
35         int lc, rc;
36         char c;
37
38         /* search for new config line */
39         if (0 == glob_come_from_cr) {
40                 while (1 == (rc = read(file, &c, 1))) {
41                         //printf("b0=%c b1=%c c=%c\n",
42                         //              b0, b1, c);
43                         b0 = b1;
44                         b1 = c;
45                         /* this looks for starting sign "<CR>[^#]" */
46                         if (((0x0a == b0) || (0x0d == b0)) &&
47                             (('#' != b1) && (0x0a != b1) && (0x0d != b1))) {
48                                 break;
49                         }
50                 }
51         } else {
52                 /* normalize */
53                 while (1 == (rc = read(file, &c, 1))) {
54                         //printf("read c=%c\n", c);
55                         if ((0x0a != c) && (0x0d != c)) {
56                                 break;
57                         }
58                 }
59                 glob_come_from_cr = 0;
60                 //printf("debug: glob_come_from_cr = 0\n");
61         }
62         if (1 != rc) {
63                 return 1;
64         }
65
66         /* now buffer it until end of line */
67         memset((void *) lnbuf, 0, MAX_LINE_SIZE);
68         lnbuf[0] = c;
69         lc = 1;
70         while ((1 == read(file, &(lnbuf[lc]), 1)) && (lc < MAX_LINE_SIZE)) {
71                 //printf("read lnbuf=%c\n", lnbuf[lc]);
72                 if ((0x0a == lnbuf[lc]) || (0x0d == lnbuf[lc])) {
73                         glob_come_from_cr = 1;
74                         //printf("debug: glob_come_from_cr = 1\n");
75                         break;
76                 }
77                 lc++;
78         }
79
80         /* allocate header */
81         hdr = malloc(sizeof(struct ffs_header_t));
82         if (NULL == hdr) {
83                 perror("alloc memory");
84                 return 2;
85         }
86         memset((void *) hdr, 0, sizeof(struct ffs_header_t));
87
88         /* attach header to chain */
89         if (0 != add_header(chain, hdr)) {
90                 return 2;
91         }
92
93         /**********************************************************/
94         /* extract token name *********************************** */
95         start = NULL;
96         if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
97                 printf("parsing error 1");
98                 return 2;
99         }
100         /* get memory for it */
101         hdr->token = malloc(end - start + 1);
102         if (NULL == hdr->token) {
103                 return 2;
104         }
105         /* set string */
106         strncpy(hdr->token, start, end - start + 1);
107         hdr->token[end - start] = 0;
108
109         /**********************************************************/
110         /* extract file name *********************************** */
111         if (NULL == next) {
112                 return 2;
113         }
114         start = next;
115         if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
116                 printf("parsing error 1");
117                 return 2;
118         }
119
120         /* get memory for it */
121         hdr->imagefile = malloc(end - start + 1);
122         if (NULL == hdr->imagefile) {
123                 return 2;
124         }
125
126         /* check if file is existing */
127
128         /* set string */
129         strncpy(hdr->imagefile, start, end - start + 1);
130         hdr->imagefile[end - start] = 0;
131
132         /* check if entry is linked to another header */
133         if (':' == *start) {
134                 printf
135                     ("\nERROR: links are removed as feature in this version\n");
136                 return 2;
137
138                 /*
139                    start++;
140                    if (0 != find_entry_by_token(chain, hdr->imagefile+1, &hdr2)) {
141                    printf("[%s]: link to [%s] not found\n", 
142                    hdr->token, hdr->imagefile+1);
143                    dump_fs_contents(chain);
144                    return 2;
145                    }
146                    hdr->linked_to = hdr2;
147                  */
148         }
149
150         /**********************************************************/
151         /* extract flags name *********************************** */
152         if (NULL == next) {
153                 return 2;
154         }
155         start = next;
156         if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
157                 printf("parsing error 1");
158                 return 2;
159         }
160         hdr->flags = strtoul(start, NULL, 16);
161
162         /**********************************************************/
163         /* extract rom start name *********************************** */
164         if (NULL == next) {
165                 return 2;
166         }
167         start = next;
168         if (inbetween_white(lnbuf, MAX_LINE_SIZE, &start, &end, &next) != 0) {
169                 printf("parsing error 1");
170                 return 2;
171         }
172         if ('-' == *start) {
173                 /* this means not specific address request for data */
174                 hdr->romaddr = 0;
175         } else {
176                 /* data has to begin at specific address */
177                 hdr->romaddr = strtoul(start, NULL, 16);
178         }
179
180         return 0;
181 }
182
183 int
184 read_config(int conf_file, struct ffs_chain_t *ffs_chain)
185 {
186         int rc;
187
188         while (1) {
189                 rc = find_next_entry(conf_file, ffs_chain);
190                 if (rc != 0)
191                         break;
192         }
193         return rc;
194 }
195
196 static int
197 inbetween_white(char *s, int max, char **start, char **end, char **next)
198 {
199         int pos = 0, posalt;
200
201         if (NULL != *start) {
202                 pos = *start - s;
203                 s = *start;
204         }
205
206         /* wind to first non white */
207         while (pos < max) {
208                 if ((' ' == *s) || ('   ' == *s)) {
209                         s++;
210                         pos++;
211                         continue;
212                 }
213                 break;
214         }
215         if (pos >= max) {
216                 /* no non-white found */
217                 return 1;
218         }
219
220         /* assign start */
221         *start = s;
222
223         /* wind to end of non white or end of buffer */
224         posalt = pos;
225         while (pos < max) {
226                 if ((' ' == *s) || ('   ' == *s) ||
227                     (0x0a == *s) || (0x0d == *s)) {
228                         break;
229                 }
230                 s++;
231                 pos++;
232         }
233
234         if (pos == posalt) {
235                 return 1;
236         }
237
238         *end = s;
239
240         if ((pos + 1) >= max) {
241                 *next = NULL;
242         } else {
243                 *next = s;
244         }
245
246         return 0;
247 }
248
249 int
250 add_header(struct ffs_chain_t *chain, struct ffs_header_t *hdr)
251 {
252         struct ffs_header_t *next;
253
254         if (NULL == chain->first) {
255                 chain->count = 1;
256                 chain->first = hdr;
257                 return 0;
258         }
259         next = chain->first;
260
261         /* find last */
262         while (NULL != next->next) {
263                 next = next->next;
264         }
265         next->next = hdr;
266         chain->count++;
267
268         return 0;
269 }
270
271 void
272 dump_fs_contents(struct ffs_chain_t *chain)
273 {
274         struct ffs_header_t *next;
275
276         if (NULL == chain->first) {
277                 printf("no contents in fs\n");
278                 return;
279         }
280         next = chain->first;
281
282         while (1) {
283                 if (NULL != next->token) {
284                         printf("Token [%s] ", next->token);
285                 } else {
286                         printf(" [not-set], ");
287                 }
288
289                 if (NULL != next->imagefile) {
290                         printf(" <%s>, ", next->imagefile);
291                 } else {
292                         printf(" file<not-set>, ");
293                 }
294
295                 printf("flags<%llx>, ", next->flags);
296                 printf("romaddr<%llx>, ", next->romaddr);
297
298                 if (NULL != next->linked_to) {
299                         printf("linked to [%s]", next->linked_to->token);
300                 }
301
302                 printf("\n");
303                 if (NULL == next->next) {
304                         break;
305                 }
306
307                 next = next->next;
308         }
309
310 }
311
312 void
313 free_chain_memory(struct ffs_chain_t *chain)
314 {
315         struct ffs_header_t *hdr, *next_hdr;
316
317         if (NULL != chain->first) {
318                 hdr = chain->first;
319                 chain->first = NULL;
320         } else {
321                 return;
322         }
323
324         while (NULL != hdr) {
325                 //printf("%p  ", hdr);
326                 if (NULL != hdr->token) {
327                         //printf("free up %s\n", hdr->token);
328                         free(hdr->token);
329                 }
330                 if (NULL != hdr->imagefile) {
331                         free(hdr->imagefile);
332                 }
333                 next_hdr = hdr->next;
334                 free(hdr);
335                 hdr = next_hdr;
336         }
337 }
338
339
340 /*
341  * Detect duplicate entries in the romfs list
342  */
343 void
344 find_duplicates(struct ffs_chain_t *chain)
345 {
346         struct ffs_header_t *act, *sub;
347
348         if (NULL == chain->first) {
349                 printf("no contents in fs\n");
350                 return;
351         }
352         act = chain->first;
353
354         do {
355                 sub = act->next;
356                 while (sub != NULL) {
357
358                         if (act->token == NULL || sub->token == NULL) {
359                                 printf("find_duplicates: token not set!\n");
360                         } else if (strcmp(act->token, sub->token) == 0) {
361                                 printf("*** NOTE: duplicate romfs file '%s'.\n",
362                                        act->token);
363                         }
364                         sub = sub->next;
365                 }
366
367                 act = act->next;
368
369         } while (act != NULL);
370
371 }