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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26