/[gxemul]/upstream/0.3.7/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.3.7/src/emul_parse.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26