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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (hide annotations)
Mon Oct 8 16:17:52 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 20691 byte(s)
0.3.1
1 dpavlin 2 /*
2     * Copyright (C) 2005 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     * $Id: emul_parse.c,v 1.29 2005/03/14 19:14:04 debug Exp $
29     *
30     * Set up an emulation by parsing a config file.
31     *
32     *
33     * TODO: This could be extended to support XML config files as well, but
34     * XML is ugly.
35     */
36    
37     #include <stdio.h>
38     #include <stdlib.h>
39     #include <string.h>
40    
41     #include "diskimage.h"
42     #include "emul.h"
43     #include "machine.h"
44     #include "misc.h"
45     #include "net.h"
46    
47    
48     #define is_word_char(ch) ( \
49     (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \
50     ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') )
51    
52    
53     #define EXPECT_WORD 1
54     #define EXPECT_LEFT_PARENTHESIS 2
55     #define EXPECT_RIGHT_PARENTHESIS 4
56    
57    
58     /*
59     * read_one_word():
60     *
61     * Reads the file f until it has read a complete word. Whitespace is ignored,
62     * and also any exclamation mark ('!') and anything following an exclamation
63     * mark on a line.
64     *
65     * Used internally by emul_parse_config().
66     */
67     static void read_one_word(FILE *f, char *buf, int buflen, int *line,
68     int expect)
69     {
70     int ch;
71     int done = 0;
72     int curlen = 0;
73     int in_word = 0;
74    
75     while (!done) {
76     if (curlen >= buflen - 1)
77     break;
78    
79     ch = fgetc(f);
80     if (ch == EOF)
81     break;
82    
83     if (in_word) {
84     if (is_word_char(ch)) {
85     buf[curlen++] = ch;
86     if (curlen == buflen - 1)
87     done = 1;
88     continue;
89     } else {
90     if (ungetc(ch, f) == EOF) {
91     fatal("ungetc() failed?\n");
92     exit(1);
93     }
94     break;
95     }
96     }
97    
98     if (ch == '\n') {
99     (*line) ++;
100     continue;
101     }
102    
103     if (ch == '\r')
104     continue;
105    
106     if (ch == '!') {
107     /* Skip until newline: */
108     while (ch != '\n' && ch != EOF)
109     ch = fgetc(f);
110     if (ch == '\n')
111     (*line) ++;
112     continue;
113     }
114    
115     if (ch == '{') {
116     int depth = 1;
117    
118     /* Skip until '}': */
119     while (depth > 0) {
120     ch = fgetc(f);
121     if (ch == '\n')
122     (*line) ++;
123     if (ch == '{')
124     depth ++;
125     if (ch == '}')
126     depth --;
127     if (ch == EOF) {
128     fatal("line %i: unexpected EOF inside"
129     " a nested comment\n", *line);
130     exit(1);
131     }
132     }
133     continue;
134     }
135    
136     /* Whitespace? */
137     if (ch <= ' ')
138     continue;
139    
140     if (ch == '"' || ch == '\'') {
141     /* This is a quoted word. */
142     int start_ch = ch;
143    
144     if (expect & EXPECT_LEFT_PARENTHESIS) {
145     fatal("unexpected character '%c', line %i\n",
146     ch, *line);
147     exit(1);
148     }
149    
150     while (curlen < buflen - 1) {
151     ch = fgetc(f);
152     if (ch == '\n') {
153     fatal("line %i: newline inside"
154     " quotes?\n", *line);
155     exit(1);
156     }
157     if (ch == EOF) {
158     fatal("line %i: EOF inside a quoted"
159     " string?\n", *line);
160     exit(1);
161     }
162     if (ch == start_ch)
163     break;
164     buf[curlen++] = ch;
165     }
166     break;
167     }
168    
169     if ((expect & EXPECT_WORD) && is_word_char(ch)) {
170     buf[curlen++] = ch;
171     in_word = 1;
172     if (curlen == buflen - 1)
173     done = 1;
174     } else {
175     if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') {
176     buf[curlen++] = ch;
177     break;
178     }
179     if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') {
180     buf[curlen++] = ch;
181     break;
182     }
183    
184     fatal("unexpected character '%c', line %i\n",
185     ch, *line);
186     exit(1);
187     }
188     }
189    
190     buf[curlen] = '\0';
191     }
192    
193    
194     #define PARSESTATE_NONE 0
195     #define PARSESTATE_EMUL 1
196     #define PARSESTATE_NET 2
197     #define PARSESTATE_MACHINE 3
198    
199     static char cur_net_ipv4net[50];
200     static char cur_net_ipv4len[50];
201    
202     static char cur_machine_name[50];
203     static char cur_machine_cpu[50];
204     static char cur_machine_type[50];
205     static char cur_machine_subtype[50];
206     static char cur_machine_bootname[150];
207     static char cur_machine_bootarg[250];
208     static char cur_machine_slowsi[10];
209     static char cur_machine_debugger_on_badaddr[10];
210     static char cur_machine_prom_emulation[10];
211     static char cur_machine_use_x11[10];
212     static char cur_machine_x11_scaledown[10];
213     static char cur_machine_bintrans[10];
214     static char cur_machine_old_bintrans[10];
215     static char cur_machine_bintrans_size[10];
216     static char cur_machine_byte_order[20];
217     static char cur_machine_random_mem[10];
218     static char cur_machine_random_cpu[10];
219     static char cur_machine_force_netboot[10];
220     static char cur_machine_start_paused[10];
221     static char cur_machine_ncpus[10];
222     static char cur_machine_n_gfx_cards[10];
223     static char cur_machine_serial_nr[10];
224     static char cur_machine_emulated_hz[10];
225     static char cur_machine_memory[10];
226     #define MAX_N_LOAD 15
227     #define MAX_LOAD_LEN 2000
228     static char *cur_machine_load[MAX_N_LOAD];
229     static int cur_machine_n_load;
230     #define MAX_N_DISK 10
231     #define MAX_DISK_LEN 2000
232     static char *cur_machine_disk[MAX_N_DISK];
233     static int cur_machine_n_disk;
234     #define MAX_N_DEVICE 20
235     #define MAX_DEVICE_LEN 400
236     static char *cur_machine_device[MAX_N_DISK];
237     static int cur_machine_n_device;
238     #define MAX_N_X11_DISP 5
239     #define MAX_X11_DISP_LEN 1000
240     static char *cur_machine_x11_disp[MAX_N_X11_DISP];
241     static int cur_machine_n_x11_disp;
242    
243     #define WORD(w,var) { \
244     if (strcmp(word, w) == 0) { \
245     read_one_word(f, word, maxbuflen, \
246     line, EXPECT_LEFT_PARENTHESIS); \
247     read_one_word(f, var, sizeof(var), \
248     line, EXPECT_WORD); \
249     read_one_word(f, word, maxbuflen, \
250     line, EXPECT_RIGHT_PARENTHESIS); \
251     return; \
252     } \
253     }
254    
255    
256     /*
257     * parse_on_off():
258     *
259     * Returns 1 for "on", "yes", "enable", or "1".
260     * Returns 0 for "off", "no", "disable", or "0".
261     * Prints a fatal warning and exit()s for other values.
262     */
263     int parse_on_off(char *s)
264     {
265     if (strcasecmp(s, "on") == 0 || strcasecmp(s, "yes") == 0 ||
266     strcasecmp(s, "enable") == 0 || strcasecmp(s, "1") == 0)
267     return 1;
268     if (strcasecmp(s, "off") == 0 || strcasecmp(s, "no") == 0 ||
269     strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0)
270     return 0;
271    
272     fatal("parse_on_off(): unknown value '%s'\n", s);
273     exit(1);
274     }
275    
276    
277     /*
278     * parse__none():
279     *
280     * emul ( [...] )
281     */
282     static void parse__none(struct emul *e, FILE *f, int *in_emul, int *line,
283     int *parsestate, char *word, size_t maxbuflen)
284     {
285     if (strcmp(word, "emul") == 0) {
286     if (*in_emul) {
287     fatal("line %i: only one emul per config "
288     "file is supported!\n", *line);
289     exit(1);
290     }
291     *parsestate = PARSESTATE_EMUL;
292     *in_emul = 1;
293     read_one_word(f, word, maxbuflen,
294     line, EXPECT_LEFT_PARENTHESIS);
295     return;
296     }
297    
298     fatal("line %i: expecting 'emul', not '%s'\n", *line, word);
299     exit(1);
300     }
301    
302    
303     /*
304     * parse__emul():
305     *
306     * name, net, machine
307     */
308     static void parse__emul(struct emul *e, FILE *f, int *in_emul, int *line,
309     int *parsestate, char *word, size_t maxbuflen)
310     {
311     if (word[0] == ')') {
312     *parsestate = PARSESTATE_NONE;
313     return;
314     }
315    
316     if (strcmp(word, "name") == 0) {
317     char tmp[200];
318     read_one_word(f, word, maxbuflen,
319     line, EXPECT_LEFT_PARENTHESIS);
320     read_one_word(f, tmp, sizeof(tmp), line, EXPECT_WORD);
321     read_one_word(f, word, maxbuflen,
322     line, EXPECT_RIGHT_PARENTHESIS);
323     if (e->name != NULL) {
324     free(e->name);
325     e->name = NULL;
326     }
327     e->name = strdup(tmp);
328     if (e->name == NULL) {
329     fprintf(stderr, "out of memory in parse__emul()\n");
330     exit(1);
331     }
332     debug("name: \"%s\"\n", e->name);
333     return;
334     }
335    
336     if (strcmp(word, "net") == 0) {
337     *parsestate = PARSESTATE_NET;
338     read_one_word(f, word, maxbuflen,
339     line, EXPECT_LEFT_PARENTHESIS);
340    
341     /* Default net: */
342     strcpy(cur_net_ipv4net, "10.0.0.0");
343     strcpy(cur_net_ipv4len, "8");
344     return;
345     }
346    
347     if (strcmp(word, "machine") == 0) {
348     *parsestate = PARSESTATE_MACHINE;
349     read_one_word(f, word, maxbuflen,
350     line, EXPECT_LEFT_PARENTHESIS);
351    
352     /* A "zero state": */
353     cur_machine_name[0] = '\0';
354     cur_machine_cpu[0] = '\0';
355     cur_machine_type[0] = '\0';
356     cur_machine_subtype[0] = '\0';
357     cur_machine_bootname[0] = '\0';
358     cur_machine_bootarg[0] = '\0';
359     cur_machine_n_load = 0;
360     cur_machine_n_disk = 0;
361     cur_machine_n_device = 0;
362     cur_machine_n_x11_disp = 0;
363     cur_machine_slowsi[0] = '\0';
364     cur_machine_debugger_on_badaddr[0] = '\0';
365     cur_machine_prom_emulation[0] = '\0';
366     cur_machine_use_x11[0] = '\0';
367     cur_machine_x11_scaledown[0] = '\0';
368     cur_machine_bintrans[0] = '\0';
369     cur_machine_old_bintrans[0] = '\0';
370     cur_machine_bintrans_size[0] = '\0';
371     cur_machine_byte_order[0] = '\0';
372     cur_machine_random_mem[0] = '\0';
373     cur_machine_random_cpu[0] = '\0';
374     cur_machine_force_netboot[0] = '\0';
375     cur_machine_start_paused[0] = '\0';
376     cur_machine_ncpus[0] = '\0';
377     cur_machine_n_gfx_cards[0] = '\0';
378     cur_machine_serial_nr[0] = '\0';
379     cur_machine_emulated_hz[0] = '\0';
380     cur_machine_memory[0] = '\0';
381     return;
382     }
383    
384     fatal("line %i: not expecting '%s' in an 'emul' section\n",
385     *line, word);
386     exit(1);
387     }
388    
389    
390     /*
391     * parse__net():
392     *
393     * Simple words: ipv4net, ipv4len
394     *
395     * TODO: more words? for example an option to disable the gateway? that would
396     * have to be implemented correctly in src/net.c first.
397     */
398     static void parse__net(struct emul *e, FILE *f, int *in_emul, int *line,
399     int *parsestate, char *word, size_t maxbuflen)
400     {
401     if (word[0] == ')') {
402     /* Finished with the 'net' section. Let's create the net: */
403     if (e->net != NULL) {
404     fatal("line %i: more than one net isn't really "
405     "supported yet\n", *line);
406     exit(1);
407     }
408    
409     e->net = net_init(e, NET_INIT_FLAG_GATEWAY,
410     cur_net_ipv4net, atoi(cur_net_ipv4len));
411    
412     if (e->net == NULL) {
413     fatal("line %i: fatal error: could not create"
414     " the net (?)\n", *line);
415     exit(1);
416     }
417    
418     *parsestate = PARSESTATE_EMUL;
419     return;
420     }
421    
422     WORD("ipv4net", cur_net_ipv4net);
423     WORD("ipv4len", cur_net_ipv4len);
424    
425     fatal("line %i: not expecting '%s' in a 'net' section\n", *line, word);
426     exit(1);
427     }
428    
429    
430     /*
431     * parse__machine():
432     */
433     static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
434     int *parsestate, char *word, size_t maxbuflen)
435     {
436     int r, i;
437    
438     if (word[0] == ')') {
439     /* Finished with the 'machine' section. */
440     struct machine *m;
441    
442     if (!cur_machine_name[0])
443     strcpy(cur_machine_name, "no_name");
444    
445     m = emul_add_machine(e, cur_machine_name);
446    
447     r = machine_name_to_type(cur_machine_type, cur_machine_subtype,
448     &m->machine_type, &m->machine_subtype, &m->arch);
449     if (!r)
450     exit(1);
451    
452     if (cur_machine_cpu[0])
453     m->cpu_name = strdup(cur_machine_cpu);
454    
455     if (!cur_machine_use_x11[0])
456     strcpy(cur_machine_use_x11, "no");
457     m->use_x11 = parse_on_off(cur_machine_use_x11);
458    
459     if (!cur_machine_slowsi[0])
460     strcpy(cur_machine_slowsi, "no");
461     m->slow_serial_interrupts_hack_for_linux =
462     parse_on_off(cur_machine_slowsi);
463    
464     if (!cur_machine_debugger_on_badaddr[0])
465     strcpy(cur_machine_debugger_on_badaddr, "no");
466     m->single_step_on_bad_addr =
467     parse_on_off(cur_machine_debugger_on_badaddr);
468    
469     if (!cur_machine_prom_emulation[0])
470     strcpy(cur_machine_prom_emulation, "yes");
471     m->prom_emulation = parse_on_off(cur_machine_prom_emulation);
472    
473     if (!cur_machine_random_mem[0])
474     strcpy(cur_machine_random_mem, "no");
475     m->random_mem_contents =
476     parse_on_off(cur_machine_random_mem);
477    
478     if (!cur_machine_random_cpu[0])
479     strcpy(cur_machine_random_cpu, "no");
480     m->use_random_bootstrap_cpu =
481     parse_on_off(cur_machine_random_cpu);
482    
483     m->byte_order_override = NO_BYTE_ORDER_OVERRIDE;
484     if (cur_machine_byte_order[0]) {
485     if (strncasecmp(cur_machine_byte_order, "big", 3) == 0)
486     m->byte_order_override = EMUL_BIG_ENDIAN;
487     else if (strncasecmp(cur_machine_byte_order, "little",
488     6) == 0)
489     m->byte_order_override = EMUL_LITTLE_ENDIAN;
490     else {
491     fatal("Byte order must be big-endian or"
492     " little-endian\n");
493     exit(1);
494     }
495     }
496    
497     if (!cur_machine_bintrans[0])
498     strcpy(cur_machine_bintrans, "yes");
499     m->bintrans_enable = m->bintrans_enabled_from_start =
500     parse_on_off(cur_machine_bintrans);
501    
502     if (!cur_machine_old_bintrans[0])
503     strcpy(cur_machine_old_bintrans, "no");
504     m->old_bintrans_enable = parse_on_off(cur_machine_old_bintrans);
505    
506     if (!m->bintrans_enable && m->old_bintrans_enable) {
507     fatal("cannot use old bintrans when bintrans is"
508     " disabled.\n");
509     exit(1);
510     }
511    
512     /* TODO: Hm... */
513     if (m->bintrans_enable)
514     m->speed_tricks = 0;
515    
516     if (cur_machine_bintrans_size[0])
517     m->bintrans_size = 1048576 *
518     atoi(cur_machine_bintrans_size);
519    
520     if (!cur_machine_force_netboot[0])
521     strcpy(cur_machine_force_netboot, "no");
522     m->force_netboot = parse_on_off(cur_machine_force_netboot);
523    
524     if (!cur_machine_start_paused[0])
525     strcpy(cur_machine_start_paused, "no");
526     m->start_paused = parse_on_off(cur_machine_start_paused);
527    
528     /* NOTE: Default nr of CPUs is 0: */
529     if (!cur_machine_ncpus[0])
530     strcpy(cur_machine_ncpus, "0");
531     m->ncpus = atoi(cur_machine_ncpus);
532    
533     if (cur_machine_n_gfx_cards[0])
534     m->n_gfx_cards = atoi(cur_machine_n_gfx_cards);
535    
536     if (cur_machine_serial_nr[0]) {
537     m->serial_nr = atoi(cur_machine_serial_nr);
538     e->next_serial_nr = m->serial_nr+1;
539     }
540    
541     if (cur_machine_emulated_hz[0]) {
542     m->emulated_hz = mystrtoull(cur_machine_emulated_hz,
543     NULL, 0);
544     m->automatic_clock_adjustment = 0;
545     }
546    
547     /* NOTE: Default nr of CPUs is 0: */
548     if (!cur_machine_memory[0])
549     strcpy(cur_machine_memory, "0");
550     m->physical_ram_in_mb = atoi(cur_machine_memory);
551    
552     if (!cur_machine_x11_scaledown[0])
553     m->x11_scaledown = 1;
554     else {
555     m->x11_scaledown = atoi(cur_machine_x11_scaledown);
556     if (m->x11_scaledown < 0) {
557     fprintf(stderr, "Invalid scaledown value"
558     " (%i)\n", m->x11_scaledown);
559     exit(1);
560     }
561     }
562    
563     for (i=0; i<cur_machine_n_disk; i++) {
564     diskimage_add(m, cur_machine_disk[i]);
565     free(cur_machine_disk[i]);
566     cur_machine_disk[i] = NULL;
567     }
568    
569     m->boot_kernel_filename = strdup(cur_machine_bootname);
570    
571     if (cur_machine_bootarg[0])
572     m->boot_string_argument = strdup(cur_machine_bootarg);
573    
574     for (i=0; i<cur_machine_n_x11_disp; i++) {
575     m->x11_n_display_names ++;
576     m->x11_display_names = realloc(
577     m->x11_display_names, m->x11_n_display_names
578     * sizeof(char *));
579     if (m->x11_display_names == NULL) {
580     printf("out of memory\n");
581     exit(1);
582     }
583     m->x11_display_names[m->x11_n_display_names-1] =
584     strdup(cur_machine_x11_disp[i]);
585     if (m->x11_display_names
586     [m->x11_n_display_names-1] == NULL) {
587     printf("out of memory\n");
588     exit(1);
589     }
590     free(cur_machine_x11_disp[i]);
591     cur_machine_x11_disp[i] = NULL;
592     }
593    
594     emul_machine_setup(m,
595     cur_machine_n_load, cur_machine_load,
596     cur_machine_n_device, cur_machine_device);
597    
598     for (i=0; i<cur_machine_n_device; i++) {
599     free(cur_machine_device[i]);
600     cur_machine_device[i] = NULL;
601     }
602    
603     for (i=0; i<cur_machine_n_load; i++) {
604     free(cur_machine_load[i]);
605     cur_machine_load[i] = NULL;
606     }
607    
608     *parsestate = PARSESTATE_EMUL;
609     return;
610     }
611    
612     WORD("name", cur_machine_name);
613     WORD("cpu", cur_machine_cpu);
614     WORD("type", cur_machine_type);
615     WORD("subtype", cur_machine_subtype);
616     WORD("bootname", cur_machine_bootname);
617     WORD("bootarg", cur_machine_bootarg);
618     WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi);
619     WORD("debugger_on_badaddr", cur_machine_debugger_on_badaddr);
620     WORD("prom_emulation", cur_machine_prom_emulation);
621     WORD("use_x11", cur_machine_use_x11);
622     WORD("x11_scaledown", cur_machine_x11_scaledown);
623     WORD("bintrans", cur_machine_bintrans);
624     WORD("old_bintrans", cur_machine_old_bintrans);
625     WORD("bintrans_size", cur_machine_bintrans_size);
626     WORD("byte_order", cur_machine_byte_order);
627     WORD("random_mem_contents", cur_machine_random_mem);
628     WORD("use_random_bootstrap_cpu", cur_machine_random_cpu);
629     WORD("force_netboot", cur_machine_force_netboot);
630     WORD("ncpus", cur_machine_ncpus);
631     WORD("serial_nr", cur_machine_serial_nr);
632     WORD("n_gfx_cards", cur_machine_n_gfx_cards);
633     WORD("emulated_hz", cur_machine_emulated_hz);
634     WORD("memory", cur_machine_memory);
635     WORD("start_paused", cur_machine_start_paused);
636    
637     if (strcmp(word, "load") == 0) {
638     read_one_word(f, word, maxbuflen,
639     line, EXPECT_LEFT_PARENTHESIS);
640     if (cur_machine_n_load >= MAX_N_LOAD) {
641     fprintf(stderr, "too many loads\n");
642     exit(1);
643     }
644     cur_machine_load[cur_machine_n_load] = malloc(MAX_LOAD_LEN);
645     if (cur_machine_load[cur_machine_n_load] == NULL) {
646     fprintf(stderr, "out of memory\n");
647     exit(1);
648     }
649     read_one_word(f, cur_machine_load[cur_machine_n_load],
650     MAX_LOAD_LEN, line, EXPECT_WORD);
651     cur_machine_n_load ++;
652     read_one_word(f, word, maxbuflen,
653     line, EXPECT_RIGHT_PARENTHESIS);
654     return;
655     }
656    
657     if (strcmp(word, "disk") == 0) {
658     read_one_word(f, word, maxbuflen,
659     line, EXPECT_LEFT_PARENTHESIS);
660     if (cur_machine_n_disk >= MAX_N_DISK) {
661     fprintf(stderr, "too many disks\n");
662     exit(1);
663     }
664     cur_machine_disk[cur_machine_n_disk] = malloc(MAX_DISK_LEN);
665     if (cur_machine_disk[cur_machine_n_disk] == NULL) {
666     fprintf(stderr, "out of memory\n");
667     exit(1);
668     }
669     read_one_word(f, cur_machine_disk[cur_machine_n_disk],
670     MAX_DISK_LEN, line, EXPECT_WORD);
671     cur_machine_n_disk ++;
672     read_one_word(f, word, maxbuflen,
673     line, EXPECT_RIGHT_PARENTHESIS);
674     return;
675     }
676    
677     if (strcmp(word, "device") == 0) {
678     read_one_word(f, word, maxbuflen,
679     line, EXPECT_LEFT_PARENTHESIS);
680     if (cur_machine_n_device >= MAX_N_DEVICE) {
681     fprintf(stderr, "too many devices\n");
682     exit(1);
683     }
684     cur_machine_device[cur_machine_n_device] =
685     malloc(MAX_DEVICE_LEN);
686     if (cur_machine_device[cur_machine_n_device] == NULL) {
687     fprintf(stderr, "out of memory\n");
688     exit(1);
689     }
690     read_one_word(f, cur_machine_device[cur_machine_n_device],
691     MAX_DEVICE_LEN, line, EXPECT_WORD);
692     cur_machine_n_device ++;
693     read_one_word(f, word, maxbuflen,
694     line, EXPECT_RIGHT_PARENTHESIS);
695     return;
696     }
697    
698     if (strcmp(word, "add_x11_display") == 0) {
699     read_one_word(f, word, maxbuflen,
700     line, EXPECT_LEFT_PARENTHESIS);
701     if (cur_machine_n_x11_disp >= MAX_N_X11_DISP) {
702     fprintf(stderr, "too many x11 displays\n");
703     exit(1);
704     }
705     cur_machine_x11_disp[cur_machine_n_x11_disp] =
706     malloc(MAX_X11_DISP_LEN);
707     if (cur_machine_x11_disp[cur_machine_n_x11_disp] == NULL) {
708     fprintf(stderr, "out of memory\n");
709     exit(1);
710     }
711     read_one_word(f, cur_machine_x11_disp[cur_machine_n_x11_disp],
712     MAX_X11_DISP_LEN, line, EXPECT_WORD);
713     cur_machine_n_x11_disp ++;
714     read_one_word(f, word, maxbuflen,
715     line, EXPECT_RIGHT_PARENTHESIS);
716     return;
717     }
718    
719     fatal("line %i: not expecting '%s' in a 'machine' section\n",
720     *line, word);
721     exit(1);
722     }
723    
724    
725     /*
726     * emul_parse_config():
727     *
728     * Set up an emulation by parsing a config file.
729     */
730     void emul_parse_config(struct emul *e, FILE *f)
731     {
732     char word[500];
733     int in_emul = 0;
734     int line = 1;
735     int parsestate = PARSESTATE_NONE;
736    
737     /* debug("emul_parse_config()\n"); */
738    
739     while (!feof(f)) {
740     read_one_word(f, word, sizeof(word), &line,
741     EXPECT_WORD | EXPECT_RIGHT_PARENTHESIS);
742     if (!word[0])
743     break;
744    
745     /* debug("word = '%s'\n", word); */
746    
747     switch (parsestate) {
748     case PARSESTATE_NONE:
749     parse__none(e, f, &in_emul, &line, &parsestate,
750     word, sizeof(word));
751     break;
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     default:
765     fatal("INTERNAL ERROR in emul_parse.c ("
766     "parsestate %i is not imlemented yet?)\n",
767     parsestate);
768     exit(1);
769     }
770     }
771    
772     if (parsestate != PARSESTATE_NONE) {
773     fatal("EOF but not enough right parentheses?\n");
774     exit(1);
775     }
776     }
777    

  ViewVC Help
Powered by ViewVC 1.1.26