1 |
/* |
/* |
2 |
* Copyright (C) 2005-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2005-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: emul_parse.c,v 1.36 2006/01/14 12:51:59 debug Exp $ |
* $Id: emul_parse.c,v 1.46 2007/06/15 17:02:38 debug Exp $ |
29 |
* |
* |
30 |
* Set up an emulation by parsing a config file. |
* Set up an emulation by parsing a config file. |
31 |
* |
* |
32 |
* TODO: This could be extended to support XML config files as well, but |
* TODO: REWRITE THIS FROM SCRATCH! :-) |
|
* XML is ugly. It is ugly right now as well. The question is: which |
|
|
* solution is the least ugly? |
|
33 |
*/ |
*/ |
34 |
|
|
35 |
#include <stdio.h> |
#include <stdio.h> |
47 |
(ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \ |
(ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \ |
48 |
ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') ) |
ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') ) |
49 |
|
|
50 |
|
#define MAX_WORD_LEN 200 |
51 |
|
|
52 |
#define EXPECT_WORD 1 |
#define EXPECT_WORD 1 |
53 |
#define EXPECT_LEFT_PARENTHESIS 2 |
#define EXPECT_LEFT_PARENTHESIS 2 |
54 |
#define EXPECT_RIGHT_PARENTHESIS 4 |
#define EXPECT_RIGHT_PARENTHESIS 4 |
55 |
|
|
56 |
|
static int parenthesis_level = 0; |
57 |
|
|
58 |
|
|
59 |
/* |
/* |
60 |
* read_one_word(): |
* read_one_word(): |
174 |
done = 1; |
done = 1; |
175 |
} else { |
} else { |
176 |
if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') { |
if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') { |
177 |
|
parenthesis_level ++; |
178 |
buf[curlen++] = ch; |
buf[curlen++] = ch; |
179 |
break; |
break; |
180 |
} |
} |
181 |
if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') { |
if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') { |
182 |
|
parenthesis_level --; |
183 |
buf[curlen++] = ch; |
buf[curlen++] = ch; |
184 |
break; |
break; |
185 |
} |
} |
214 |
static char cur_machine_bootname[150]; |
static char cur_machine_bootname[150]; |
215 |
static char cur_machine_bootarg[250]; |
static char cur_machine_bootarg[250]; |
216 |
static char cur_machine_slowsi[10]; |
static char cur_machine_slowsi[10]; |
|
static char cur_machine_debugger_on_badaddr[10]; |
|
217 |
static char cur_machine_prom_emulation[10]; |
static char cur_machine_prom_emulation[10]; |
218 |
static char cur_machine_use_x11[10]; |
static char cur_machine_use_x11[10]; |
219 |
static char cur_machine_x11_scaledown[10]; |
static char cur_machine_x11_scaledown[10]; |
|
static char cur_machine_bintrans[10]; |
|
|
static char cur_machine_old_bintrans[10]; |
|
|
static char cur_machine_bintrans_size[10]; |
|
220 |
static char cur_machine_byte_order[20]; |
static char cur_machine_byte_order[20]; |
221 |
static char cur_machine_random_mem[10]; |
static char cur_machine_random_mem[10]; |
222 |
static char cur_machine_random_cpu[10]; |
static char cur_machine_random_cpu[10]; |
227 |
static char cur_machine_serial_nr[10]; |
static char cur_machine_serial_nr[10]; |
228 |
static char cur_machine_emulated_hz[10]; |
static char cur_machine_emulated_hz[10]; |
229 |
static char cur_machine_memory[10]; |
static char cur_machine_memory[10]; |
|
static char cur_machine_max_random_cycles[10]; |
|
230 |
#define MAX_N_LOAD 15 |
#define MAX_N_LOAD 15 |
231 |
#define MAX_LOAD_LEN 2000 |
#define MAX_LOAD_LEN 2000 |
232 |
static char *cur_machine_load[MAX_N_LOAD]; |
static char *cur_machine_load[MAX_N_LOAD]; |
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(): |
* parse_on_off(): |
276 |
strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0) |
strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0) |
277 |
return 0; |
return 0; |
278 |
|
|
279 |
fatal("parse_on_off(): unknown value '%s'\n", s); |
fprintf(stderr, "parse_on_off(): WARNING: unknown value '%s'\n", s); |
|
exit(1); |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
* parse__none(): |
|
|
* |
|
|
* emul ( [...] ) |
|
|
*/ |
|
|
static void parse__none(struct emul *e, FILE *f, int *in_emul, int *line, |
|
|
int *parsestate, char *word, size_t maxbuflen) |
|
|
{ |
|
|
if (strcmp(word, "emul") == 0) { |
|
|
if (*in_emul) { |
|
|
fatal("line %i: only one emul per config " |
|
|
"file is supported!\n", *line); |
|
|
exit(1); |
|
|
} |
|
|
*parsestate = PARSESTATE_EMUL; |
|
|
*in_emul = 1; |
|
|
read_one_word(f, word, maxbuflen, |
|
|
line, EXPECT_LEFT_PARENTHESIS); |
|
|
return; |
|
|
} |
|
280 |
|
|
281 |
fatal("line %i: expecting 'emul', not '%s'\n", *line, word); |
return 0; |
|
exit(1); |
|
282 |
} |
} |
283 |
|
|
284 |
|
|
306 |
free(e->name); |
free(e->name); |
307 |
e->name = NULL; |
e->name = NULL; |
308 |
} |
} |
309 |
e->name = strdup(tmp); |
CHECK_ALLOCATION(e->name = strdup(tmp)); |
|
if (e->name == NULL) { |
|
|
fprintf(stderr, "out of memory in parse__emul()\n"); |
|
|
exit(1); |
|
|
} |
|
310 |
debug("name: \"%s\"\n", e->name); |
debug("name: \"%s\"\n", e->name); |
311 |
return; |
return; |
312 |
} |
} |
317 |
line, EXPECT_LEFT_PARENTHESIS); |
line, EXPECT_LEFT_PARENTHESIS); |
318 |
|
|
319 |
/* Default net: */ |
/* Default net: */ |
320 |
strlcpy(cur_net_ipv4net, "10.0.0.0", sizeof(cur_net_ipv4net)); |
strlcpy(cur_net_ipv4net, NET_DEFAULT_IPV4_MASK, |
321 |
strlcpy(cur_net_ipv4len, "8", sizeof(cur_net_ipv4len)); |
sizeof(cur_net_ipv4net)); |
322 |
|
snprintf(cur_net_ipv4len, sizeof(cur_net_ipv4len), "%i", |
323 |
|
NET_DEFAULT_IPV4_LEN); |
324 |
strlcpy(cur_net_local_port, "", sizeof(cur_net_local_port)); |
strlcpy(cur_net_local_port, "", sizeof(cur_net_local_port)); |
325 |
cur_net_n_remote = 0; |
cur_net_n_remote = 0; |
326 |
return; |
return; |
343 |
cur_machine_n_device = 0; |
cur_machine_n_device = 0; |
344 |
cur_machine_n_x11_disp = 0; |
cur_machine_n_x11_disp = 0; |
345 |
cur_machine_slowsi[0] = '\0'; |
cur_machine_slowsi[0] = '\0'; |
|
cur_machine_debugger_on_badaddr[0] = '\0'; |
|
346 |
cur_machine_prom_emulation[0] = '\0'; |
cur_machine_prom_emulation[0] = '\0'; |
347 |
cur_machine_use_x11[0] = '\0'; |
cur_machine_use_x11[0] = '\0'; |
348 |
cur_machine_x11_scaledown[0] = '\0'; |
cur_machine_x11_scaledown[0] = '\0'; |
|
cur_machine_bintrans[0] = '\0'; |
|
|
cur_machine_old_bintrans[0] = '\0'; |
|
|
cur_machine_bintrans_size[0] = '\0'; |
|
349 |
cur_machine_byte_order[0] = '\0'; |
cur_machine_byte_order[0] = '\0'; |
350 |
cur_machine_random_mem[0] = '\0'; |
cur_machine_random_mem[0] = '\0'; |
351 |
cur_machine_random_cpu[0] = '\0'; |
cur_machine_random_cpu[0] = '\0'; |
356 |
cur_machine_serial_nr[0] = '\0'; |
cur_machine_serial_nr[0] = '\0'; |
357 |
cur_machine_emulated_hz[0] = '\0'; |
cur_machine_emulated_hz[0] = '\0'; |
358 |
cur_machine_memory[0] = '\0'; |
cur_machine_memory[0] = '\0'; |
|
cur_machine_max_random_cycles[0] = '\0'; |
|
359 |
return; |
return; |
360 |
} |
} |
361 |
|
|
395 |
e->net = net_init(e, NET_INIT_FLAG_GATEWAY, |
e->net = net_init(e, NET_INIT_FLAG_GATEWAY, |
396 |
cur_net_ipv4net, atoi(cur_net_ipv4len), |
cur_net_ipv4net, atoi(cur_net_ipv4len), |
397 |
cur_net_remote, cur_net_n_remote, |
cur_net_remote, cur_net_n_remote, |
398 |
atoi(cur_net_local_port)); |
atoi(cur_net_local_port), NULL); |
399 |
|
|
400 |
if (e->net == NULL) { |
if (e->net == NULL) { |
401 |
fatal("line %i: fatal error: could not create" |
fatal("line %i: fatal error: could not create" |
423 |
fprintf(stderr, "too many remote networks\n"); |
fprintf(stderr, "too many remote networks\n"); |
424 |
exit(1); |
exit(1); |
425 |
} |
} |
426 |
cur_net_remote[cur_net_n_remote] = malloc(MAX_REMOTE_LEN); |
|
427 |
if (cur_net_remote[cur_net_n_remote] == NULL) { |
CHECK_ALLOCATION(cur_net_remote[cur_net_n_remote] = |
428 |
fprintf(stderr, "out of memory\n"); |
malloc(MAX_REMOTE_LEN)); |
|
exit(1); |
|
|
} |
|
429 |
read_one_word(f, cur_net_remote[cur_net_n_remote], |
read_one_word(f, cur_net_remote[cur_net_n_remote], |
430 |
MAX_REMOTE_LEN, line, EXPECT_WORD); |
MAX_REMOTE_LEN, line, EXPECT_WORD); |
431 |
cur_net_n_remote ++; |
cur_net_n_remote ++; |
463 |
exit(1); |
exit(1); |
464 |
|
|
465 |
if (cur_machine_cpu[0]) |
if (cur_machine_cpu[0]) |
466 |
m->cpu_name = strdup(cur_machine_cpu); |
CHECK_ALLOCATION(m->cpu_name = strdup(cur_machine_cpu)); |
467 |
|
|
468 |
if (!cur_machine_use_x11[0]) |
if (!cur_machine_use_x11[0]) |
469 |
strlcpy(cur_machine_use_x11, "no", |
strlcpy(cur_machine_use_x11, "no", |
470 |
sizeof(cur_machine_use_x11)); |
sizeof(cur_machine_use_x11)); |
471 |
m->use_x11 = parse_on_off(cur_machine_use_x11); |
m->x11_md.in_use = parse_on_off(cur_machine_use_x11); |
472 |
|
|
473 |
if (!cur_machine_slowsi[0]) |
if (!cur_machine_slowsi[0]) |
474 |
strlcpy(cur_machine_slowsi, "no", |
strlcpy(cur_machine_slowsi, "no", |
476 |
m->slow_serial_interrupts_hack_for_linux = |
m->slow_serial_interrupts_hack_for_linux = |
477 |
parse_on_off(cur_machine_slowsi); |
parse_on_off(cur_machine_slowsi); |
478 |
|
|
|
if (!cur_machine_debugger_on_badaddr[0]) |
|
|
strlcpy(cur_machine_debugger_on_badaddr, "no", |
|
|
sizeof(cur_machine_debugger_on_badaddr)); |
|
|
m->single_step_on_bad_addr = |
|
|
parse_on_off(cur_machine_debugger_on_badaddr); |
|
|
|
|
479 |
if (!cur_machine_prom_emulation[0]) |
if (!cur_machine_prom_emulation[0]) |
480 |
strlcpy(cur_machine_prom_emulation, "yes", |
strlcpy(cur_machine_prom_emulation, "yes", |
481 |
sizeof(cur_machine_prom_emulation)); |
sizeof(cur_machine_prom_emulation)); |
507 |
} |
} |
508 |
} |
} |
509 |
|
|
|
if (!cur_machine_bintrans[0]) |
|
|
strlcpy(cur_machine_bintrans, "yes", |
|
|
sizeof(cur_machine_bintrans)); |
|
|
m->bintrans_enable = m->bintrans_enabled_from_start = |
|
|
parse_on_off(cur_machine_bintrans); |
|
|
|
|
|
if (!cur_machine_old_bintrans[0]) |
|
|
strlcpy(cur_machine_old_bintrans, "yes", |
|
|
sizeof(cur_machine_old_bintrans)); |
|
|
m->old_bintrans_enable = parse_on_off(cur_machine_old_bintrans); |
|
|
|
|
|
if (!m->bintrans_enable && m->old_bintrans_enable) |
|
|
m->old_bintrans_enable = 0; |
|
|
|
|
|
/* TODO: Hm... */ |
|
|
if (m->bintrans_enable && m->arch == ARCH_MIPS) |
|
|
m->speed_tricks = 0; |
|
|
|
|
|
if (cur_machine_bintrans_size[0]) |
|
|
m->bintrans_size = 1048576 * |
|
|
atoi(cur_machine_bintrans_size); |
|
|
|
|
510 |
if (!cur_machine_force_netboot[0]) |
if (!cur_machine_force_netboot[0]) |
511 |
strlcpy(cur_machine_force_netboot, "no", |
strlcpy(cur_machine_force_netboot, "no", |
512 |
sizeof(cur_machine_force_netboot)); |
sizeof(cur_machine_force_netboot)); |
534 |
if (cur_machine_emulated_hz[0]) { |
if (cur_machine_emulated_hz[0]) { |
535 |
m->emulated_hz = mystrtoull(cur_machine_emulated_hz, |
m->emulated_hz = mystrtoull(cur_machine_emulated_hz, |
536 |
NULL, 0); |
NULL, 0); |
|
m->automatic_clock_adjustment = 0; |
|
537 |
} |
} |
538 |
|
|
539 |
/* NOTE: Default nr of CPUs is 0: */ |
/* NOTE: Default nr of CPUs is 0: */ |
542 |
sizeof(cur_machine_memory)); |
sizeof(cur_machine_memory)); |
543 |
m->physical_ram_in_mb = atoi(cur_machine_memory); |
m->physical_ram_in_mb = atoi(cur_machine_memory); |
544 |
|
|
|
if (cur_machine_max_random_cycles[0]) { |
|
|
if (m->bintrans_enable) { |
|
|
fprintf(stderr, "max_random_cycles doesn't" |
|
|
" work with bintrans\n"); |
|
|
exit(1); |
|
|
} |
|
|
m->max_random_cycles_per_chunk = atoi( |
|
|
cur_machine_max_random_cycles); |
|
|
} |
|
|
|
|
545 |
if (!cur_machine_x11_scaledown[0]) |
if (!cur_machine_x11_scaledown[0]) |
546 |
m->x11_scaledown = 1; |
m->x11_md.scaledown = 1; |
547 |
else { |
else { |
548 |
m->x11_scaledown = atoi(cur_machine_x11_scaledown); |
m->x11_md.scaledown = atoi(cur_machine_x11_scaledown); |
549 |
if (m->x11_scaledown < 0) { |
if (m->x11_md.scaledown < 0) { |
550 |
m->x11_scaleup = 0 - m->x11_scaledown; |
m->x11_md.scaleup = 0 - m->x11_md.scaledown; |
551 |
m->x11_scaledown = 1; |
m->x11_md.scaledown = 1; |
552 |
} |
} |
553 |
if (m->x11_scaledown < 1) { |
if (m->x11_md.scaledown < 1) { |
554 |
fprintf(stderr, "Invalid scaledown value" |
fprintf(stderr, "Invalid scaledown value" |
555 |
" (%i)\n", m->x11_scaledown); |
" (%i)\n", m->x11_md.scaledown); |
556 |
exit(1); |
exit(1); |
557 |
} |
} |
558 |
} |
} |
569 |
m->boot_string_argument = strdup(cur_machine_bootarg); |
m->boot_string_argument = strdup(cur_machine_bootarg); |
570 |
|
|
571 |
for (i=0; i<cur_machine_n_x11_disp; i++) { |
for (i=0; i<cur_machine_n_x11_disp; i++) { |
572 |
m->x11_n_display_names ++; |
m->x11_md.n_display_names ++; |
573 |
m->x11_display_names = realloc( |
CHECK_ALLOCATION(m->x11_md.display_names = realloc( |
574 |
m->x11_display_names, m->x11_n_display_names |
m->x11_md.display_names, m->x11_md.n_display_names |
575 |
* sizeof(char *)); |
* sizeof(char *))); |
576 |
if (m->x11_display_names == NULL) { |
CHECK_ALLOCATION(m->x11_md.display_names[ |
577 |
printf("out of memory\n"); |
m->x11_md.n_display_names-1] = |
578 |
exit(1); |
strdup(cur_machine_x11_disp[i])); |
|
} |
|
|
m->x11_display_names[m->x11_n_display_names-1] = |
|
|
strdup(cur_machine_x11_disp[i]); |
|
|
if (m->x11_display_names |
|
|
[m->x11_n_display_names-1] == NULL) { |
|
|
printf("out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
579 |
free(cur_machine_x11_disp[i]); |
free(cur_machine_x11_disp[i]); |
580 |
cur_machine_x11_disp[i] = NULL; |
cur_machine_x11_disp[i] = NULL; |
581 |
} |
} |
605 |
WORD("bootname", cur_machine_bootname); |
WORD("bootname", cur_machine_bootname); |
606 |
WORD("bootarg", cur_machine_bootarg); |
WORD("bootarg", cur_machine_bootarg); |
607 |
WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi); |
WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi); |
|
WORD("debugger_on_badaddr", cur_machine_debugger_on_badaddr); |
|
608 |
WORD("prom_emulation", cur_machine_prom_emulation); |
WORD("prom_emulation", cur_machine_prom_emulation); |
609 |
WORD("use_x11", cur_machine_use_x11); |
WORD("use_x11", cur_machine_use_x11); |
610 |
WORD("x11_scaledown", cur_machine_x11_scaledown); |
WORD("x11_scaledown", cur_machine_x11_scaledown); |
|
WORD("bintrans", cur_machine_bintrans); |
|
|
WORD("old_bintrans", cur_machine_old_bintrans); |
|
|
WORD("bintrans_size", cur_machine_bintrans_size); |
|
611 |
WORD("byte_order", cur_machine_byte_order); |
WORD("byte_order", cur_machine_byte_order); |
612 |
WORD("random_mem_contents", cur_machine_random_mem); |
WORD("random_mem_contents", cur_machine_random_mem); |
613 |
WORD("use_random_bootstrap_cpu", cur_machine_random_cpu); |
WORD("use_random_bootstrap_cpu", cur_machine_random_cpu); |
617 |
WORD("n_gfx_cards", cur_machine_n_gfx_cards); |
WORD("n_gfx_cards", cur_machine_n_gfx_cards); |
618 |
WORD("emulated_hz", cur_machine_emulated_hz); |
WORD("emulated_hz", cur_machine_emulated_hz); |
619 |
WORD("memory", cur_machine_memory); |
WORD("memory", cur_machine_memory); |
|
WORD("max_random_cycles", cur_machine_max_random_cycles); |
|
620 |
WORD("start_paused", cur_machine_start_paused); |
WORD("start_paused", cur_machine_start_paused); |
621 |
|
|
622 |
if (strcmp(word, "load") == 0) { |
if (strcmp(word, "load") == 0) { |
626 |
fprintf(stderr, "too many loads\n"); |
fprintf(stderr, "too many loads\n"); |
627 |
exit(1); |
exit(1); |
628 |
} |
} |
629 |
cur_machine_load[cur_machine_n_load] = malloc(MAX_LOAD_LEN); |
CHECK_ALLOCATION(cur_machine_load[cur_machine_n_load] = |
630 |
if (cur_machine_load[cur_machine_n_load] == NULL) { |
malloc(MAX_LOAD_LEN)); |
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
631 |
read_one_word(f, cur_machine_load[cur_machine_n_load], |
read_one_word(f, cur_machine_load[cur_machine_n_load], |
632 |
MAX_LOAD_LEN, line, EXPECT_WORD); |
MAX_LOAD_LEN, line, EXPECT_WORD); |
633 |
cur_machine_n_load ++; |
cur_machine_n_load ++; |
643 |
fprintf(stderr, "too many disks\n"); |
fprintf(stderr, "too many disks\n"); |
644 |
exit(1); |
exit(1); |
645 |
} |
} |
646 |
cur_machine_disk[cur_machine_n_disk] = malloc(MAX_DISK_LEN); |
CHECK_ALLOCATION(cur_machine_disk[cur_machine_n_disk] = |
647 |
if (cur_machine_disk[cur_machine_n_disk] == NULL) { |
malloc(MAX_DISK_LEN)); |
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
648 |
read_one_word(f, cur_machine_disk[cur_machine_n_disk], |
read_one_word(f, cur_machine_disk[cur_machine_n_disk], |
649 |
MAX_DISK_LEN, line, EXPECT_WORD); |
MAX_DISK_LEN, line, EXPECT_WORD); |
650 |
cur_machine_n_disk ++; |
cur_machine_n_disk ++; |
660 |
fprintf(stderr, "too many devices\n"); |
fprintf(stderr, "too many devices\n"); |
661 |
exit(1); |
exit(1); |
662 |
} |
} |
663 |
cur_machine_device[cur_machine_n_device] = |
CHECK_ALLOCATION(cur_machine_device[cur_machine_n_device] = |
664 |
malloc(MAX_DEVICE_LEN); |
malloc(MAX_DEVICE_LEN)); |
|
if (cur_machine_device[cur_machine_n_device] == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
665 |
read_one_word(f, cur_machine_device[cur_machine_n_device], |
read_one_word(f, cur_machine_device[cur_machine_n_device], |
666 |
MAX_DEVICE_LEN, line, EXPECT_WORD); |
MAX_DEVICE_LEN, line, EXPECT_WORD); |
667 |
cur_machine_n_device ++; |
cur_machine_n_device ++; |
677 |
fprintf(stderr, "too many x11 displays\n"); |
fprintf(stderr, "too many x11 displays\n"); |
678 |
exit(1); |
exit(1); |
679 |
} |
} |
680 |
cur_machine_x11_disp[cur_machine_n_x11_disp] = |
CHECK_ALLOCATION(cur_machine_x11_disp[cur_machine_n_x11_disp] = |
681 |
malloc(MAX_X11_DISP_LEN); |
malloc(MAX_X11_DISP_LEN)); |
|
if (cur_machine_x11_disp[cur_machine_n_x11_disp] == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
682 |
read_one_word(f, cur_machine_x11_disp[cur_machine_n_x11_disp], |
read_one_word(f, cur_machine_x11_disp[cur_machine_n_x11_disp], |
683 |
MAX_X11_DISP_LEN, line, EXPECT_WORD); |
MAX_X11_DISP_LEN, line, EXPECT_WORD); |
684 |
cur_machine_n_x11_disp ++; |
cur_machine_n_x11_disp ++; |
698 |
* |
* |
699 |
* Set up an emulation by parsing a config file. |
* Set up an emulation by parsing a config file. |
700 |
*/ |
*/ |
701 |
void emul_parse_config(struct emul *e, FILE *f) |
void emul_parse_config(struct emul *e, char *fname) |
702 |
{ |
{ |
703 |
char word[500]; |
FILE *f = fopen(fname, "r"); |
704 |
|
char word[MAX_WORD_LEN]; |
705 |
int in_emul = 0; |
int in_emul = 0; |
706 |
int line = 1; |
int line = 1; |
707 |
int parsestate = PARSESTATE_NONE; |
int parsestate = PARSESTATE_EMUL; |
708 |
|
|
709 |
/* debug("emul_parse_config()\n"); */ |
/* debug("emul_parse_config()\n"); */ |
710 |
|
if (f == NULL) { |
711 |
|
perror(fname); |
712 |
|
exit(1); |
713 |
|
} |
714 |
|
|
715 |
while (!feof(f)) { |
while (!feof(f)) { |
716 |
read_one_word(f, word, sizeof(word), &line, |
read_one_word(f, word, sizeof(word), &line, |
721 |
/* debug("word = '%s'\n", word); */ |
/* debug("word = '%s'\n", word); */ |
722 |
|
|
723 |
switch (parsestate) { |
switch (parsestate) { |
|
case PARSESTATE_NONE: |
|
|
parse__none(e, f, &in_emul, &line, &parsestate, |
|
|
word, sizeof(word)); |
|
|
break; |
|
724 |
case PARSESTATE_EMUL: |
case PARSESTATE_EMUL: |
725 |
parse__emul(e, f, &in_emul, &line, &parsestate, |
parse__emul(e, f, &in_emul, &line, &parsestate, |
726 |
word, sizeof(word)); |
word, sizeof(word)); |
733 |
parse__machine(e, f, &in_emul, &line, &parsestate, |
parse__machine(e, f, &in_emul, &line, &parsestate, |
734 |
word, sizeof(word)); |
word, sizeof(word)); |
735 |
break; |
break; |
736 |
|
case PARSESTATE_NONE: |
737 |
|
break; |
738 |
default: |
default: |
739 |
fatal("INTERNAL ERROR in emul_parse.c (" |
fatal("INTERNAL ERROR in emul_parse.c (" |
740 |
"parsestate %i is not imlemented yet?)\n", |
"parsestate %i is not imlemented yet?)\n", |
743 |
} |
} |
744 |
} |
} |
745 |
|
|
746 |
if (parsestate != PARSESTATE_NONE) { |
if (parenthesis_level != 0) { |
747 |
fatal("EOF but not enough right parentheses?\n"); |
fatal("EOF but not enough right parentheses?\n"); |
748 |
exit(1); |
exit(1); |
749 |
} |
} |
750 |
|
|
751 |
|
fclose(f); |
752 |
} |
} |
753 |
|
|