emul_parse.cc Source File

Back to the index.

emul_parse.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2009 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  * Set up an emulation by parsing a config file.
29  *
30  * TODO: REWRITE THIS FROM SCRATCH! :-)
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include "diskimage.h"
38 #include "emul.h"
39 #include "machine.h"
40 #include "misc.h"
41 #include "net.h"
42 
43 
44 #define is_word_char(ch) ( \
45  (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \
46  ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') )
47 
48 #define MAX_WORD_LEN 200
49 
50 #define EXPECT_WORD 1
51 #define EXPECT_LEFT_PARENTHESIS 2
52 #define EXPECT_RIGHT_PARENTHESIS 4
53 
54 static int parenthesis_level = 0;
55 
56 
57 /*
58  * read_one_word():
59  *
60  * Reads the file f until it has read a complete word. Whitespace is ignored,
61  * and also any exclamation mark ('!') and anything following an exclamation
62  * mark on a line.
63  *
64  * Used internally by emul_parse_config().
65  */
66 static void read_one_word(FILE *f, char *buf, int buflen, int *line,
67  int expect)
68 {
69  int ch;
70  int done = 0;
71  int curlen = 0;
72  int in_word = 0;
73 
74  while (!done) {
75  if (curlen >= buflen - 1)
76  break;
77 
78  ch = fgetc(f);
79  if (ch == EOF)
80  break;
81 
82  if (in_word) {
83  if (is_word_char(ch)) {
84  buf[curlen++] = ch;
85  if (curlen == buflen - 1)
86  done = 1;
87  continue;
88  } else {
89  if (ungetc(ch, f) == EOF) {
90  fatal("ungetc() failed?\n");
91  exit(1);
92  }
93  break;
94  }
95  }
96 
97  if (ch == '\n') {
98  (*line) ++;
99  continue;
100  }
101 
102  if (ch == '\r')
103  continue;
104 
105  if (ch == '!') {
106  /* Skip until newline: */
107  while (ch != '\n' && ch != EOF)
108  ch = fgetc(f);
109  if (ch == '\n')
110  (*line) ++;
111  continue;
112  }
113 
114  if (ch == '{') {
115  int depth = 1;
116 
117  /* Skip until '}': */
118  while (depth > 0) {
119  ch = fgetc(f);
120  if (ch == '\n')
121  (*line) ++;
122  if (ch == '{')
123  depth ++;
124  if (ch == '}')
125  depth --;
126  if (ch == EOF) {
127  fatal("line %i: unexpected EOF inside"
128  " a nested comment\n", *line);
129  exit(1);
130  }
131  }
132  continue;
133  }
134 
135  /* Whitespace? */
136  if (ch <= ' ')
137  continue;
138 
139  if (ch == '"' || ch == '\'') {
140  /* This is a quoted word. */
141  int start_ch = ch;
142 
143  if (expect & EXPECT_LEFT_PARENTHESIS) {
144  fatal("unexpected character '%c', line %i\n",
145  ch, *line);
146  exit(1);
147  }
148 
149  while (curlen < buflen - 1) {
150  ch = fgetc(f);
151  if (ch == '\n') {
152  fatal("line %i: newline inside"
153  " quotes?\n", *line);
154  exit(1);
155  }
156  if (ch == EOF) {
157  fatal("line %i: EOF inside a quoted"
158  " string?\n", *line);
159  exit(1);
160  }
161  if (ch == start_ch)
162  break;
163  buf[curlen++] = ch;
164  }
165  break;
166  }
167 
168  if ((expect & EXPECT_WORD) && is_word_char(ch)) {
169  buf[curlen++] = ch;
170  in_word = 1;
171  if (curlen == buflen - 1)
172  done = 1;
173  } else {
174  if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') {
175  parenthesis_level ++;
176  buf[curlen++] = ch;
177  break;
178  }
179  if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') {
180  parenthesis_level --;
181  buf[curlen++] = ch;
182  break;
183  }
184 
185  fatal("unexpected character '%c', line %i\n",
186  ch, *line);
187  exit(1);
188  }
189  }
190 
191  buf[curlen] = '\0';
192 }
193 
194 
195 #define PARSESTATE_NONE 0
196 #define PARSESTATE_EMUL 1
197 #define PARSESTATE_NET 2
198 #define PARSESTATE_MACHINE 3
199 
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
205 static char *cur_net_remote[MAX_N_REMOTE];
206 static int cur_net_n_remote;
207 
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
230 static char *cur_machine_load[MAX_N_LOAD];
231 static int cur_machine_n_load;
232 #define MAX_N_DISK 10
233 #define MAX_DISK_LEN 2000
234 static char *cur_machine_disk[MAX_N_DISK];
235 static int cur_machine_n_disk;
236 #define MAX_N_DEVICE 20
237 #define MAX_DEVICE_LEN 400
238 static char *cur_machine_device[MAX_N_DISK];
239 static int cur_machine_n_device;
240 #define MAX_N_X11_DISP 5
241 #define MAX_X11_DISP_LEN 1000
242 static char *cur_machine_x11_disp[MAX_N_X11_DISP];
243 static int cur_machine_n_x11_disp;
244 
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); \
253  return; \
254  } \
255  }
256 
257 static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
258  int *parsestate, char *word, size_t maxbuflen);
259 
260 
261 /*
262  * parse_on_off():
263  *
264  * Returns 1 for "on", "yes", "enable", or "1".
265  * Returns 0 for "off", "no", "disable", or "0".
266  * Prints a fatal warning and exit()s for other values.
267  */
268 int parse_on_off(char *s)
269 {
270  if (strcasecmp(s, "on") == 0 || strcasecmp(s, "yes") == 0 ||
271  strcasecmp(s, "enable") == 0 || strcasecmp(s, "1") == 0)
272  return 1;
273  if (strcasecmp(s, "off") == 0 || strcasecmp(s, "no") == 0 ||
274  strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0)
275  return 0;
276 
277  fprintf(stderr, "parse_on_off(): WARNING: unknown value '%s'\n", s);
278 
279  return 0;
280 }
281 
282 
283 /*
284  * parse__emul():
285  *
286  * name, net, machine
287  */
288 static void parse__emul(struct emul *e, FILE *f, int *in_emul, int *line,
289  int *parsestate, char *word, size_t maxbuflen)
290 {
291  if (word[0] == ')') {
292  *parsestate = PARSESTATE_NONE;
293  return;
294  }
295 
296  if (strcmp(word, "name") == 0) {
297  char tmp[200];
298  read_one_word(f, word, maxbuflen,
300  read_one_word(f, tmp, sizeof(tmp), line, EXPECT_WORD);
301  read_one_word(f, word, maxbuflen,
303  if (e->name != NULL) {
304  free(e->name);
305  e->name = NULL;
306  }
307  CHECK_ALLOCATION(e->name = strdup(tmp));
308  debug("name: \"%s\"\n", e->name);
309  return;
310  }
311 
312  if (strcmp(word, "net") == 0) {
313  *parsestate = PARSESTATE_NET;
314  read_one_word(f, word, maxbuflen,
316 
317  /* Default net: */
318  strlcpy(cur_net_ipv4net, NET_DEFAULT_IPV4_MASK,
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;
324  return;
325  }
326 
327  if (strcmp(word, "machine") == 0) {
328  *parsestate = PARSESTATE_MACHINE;
329  read_one_word(f, word, maxbuflen,
331 
332  /* A "zero state": */
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';
357  return;
358  }
359 
360  fatal("line %i: not expecting '%s' in an 'emul' section\n",
361  *line, word);
362  exit(1);
363 }
364 
365 
366 /*
367  * parse__net():
368  *
369  * Simple words: ipv4net, ipv4len, local_port
370  *
371  * Complex: add_remote
372  *
373  * TODO: more words? for example an option to disable the gateway? that would
374  * have to be implemented correctly in src/net.c first.
375  */
376 static void parse__net(struct emul *e, FILE *f, int *in_emul, int *line,
377  int *parsestate, char *word, size_t maxbuflen)
378 {
379  int i;
380 
381  if (word[0] == ')') {
382  /* Finished with the 'net' section. Let's create the net: */
383  if (e->net != NULL) {
384  fatal("line %i: more than one net isn't really "
385  "supported yet\n", *line);
386  exit(1);
387  }
388 
389  if (!cur_net_local_port[0])
390  strlcpy(cur_net_local_port, "0",
391  sizeof(cur_net_local_port));
392 
394  cur_net_ipv4net, atoi(cur_net_ipv4len),
395  cur_net_remote, cur_net_n_remote,
396  atoi(cur_net_local_port), NULL);
397 
398  if (e->net == NULL) {
399  fatal("line %i: fatal error: could not create"
400  " the net (?)\n", *line);
401  exit(1);
402  }
403 
404  for (i=0; i<cur_net_n_remote; i++) {
405  free(cur_net_remote[i]);
406  cur_net_remote[i] = NULL;
407  }
408 
409  *parsestate = PARSESTATE_EMUL;
410  return;
411  }
412 
413  WORD("ipv4net", cur_net_ipv4net);
414  WORD("ipv4len", cur_net_ipv4len);
415  WORD("local_port", cur_net_local_port);
416 
417  if (strcmp(word, "add_remote") == 0) {
418  read_one_word(f, word, maxbuflen,
420  if (cur_net_n_remote >= MAX_N_REMOTE) {
421  fprintf(stderr, "too many remote networks\n");
422  exit(1);
423  }
424 
425  CHECK_ALLOCATION(cur_net_remote[cur_net_n_remote] =
426  (char *) malloc(MAX_REMOTE_LEN));
427  read_one_word(f, cur_net_remote[cur_net_n_remote],
428  MAX_REMOTE_LEN, line, EXPECT_WORD);
429  cur_net_n_remote ++;
430  read_one_word(f, word, maxbuflen, line,
432  return;
433  }
434 
435  fatal("line %i: not expecting '%s' in a 'net' section\n", *line, word);
436  exit(1);
437 }
438 
439 
440 /*
441  * parse__machine():
442  */
443 static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
444  int *parsestate, char *word, size_t maxbuflen)
445 {
446  int r, i;
447 
448  if (word[0] == ')') {
449  /* Finished with the 'machine' section. */
450  struct machine *m;
451 
452  if (!cur_machine_name[0])
453  strlcpy(cur_machine_name, "no_name",
454  sizeof(cur_machine_name));
455 
456  m = emul_add_machine(e, cur_machine_name);
457 
458  r = machine_name_to_type(cur_machine_type, cur_machine_subtype,
459  &m->machine_type, &m->machine_subtype, &m->arch);
460  if (!r)
461  exit(1);
462 
463  if (cur_machine_cpu[0])
464  CHECK_ALLOCATION(m->cpu_name = strdup(cur_machine_cpu));
465 
466  if (!cur_machine_use_x11[0])
467  strlcpy(cur_machine_use_x11, "no",
468  sizeof(cur_machine_use_x11));
469  m->x11_md.in_use = parse_on_off(cur_machine_use_x11);
470 
471  if (!cur_machine_slowsi[0])
472  strlcpy(cur_machine_slowsi, "no",
473  sizeof(cur_machine_slowsi));
475  parse_on_off(cur_machine_slowsi);
476 
477  if (!cur_machine_prom_emulation[0])
478  strlcpy(cur_machine_prom_emulation, "yes",
479  sizeof(cur_machine_prom_emulation));
480  m->prom_emulation = parse_on_off(cur_machine_prom_emulation);
481 
482  if (!cur_machine_random_mem[0])
483  strlcpy(cur_machine_random_mem, "no",
484  sizeof(cur_machine_random_mem));
486  parse_on_off(cur_machine_random_mem);
487 
488  if (!cur_machine_random_cpu[0])
489  strlcpy(cur_machine_random_cpu, "no",
490  sizeof(cur_machine_random_cpu));
492  parse_on_off(cur_machine_random_cpu);
493 
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",
499  6) == 0)
501  else {
502  fatal("Byte order must be big-endian or"
503  " little-endian\n");
504  exit(1);
505  }
506  }
507 
508  if (!cur_machine_force_netboot[0])
509  strlcpy(cur_machine_force_netboot, "no",
510  sizeof(cur_machine_force_netboot));
511  m->force_netboot = parse_on_off(cur_machine_force_netboot);
512 
513  if (!cur_machine_start_paused[0])
514  strlcpy(cur_machine_start_paused, "no",
515  sizeof(cur_machine_start_paused));
516  m->start_paused = parse_on_off(cur_machine_start_paused);
517 
518  /* NOTE: Default nr of CPUs is 0: */
519  if (!cur_machine_ncpus[0])
520  strlcpy(cur_machine_ncpus, "0",
521  sizeof(cur_machine_ncpus));
522  m->ncpus = atoi(cur_machine_ncpus);
523 
524  if (cur_machine_n_gfx_cards[0])
525  m->n_gfx_cards = atoi(cur_machine_n_gfx_cards);
526 
527  if (cur_machine_serial_nr[0]) {
528  m->serial_nr = atoi(cur_machine_serial_nr);
529  e->next_serial_nr = m->serial_nr+1;
530  }
531 
532  if (cur_machine_emulated_hz[0]) {
533  m->emulated_hz = mystrtoull(cur_machine_emulated_hz,
534  NULL, 0);
535  }
536 
537  /* NOTE: Default nr of CPUs is 0: */
538  if (!cur_machine_memory[0])
539  strlcpy(cur_machine_memory, "0",
540  sizeof(cur_machine_memory));
541  m->physical_ram_in_mb = atoi(cur_machine_memory);
542 
543  if (!cur_machine_x11_scaledown[0])
544  m->x11_md.scaledown = 1;
545  else {
546  m->x11_md.scaledown = atoi(cur_machine_x11_scaledown);
547  if (m->x11_md.scaledown < 0) {
548  m->x11_md.scaleup = 0 - m->x11_md.scaledown;
549  m->x11_md.scaledown = 1;
550  }
551  if (m->x11_md.scaledown < 1) {
552  fprintf(stderr, "Invalid scaledown value"
553  " (%i)\n", m->x11_md.scaledown);
554  exit(1);
555  }
556  }
557 
558  for (i=0; i<cur_machine_n_disk; i++) {
559  diskimage_add(m, cur_machine_disk[i]);
560  free(cur_machine_disk[i]);
561  cur_machine_disk[i] = NULL;
562  }
563 
564  m->boot_kernel_filename = strdup(cur_machine_bootname);
565 
566  if (cur_machine_bootarg[0])
567  m->boot_string_argument = strdup(cur_machine_bootarg);
568 
569  for (i=0; i<cur_machine_n_x11_disp; i++) {
570  m->x11_md.n_display_names ++;
571  CHECK_ALLOCATION(m->x11_md.display_names = (char **) realloc(
573  * sizeof(char *)));
575  m->x11_md.n_display_names-1] =
576  strdup(cur_machine_x11_disp[i]));
577  free(cur_machine_x11_disp[i]);
578  cur_machine_x11_disp[i] = NULL;
579  }
580 
582  cur_machine_n_load, cur_machine_load,
583  cur_machine_n_device, cur_machine_device);
584 
585  for (i=0; i<cur_machine_n_device; i++) {
586  free(cur_machine_device[i]);
587  cur_machine_device[i] = NULL;
588  }
589 
590  for (i=0; i<cur_machine_n_load; i++) {
591  free(cur_machine_load[i]);
592  cur_machine_load[i] = NULL;
593  }
594 
595  *parsestate = PARSESTATE_EMUL;
596  return;
597  }
598 
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);
619 
620  if (strcmp(word, "load") == 0) {
621  read_one_word(f, word, maxbuflen,
623  if (cur_machine_n_load >= MAX_N_LOAD) {
624  fprintf(stderr, "too many loads\n");
625  exit(1);
626  }
627  CHECK_ALLOCATION(cur_machine_load[cur_machine_n_load] =
628  (char*) malloc(MAX_LOAD_LEN));
629  read_one_word(f, cur_machine_load[cur_machine_n_load],
630  MAX_LOAD_LEN, line, EXPECT_WORD);
631  cur_machine_n_load ++;
632  read_one_word(f, word, maxbuflen,
634  return;
635  }
636 
637  if (strcmp(word, "disk") == 0) {
638  read_one_word(f, word, maxbuflen,
640  if (cur_machine_n_disk >= MAX_N_DISK) {
641  fprintf(stderr, "too many disks\n");
642  exit(1);
643  }
644  CHECK_ALLOCATION(cur_machine_disk[cur_machine_n_disk] =
645  (char*) malloc(MAX_DISK_LEN));
646  read_one_word(f, cur_machine_disk[cur_machine_n_disk],
647  MAX_DISK_LEN, line, EXPECT_WORD);
648  cur_machine_n_disk ++;
649  read_one_word(f, word, maxbuflen,
651  return;
652  }
653 
654  if (strcmp(word, "device") == 0) {
655  read_one_word(f, word, maxbuflen,
657  if (cur_machine_n_device >= MAX_N_DEVICE) {
658  fprintf(stderr, "too many devices\n");
659  exit(1);
660  }
661  CHECK_ALLOCATION(cur_machine_device[cur_machine_n_device] =
662  (char*) malloc(MAX_DEVICE_LEN));
663  read_one_word(f, cur_machine_device[cur_machine_n_device],
664  MAX_DEVICE_LEN, line, EXPECT_WORD);
665  cur_machine_n_device ++;
666  read_one_word(f, word, maxbuflen,
668  return;
669  }
670 
671  if (strcmp(word, "add_x11_display") == 0) {
672  read_one_word(f, word, maxbuflen,
674  if (cur_machine_n_x11_disp >= MAX_N_X11_DISP) {
675  fprintf(stderr, "too many x11 displays\n");
676  exit(1);
677  }
678  CHECK_ALLOCATION(cur_machine_x11_disp[cur_machine_n_x11_disp] =
679  (char*) malloc(MAX_X11_DISP_LEN));
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,
685  return;
686  }
687 
688  fatal("line %i: not expecting '%s' in a 'machine' section\n",
689  *line, word);
690  exit(1);
691 }
692 
693 
694 /*
695  * emul_parse_config():
696  *
697  * Set up an emulation by parsing a config file.
698  */
699 void emul_parse_config(struct emul *e, char *fname)
700 {
701  FILE *f = fopen(fname, "r");
702  char word[MAX_WORD_LEN];
703  int in_emul = 0;
704  int line = 1;
705  int parsestate = PARSESTATE_EMUL;
706 
707  /* debug("emul_parse_config()\n"); */
708  if (f == NULL) {
709  perror(fname);
710  exit(1);
711  }
712 
713  while (!feof(f)) {
714  read_one_word(f, word, sizeof(word), &line,
716  if (!word[0])
717  break;
718 
719  /* debug("word = '%s'\n", word); */
720 
721  switch (parsestate) {
722  case PARSESTATE_EMUL:
723  parse__emul(e, f, &in_emul, &line, &parsestate,
724  word, sizeof(word));
725  break;
726  case PARSESTATE_NET:
727  parse__net(e, f, &in_emul, &line, &parsestate,
728  word, sizeof(word));
729  break;
730  case PARSESTATE_MACHINE:
731  parse__machine(e, f, &in_emul, &line, &parsestate,
732  word, sizeof(word));
733  break;
734  case PARSESTATE_NONE:
735  break;
736  default:
737  fatal("INTERNAL ERROR in emul_parse.c ("
738  "parsestate %i is not imlemented yet?)\n",
739  parsestate);
740  exit(1);
741  }
742  }
743 
744  if (parenthesis_level != 0) {
745  fatal("EOF but not enough right parentheses?\n");
746  exit(1);
747  }
748 
749  fclose(f);
750 }
751 
void fatal(const char *fmt,...)
Definition: main.cc:152
int emulated_hz
Definition: machine.h:165
#define PARSESTATE_EMUL
Definition: emul_parse.cc:196
int prom_emulation
Definition: machine.h:149
char * cpu_name
Definition: machine.h:133
int serial_nr
Definition: machine.h:120
#define MAX_N_X11_DISP
Definition: emul_parse.cc:240
#define PARSESTATE_NET
Definition: emul_parse.cc:197
int machine_type
Definition: machine.h:111
int parse_on_off(char *s)
Definition: emul_parse.cc:268
#define MAX_N_LOAD
Definition: emul_parse.cc:228
int scaleup
Definition: machine.h:84
void f(int s, int func, int only_name)
int slow_serial_interrupts_hack_for_linux
Definition: machine.h:168
#define MAX_DISK_LEN
Definition: emul_parse.cc:233
#define MAX_DEVICE_LEN
Definition: emul_parse.cc:237
#define MAX_N_REMOTE
Definition: emul_parse.cc:203
char * name
Definition: emul.h:40
int physical_ram_in_mb
Definition: machine.h:147
int ncpus
Definition: machine.h:139
int scaledown
Definition: machine.h:83
#define EMUL_LITTLE_ENDIAN
Definition: misc.h:164
char * boot_string_argument
Definition: machine.h:171
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239
char * boot_kernel_filename
Definition: machine.h:170
struct machine * emul_add_machine(struct emul *e, char *name)
Definition: emul.cc:209
#define MAX_X11_DISP_LEN
Definition: emul_parse.cc:241
#define MAX_REMOTE_LEN
Definition: emul_parse.cc:204
#define MAX_N_DISK
Definition: emul_parse.cc:232
#define PARSESTATE_NONE
Definition: emul_parse.cc:195
unsigned long long mystrtoull(const char *s, char **endp, int base)
Definition: misc.cc:46
int start_paused
Definition: machine.h:138
int force_netboot
Definition: machine.h:167
#define NET_DEFAULT_IPV4_MASK
Definition: net.h:44
Definition: emul.h:37
#define NET_INIT_FLAG_GATEWAY
Definition: net.h:188
void emul_parse_config(struct emul *e, char *fname)
Definition: emul_parse.cc:699
void emul_machine_setup(struct machine *machine, int n_load, char **load_names, int n_devices, char **device_names)
Definition: emul.cc:354
char ** display_names
Definition: machine.h:86
int machine_name_to_type(char *stype, char *ssubtype, int *type, int *subtype, int *arch)
Definition: machine.cc:156
int random_mem_contents
Definition: machine.h:146
struct x11_md x11_md
Definition: machine.h:179
#define is_word_char(ch)
Definition: emul_parse.cc:44
#define debug
Definition: dev_adb.cc:57
#define NO_BYTE_ORDER_OVERRIDE
Definition: misc.h:162
#define EXPECT_LEFT_PARENTHESIS
Definition: emul_parse.cc:51
struct net * net_init(struct emul *emul, int init_flags, const char *ipv4addr, int netipv4len, char **remote, int n_remote, int local_port, const char *settings_prefix)
Definition: net.cc:720
#define EXPECT_RIGHT_PARENTHESIS
Definition: emul_parse.cc:52
struct net * net
Definition: emul.h:43
int in_use
Definition: machine.h:82
#define NET_DEFAULT_IPV4_LEN
Definition: net.h:45
#define MAX_WORD_LEN
Definition: emul_parse.cc:48
#define MAX_LOAD_LEN
Definition: emul_parse.cc:229
#define MAX_N_DEVICE
Definition: emul_parse.cc:236
int n_display_names
Definition: machine.h:85
#define WORD(w, var)
Definition: emul_parse.cc:245
#define PARSESTATE_MACHINE
Definition: emul_parse.cc:198
int arch
Definition: machine.h:110
int diskimage_add(struct machine *machine, char *fname)
Definition: diskimage.cc:659
int machine_subtype
Definition: machine.h:112
#define EXPECT_WORD
Definition: emul_parse.cc:50
int use_random_bootstrap_cpu
Definition: machine.h:137
int byte_order_override
Definition: machine.h:135
int n_gfx_cards
Definition: machine.h:173
#define EMUL_BIG_ENDIAN
Definition: misc.h:165
int next_serial_nr
Definition: emul.h:42

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13