/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 35 - (hide 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 dpavlin 2 /*
2 dpavlin 34 * Copyright (C) 2005-2007 Anders Gavare. All rights reserved.
3 dpavlin 2 *
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 dpavlin 34 * $Id: emul_parse.c,v 1.45 2006/12/30 13:30:52 debug Exp $
29 dpavlin 2 *
30     * Set up an emulation by parsing a config file.
31     *
32 dpavlin 24 * TODO: REWRITE THIS FROM SCRATCH! :-)
33 dpavlin 2 */
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 dpavlin 24 #define MAX_WORD_LEN 200
51 dpavlin 2
52     #define EXPECT_WORD 1
53     #define EXPECT_LEFT_PARENTHESIS 2
54     #define EXPECT_RIGHT_PARENTHESIS 4
55    
56 dpavlin 24 static int parenthesis_level = 0;
57 dpavlin 2
58 dpavlin 24
59 dpavlin 2 /*
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 dpavlin 24 parenthesis_level ++;
178 dpavlin 2 buf[curlen++] = ch;
179     break;
180     }
181     if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') {
182 dpavlin 24 parenthesis_level --;
183 dpavlin 2 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 dpavlin 10 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 dpavlin 2
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 dpavlin 24 static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
260     int *parsestate, char *word, size_t maxbuflen);
261 dpavlin 2
262 dpavlin 24
263 dpavlin 2 /*
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 dpavlin 24 fprintf(stderr, "parse_on_off(): WARNING: unknown value '%s'\n", s);
280 dpavlin 2
281 dpavlin 24 return 0;
282 dpavlin 2 }
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 dpavlin 32 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 dpavlin 10 strlcpy(cur_net_local_port, "", sizeof(cur_net_local_port));
329     cur_net_n_remote = 0;
330 dpavlin 2 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 dpavlin 10 * Simple words: ipv4net, ipv4len, local_port
376 dpavlin 2 *
377 dpavlin 10 * Complex: add_remote
378     *
379 dpavlin 2 * 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 dpavlin 10 int i;
386    
387 dpavlin 2 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 dpavlin 10 if (!cur_net_local_port[0])
396     strlcpy(cur_net_local_port, "0",
397     sizeof(cur_net_local_port));
398    
399 dpavlin 2 e->net = net_init(e, NET_INIT_FLAG_GATEWAY,
400 dpavlin 10 cur_net_ipv4net, atoi(cur_net_ipv4len),
401     cur_net_remote, cur_net_n_remote,
402 dpavlin 32 atoi(cur_net_local_port), NULL);
403 dpavlin 2
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 dpavlin 10 for (i=0; i<cur_net_n_remote; i++) {
411     free(cur_net_remote[i]);
412     cur_net_remote[i] = NULL;
413     }
414    
415 dpavlin 2 *parsestate = PARSESTATE_EMUL;
416     return;
417     }
418    
419     WORD("ipv4net", cur_net_ipv4net);
420     WORD("ipv4len", cur_net_ipv4len);
421 dpavlin 10 WORD("local_port", cur_net_local_port);
422 dpavlin 2
423 dpavlin 10 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 dpavlin 2 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 dpavlin 10 strlcpy(cur_machine_name, "no_name",
462     sizeof(cur_machine_name));
463 dpavlin 2
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 dpavlin 10 strlcpy(cur_machine_use_x11, "no",
476     sizeof(cur_machine_use_x11));
477 dpavlin 2 m->use_x11 = parse_on_off(cur_machine_use_x11);
478    
479     if (!cur_machine_slowsi[0])
480 dpavlin 10 strlcpy(cur_machine_slowsi, "no",
481     sizeof(cur_machine_slowsi));
482 dpavlin 2 m->slow_serial_interrupts_hack_for_linux =
483     parse_on_off(cur_machine_slowsi);
484    
485     if (!cur_machine_prom_emulation[0])
486 dpavlin 10 strlcpy(cur_machine_prom_emulation, "yes",
487     sizeof(cur_machine_prom_emulation));
488 dpavlin 2 m->prom_emulation = parse_on_off(cur_machine_prom_emulation);
489    
490     if (!cur_machine_random_mem[0])
491 dpavlin 10 strlcpy(cur_machine_random_mem, "no",
492     sizeof(cur_machine_random_mem));
493 dpavlin 2 m->random_mem_contents =
494     parse_on_off(cur_machine_random_mem);
495    
496     if (!cur_machine_random_cpu[0])
497 dpavlin 10 strlcpy(cur_machine_random_cpu, "no",
498     sizeof(cur_machine_random_cpu));
499 dpavlin 2 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 dpavlin 10 strlcpy(cur_machine_force_netboot, "no",
518     sizeof(cur_machine_force_netboot));
519 dpavlin 2 m->force_netboot = parse_on_off(cur_machine_force_netboot);
520    
521     if (!cur_machine_start_paused[0])
522 dpavlin 10 strlcpy(cur_machine_start_paused, "no",
523     sizeof(cur_machine_start_paused));
524 dpavlin 2 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 dpavlin 10 strlcpy(cur_machine_ncpus, "0",
529     sizeof(cur_machine_ncpus));
530 dpavlin 2 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 dpavlin 10 strlcpy(cur_machine_memory, "0",
548     sizeof(cur_machine_memory));
549 dpavlin 2 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 dpavlin 20 m->x11_scaleup = 0 - m->x11_scaledown;
557     m->x11_scaledown = 1;
558     }
559     if (m->x11_scaledown < 1) {
560 dpavlin 2 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 dpavlin 24 void emul_parse_config(struct emul *e, char *fname)
730 dpavlin 2 {
731 dpavlin 24 FILE *f = fopen(fname, "r");
732     char word[MAX_WORD_LEN];
733 dpavlin 2 int in_emul = 0;
734     int line = 1;
735 dpavlin 24 int parsestate = PARSESTATE_EMUL;
736 dpavlin 2
737     /* debug("emul_parse_config()\n"); */
738 dpavlin 24 if (f == NULL) {
739     perror(fname);
740     exit(1);
741     }
742 dpavlin 2
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 dpavlin 24 case PARSESTATE_NONE:
765     break;
766 dpavlin 2 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 dpavlin 24 if (parenthesis_level != 0) {
775 dpavlin 2 fatal("EOF but not enough right parentheses?\n");
776     exit(1);
777     }
778 dpavlin 24
779     fclose(f);
780 dpavlin 2 }
781    

  ViewVC Help
Powered by ViewVC 1.1.26