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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations)
Mon Oct 8 16:20:48 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 20773 byte(s)
0.4.2
1 dpavlin 2 /*
2 dpavlin 22 * Copyright (C) 2005-2006 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 24 * $Id: emul_parse.c,v 1.42 2006/06/22 13:22:41 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 10 strlcpy(cur_net_ipv4net, "10.0.0.0", sizeof(cur_net_ipv4net));
325     strlcpy(cur_net_ipv4len, "8", sizeof(cur_net_ipv4len));
326     strlcpy(cur_net_local_port, "", sizeof(cur_net_local_port));
327     cur_net_n_remote = 0;
328 dpavlin 2 return;
329     }
330    
331     if (strcmp(word, "machine") == 0) {
332     *parsestate = PARSESTATE_MACHINE;
333     read_one_word(f, word, maxbuflen,
334     line, EXPECT_LEFT_PARENTHESIS);
335    
336     /* A "zero state": */
337     cur_machine_name[0] = '\0';
338     cur_machine_cpu[0] = '\0';
339     cur_machine_type[0] = '\0';
340     cur_machine_subtype[0] = '\0';
341     cur_machine_bootname[0] = '\0';
342     cur_machine_bootarg[0] = '\0';
343     cur_machine_n_load = 0;
344     cur_machine_n_disk = 0;
345     cur_machine_n_device = 0;
346     cur_machine_n_x11_disp = 0;
347     cur_machine_slowsi[0] = '\0';
348     cur_machine_prom_emulation[0] = '\0';
349     cur_machine_use_x11[0] = '\0';
350     cur_machine_x11_scaledown[0] = '\0';
351     cur_machine_byte_order[0] = '\0';
352     cur_machine_random_mem[0] = '\0';
353     cur_machine_random_cpu[0] = '\0';
354     cur_machine_force_netboot[0] = '\0';
355     cur_machine_start_paused[0] = '\0';
356     cur_machine_ncpus[0] = '\0';
357     cur_machine_n_gfx_cards[0] = '\0';
358     cur_machine_serial_nr[0] = '\0';
359     cur_machine_emulated_hz[0] = '\0';
360     cur_machine_memory[0] = '\0';
361     return;
362     }
363    
364     fatal("line %i: not expecting '%s' in an 'emul' section\n",
365     *line, word);
366     exit(1);
367     }
368    
369    
370     /*
371     * parse__net():
372     *
373 dpavlin 10 * Simple words: ipv4net, ipv4len, local_port
374 dpavlin 2 *
375 dpavlin 10 * Complex: add_remote
376     *
377 dpavlin 2 * TODO: more words? for example an option to disable the gateway? that would
378     * have to be implemented correctly in src/net.c first.
379     */
380     static void parse__net(struct emul *e, FILE *f, int *in_emul, int *line,
381     int *parsestate, char *word, size_t maxbuflen)
382     {
383 dpavlin 10 int i;
384    
385 dpavlin 2 if (word[0] == ')') {
386     /* Finished with the 'net' section. Let's create the net: */
387     if (e->net != NULL) {
388     fatal("line %i: more than one net isn't really "
389     "supported yet\n", *line);
390     exit(1);
391     }
392    
393 dpavlin 10 if (!cur_net_local_port[0])
394     strlcpy(cur_net_local_port, "0",
395     sizeof(cur_net_local_port));
396    
397 dpavlin 2 e->net = net_init(e, NET_INIT_FLAG_GATEWAY,
398 dpavlin 10 cur_net_ipv4net, atoi(cur_net_ipv4len),
399     cur_net_remote, cur_net_n_remote,
400     atoi(cur_net_local_port));
401 dpavlin 2
402     if (e->net == NULL) {
403     fatal("line %i: fatal error: could not create"
404     " the net (?)\n", *line);
405     exit(1);
406     }
407    
408 dpavlin 10 for (i=0; i<cur_net_n_remote; i++) {
409     free(cur_net_remote[i]);
410     cur_net_remote[i] = NULL;
411     }
412    
413 dpavlin 2 *parsestate = PARSESTATE_EMUL;
414     return;
415     }
416    
417     WORD("ipv4net", cur_net_ipv4net);
418     WORD("ipv4len", cur_net_ipv4len);
419 dpavlin 10 WORD("local_port", cur_net_local_port);
420 dpavlin 2
421 dpavlin 10 if (strcmp(word, "add_remote") == 0) {
422     read_one_word(f, word, maxbuflen,
423     line, EXPECT_LEFT_PARENTHESIS);
424     if (cur_net_n_remote >= MAX_N_REMOTE) {
425     fprintf(stderr, "too many remote networks\n");
426     exit(1);
427     }
428     cur_net_remote[cur_net_n_remote] = malloc(MAX_REMOTE_LEN);
429     if (cur_net_remote[cur_net_n_remote] == NULL) {
430     fprintf(stderr, "out of memory\n");
431     exit(1);
432     }
433     read_one_word(f, cur_net_remote[cur_net_n_remote],
434     MAX_REMOTE_LEN, line, EXPECT_WORD);
435     cur_net_n_remote ++;
436     read_one_word(f, word, maxbuflen, line,
437     EXPECT_RIGHT_PARENTHESIS);
438     return;
439     }
440    
441 dpavlin 2 fatal("line %i: not expecting '%s' in a 'net' section\n", *line, word);
442     exit(1);
443     }
444    
445    
446     /*
447     * parse__machine():
448     */
449     static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
450     int *parsestate, char *word, size_t maxbuflen)
451     {
452     int r, i;
453    
454     if (word[0] == ')') {
455     /* Finished with the 'machine' section. */
456     struct machine *m;
457    
458     if (!cur_machine_name[0])
459 dpavlin 10 strlcpy(cur_machine_name, "no_name",
460     sizeof(cur_machine_name));
461 dpavlin 2
462     m = emul_add_machine(e, cur_machine_name);
463    
464     r = machine_name_to_type(cur_machine_type, cur_machine_subtype,
465     &m->machine_type, &m->machine_subtype, &m->arch);
466     if (!r)
467     exit(1);
468    
469     if (cur_machine_cpu[0])
470     m->cpu_name = strdup(cur_machine_cpu);
471    
472     if (!cur_machine_use_x11[0])
473 dpavlin 10 strlcpy(cur_machine_use_x11, "no",
474     sizeof(cur_machine_use_x11));
475 dpavlin 2 m->use_x11 = parse_on_off(cur_machine_use_x11);
476    
477     if (!cur_machine_slowsi[0])
478 dpavlin 10 strlcpy(cur_machine_slowsi, "no",
479     sizeof(cur_machine_slowsi));
480 dpavlin 2 m->slow_serial_interrupts_hack_for_linux =
481     parse_on_off(cur_machine_slowsi);
482    
483     if (!cur_machine_prom_emulation[0])
484 dpavlin 10 strlcpy(cur_machine_prom_emulation, "yes",
485     sizeof(cur_machine_prom_emulation));
486 dpavlin 2 m->prom_emulation = parse_on_off(cur_machine_prom_emulation);
487    
488     if (!cur_machine_random_mem[0])
489 dpavlin 10 strlcpy(cur_machine_random_mem, "no",
490     sizeof(cur_machine_random_mem));
491 dpavlin 2 m->random_mem_contents =
492     parse_on_off(cur_machine_random_mem);
493    
494     if (!cur_machine_random_cpu[0])
495 dpavlin 10 strlcpy(cur_machine_random_cpu, "no",
496     sizeof(cur_machine_random_cpu));
497 dpavlin 2 m->use_random_bootstrap_cpu =
498     parse_on_off(cur_machine_random_cpu);
499    
500     m->byte_order_override = NO_BYTE_ORDER_OVERRIDE;
501     if (cur_machine_byte_order[0]) {
502     if (strncasecmp(cur_machine_byte_order, "big", 3) == 0)
503     m->byte_order_override = EMUL_BIG_ENDIAN;
504     else if (strncasecmp(cur_machine_byte_order, "little",
505     6) == 0)
506     m->byte_order_override = EMUL_LITTLE_ENDIAN;
507     else {
508     fatal("Byte order must be big-endian or"
509     " little-endian\n");
510     exit(1);
511     }
512     }
513    
514     if (!cur_machine_force_netboot[0])
515 dpavlin 10 strlcpy(cur_machine_force_netboot, "no",
516     sizeof(cur_machine_force_netboot));
517 dpavlin 2 m->force_netboot = parse_on_off(cur_machine_force_netboot);
518    
519     if (!cur_machine_start_paused[0])
520 dpavlin 10 strlcpy(cur_machine_start_paused, "no",
521     sizeof(cur_machine_start_paused));
522 dpavlin 2 m->start_paused = parse_on_off(cur_machine_start_paused);
523    
524     /* NOTE: Default nr of CPUs is 0: */
525     if (!cur_machine_ncpus[0])
526 dpavlin 10 strlcpy(cur_machine_ncpus, "0",
527     sizeof(cur_machine_ncpus));
528 dpavlin 2 m->ncpus = atoi(cur_machine_ncpus);
529    
530     if (cur_machine_n_gfx_cards[0])
531     m->n_gfx_cards = atoi(cur_machine_n_gfx_cards);
532    
533     if (cur_machine_serial_nr[0]) {
534     m->serial_nr = atoi(cur_machine_serial_nr);
535     e->next_serial_nr = m->serial_nr+1;
536     }
537    
538     if (cur_machine_emulated_hz[0]) {
539     m->emulated_hz = mystrtoull(cur_machine_emulated_hz,
540     NULL, 0);
541     m->automatic_clock_adjustment = 0;
542     }
543    
544     /* NOTE: Default nr of CPUs is 0: */
545     if (!cur_machine_memory[0])
546 dpavlin 10 strlcpy(cur_machine_memory, "0",
547     sizeof(cur_machine_memory));
548 dpavlin 2 m->physical_ram_in_mb = atoi(cur_machine_memory);
549    
550     if (!cur_machine_x11_scaledown[0])
551     m->x11_scaledown = 1;
552     else {
553     m->x11_scaledown = atoi(cur_machine_x11_scaledown);
554     if (m->x11_scaledown < 0) {
555 dpavlin 20 m->x11_scaleup = 0 - m->x11_scaledown;
556     m->x11_scaledown = 1;
557     }
558     if (m->x11_scaledown < 1) {
559 dpavlin 2 fprintf(stderr, "Invalid scaledown value"
560     " (%i)\n", m->x11_scaledown);
561     exit(1);
562     }
563     }
564    
565     for (i=0; i<cur_machine_n_disk; i++) {
566     diskimage_add(m, cur_machine_disk[i]);
567     free(cur_machine_disk[i]);
568     cur_machine_disk[i] = NULL;
569     }
570    
571     m->boot_kernel_filename = strdup(cur_machine_bootname);
572    
573     if (cur_machine_bootarg[0])
574     m->boot_string_argument = strdup(cur_machine_bootarg);
575    
576     for (i=0; i<cur_machine_n_x11_disp; i++) {
577     m->x11_n_display_names ++;
578     m->x11_display_names = realloc(
579     m->x11_display_names, m->x11_n_display_names
580     * sizeof(char *));
581     if (m->x11_display_names == NULL) {
582     printf("out of memory\n");
583     exit(1);
584     }
585     m->x11_display_names[m->x11_n_display_names-1] =
586     strdup(cur_machine_x11_disp[i]);
587     if (m->x11_display_names
588     [m->x11_n_display_names-1] == NULL) {
589     printf("out of memory\n");
590     exit(1);
591     }
592     free(cur_machine_x11_disp[i]);
593     cur_machine_x11_disp[i] = NULL;
594     }
595    
596     emul_machine_setup(m,
597     cur_machine_n_load, cur_machine_load,
598     cur_machine_n_device, cur_machine_device);
599    
600     for (i=0; i<cur_machine_n_device; i++) {
601     free(cur_machine_device[i]);
602     cur_machine_device[i] = NULL;
603     }
604    
605     for (i=0; i<cur_machine_n_load; i++) {
606     free(cur_machine_load[i]);
607     cur_machine_load[i] = NULL;
608     }
609    
610     *parsestate = PARSESTATE_EMUL;
611     return;
612     }
613    
614     WORD("name", cur_machine_name);
615     WORD("cpu", cur_machine_cpu);
616     WORD("type", cur_machine_type);
617     WORD("subtype", cur_machine_subtype);
618     WORD("bootname", cur_machine_bootname);
619     WORD("bootarg", cur_machine_bootarg);
620     WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi);
621     WORD("prom_emulation", cur_machine_prom_emulation);
622     WORD("use_x11", cur_machine_use_x11);
623     WORD("x11_scaledown", cur_machine_x11_scaledown);
624     WORD("byte_order", cur_machine_byte_order);
625     WORD("random_mem_contents", cur_machine_random_mem);
626     WORD("use_random_bootstrap_cpu", cur_machine_random_cpu);
627     WORD("force_netboot", cur_machine_force_netboot);
628     WORD("ncpus", cur_machine_ncpus);
629     WORD("serial_nr", cur_machine_serial_nr);
630     WORD("n_gfx_cards", cur_machine_n_gfx_cards);
631     WORD("emulated_hz", cur_machine_emulated_hz);
632     WORD("memory", cur_machine_memory);
633     WORD("start_paused", cur_machine_start_paused);
634    
635     if (strcmp(word, "load") == 0) {
636     read_one_word(f, word, maxbuflen,
637     line, EXPECT_LEFT_PARENTHESIS);
638     if (cur_machine_n_load >= MAX_N_LOAD) {
639     fprintf(stderr, "too many loads\n");
640     exit(1);
641     }
642     cur_machine_load[cur_machine_n_load] = malloc(MAX_LOAD_LEN);
643     if (cur_machine_load[cur_machine_n_load] == NULL) {
644     fprintf(stderr, "out of memory\n");
645     exit(1);
646     }
647     read_one_word(f, cur_machine_load[cur_machine_n_load],
648     MAX_LOAD_LEN, line, EXPECT_WORD);
649     cur_machine_n_load ++;
650     read_one_word(f, word, maxbuflen,
651     line, EXPECT_RIGHT_PARENTHESIS);
652     return;
653     }
654    
655     if (strcmp(word, "disk") == 0) {
656     read_one_word(f, word, maxbuflen,
657     line, EXPECT_LEFT_PARENTHESIS);
658     if (cur_machine_n_disk >= MAX_N_DISK) {
659     fprintf(stderr, "too many disks\n");
660     exit(1);
661     }
662     cur_machine_disk[cur_machine_n_disk] = malloc(MAX_DISK_LEN);
663     if (cur_machine_disk[cur_machine_n_disk] == NULL) {
664     fprintf(stderr, "out of memory\n");
665     exit(1);
666     }
667     read_one_word(f, cur_machine_disk[cur_machine_n_disk],
668     MAX_DISK_LEN, line, EXPECT_WORD);
669     cur_machine_n_disk ++;
670     read_one_word(f, word, maxbuflen,
671     line, EXPECT_RIGHT_PARENTHESIS);
672     return;
673     }
674    
675     if (strcmp(word, "device") == 0) {
676     read_one_word(f, word, maxbuflen,
677     line, EXPECT_LEFT_PARENTHESIS);
678     if (cur_machine_n_device >= MAX_N_DEVICE) {
679     fprintf(stderr, "too many devices\n");
680     exit(1);
681     }
682     cur_machine_device[cur_machine_n_device] =
683     malloc(MAX_DEVICE_LEN);
684     if (cur_machine_device[cur_machine_n_device] == NULL) {
685     fprintf(stderr, "out of memory\n");
686     exit(1);
687     }
688     read_one_word(f, cur_machine_device[cur_machine_n_device],
689     MAX_DEVICE_LEN, line, EXPECT_WORD);
690     cur_machine_n_device ++;
691     read_one_word(f, word, maxbuflen,
692     line, EXPECT_RIGHT_PARENTHESIS);
693     return;
694     }
695    
696     if (strcmp(word, "add_x11_display") == 0) {
697     read_one_word(f, word, maxbuflen,
698     line, EXPECT_LEFT_PARENTHESIS);
699     if (cur_machine_n_x11_disp >= MAX_N_X11_DISP) {
700     fprintf(stderr, "too many x11 displays\n");
701     exit(1);
702     }
703     cur_machine_x11_disp[cur_machine_n_x11_disp] =
704     malloc(MAX_X11_DISP_LEN);
705     if (cur_machine_x11_disp[cur_machine_n_x11_disp] == NULL) {
706     fprintf(stderr, "out of memory\n");
707     exit(1);
708     }
709     read_one_word(f, cur_machine_x11_disp[cur_machine_n_x11_disp],
710     MAX_X11_DISP_LEN, line, EXPECT_WORD);
711     cur_machine_n_x11_disp ++;
712     read_one_word(f, word, maxbuflen,
713     line, EXPECT_RIGHT_PARENTHESIS);
714     return;
715     }
716    
717     fatal("line %i: not expecting '%s' in a 'machine' section\n",
718     *line, word);
719     exit(1);
720     }
721    
722    
723     /*
724     * emul_parse_config():
725     *
726     * Set up an emulation by parsing a config file.
727     */
728 dpavlin 24 void emul_parse_config(struct emul *e, char *fname)
729 dpavlin 2 {
730 dpavlin 24 FILE *f = fopen(fname, "r");
731     char word[MAX_WORD_LEN];
732 dpavlin 2 int in_emul = 0;
733     int line = 1;
734 dpavlin 24 int parsestate = PARSESTATE_EMUL;
735 dpavlin 2
736     /* debug("emul_parse_config()\n"); */
737 dpavlin 24 if (f == NULL) {
738     perror(fname);
739     exit(1);
740     }
741 dpavlin 2
742     while (!feof(f)) {
743     read_one_word(f, word, sizeof(word), &line,
744     EXPECT_WORD | EXPECT_RIGHT_PARENTHESIS);
745     if (!word[0])
746     break;
747    
748     /* debug("word = '%s'\n", word); */
749    
750     switch (parsestate) {
751     case PARSESTATE_EMUL:
752     parse__emul(e, f, &in_emul, &line, &parsestate,
753     word, sizeof(word));
754     break;
755     case PARSESTATE_NET:
756     parse__net(e, f, &in_emul, &line, &parsestate,
757     word, sizeof(word));
758     break;
759     case PARSESTATE_MACHINE:
760     parse__machine(e, f, &in_emul, &line, &parsestate,
761     word, sizeof(word));
762     break;
763 dpavlin 24 case PARSESTATE_NONE:
764     break;
765 dpavlin 2 default:
766     fatal("INTERNAL ERROR in emul_parse.c ("
767     "parsestate %i is not imlemented yet?)\n",
768     parsestate);
769     exit(1);
770     }
771     }
772    
773 dpavlin 24 if (parenthesis_level != 0) {
774 dpavlin 2 fatal("EOF but not enough right parentheses?\n");
775     exit(1);
776     }
777 dpavlin 24
778     fclose(f);
779 dpavlin 2 }
780    

  ViewVC Help
Powered by ViewVC 1.1.26