44 #define is_word_char(ch) ( \
45 (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \
46 ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') )
48 #define MAX_WORD_LEN 200
51 #define EXPECT_LEFT_PARENTHESIS 2
52 #define EXPECT_RIGHT_PARENTHESIS 4
54 static int parenthesis_level = 0;
66 static void read_one_word(FILE *
f,
char *buf,
int buflen,
int *line,
75 if (curlen >= buflen - 1)
85 if (curlen == buflen - 1)
89 if (ungetc(ch,
f) == EOF) {
90 fatal(
"ungetc() failed?\n");
107 while (ch !=
'\n' && ch != EOF)
127 fatal(
"line %i: unexpected EOF inside"
128 " a nested comment\n", *line);
139 if (ch ==
'"' || ch ==
'\'') {
144 fatal(
"unexpected character '%c', line %i\n",
149 while (curlen < buflen - 1) {
152 fatal(
"line %i: newline inside"
153 " quotes?\n", *line);
157 fatal(
"line %i: EOF inside a quoted"
158 " string?\n", *line);
171 if (curlen == buflen - 1)
175 parenthesis_level ++;
180 parenthesis_level --;
185 fatal(
"unexpected character '%c', line %i\n",
195 #define PARSESTATE_NONE 0
196 #define PARSESTATE_EMUL 1
197 #define PARSESTATE_NET 2
198 #define PARSESTATE_MACHINE 3
200 static char cur_net_ipv4net[50];
201 static char cur_net_ipv4len[50];
202 static char cur_net_local_port[10];
203 #define MAX_N_REMOTE 20
204 #define MAX_REMOTE_LEN 100
206 static int cur_net_n_remote;
208 static char cur_machine_name[50];
209 static char cur_machine_cpu[50];
210 static char cur_machine_type[50];
211 static char cur_machine_subtype[50];
212 static char cur_machine_bootname[150];
213 static char cur_machine_bootarg[250];
214 static char cur_machine_slowsi[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_byte_order[20];
219 static char cur_machine_random_mem[10];
220 static char cur_machine_random_cpu[10];
221 static char cur_machine_force_netboot[10];
222 static char cur_machine_start_paused[10];
223 static char cur_machine_ncpus[10];
224 static char cur_machine_n_gfx_cards[10];
225 static char cur_machine_serial_nr[10];
226 static char cur_machine_emulated_hz[10];
227 static char cur_machine_memory[10];
228 #define MAX_N_LOAD 15
229 #define MAX_LOAD_LEN 2000
231 static int cur_machine_n_load;
232 #define MAX_N_DISK 10
233 #define MAX_DISK_LEN 2000
235 static int cur_machine_n_disk;
236 #define MAX_N_DEVICE 20
237 #define MAX_DEVICE_LEN 400
239 static int cur_machine_n_device;
240 #define MAX_N_X11_DISP 5
241 #define MAX_X11_DISP_LEN 1000
243 static int cur_machine_n_x11_disp;
245 #define WORD(w,var) { \
246 if (strcmp(word, w) == 0) { \
247 read_one_word(f, word, maxbuflen, \
248 line, EXPECT_LEFT_PARENTHESIS); \
249 read_one_word(f, var, sizeof(var), \
250 line, EXPECT_WORD); \
251 read_one_word(f, word, maxbuflen, \
252 line, EXPECT_RIGHT_PARENTHESIS); \
257 static void parse__machine(
struct emul *e, FILE *
f,
int *in_emul,
int *line,
258 int *parsestate,
char *word,
size_t maxbuflen);
270 if (strcasecmp(s,
"on") == 0 || strcasecmp(s,
"yes") == 0 ||
271 strcasecmp(s,
"enable") == 0 || strcasecmp(s,
"1") == 0)
273 if (strcasecmp(s,
"off") == 0 || strcasecmp(s,
"no") == 0 ||
274 strcasecmp(s,
"disable") == 0 || strcasecmp(s,
"0") == 0)
277 fprintf(stderr,
"parse_on_off(): WARNING: unknown value '%s'\n", s);
288 static void parse__emul(
struct emul *e, FILE *
f,
int *in_emul,
int *line,
289 int *parsestate,
char *word,
size_t maxbuflen)
291 if (word[0] ==
')') {
296 if (strcmp(word,
"name") == 0) {
298 read_one_word(
f, word, maxbuflen,
301 read_one_word(
f, word, maxbuflen,
303 if (e->
name != NULL) {
312 if (strcmp(word,
"net") == 0) {
314 read_one_word(
f, word, maxbuflen,
319 sizeof(cur_net_ipv4net));
320 snprintf(cur_net_ipv4len,
sizeof(cur_net_ipv4len),
"%i",
322 strlcpy(cur_net_local_port,
"",
sizeof(cur_net_local_port));
323 cur_net_n_remote = 0;
327 if (strcmp(word,
"machine") == 0) {
329 read_one_word(
f, word, maxbuflen,
333 cur_machine_name[0] =
'\0';
334 cur_machine_cpu[0] =
'\0';
335 cur_machine_type[0] =
'\0';
336 cur_machine_subtype[0] =
'\0';
337 cur_machine_bootname[0] =
'\0';
338 cur_machine_bootarg[0] =
'\0';
339 cur_machine_n_load = 0;
340 cur_machine_n_disk = 0;
341 cur_machine_n_device = 0;
342 cur_machine_n_x11_disp = 0;
343 cur_machine_slowsi[0] =
'\0';
344 cur_machine_prom_emulation[0] =
'\0';
345 cur_machine_use_x11[0] =
'\0';
346 cur_machine_x11_scaledown[0] =
'\0';
347 cur_machine_byte_order[0] =
'\0';
348 cur_machine_random_mem[0] =
'\0';
349 cur_machine_random_cpu[0] =
'\0';
350 cur_machine_force_netboot[0] =
'\0';
351 cur_machine_start_paused[0] =
'\0';
352 cur_machine_ncpus[0] =
'\0';
353 cur_machine_n_gfx_cards[0] =
'\0';
354 cur_machine_serial_nr[0] =
'\0';
355 cur_machine_emulated_hz[0] =
'\0';
356 cur_machine_memory[0] =
'\0';
360 fatal(
"line %i: not expecting '%s' in an 'emul' section\n",
376 static void parse__net(
struct emul *e, FILE *
f,
int *in_emul,
int *line,
377 int *parsestate,
char *word,
size_t maxbuflen)
381 if (word[0] ==
')') {
383 if (e->
net != NULL) {
384 fatal(
"line %i: more than one net isn't really "
385 "supported yet\n", *line);
389 if (!cur_net_local_port[0])
390 strlcpy(cur_net_local_port,
"0",
391 sizeof(cur_net_local_port));
394 cur_net_ipv4net, atoi(cur_net_ipv4len),
395 cur_net_remote, cur_net_n_remote,
396 atoi(cur_net_local_port), NULL);
398 if (e->
net == NULL) {
399 fatal(
"line %i: fatal error: could not create"
400 " the net (?)\n", *line);
404 for (i=0; i<cur_net_n_remote; i++) {
405 free(cur_net_remote[i]);
406 cur_net_remote[i] = NULL;
413 WORD(
"ipv4net", cur_net_ipv4net);
414 WORD(
"ipv4len", cur_net_ipv4len);
415 WORD(
"local_port", cur_net_local_port);
417 if (strcmp(word,
"add_remote") == 0) {
418 read_one_word(
f, word, maxbuflen,
421 fprintf(stderr,
"too many remote networks\n");
427 read_one_word(
f, cur_net_remote[cur_net_n_remote],
430 read_one_word(
f, word, maxbuflen, line,
435 fatal(
"line %i: not expecting '%s' in a 'net' section\n", *line, word);
443 static void parse__machine(
struct emul *e, FILE *
f,
int *in_emul,
int *line,
444 int *parsestate,
char *word,
size_t maxbuflen)
448 if (word[0] ==
')') {
452 if (!cur_machine_name[0])
453 strlcpy(cur_machine_name,
"no_name",
454 sizeof(cur_machine_name));
463 if (cur_machine_cpu[0])
466 if (!cur_machine_use_x11[0])
467 strlcpy(cur_machine_use_x11,
"no",
468 sizeof(cur_machine_use_x11));
471 if (!cur_machine_slowsi[0])
472 strlcpy(cur_machine_slowsi,
"no",
473 sizeof(cur_machine_slowsi));
477 if (!cur_machine_prom_emulation[0])
478 strlcpy(cur_machine_prom_emulation,
"yes",
479 sizeof(cur_machine_prom_emulation));
482 if (!cur_machine_random_mem[0])
483 strlcpy(cur_machine_random_mem,
"no",
484 sizeof(cur_machine_random_mem));
488 if (!cur_machine_random_cpu[0])
489 strlcpy(cur_machine_random_cpu,
"no",
490 sizeof(cur_machine_random_cpu));
495 if (cur_machine_byte_order[0]) {
496 if (strncasecmp(cur_machine_byte_order,
"big", 3) == 0)
498 else if (strncasecmp(cur_machine_byte_order,
"little",
502 fatal(
"Byte order must be big-endian or"
508 if (!cur_machine_force_netboot[0])
509 strlcpy(cur_machine_force_netboot,
"no",
510 sizeof(cur_machine_force_netboot));
513 if (!cur_machine_start_paused[0])
514 strlcpy(cur_machine_start_paused,
"no",
515 sizeof(cur_machine_start_paused));
519 if (!cur_machine_ncpus[0])
520 strlcpy(cur_machine_ncpus,
"0",
521 sizeof(cur_machine_ncpus));
522 m->
ncpus = atoi(cur_machine_ncpus);
524 if (cur_machine_n_gfx_cards[0])
527 if (cur_machine_serial_nr[0]) {
528 m->
serial_nr = atoi(cur_machine_serial_nr);
532 if (cur_machine_emulated_hz[0]) {
538 if (!cur_machine_memory[0])
539 strlcpy(cur_machine_memory,
"0",
540 sizeof(cur_machine_memory));
543 if (!cur_machine_x11_scaledown[0])
552 fprintf(stderr,
"Invalid scaledown value"
558 for (i=0; i<cur_machine_n_disk; i++) {
560 free(cur_machine_disk[i]);
561 cur_machine_disk[i] = NULL;
566 if (cur_machine_bootarg[0])
569 for (i=0; i<cur_machine_n_x11_disp; i++) {
576 strdup(cur_machine_x11_disp[i]));
577 free(cur_machine_x11_disp[i]);
578 cur_machine_x11_disp[i] = NULL;
582 cur_machine_n_load, cur_machine_load,
583 cur_machine_n_device, cur_machine_device);
585 for (i=0; i<cur_machine_n_device; i++) {
586 free(cur_machine_device[i]);
587 cur_machine_device[i] = NULL;
590 for (i=0; i<cur_machine_n_load; i++) {
591 free(cur_machine_load[i]);
592 cur_machine_load[i] = NULL;
599 WORD(
"name", cur_machine_name);
600 WORD(
"cpu", cur_machine_cpu);
601 WORD(
"type", cur_machine_type);
602 WORD(
"subtype", cur_machine_subtype);
603 WORD(
"bootname", cur_machine_bootname);
604 WORD(
"bootarg", cur_machine_bootarg);
605 WORD(
"slow_serial_interrupts_hack_for_linux", cur_machine_slowsi);
606 WORD(
"prom_emulation", cur_machine_prom_emulation);
607 WORD(
"use_x11", cur_machine_use_x11);
608 WORD(
"x11_scaledown", cur_machine_x11_scaledown);
609 WORD(
"byte_order", cur_machine_byte_order);
610 WORD(
"random_mem_contents", cur_machine_random_mem);
611 WORD(
"use_random_bootstrap_cpu", cur_machine_random_cpu);
612 WORD(
"force_netboot", cur_machine_force_netboot);
613 WORD(
"ncpus", cur_machine_ncpus);
614 WORD(
"serial_nr", cur_machine_serial_nr);
615 WORD(
"n_gfx_cards", cur_machine_n_gfx_cards);
616 WORD(
"emulated_hz", cur_machine_emulated_hz);
617 WORD(
"memory", cur_machine_memory);
618 WORD(
"start_paused", cur_machine_start_paused);
620 if (strcmp(word,
"load") == 0) {
621 read_one_word(
f, word, maxbuflen,
624 fprintf(stderr,
"too many loads\n");
629 read_one_word(
f, cur_machine_load[cur_machine_n_load],
631 cur_machine_n_load ++;
632 read_one_word(
f, word, maxbuflen,
637 if (strcmp(word,
"disk") == 0) {
638 read_one_word(
f, word, maxbuflen,
641 fprintf(stderr,
"too many disks\n");
646 read_one_word(
f, cur_machine_disk[cur_machine_n_disk],
648 cur_machine_n_disk ++;
649 read_one_word(
f, word, maxbuflen,
654 if (strcmp(word,
"device") == 0) {
655 read_one_word(
f, word, maxbuflen,
658 fprintf(stderr,
"too many devices\n");
663 read_one_word(
f, cur_machine_device[cur_machine_n_device],
665 cur_machine_n_device ++;
666 read_one_word(
f, word, maxbuflen,
671 if (strcmp(word,
"add_x11_display") == 0) {
672 read_one_word(
f, word, maxbuflen,
675 fprintf(stderr,
"too many x11 displays\n");
680 read_one_word(
f, cur_machine_x11_disp[cur_machine_n_x11_disp],
682 cur_machine_n_x11_disp ++;
683 read_one_word(
f, word, maxbuflen,
688 fatal(
"line %i: not expecting '%s' in a 'machine' section\n",
701 FILE *
f = fopen(fname,
"r");
714 read_one_word(
f, word,
sizeof(word), &line,
721 switch (parsestate) {
723 parse__emul(e,
f, &in_emul, &line, &parsestate,
727 parse__net(e,
f, &in_emul, &line, &parsestate,
731 parse__machine(e,
f, &in_emul, &line, &parsestate,
737 fatal(
"INTERNAL ERROR in emul_parse.c ("
738 "parsestate %i is not imlemented yet?)\n",
744 if (parenthesis_level != 0) {
745 fatal(
"EOF but not enough right parentheses?\n");