/[gxemul]/upstream/0.4.4/src/emul_parse.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.4.4/src/emul_parse.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (show annotations)
Mon Oct 8 16:21:26 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 20788 byte(s)
0.4.4
1 /*
2 * Copyright (C) 2005-2007 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: emul_parse.c,v 1.45 2006/12/30 13:30:52 debug Exp $
29 *
30 * Set up an emulation by parsing a config file.
31 *
32 * TODO: REWRITE THIS FROM SCRATCH! :-)
33 */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #include "diskimage.h"
40 #include "emul.h"
41 #include "machine.h"
42 #include "misc.h"
43 #include "net.h"
44
45
46 #define is_word_char(ch) ( \
47 (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \
48 ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') )
49
50 #define MAX_WORD_LEN 200
51
52 #define EXPECT_WORD 1
53 #define EXPECT_LEFT_PARENTHESIS 2
54 #define EXPECT_RIGHT_PARENTHESIS 4
55
56 static int parenthesis_level = 0;
57
58
59 /*
60 * read_one_word():
61 *
62 * Reads the file f until it has read a complete word. Whitespace is ignored,
63 * and also any exclamation mark ('!') and anything following an exclamation
64 * mark on a line.
65 *
66 * Used internally by emul_parse_config().
67 */
68 static void read_one_word(FILE *f, char *buf, int buflen, int *line,
69 int expect)
70 {
71 int ch;
72 int done = 0;
73 int curlen = 0;
74 int in_word = 0;
75
76 while (!done) {
77 if (curlen >= buflen - 1)
78 break;
79
80 ch = fgetc(f);
81 if (ch == EOF)
82 break;
83
84 if (in_word) {
85 if (is_word_char(ch)) {
86 buf[curlen++] = ch;
87 if (curlen == buflen - 1)
88 done = 1;
89 continue;
90 } else {
91 if (ungetc(ch, f) == EOF) {
92 fatal("ungetc() failed?\n");
93 exit(1);
94 }
95 break;
96 }
97 }
98
99 if (ch == '\n') {
100 (*line) ++;
101 continue;
102 }
103
104 if (ch == '\r')
105 continue;
106
107 if (ch == '!') {
108 /* Skip until newline: */
109 while (ch != '\n' && ch != EOF)
110 ch = fgetc(f);
111 if (ch == '\n')
112 (*line) ++;
113 continue;
114 }
115
116 if (ch == '{') {
117 int depth = 1;
118
119 /* Skip until '}': */
120 while (depth > 0) {
121 ch = fgetc(f);
122 if (ch == '\n')
123 (*line) ++;
124 if (ch == '{')
125 depth ++;
126 if (ch == '}')
127 depth --;
128 if (ch == EOF) {
129 fatal("line %i: unexpected EOF inside"
130 " a nested comment\n", *line);
131 exit(1);
132 }
133 }
134 continue;
135 }
136
137 /* Whitespace? */
138 if (ch <= ' ')
139 continue;
140
141 if (ch == '"' || ch == '\'') {
142 /* This is a quoted word. */
143 int start_ch = ch;
144
145 if (expect & EXPECT_LEFT_PARENTHESIS) {
146 fatal("unexpected character '%c', line %i\n",
147 ch, *line);
148 exit(1);
149 }
150
151 while (curlen < buflen - 1) {
152 ch = fgetc(f);
153 if (ch == '\n') {
154 fatal("line %i: newline inside"
155 " quotes?\n", *line);
156 exit(1);
157 }
158 if (ch == EOF) {
159 fatal("line %i: EOF inside a quoted"
160 " string?\n", *line);
161 exit(1);
162 }
163 if (ch == start_ch)
164 break;
165 buf[curlen++] = ch;
166 }
167 break;
168 }
169
170 if ((expect & EXPECT_WORD) && is_word_char(ch)) {
171 buf[curlen++] = ch;
172 in_word = 1;
173 if (curlen == buflen - 1)
174 done = 1;
175 } else {
176 if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') {
177 parenthesis_level ++;
178 buf[curlen++] = ch;
179 break;
180 }
181 if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') {
182 parenthesis_level --;
183 buf[curlen++] = ch;
184 break;
185 }
186
187 fatal("unexpected character '%c', line %i\n",
188 ch, *line);
189 exit(1);
190 }
191 }
192
193 buf[curlen] = '\0';
194 }
195
196
197 #define PARSESTATE_NONE 0
198 #define PARSESTATE_EMUL 1
199 #define PARSESTATE_NET 2
200 #define PARSESTATE_MACHINE 3
201
202 static char cur_net_ipv4net[50];
203 static char cur_net_ipv4len[50];
204 static char cur_net_local_port[10];
205 #define MAX_N_REMOTE 20
206 #define MAX_REMOTE_LEN 100
207 static char *cur_net_remote[MAX_N_REMOTE];
208 static int cur_net_n_remote;
209
210 static char cur_machine_name[50];
211 static char cur_machine_cpu[50];
212 static char cur_machine_type[50];
213 static char cur_machine_subtype[50];
214 static char cur_machine_bootname[150];
215 static char cur_machine_bootarg[250];
216 static char cur_machine_slowsi[10];
217 static char cur_machine_prom_emulation[10];
218 static char cur_machine_use_x11[10];
219 static char cur_machine_x11_scaledown[10];
220 static char cur_machine_byte_order[20];
221 static char cur_machine_random_mem[10];
222 static char cur_machine_random_cpu[10];
223 static char cur_machine_force_netboot[10];
224 static char cur_machine_start_paused[10];
225 static char cur_machine_ncpus[10];
226 static char cur_machine_n_gfx_cards[10];
227 static char cur_machine_serial_nr[10];
228 static char cur_machine_emulated_hz[10];
229 static char cur_machine_memory[10];
230 #define MAX_N_LOAD 15
231 #define MAX_LOAD_LEN 2000
232 static char *cur_machine_load[MAX_N_LOAD];
233 static int cur_machine_n_load;
234 #define MAX_N_DISK 10
235 #define MAX_DISK_LEN 2000
236 static char *cur_machine_disk[MAX_N_DISK];
237 static int cur_machine_n_disk;
238 #define MAX_N_DEVICE 20
239 #define MAX_DEVICE_LEN 400
240 static char *cur_machine_device[MAX_N_DISK];
241 static int cur_machine_n_device;
242 #define MAX_N_X11_DISP 5
243 #define MAX_X11_DISP_LEN 1000
244 static char *cur_machine_x11_disp[MAX_N_X11_DISP];
245 static int cur_machine_n_x11_disp;
246
247 #define WORD(w,var) { \
248 if (strcmp(word, w) == 0) { \
249 read_one_word(f, word, maxbuflen, \
250 line, EXPECT_LEFT_PARENTHESIS); \
251 read_one_word(f, var, sizeof(var), \
252 line, EXPECT_WORD); \
253 read_one_word(f, word, maxbuflen, \
254 line, EXPECT_RIGHT_PARENTHESIS); \
255 return; \
256 } \
257 }
258
259 static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
260 int *parsestate, char *word, size_t maxbuflen);
261
262
263 /*
264 * parse_on_off():
265 *
266 * Returns 1 for "on", "yes", "enable", or "1".
267 * Returns 0 for "off", "no", "disable", or "0".
268 * Prints a fatal warning and exit()s for other values.
269 */
270 int parse_on_off(char *s)
271 {
272 if (strcasecmp(s, "on") == 0 || strcasecmp(s, "yes") == 0 ||
273 strcasecmp(s, "enable") == 0 || strcasecmp(s, "1") == 0)
274 return 1;
275 if (strcasecmp(s, "off") == 0 || strcasecmp(s, "no") == 0 ||
276 strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0)
277 return 0;
278
279 fprintf(stderr, "parse_on_off(): WARNING: unknown value '%s'\n", s);
280
281 return 0;
282 }
283
284
285 /*
286 * parse__emul():
287 *
288 * name, net, machine
289 */
290 static void parse__emul(struct emul *e, FILE *f, int *in_emul, int *line,
291 int *parsestate, char *word, size_t maxbuflen)
292 {
293 if (word[0] == ')') {
294 *parsestate = PARSESTATE_NONE;
295 return;
296 }
297
298 if (strcmp(word, "name") == 0) {
299 char tmp[200];
300 read_one_word(f, word, maxbuflen,
301 line, EXPECT_LEFT_PARENTHESIS);
302 read_one_word(f, tmp, sizeof(tmp), line, EXPECT_WORD);
303 read_one_word(f, word, maxbuflen,
304 line, EXPECT_RIGHT_PARENTHESIS);
305 if (e->name != NULL) {
306 free(e->name);
307 e->name = NULL;
308 }
309 e->name = strdup(tmp);
310 if (e->name == NULL) {
311 fprintf(stderr, "out of memory in parse__emul()\n");
312 exit(1);
313 }
314 debug("name: \"%s\"\n", e->name);
315 return;
316 }
317
318 if (strcmp(word, "net") == 0) {
319 *parsestate = PARSESTATE_NET;
320 read_one_word(f, word, maxbuflen,
321 line, EXPECT_LEFT_PARENTHESIS);
322
323 /* Default net: */
324 strlcpy(cur_net_ipv4net, NET_DEFAULT_IPV4_MASK,
325 sizeof(cur_net_ipv4net));
326 snprintf(cur_net_ipv4len, sizeof(cur_net_ipv4len), "%i",
327 NET_DEFAULT_IPV4_LEN);
328 strlcpy(cur_net_local_port, "", sizeof(cur_net_local_port));
329 cur_net_n_remote = 0;
330 return;
331 }
332
333 if (strcmp(word, "machine") == 0) {
334 *parsestate = PARSESTATE_MACHINE;
335 read_one_word(f, word, maxbuflen,
336 line, EXPECT_LEFT_PARENTHESIS);
337
338 /* A "zero state": */
339 cur_machine_name[0] = '\0';
340 cur_machine_cpu[0] = '\0';
341 cur_machine_type[0] = '\0';
342 cur_machine_subtype[0] = '\0';
343 cur_machine_bootname[0] = '\0';
344 cur_machine_bootarg[0] = '\0';
345 cur_machine_n_load = 0;
346 cur_machine_n_disk = 0;
347 cur_machine_n_device = 0;
348 cur_machine_n_x11_disp = 0;
349 cur_machine_slowsi[0] = '\0';
350 cur_machine_prom_emulation[0] = '\0';
351 cur_machine_use_x11[0] = '\0';
352 cur_machine_x11_scaledown[0] = '\0';
353 cur_machine_byte_order[0] = '\0';
354 cur_machine_random_mem[0] = '\0';
355 cur_machine_random_cpu[0] = '\0';
356 cur_machine_force_netboot[0] = '\0';
357 cur_machine_start_paused[0] = '\0';
358 cur_machine_ncpus[0] = '\0';
359 cur_machine_n_gfx_cards[0] = '\0';
360 cur_machine_serial_nr[0] = '\0';
361 cur_machine_emulated_hz[0] = '\0';
362 cur_machine_memory[0] = '\0';
363 return;
364 }
365
366 fatal("line %i: not expecting '%s' in an 'emul' section\n",
367 *line, word);
368 exit(1);
369 }
370
371
372 /*
373 * parse__net():
374 *
375 * Simple words: ipv4net, ipv4len, local_port
376 *
377 * Complex: add_remote
378 *
379 * TODO: more words? for example an option to disable the gateway? that would
380 * have to be implemented correctly in src/net.c first.
381 */
382 static void parse__net(struct emul *e, FILE *f, int *in_emul, int *line,
383 int *parsestate, char *word, size_t maxbuflen)
384 {
385 int i;
386
387 if (word[0] == ')') {
388 /* Finished with the 'net' section. Let's create the net: */
389 if (e->net != NULL) {
390 fatal("line %i: more than one net isn't really "
391 "supported yet\n", *line);
392 exit(1);
393 }
394
395 if (!cur_net_local_port[0])
396 strlcpy(cur_net_local_port, "0",
397 sizeof(cur_net_local_port));
398
399 e->net = net_init(e, NET_INIT_FLAG_GATEWAY,
400 cur_net_ipv4net, atoi(cur_net_ipv4len),
401 cur_net_remote, cur_net_n_remote,
402 atoi(cur_net_local_port), NULL);
403
404 if (e->net == NULL) {
405 fatal("line %i: fatal error: could not create"
406 " the net (?)\n", *line);
407 exit(1);
408 }
409
410 for (i=0; i<cur_net_n_remote; i++) {
411 free(cur_net_remote[i]);
412 cur_net_remote[i] = NULL;
413 }
414
415 *parsestate = PARSESTATE_EMUL;
416 return;
417 }
418
419 WORD("ipv4net", cur_net_ipv4net);
420 WORD("ipv4len", cur_net_ipv4len);
421 WORD("local_port", cur_net_local_port);
422
423 if (strcmp(word, "add_remote") == 0) {
424 read_one_word(f, word, maxbuflen,
425 line, EXPECT_LEFT_PARENTHESIS);
426 if (cur_net_n_remote >= MAX_N_REMOTE) {
427 fprintf(stderr, "too many remote networks\n");
428 exit(1);
429 }
430 cur_net_remote[cur_net_n_remote] = malloc(MAX_REMOTE_LEN);
431 if (cur_net_remote[cur_net_n_remote] == NULL) {
432 fprintf(stderr, "out of memory\n");
433 exit(1);
434 }
435 read_one_word(f, cur_net_remote[cur_net_n_remote],
436 MAX_REMOTE_LEN, line, EXPECT_WORD);
437 cur_net_n_remote ++;
438 read_one_word(f, word, maxbuflen, line,
439 EXPECT_RIGHT_PARENTHESIS);
440 return;
441 }
442
443 fatal("line %i: not expecting '%s' in a 'net' section\n", *line, word);
444 exit(1);
445 }
446
447
448 /*
449 * parse__machine():
450 */
451 static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
452 int *parsestate, char *word, size_t maxbuflen)
453 {
454 int r, i;
455
456 if (word[0] == ')') {
457 /* Finished with the 'machine' section. */
458 struct machine *m;
459
460 if (!cur_machine_name[0])
461 strlcpy(cur_machine_name, "no_name",
462 sizeof(cur_machine_name));
463
464 m = emul_add_machine(e, cur_machine_name);
465
466 r = machine_name_to_type(cur_machine_type, cur_machine_subtype,
467 &m->machine_type, &m->machine_subtype, &m->arch);
468 if (!r)
469 exit(1);
470
471 if (cur_machine_cpu[0])
472 m->cpu_name = strdup(cur_machine_cpu);
473
474 if (!cur_machine_use_x11[0])
475 strlcpy(cur_machine_use_x11, "no",
476 sizeof(cur_machine_use_x11));
477 m->use_x11 = parse_on_off(cur_machine_use_x11);
478
479 if (!cur_machine_slowsi[0])
480 strlcpy(cur_machine_slowsi, "no",
481 sizeof(cur_machine_slowsi));
482 m->slow_serial_interrupts_hack_for_linux =
483 parse_on_off(cur_machine_slowsi);
484
485 if (!cur_machine_prom_emulation[0])
486 strlcpy(cur_machine_prom_emulation, "yes",
487 sizeof(cur_machine_prom_emulation));
488 m->prom_emulation = parse_on_off(cur_machine_prom_emulation);
489
490 if (!cur_machine_random_mem[0])
491 strlcpy(cur_machine_random_mem, "no",
492 sizeof(cur_machine_random_mem));
493 m->random_mem_contents =
494 parse_on_off(cur_machine_random_mem);
495
496 if (!cur_machine_random_cpu[0])
497 strlcpy(cur_machine_random_cpu, "no",
498 sizeof(cur_machine_random_cpu));
499 m->use_random_bootstrap_cpu =
500 parse_on_off(cur_machine_random_cpu);
501
502 m->byte_order_override = NO_BYTE_ORDER_OVERRIDE;
503 if (cur_machine_byte_order[0]) {
504 if (strncasecmp(cur_machine_byte_order, "big", 3) == 0)
505 m->byte_order_override = EMUL_BIG_ENDIAN;
506 else if (strncasecmp(cur_machine_byte_order, "little",
507 6) == 0)
508 m->byte_order_override = EMUL_LITTLE_ENDIAN;
509 else {
510 fatal("Byte order must be big-endian or"
511 " little-endian\n");
512 exit(1);
513 }
514 }
515
516 if (!cur_machine_force_netboot[0])
517 strlcpy(cur_machine_force_netboot, "no",
518 sizeof(cur_machine_force_netboot));
519 m->force_netboot = parse_on_off(cur_machine_force_netboot);
520
521 if (!cur_machine_start_paused[0])
522 strlcpy(cur_machine_start_paused, "no",
523 sizeof(cur_machine_start_paused));
524 m->start_paused = parse_on_off(cur_machine_start_paused);
525
526 /* NOTE: Default nr of CPUs is 0: */
527 if (!cur_machine_ncpus[0])
528 strlcpy(cur_machine_ncpus, "0",
529 sizeof(cur_machine_ncpus));
530 m->ncpus = atoi(cur_machine_ncpus);
531
532 if (cur_machine_n_gfx_cards[0])
533 m->n_gfx_cards = atoi(cur_machine_n_gfx_cards);
534
535 if (cur_machine_serial_nr[0]) {
536 m->serial_nr = atoi(cur_machine_serial_nr);
537 e->next_serial_nr = m->serial_nr+1;
538 }
539
540 if (cur_machine_emulated_hz[0]) {
541 m->emulated_hz = mystrtoull(cur_machine_emulated_hz,
542 NULL, 0);
543 }
544
545 /* NOTE: Default nr of CPUs is 0: */
546 if (!cur_machine_memory[0])
547 strlcpy(cur_machine_memory, "0",
548 sizeof(cur_machine_memory));
549 m->physical_ram_in_mb = atoi(cur_machine_memory);
550
551 if (!cur_machine_x11_scaledown[0])
552 m->x11_scaledown = 1;
553 else {
554 m->x11_scaledown = atoi(cur_machine_x11_scaledown);
555 if (m->x11_scaledown < 0) {
556 m->x11_scaleup = 0 - m->x11_scaledown;
557 m->x11_scaledown = 1;
558 }
559 if (m->x11_scaledown < 1) {
560 fprintf(stderr, "Invalid scaledown value"
561 " (%i)\n", m->x11_scaledown);
562 exit(1);
563 }
564 }
565
566 for (i=0; i<cur_machine_n_disk; i++) {
567 diskimage_add(m, cur_machine_disk[i]);
568 free(cur_machine_disk[i]);
569 cur_machine_disk[i] = NULL;
570 }
571
572 m->boot_kernel_filename = strdup(cur_machine_bootname);
573
574 if (cur_machine_bootarg[0])
575 m->boot_string_argument = strdup(cur_machine_bootarg);
576
577 for (i=0; i<cur_machine_n_x11_disp; i++) {
578 m->x11_n_display_names ++;
579 m->x11_display_names = realloc(
580 m->x11_display_names, m->x11_n_display_names
581 * sizeof(char *));
582 if (m->x11_display_names == NULL) {
583 printf("out of memory\n");
584 exit(1);
585 }
586 m->x11_display_names[m->x11_n_display_names-1] =
587 strdup(cur_machine_x11_disp[i]);
588 if (m->x11_display_names
589 [m->x11_n_display_names-1] == NULL) {
590 printf("out of memory\n");
591 exit(1);
592 }
593 free(cur_machine_x11_disp[i]);
594 cur_machine_x11_disp[i] = NULL;
595 }
596
597 emul_machine_setup(m,
598 cur_machine_n_load, cur_machine_load,
599 cur_machine_n_device, cur_machine_device);
600
601 for (i=0; i<cur_machine_n_device; i++) {
602 free(cur_machine_device[i]);
603 cur_machine_device[i] = NULL;
604 }
605
606 for (i=0; i<cur_machine_n_load; i++) {
607 free(cur_machine_load[i]);
608 cur_machine_load[i] = NULL;
609 }
610
611 *parsestate = PARSESTATE_EMUL;
612 return;
613 }
614
615 WORD("name", cur_machine_name);
616 WORD("cpu", cur_machine_cpu);
617 WORD("type", cur_machine_type);
618 WORD("subtype", cur_machine_subtype);
619 WORD("bootname", cur_machine_bootname);
620 WORD("bootarg", cur_machine_bootarg);
621 WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi);
622 WORD("prom_emulation", cur_machine_prom_emulation);
623 WORD("use_x11", cur_machine_use_x11);
624 WORD("x11_scaledown", cur_machine_x11_scaledown);
625 WORD("byte_order", cur_machine_byte_order);
626 WORD("random_mem_contents", cur_machine_random_mem);
627 WORD("use_random_bootstrap_cpu", cur_machine_random_cpu);
628 WORD("force_netboot", cur_machine_force_netboot);
629 WORD("ncpus", cur_machine_ncpus);
630 WORD("serial_nr", cur_machine_serial_nr);
631 WORD("n_gfx_cards", cur_machine_n_gfx_cards);
632 WORD("emulated_hz", cur_machine_emulated_hz);
633 WORD("memory", cur_machine_memory);
634 WORD("start_paused", cur_machine_start_paused);
635
636 if (strcmp(word, "load") == 0) {
637 read_one_word(f, word, maxbuflen,
638 line, EXPECT_LEFT_PARENTHESIS);
639 if (cur_machine_n_load >= MAX_N_LOAD) {
640 fprintf(stderr, "too many loads\n");
641 exit(1);
642 }
643 cur_machine_load[cur_machine_n_load] = malloc(MAX_LOAD_LEN);
644 if (cur_machine_load[cur_machine_n_load] == NULL) {
645 fprintf(stderr, "out of memory\n");
646 exit(1);
647 }
648 read_one_word(f, cur_machine_load[cur_machine_n_load],
649 MAX_LOAD_LEN, line, EXPECT_WORD);
650 cur_machine_n_load ++;
651 read_one_word(f, word, maxbuflen,
652 line, EXPECT_RIGHT_PARENTHESIS);
653 return;
654 }
655
656 if (strcmp(word, "disk") == 0) {
657 read_one_word(f, word, maxbuflen,
658 line, EXPECT_LEFT_PARENTHESIS);
659 if (cur_machine_n_disk >= MAX_N_DISK) {
660 fprintf(stderr, "too many disks\n");
661 exit(1);
662 }
663 cur_machine_disk[cur_machine_n_disk] = malloc(MAX_DISK_LEN);
664 if (cur_machine_disk[cur_machine_n_disk] == NULL) {
665 fprintf(stderr, "out of memory\n");
666 exit(1);
667 }
668 read_one_word(f, cur_machine_disk[cur_machine_n_disk],
669 MAX_DISK_LEN, line, EXPECT_WORD);
670 cur_machine_n_disk ++;
671 read_one_word(f, word, maxbuflen,
672 line, EXPECT_RIGHT_PARENTHESIS);
673 return;
674 }
675
676 if (strcmp(word, "device") == 0) {
677 read_one_word(f, word, maxbuflen,
678 line, EXPECT_LEFT_PARENTHESIS);
679 if (cur_machine_n_device >= MAX_N_DEVICE) {
680 fprintf(stderr, "too many devices\n");
681 exit(1);
682 }
683 cur_machine_device[cur_machine_n_device] =
684 malloc(MAX_DEVICE_LEN);
685 if (cur_machine_device[cur_machine_n_device] == NULL) {
686 fprintf(stderr, "out of memory\n");
687 exit(1);
688 }
689 read_one_word(f, cur_machine_device[cur_machine_n_device],
690 MAX_DEVICE_LEN, line, EXPECT_WORD);
691 cur_machine_n_device ++;
692 read_one_word(f, word, maxbuflen,
693 line, EXPECT_RIGHT_PARENTHESIS);
694 return;
695 }
696
697 if (strcmp(word, "add_x11_display") == 0) {
698 read_one_word(f, word, maxbuflen,
699 line, EXPECT_LEFT_PARENTHESIS);
700 if (cur_machine_n_x11_disp >= MAX_N_X11_DISP) {
701 fprintf(stderr, "too many x11 displays\n");
702 exit(1);
703 }
704 cur_machine_x11_disp[cur_machine_n_x11_disp] =
705 malloc(MAX_X11_DISP_LEN);
706 if (cur_machine_x11_disp[cur_machine_n_x11_disp] == NULL) {
707 fprintf(stderr, "out of memory\n");
708 exit(1);
709 }
710 read_one_word(f, cur_machine_x11_disp[cur_machine_n_x11_disp],
711 MAX_X11_DISP_LEN, line, EXPECT_WORD);
712 cur_machine_n_x11_disp ++;
713 read_one_word(f, word, maxbuflen,
714 line, EXPECT_RIGHT_PARENTHESIS);
715 return;
716 }
717
718 fatal("line %i: not expecting '%s' in a 'machine' section\n",
719 *line, word);
720 exit(1);
721 }
722
723
724 /*
725 * emul_parse_config():
726 *
727 * Set up an emulation by parsing a config file.
728 */
729 void emul_parse_config(struct emul *e, char *fname)
730 {
731 FILE *f = fopen(fname, "r");
732 char word[MAX_WORD_LEN];
733 int in_emul = 0;
734 int line = 1;
735 int parsestate = PARSESTATE_EMUL;
736
737 /* debug("emul_parse_config()\n"); */
738 if (f == NULL) {
739 perror(fname);
740 exit(1);
741 }
742
743 while (!feof(f)) {
744 read_one_word(f, word, sizeof(word), &line,
745 EXPECT_WORD | EXPECT_RIGHT_PARENTHESIS);
746 if (!word[0])
747 break;
748
749 /* debug("word = '%s'\n", word); */
750
751 switch (parsestate) {
752 case PARSESTATE_EMUL:
753 parse__emul(e, f, &in_emul, &line, &parsestate,
754 word, sizeof(word));
755 break;
756 case PARSESTATE_NET:
757 parse__net(e, f, &in_emul, &line, &parsestate,
758 word, sizeof(word));
759 break;
760 case PARSESTATE_MACHINE:
761 parse__machine(e, f, &in_emul, &line, &parsestate,
762 word, sizeof(word));
763 break;
764 case PARSESTATE_NONE:
765 break;
766 default:
767 fatal("INTERNAL ERROR in emul_parse.c ("
768 "parsestate %i is not imlemented yet?)\n",
769 parsestate);
770 exit(1);
771 }
772 }
773
774 if (parenthesis_level != 0) {
775 fatal("EOF but not enough right parentheses?\n");
776 exit(1);
777 }
778
779 fclose(f);
780 }
781

  ViewVC Help
Powered by ViewVC 1.1.26