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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (hide annotations)
Mon Oct 8 16:18:56 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 22899 byte(s)
0.3.6
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 dpavlin 12 * $Id: emul_parse.c,v 1.33 2005/08/12 06:02:56 debug Exp $
29 dpavlin 2 *
30     * Set up an emulation by parsing a config file.
31     *
32     * TODO: This could be extended to support XML config files as well, but
33 dpavlin 10 * XML is ugly. It is ugly right now as well. The question is: which
34     * solution is the least ugly?
35 dpavlin 2 */
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 dpavlin 10 static char cur_net_local_port[10];
202     #define MAX_N_REMOTE 20
203     #define MAX_REMOTE_LEN 100
204     static char *cur_net_remote[MAX_N_REMOTE];
205     static int cur_net_n_remote;
206 dpavlin 2
207     static char cur_machine_name[50];
208     static char cur_machine_cpu[50];
209     static char cur_machine_type[50];
210     static char cur_machine_subtype[50];
211     static char cur_machine_bootname[150];
212     static char cur_machine_bootarg[250];
213     static char cur_machine_slowsi[10];
214     static char cur_machine_debugger_on_badaddr[10];
215     static char cur_machine_prom_emulation[10];
216     static char cur_machine_use_x11[10];
217     static char cur_machine_x11_scaledown[10];
218     static char cur_machine_bintrans[10];
219     static char cur_machine_old_bintrans[10];
220     static char cur_machine_bintrans_size[10];
221     static char cur_machine_byte_order[20];
222     static char cur_machine_random_mem[10];
223     static char cur_machine_random_cpu[10];
224     static char cur_machine_force_netboot[10];
225     static char cur_machine_start_paused[10];
226     static char cur_machine_ncpus[10];
227     static char cur_machine_n_gfx_cards[10];
228     static char cur_machine_serial_nr[10];
229     static char cur_machine_emulated_hz[10];
230     static char cur_machine_memory[10];
231 dpavlin 12 static char cur_machine_max_random_cycles[10];
232 dpavlin 2 #define MAX_N_LOAD 15
233     #define MAX_LOAD_LEN 2000
234     static char *cur_machine_load[MAX_N_LOAD];
235     static int cur_machine_n_load;
236     #define MAX_N_DISK 10
237     #define MAX_DISK_LEN 2000
238     static char *cur_machine_disk[MAX_N_DISK];
239     static int cur_machine_n_disk;
240     #define MAX_N_DEVICE 20
241     #define MAX_DEVICE_LEN 400
242     static char *cur_machine_device[MAX_N_DISK];
243     static int cur_machine_n_device;
244     #define MAX_N_X11_DISP 5
245     #define MAX_X11_DISP_LEN 1000
246     static char *cur_machine_x11_disp[MAX_N_X11_DISP];
247     static int cur_machine_n_x11_disp;
248    
249     #define WORD(w,var) { \
250     if (strcmp(word, w) == 0) { \
251     read_one_word(f, word, maxbuflen, \
252     line, EXPECT_LEFT_PARENTHESIS); \
253     read_one_word(f, var, sizeof(var), \
254     line, EXPECT_WORD); \
255     read_one_word(f, word, maxbuflen, \
256     line, EXPECT_RIGHT_PARENTHESIS); \
257     return; \
258     } \
259     }
260    
261    
262     /*
263     * parse_on_off():
264     *
265     * Returns 1 for "on", "yes", "enable", or "1".
266     * Returns 0 for "off", "no", "disable", or "0".
267     * Prints a fatal warning and exit()s for other values.
268     */
269     int parse_on_off(char *s)
270     {
271     if (strcasecmp(s, "on") == 0 || strcasecmp(s, "yes") == 0 ||
272     strcasecmp(s, "enable") == 0 || strcasecmp(s, "1") == 0)
273     return 1;
274     if (strcasecmp(s, "off") == 0 || strcasecmp(s, "no") == 0 ||
275     strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0)
276     return 0;
277    
278     fatal("parse_on_off(): unknown value '%s'\n", s);
279     exit(1);
280     }
281    
282    
283     /*
284     * parse__none():
285     *
286     * emul ( [...] )
287     */
288     static void parse__none(struct emul *e, FILE *f, int *in_emul, int *line,
289     int *parsestate, char *word, size_t maxbuflen)
290     {
291     if (strcmp(word, "emul") == 0) {
292     if (*in_emul) {
293     fatal("line %i: only one emul per config "
294     "file is supported!\n", *line);
295     exit(1);
296     }
297     *parsestate = PARSESTATE_EMUL;
298     *in_emul = 1;
299     read_one_word(f, word, maxbuflen,
300     line, EXPECT_LEFT_PARENTHESIS);
301     return;
302     }
303    
304     fatal("line %i: expecting 'emul', not '%s'\n", *line, word);
305     exit(1);
306     }
307    
308    
309     /*
310     * parse__emul():
311     *
312     * name, net, machine
313     */
314     static void parse__emul(struct emul *e, FILE *f, int *in_emul, int *line,
315     int *parsestate, char *word, size_t maxbuflen)
316     {
317     if (word[0] == ')') {
318     *parsestate = PARSESTATE_NONE;
319     return;
320     }
321    
322     if (strcmp(word, "name") == 0) {
323     char tmp[200];
324     read_one_word(f, word, maxbuflen,
325     line, EXPECT_LEFT_PARENTHESIS);
326     read_one_word(f, tmp, sizeof(tmp), line, EXPECT_WORD);
327     read_one_word(f, word, maxbuflen,
328     line, EXPECT_RIGHT_PARENTHESIS);
329     if (e->name != NULL) {
330     free(e->name);
331     e->name = NULL;
332     }
333     e->name = strdup(tmp);
334     if (e->name == NULL) {
335     fprintf(stderr, "out of memory in parse__emul()\n");
336     exit(1);
337     }
338     debug("name: \"%s\"\n", e->name);
339     return;
340     }
341    
342     if (strcmp(word, "net") == 0) {
343     *parsestate = PARSESTATE_NET;
344     read_one_word(f, word, maxbuflen,
345     line, EXPECT_LEFT_PARENTHESIS);
346    
347     /* Default net: */
348 dpavlin 10 strlcpy(cur_net_ipv4net, "10.0.0.0", sizeof(cur_net_ipv4net));
349     strlcpy(cur_net_ipv4len, "8", sizeof(cur_net_ipv4len));
350     strlcpy(cur_net_local_port, "", sizeof(cur_net_local_port));
351     cur_net_n_remote = 0;
352 dpavlin 2 return;
353     }
354    
355     if (strcmp(word, "machine") == 0) {
356     *parsestate = PARSESTATE_MACHINE;
357     read_one_word(f, word, maxbuflen,
358     line, EXPECT_LEFT_PARENTHESIS);
359    
360     /* A "zero state": */
361     cur_machine_name[0] = '\0';
362     cur_machine_cpu[0] = '\0';
363     cur_machine_type[0] = '\0';
364     cur_machine_subtype[0] = '\0';
365     cur_machine_bootname[0] = '\0';
366     cur_machine_bootarg[0] = '\0';
367     cur_machine_n_load = 0;
368     cur_machine_n_disk = 0;
369     cur_machine_n_device = 0;
370     cur_machine_n_x11_disp = 0;
371     cur_machine_slowsi[0] = '\0';
372     cur_machine_debugger_on_badaddr[0] = '\0';
373     cur_machine_prom_emulation[0] = '\0';
374     cur_machine_use_x11[0] = '\0';
375     cur_machine_x11_scaledown[0] = '\0';
376     cur_machine_bintrans[0] = '\0';
377     cur_machine_old_bintrans[0] = '\0';
378     cur_machine_bintrans_size[0] = '\0';
379     cur_machine_byte_order[0] = '\0';
380     cur_machine_random_mem[0] = '\0';
381     cur_machine_random_cpu[0] = '\0';
382     cur_machine_force_netboot[0] = '\0';
383     cur_machine_start_paused[0] = '\0';
384     cur_machine_ncpus[0] = '\0';
385     cur_machine_n_gfx_cards[0] = '\0';
386     cur_machine_serial_nr[0] = '\0';
387     cur_machine_emulated_hz[0] = '\0';
388     cur_machine_memory[0] = '\0';
389 dpavlin 12 cur_machine_max_random_cycles[0] = '\0';
390 dpavlin 2 return;
391     }
392    
393     fatal("line %i: not expecting '%s' in an 'emul' section\n",
394     *line, word);
395     exit(1);
396     }
397    
398    
399     /*
400     * parse__net():
401     *
402 dpavlin 10 * Simple words: ipv4net, ipv4len, local_port
403 dpavlin 2 *
404 dpavlin 10 * Complex: add_remote
405     *
406 dpavlin 2 * TODO: more words? for example an option to disable the gateway? that would
407     * have to be implemented correctly in src/net.c first.
408     */
409     static void parse__net(struct emul *e, FILE *f, int *in_emul, int *line,
410     int *parsestate, char *word, size_t maxbuflen)
411     {
412 dpavlin 10 int i;
413    
414 dpavlin 2 if (word[0] == ')') {
415     /* Finished with the 'net' section. Let's create the net: */
416     if (e->net != NULL) {
417     fatal("line %i: more than one net isn't really "
418     "supported yet\n", *line);
419     exit(1);
420     }
421    
422 dpavlin 10 if (!cur_net_local_port[0])
423     strlcpy(cur_net_local_port, "0",
424     sizeof(cur_net_local_port));
425    
426 dpavlin 2 e->net = net_init(e, NET_INIT_FLAG_GATEWAY,
427 dpavlin 10 cur_net_ipv4net, atoi(cur_net_ipv4len),
428     cur_net_remote, cur_net_n_remote,
429     atoi(cur_net_local_port));
430 dpavlin 2
431     if (e->net == NULL) {
432     fatal("line %i: fatal error: could not create"
433     " the net (?)\n", *line);
434     exit(1);
435     }
436    
437 dpavlin 10 for (i=0; i<cur_net_n_remote; i++) {
438     free(cur_net_remote[i]);
439     cur_net_remote[i] = NULL;
440     }
441    
442 dpavlin 2 *parsestate = PARSESTATE_EMUL;
443     return;
444     }
445    
446     WORD("ipv4net", cur_net_ipv4net);
447     WORD("ipv4len", cur_net_ipv4len);
448 dpavlin 10 WORD("local_port", cur_net_local_port);
449 dpavlin 2
450 dpavlin 10 if (strcmp(word, "add_remote") == 0) {
451     read_one_word(f, word, maxbuflen,
452     line, EXPECT_LEFT_PARENTHESIS);
453     if (cur_net_n_remote >= MAX_N_REMOTE) {
454     fprintf(stderr, "too many remote networks\n");
455     exit(1);
456     }
457     cur_net_remote[cur_net_n_remote] = malloc(MAX_REMOTE_LEN);
458     if (cur_net_remote[cur_net_n_remote] == NULL) {
459     fprintf(stderr, "out of memory\n");
460     exit(1);
461     }
462     read_one_word(f, cur_net_remote[cur_net_n_remote],
463     MAX_REMOTE_LEN, line, EXPECT_WORD);
464     cur_net_n_remote ++;
465     read_one_word(f, word, maxbuflen, line,
466     EXPECT_RIGHT_PARENTHESIS);
467     return;
468     }
469    
470 dpavlin 2 fatal("line %i: not expecting '%s' in a 'net' section\n", *line, word);
471     exit(1);
472     }
473    
474    
475     /*
476     * parse__machine():
477     */
478     static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
479     int *parsestate, char *word, size_t maxbuflen)
480     {
481     int r, i;
482    
483     if (word[0] == ')') {
484     /* Finished with the 'machine' section. */
485     struct machine *m;
486    
487     if (!cur_machine_name[0])
488 dpavlin 10 strlcpy(cur_machine_name, "no_name",
489     sizeof(cur_machine_name));
490 dpavlin 2
491     m = emul_add_machine(e, cur_machine_name);
492    
493     r = machine_name_to_type(cur_machine_type, cur_machine_subtype,
494     &m->machine_type, &m->machine_subtype, &m->arch);
495     if (!r)
496     exit(1);
497    
498     if (cur_machine_cpu[0])
499     m->cpu_name = strdup(cur_machine_cpu);
500    
501     if (!cur_machine_use_x11[0])
502 dpavlin 10 strlcpy(cur_machine_use_x11, "no",
503     sizeof(cur_machine_use_x11));
504 dpavlin 2 m->use_x11 = parse_on_off(cur_machine_use_x11);
505    
506     if (!cur_machine_slowsi[0])
507 dpavlin 10 strlcpy(cur_machine_slowsi, "no",
508     sizeof(cur_machine_slowsi));
509 dpavlin 2 m->slow_serial_interrupts_hack_for_linux =
510     parse_on_off(cur_machine_slowsi);
511    
512     if (!cur_machine_debugger_on_badaddr[0])
513 dpavlin 10 strlcpy(cur_machine_debugger_on_badaddr, "no",
514     sizeof(cur_machine_debugger_on_badaddr));
515 dpavlin 2 m->single_step_on_bad_addr =
516     parse_on_off(cur_machine_debugger_on_badaddr);
517    
518     if (!cur_machine_prom_emulation[0])
519 dpavlin 10 strlcpy(cur_machine_prom_emulation, "yes",
520     sizeof(cur_machine_prom_emulation));
521 dpavlin 2 m->prom_emulation = parse_on_off(cur_machine_prom_emulation);
522    
523     if (!cur_machine_random_mem[0])
524 dpavlin 10 strlcpy(cur_machine_random_mem, "no",
525     sizeof(cur_machine_random_mem));
526 dpavlin 2 m->random_mem_contents =
527     parse_on_off(cur_machine_random_mem);
528    
529     if (!cur_machine_random_cpu[0])
530 dpavlin 10 strlcpy(cur_machine_random_cpu, "no",
531     sizeof(cur_machine_random_cpu));
532 dpavlin 2 m->use_random_bootstrap_cpu =
533     parse_on_off(cur_machine_random_cpu);
534    
535     m->byte_order_override = NO_BYTE_ORDER_OVERRIDE;
536     if (cur_machine_byte_order[0]) {
537     if (strncasecmp(cur_machine_byte_order, "big", 3) == 0)
538     m->byte_order_override = EMUL_BIG_ENDIAN;
539     else if (strncasecmp(cur_machine_byte_order, "little",
540     6) == 0)
541     m->byte_order_override = EMUL_LITTLE_ENDIAN;
542     else {
543     fatal("Byte order must be big-endian or"
544     " little-endian\n");
545     exit(1);
546     }
547     }
548    
549     if (!cur_machine_bintrans[0])
550 dpavlin 10 strlcpy(cur_machine_bintrans, "yes",
551     sizeof(cur_machine_bintrans));
552 dpavlin 2 m->bintrans_enable = m->bintrans_enabled_from_start =
553     parse_on_off(cur_machine_bintrans);
554    
555     if (!cur_machine_old_bintrans[0])
556 dpavlin 10 strlcpy(cur_machine_old_bintrans, "yes",
557     sizeof(cur_machine_old_bintrans));
558 dpavlin 2 m->old_bintrans_enable = parse_on_off(cur_machine_old_bintrans);
559    
560 dpavlin 12 if (!m->bintrans_enable && m->old_bintrans_enable)
561     m->old_bintrans_enable = 0;
562 dpavlin 2
563     /* TODO: Hm... */
564     if (m->bintrans_enable)
565     m->speed_tricks = 0;
566    
567     if (cur_machine_bintrans_size[0])
568     m->bintrans_size = 1048576 *
569     atoi(cur_machine_bintrans_size);
570    
571     if (!cur_machine_force_netboot[0])
572 dpavlin 10 strlcpy(cur_machine_force_netboot, "no",
573     sizeof(cur_machine_force_netboot));
574 dpavlin 2 m->force_netboot = parse_on_off(cur_machine_force_netboot);
575    
576     if (!cur_machine_start_paused[0])
577 dpavlin 10 strlcpy(cur_machine_start_paused, "no",
578     sizeof(cur_machine_start_paused));
579 dpavlin 2 m->start_paused = parse_on_off(cur_machine_start_paused);
580    
581     /* NOTE: Default nr of CPUs is 0: */
582     if (!cur_machine_ncpus[0])
583 dpavlin 10 strlcpy(cur_machine_ncpus, "0",
584     sizeof(cur_machine_ncpus));
585 dpavlin 2 m->ncpus = atoi(cur_machine_ncpus);
586    
587     if (cur_machine_n_gfx_cards[0])
588     m->n_gfx_cards = atoi(cur_machine_n_gfx_cards);
589    
590     if (cur_machine_serial_nr[0]) {
591     m->serial_nr = atoi(cur_machine_serial_nr);
592     e->next_serial_nr = m->serial_nr+1;
593     }
594    
595     if (cur_machine_emulated_hz[0]) {
596     m->emulated_hz = mystrtoull(cur_machine_emulated_hz,
597     NULL, 0);
598     m->automatic_clock_adjustment = 0;
599     }
600    
601     /* NOTE: Default nr of CPUs is 0: */
602     if (!cur_machine_memory[0])
603 dpavlin 10 strlcpy(cur_machine_memory, "0",
604     sizeof(cur_machine_memory));
605 dpavlin 2 m->physical_ram_in_mb = atoi(cur_machine_memory);
606    
607 dpavlin 12 if (cur_machine_max_random_cycles[0]) {
608     if (m->bintrans_enable) {
609     fprintf(stderr, "max_random_cycles doesn't"
610     " work with bintrans\n");
611     exit(1);
612     }
613     m->max_random_cycles_per_chunk = atoi(
614     cur_machine_max_random_cycles);
615     }
616    
617 dpavlin 2 if (!cur_machine_x11_scaledown[0])
618     m->x11_scaledown = 1;
619     else {
620     m->x11_scaledown = atoi(cur_machine_x11_scaledown);
621     if (m->x11_scaledown < 0) {
622     fprintf(stderr, "Invalid scaledown value"
623     " (%i)\n", m->x11_scaledown);
624     exit(1);
625     }
626     }
627    
628     for (i=0; i<cur_machine_n_disk; i++) {
629     diskimage_add(m, cur_machine_disk[i]);
630     free(cur_machine_disk[i]);
631     cur_machine_disk[i] = NULL;
632     }
633    
634     m->boot_kernel_filename = strdup(cur_machine_bootname);
635    
636     if (cur_machine_bootarg[0])
637     m->boot_string_argument = strdup(cur_machine_bootarg);
638    
639     for (i=0; i<cur_machine_n_x11_disp; i++) {
640     m->x11_n_display_names ++;
641     m->x11_display_names = realloc(
642     m->x11_display_names, m->x11_n_display_names
643     * sizeof(char *));
644     if (m->x11_display_names == NULL) {
645     printf("out of memory\n");
646     exit(1);
647     }
648     m->x11_display_names[m->x11_n_display_names-1] =
649     strdup(cur_machine_x11_disp[i]);
650     if (m->x11_display_names
651     [m->x11_n_display_names-1] == NULL) {
652     printf("out of memory\n");
653     exit(1);
654     }
655     free(cur_machine_x11_disp[i]);
656     cur_machine_x11_disp[i] = NULL;
657     }
658    
659     emul_machine_setup(m,
660     cur_machine_n_load, cur_machine_load,
661     cur_machine_n_device, cur_machine_device);
662    
663     for (i=0; i<cur_machine_n_device; i++) {
664     free(cur_machine_device[i]);
665     cur_machine_device[i] = NULL;
666     }
667    
668     for (i=0; i<cur_machine_n_load; i++) {
669     free(cur_machine_load[i]);
670     cur_machine_load[i] = NULL;
671     }
672    
673     *parsestate = PARSESTATE_EMUL;
674     return;
675     }
676    
677     WORD("name", cur_machine_name);
678     WORD("cpu", cur_machine_cpu);
679     WORD("type", cur_machine_type);
680     WORD("subtype", cur_machine_subtype);
681     WORD("bootname", cur_machine_bootname);
682     WORD("bootarg", cur_machine_bootarg);
683     WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi);
684     WORD("debugger_on_badaddr", cur_machine_debugger_on_badaddr);
685     WORD("prom_emulation", cur_machine_prom_emulation);
686     WORD("use_x11", cur_machine_use_x11);
687     WORD("x11_scaledown", cur_machine_x11_scaledown);
688     WORD("bintrans", cur_machine_bintrans);
689     WORD("old_bintrans", cur_machine_old_bintrans);
690     WORD("bintrans_size", cur_machine_bintrans_size);
691     WORD("byte_order", cur_machine_byte_order);
692     WORD("random_mem_contents", cur_machine_random_mem);
693     WORD("use_random_bootstrap_cpu", cur_machine_random_cpu);
694     WORD("force_netboot", cur_machine_force_netboot);
695     WORD("ncpus", cur_machine_ncpus);
696     WORD("serial_nr", cur_machine_serial_nr);
697     WORD("n_gfx_cards", cur_machine_n_gfx_cards);
698     WORD("emulated_hz", cur_machine_emulated_hz);
699     WORD("memory", cur_machine_memory);
700 dpavlin 12 WORD("max_random_cycles", cur_machine_max_random_cycles);
701 dpavlin 2 WORD("start_paused", cur_machine_start_paused);
702    
703     if (strcmp(word, "load") == 0) {
704     read_one_word(f, word, maxbuflen,
705     line, EXPECT_LEFT_PARENTHESIS);
706     if (cur_machine_n_load >= MAX_N_LOAD) {
707     fprintf(stderr, "too many loads\n");
708     exit(1);
709     }
710     cur_machine_load[cur_machine_n_load] = malloc(MAX_LOAD_LEN);
711     if (cur_machine_load[cur_machine_n_load] == NULL) {
712     fprintf(stderr, "out of memory\n");
713     exit(1);
714     }
715     read_one_word(f, cur_machine_load[cur_machine_n_load],
716     MAX_LOAD_LEN, line, EXPECT_WORD);
717     cur_machine_n_load ++;
718     read_one_word(f, word, maxbuflen,
719     line, EXPECT_RIGHT_PARENTHESIS);
720     return;
721     }
722    
723     if (strcmp(word, "disk") == 0) {
724     read_one_word(f, word, maxbuflen,
725     line, EXPECT_LEFT_PARENTHESIS);
726     if (cur_machine_n_disk >= MAX_N_DISK) {
727     fprintf(stderr, "too many disks\n");
728     exit(1);
729     }
730     cur_machine_disk[cur_machine_n_disk] = malloc(MAX_DISK_LEN);
731     if (cur_machine_disk[cur_machine_n_disk] == NULL) {
732     fprintf(stderr, "out of memory\n");
733     exit(1);
734     }
735     read_one_word(f, cur_machine_disk[cur_machine_n_disk],
736     MAX_DISK_LEN, line, EXPECT_WORD);
737     cur_machine_n_disk ++;
738     read_one_word(f, word, maxbuflen,
739     line, EXPECT_RIGHT_PARENTHESIS);
740     return;
741     }
742    
743     if (strcmp(word, "device") == 0) {
744     read_one_word(f, word, maxbuflen,
745     line, EXPECT_LEFT_PARENTHESIS);
746     if (cur_machine_n_device >= MAX_N_DEVICE) {
747     fprintf(stderr, "too many devices\n");
748     exit(1);
749     }
750     cur_machine_device[cur_machine_n_device] =
751     malloc(MAX_DEVICE_LEN);
752     if (cur_machine_device[cur_machine_n_device] == NULL) {
753     fprintf(stderr, "out of memory\n");
754     exit(1);
755     }
756     read_one_word(f, cur_machine_device[cur_machine_n_device],
757     MAX_DEVICE_LEN, line, EXPECT_WORD);
758     cur_machine_n_device ++;
759     read_one_word(f, word, maxbuflen,
760     line, EXPECT_RIGHT_PARENTHESIS);
761     return;
762     }
763    
764     if (strcmp(word, "add_x11_display") == 0) {
765     read_one_word(f, word, maxbuflen,
766     line, EXPECT_LEFT_PARENTHESIS);
767     if (cur_machine_n_x11_disp >= MAX_N_X11_DISP) {
768     fprintf(stderr, "too many x11 displays\n");
769     exit(1);
770     }
771     cur_machine_x11_disp[cur_machine_n_x11_disp] =
772     malloc(MAX_X11_DISP_LEN);
773     if (cur_machine_x11_disp[cur_machine_n_x11_disp] == NULL) {
774     fprintf(stderr, "out of memory\n");
775     exit(1);
776     }
777     read_one_word(f, cur_machine_x11_disp[cur_machine_n_x11_disp],
778     MAX_X11_DISP_LEN, line, EXPECT_WORD);
779     cur_machine_n_x11_disp ++;
780     read_one_word(f, word, maxbuflen,
781     line, EXPECT_RIGHT_PARENTHESIS);
782     return;
783     }
784    
785     fatal("line %i: not expecting '%s' in a 'machine' section\n",
786     *line, word);
787     exit(1);
788     }
789    
790    
791     /*
792     * emul_parse_config():
793     *
794     * Set up an emulation by parsing a config file.
795     */
796     void emul_parse_config(struct emul *e, FILE *f)
797     {
798     char word[500];
799     int in_emul = 0;
800     int line = 1;
801     int parsestate = PARSESTATE_NONE;
802    
803     /* debug("emul_parse_config()\n"); */
804    
805     while (!feof(f)) {
806     read_one_word(f, word, sizeof(word), &line,
807     EXPECT_WORD | EXPECT_RIGHT_PARENTHESIS);
808     if (!word[0])
809     break;
810    
811     /* debug("word = '%s'\n", word); */
812    
813     switch (parsestate) {
814     case PARSESTATE_NONE:
815     parse__none(e, f, &in_emul, &line, &parsestate,
816     word, sizeof(word));
817     break;
818     case PARSESTATE_EMUL:
819     parse__emul(e, f, &in_emul, &line, &parsestate,
820     word, sizeof(word));
821     break;
822     case PARSESTATE_NET:
823     parse__net(e, f, &in_emul, &line, &parsestate,
824     word, sizeof(word));
825     break;
826     case PARSESTATE_MACHINE:
827     parse__machine(e, f, &in_emul, &line, &parsestate,
828     word, sizeof(word));
829     break;
830     default:
831     fatal("INTERNAL ERROR in emul_parse.c ("
832     "parsestate %i is not imlemented yet?)\n",
833     parsestate);
834     exit(1);
835     }
836     }
837    
838     if (parsestate != PARSESTATE_NONE) {
839     fatal("EOF but not enough right parentheses?\n");
840     exit(1);
841     }
842     }
843    

  ViewVC Help
Powered by ViewVC 1.1.26