/[gxemul]/trunk/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

Diff of /trunk/src/emul_parse.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: emul_parse.c,v 1.29 2005/03/14 19:14:04 debug Exp $   *  $Id: emul_parse.c,v 1.42 2006/06/22 13:22:41 debug Exp $
29   *   *
30   *  Set up an emulation by parsing a config file.   *  Set up an emulation by parsing a config file.
31   *   *
32   *   *  TODO: REWRITE THIS FROM SCRATCH! :-)
  *  TODO: This could be extended to support XML config files as well, but  
  *        XML is ugly.  
33   */   */
34    
35  #include <stdio.h>  #include <stdio.h>
# Line 49  Line 47 
47          (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \          (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || \
48          ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') )          ch == '_' || ch == '$' || (ch >= '0' && ch <= '9') )
49    
50    #define MAX_WORD_LEN            200
51    
52  #define EXPECT_WORD                     1  #define EXPECT_WORD                     1
53  #define EXPECT_LEFT_PARENTHESIS         2  #define EXPECT_LEFT_PARENTHESIS         2
54  #define EXPECT_RIGHT_PARENTHESIS        4  #define EXPECT_RIGHT_PARENTHESIS        4
55    
56    static int parenthesis_level = 0;
57    
58    
59  /*  /*
60   *  read_one_word():   *  read_one_word():
# Line 173  static void read_one_word(FILE *f, char Line 174  static void read_one_word(FILE *f, char
174                                  done = 1;                                  done = 1;
175                  } else {                  } else {
176                          if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') {                          if ((expect & EXPECT_LEFT_PARENTHESIS) && ch == '(') {
177                                    parenthesis_level ++;
178                                  buf[curlen++] = ch;                                  buf[curlen++] = ch;
179                                  break;                                  break;
180                          }                          }
181                          if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') {                          if ((expect & EXPECT_RIGHT_PARENTHESIS) && ch == ')') {
182                                    parenthesis_level --;
183                                  buf[curlen++] = ch;                                  buf[curlen++] = ch;
184                                  break;                                  break;
185                          }                          }
# Line 198  static void read_one_word(FILE *f, char Line 201  static void read_one_word(FILE *f, char
201    
202  static char cur_net_ipv4net[50];  static char cur_net_ipv4net[50];
203  static char cur_net_ipv4len[50];  static char cur_net_ipv4len[50];
204    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    
210  static char cur_machine_name[50];  static char cur_machine_name[50];
211  static char cur_machine_cpu[50];  static char cur_machine_cpu[50];
# Line 206  static char cur_machine_subtype[50]; Line 214  static char cur_machine_subtype[50];
214  static char cur_machine_bootname[150];  static char cur_machine_bootname[150];
215  static char cur_machine_bootarg[250];  static char cur_machine_bootarg[250];
216  static char cur_machine_slowsi[10];  static char cur_machine_slowsi[10];
 static char cur_machine_debugger_on_badaddr[10];  
217  static char cur_machine_prom_emulation[10];  static char cur_machine_prom_emulation[10];
218  static char cur_machine_use_x11[10];  static char cur_machine_use_x11[10];
219  static char cur_machine_x11_scaledown[10];  static char cur_machine_x11_scaledown[10];
 static char cur_machine_bintrans[10];  
 static char cur_machine_old_bintrans[10];  
 static char cur_machine_bintrans_size[10];  
220  static char cur_machine_byte_order[20];  static char cur_machine_byte_order[20];
221  static char cur_machine_random_mem[10];  static char cur_machine_random_mem[10];
222  static char cur_machine_random_cpu[10];  static char cur_machine_random_cpu[10];
# Line 252  static int cur_machine_n_x11_disp; Line 256  static int cur_machine_n_x11_disp;
256                  }                                               \                  }                                               \
257          }          }
258    
259    static void parse__machine(struct emul *e, FILE *f, int *in_emul, int *line,
260            int *parsestate, char *word, size_t maxbuflen);
261    
262    
263  /*  /*
264   *  parse_on_off():   *  parse_on_off():
# Line 269  int parse_on_off(char *s) Line 276  int parse_on_off(char *s)
276              strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0)              strcasecmp(s, "disable") == 0 || strcasecmp(s, "0") == 0)
277                  return 0;                  return 0;
278    
279          fatal("parse_on_off(): unknown value '%s'\n", s);          fprintf(stderr, "parse_on_off(): WARNING: unknown value '%s'\n", s);
         exit(1);  
 }  
   
280    
281  /*          return 0;
  *  parse__none():  
  *  
  *  emul ( [...] )  
  */  
 static void parse__none(struct emul *e, FILE *f, int *in_emul, int *line,  
         int *parsestate, char *word, size_t maxbuflen)  
 {  
         if (strcmp(word, "emul") == 0) {  
                 if (*in_emul) {  
                         fatal("line %i: only one emul per config "  
                             "file is supported!\n", *line);  
                         exit(1);  
                 }  
                 *parsestate = PARSESTATE_EMUL;  
                 *in_emul = 1;  
                 read_one_word(f, word, maxbuflen,  
                     line, EXPECT_LEFT_PARENTHESIS);  
                 return;  
         }  
   
         fatal("line %i: expecting 'emul', not '%s'\n", *line, word);  
         exit(1);  
282  }  }
283    
284    
# Line 339  static void parse__emul(struct emul *e, Line 321  static void parse__emul(struct emul *e,
321                      line, EXPECT_LEFT_PARENTHESIS);                      line, EXPECT_LEFT_PARENTHESIS);
322    
323                  /*  Default net:  */                  /*  Default net:  */
324                  strcpy(cur_net_ipv4net, "10.0.0.0");                  strlcpy(cur_net_ipv4net, "10.0.0.0", sizeof(cur_net_ipv4net));
325                  strcpy(cur_net_ipv4len, "8");                  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                  return;                  return;
329          }          }
330    
# Line 361  static void parse__emul(struct emul *e, Line 345  static void parse__emul(struct emul *e,
345                  cur_machine_n_device = 0;                  cur_machine_n_device = 0;
346                  cur_machine_n_x11_disp = 0;                  cur_machine_n_x11_disp = 0;
347                  cur_machine_slowsi[0] = '\0';                  cur_machine_slowsi[0] = '\0';
                 cur_machine_debugger_on_badaddr[0] = '\0';  
348                  cur_machine_prom_emulation[0] = '\0';                  cur_machine_prom_emulation[0] = '\0';
349                  cur_machine_use_x11[0] = '\0';                  cur_machine_use_x11[0] = '\0';
350                  cur_machine_x11_scaledown[0] = '\0';                  cur_machine_x11_scaledown[0] = '\0';
                 cur_machine_bintrans[0] = '\0';  
                 cur_machine_old_bintrans[0] = '\0';  
                 cur_machine_bintrans_size[0] = '\0';  
351                  cur_machine_byte_order[0] = '\0';                  cur_machine_byte_order[0] = '\0';
352                  cur_machine_random_mem[0] = '\0';                  cur_machine_random_mem[0] = '\0';
353                  cur_machine_random_cpu[0] = '\0';                  cur_machine_random_cpu[0] = '\0';
# Line 390  static void parse__emul(struct emul *e, Line 370  static void parse__emul(struct emul *e,
370  /*  /*
371   *  parse__net():   *  parse__net():
372   *   *
373   *  Simple words: ipv4net, ipv4len   *  Simple words: ipv4net, ipv4len, local_port
374     *
375     *  Complex: add_remote
376   *   *
377   *  TODO: more words? for example an option to disable the gateway? that would   *  TODO: more words? for example an option to disable the gateway? that would
378   *  have to be implemented correctly in src/net.c first.   *  have to be implemented correctly in src/net.c first.
# Line 398  static void parse__emul(struct emul *e, Line 380  static void parse__emul(struct emul *e,
380  static void parse__net(struct emul *e, FILE *f, int *in_emul, int *line,  static void parse__net(struct emul *e, FILE *f, int *in_emul, int *line,
381          int *parsestate, char *word, size_t maxbuflen)          int *parsestate, char *word, size_t maxbuflen)
382  {  {
383            int i;
384    
385          if (word[0] == ')') {          if (word[0] == ')') {
386                  /*  Finished with the 'net' section. Let's create the net:  */                  /*  Finished with the 'net' section. Let's create the net:  */
387                  if (e->net != NULL) {                  if (e->net != NULL) {
# Line 406  static void parse__net(struct emul *e, F Line 390  static void parse__net(struct emul *e, F
390                          exit(1);                          exit(1);
391                  }                  }
392    
393                    if (!cur_net_local_port[0])
394                            strlcpy(cur_net_local_port, "0",
395                                sizeof(cur_net_local_port));
396    
397                  e->net = net_init(e, NET_INIT_FLAG_GATEWAY,                  e->net = net_init(e, NET_INIT_FLAG_GATEWAY,
398                      cur_net_ipv4net, atoi(cur_net_ipv4len));                      cur_net_ipv4net, atoi(cur_net_ipv4len),
399                        cur_net_remote, cur_net_n_remote,
400                        atoi(cur_net_local_port));
401    
402                  if (e->net == NULL) {                  if (e->net == NULL) {
403                          fatal("line %i: fatal error: could not create"                          fatal("line %i: fatal error: could not create"
# Line 415  static void parse__net(struct emul *e, F Line 405  static void parse__net(struct emul *e, F
405                          exit(1);                          exit(1);
406                  }                  }
407    
408                    for (i=0; i<cur_net_n_remote; i++) {
409                            free(cur_net_remote[i]);
410                            cur_net_remote[i] = NULL;
411                    }
412    
413                  *parsestate = PARSESTATE_EMUL;                  *parsestate = PARSESTATE_EMUL;
414                  return;                  return;
415          }          }
416    
417          WORD("ipv4net", cur_net_ipv4net);          WORD("ipv4net", cur_net_ipv4net);
418          WORD("ipv4len", cur_net_ipv4len);          WORD("ipv4len", cur_net_ipv4len);
419            WORD("local_port", cur_net_local_port);
420    
421            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          fatal("line %i: not expecting '%s' in a 'net' section\n", *line, word);          fatal("line %i: not expecting '%s' in a 'net' section\n", *line, word);
442          exit(1);          exit(1);
# Line 440  static void parse__machine(struct emul * Line 456  static void parse__machine(struct emul *
456                  struct machine *m;                  struct machine *m;
457    
458                  if (!cur_machine_name[0])                  if (!cur_machine_name[0])
459                          strcpy(cur_machine_name, "no_name");                          strlcpy(cur_machine_name, "no_name",
460                                sizeof(cur_machine_name));
461    
462                  m = emul_add_machine(e, cur_machine_name);                  m = emul_add_machine(e, cur_machine_name);
463    
# Line 453  static void parse__machine(struct emul * Line 470  static void parse__machine(struct emul *
470                          m->cpu_name = strdup(cur_machine_cpu);                          m->cpu_name = strdup(cur_machine_cpu);
471    
472                  if (!cur_machine_use_x11[0])                  if (!cur_machine_use_x11[0])
473                          strcpy(cur_machine_use_x11, "no");                          strlcpy(cur_machine_use_x11, "no",
474                                sizeof(cur_machine_use_x11));
475                  m->use_x11 = parse_on_off(cur_machine_use_x11);                  m->use_x11 = parse_on_off(cur_machine_use_x11);
476    
477                  if (!cur_machine_slowsi[0])                  if (!cur_machine_slowsi[0])
478                          strcpy(cur_machine_slowsi, "no");                          strlcpy(cur_machine_slowsi, "no",
479                                sizeof(cur_machine_slowsi));
480                  m->slow_serial_interrupts_hack_for_linux =                  m->slow_serial_interrupts_hack_for_linux =
481                      parse_on_off(cur_machine_slowsi);                      parse_on_off(cur_machine_slowsi);
482    
                 if (!cur_machine_debugger_on_badaddr[0])  
                         strcpy(cur_machine_debugger_on_badaddr, "no");  
                 m->single_step_on_bad_addr =  
                     parse_on_off(cur_machine_debugger_on_badaddr);  
   
483                  if (!cur_machine_prom_emulation[0])                  if (!cur_machine_prom_emulation[0])
484                          strcpy(cur_machine_prom_emulation, "yes");                          strlcpy(cur_machine_prom_emulation, "yes",
485                                sizeof(cur_machine_prom_emulation));
486                  m->prom_emulation = parse_on_off(cur_machine_prom_emulation);                  m->prom_emulation = parse_on_off(cur_machine_prom_emulation);
487    
488                  if (!cur_machine_random_mem[0])                  if (!cur_machine_random_mem[0])
489                          strcpy(cur_machine_random_mem, "no");                          strlcpy(cur_machine_random_mem, "no",
490                                sizeof(cur_machine_random_mem));
491                  m->random_mem_contents =                  m->random_mem_contents =
492                      parse_on_off(cur_machine_random_mem);                      parse_on_off(cur_machine_random_mem);
493    
494                  if (!cur_machine_random_cpu[0])                  if (!cur_machine_random_cpu[0])
495                          strcpy(cur_machine_random_cpu, "no");                          strlcpy(cur_machine_random_cpu, "no",
496                                sizeof(cur_machine_random_cpu));
497                  m->use_random_bootstrap_cpu =                  m->use_random_bootstrap_cpu =
498                      parse_on_off(cur_machine_random_cpu);                      parse_on_off(cur_machine_random_cpu);
499    
# Line 494  static void parse__machine(struct emul * Line 511  static void parse__machine(struct emul *
511                          }                          }
512                  }                  }
513    
                 if (!cur_machine_bintrans[0])  
                         strcpy(cur_machine_bintrans, "yes");  
                 m->bintrans_enable = m->bintrans_enabled_from_start =  
                     parse_on_off(cur_machine_bintrans);  
   
                 if (!cur_machine_old_bintrans[0])  
                         strcpy(cur_machine_old_bintrans, "no");  
                 m->old_bintrans_enable = parse_on_off(cur_machine_old_bintrans);  
   
                 if (!m->bintrans_enable && m->old_bintrans_enable) {  
                         fatal("cannot use old bintrans when bintrans is"  
                             " disabled.\n");  
                         exit(1);  
                 }  
   
                 /*  TODO: Hm...  */  
                 if (m->bintrans_enable)  
                         m->speed_tricks = 0;  
   
                 if (cur_machine_bintrans_size[0])  
                         m->bintrans_size = 1048576 *  
                             atoi(cur_machine_bintrans_size);  
   
514                  if (!cur_machine_force_netboot[0])                  if (!cur_machine_force_netboot[0])
515                          strcpy(cur_machine_force_netboot, "no");                          strlcpy(cur_machine_force_netboot, "no",
516                                sizeof(cur_machine_force_netboot));
517                  m->force_netboot = parse_on_off(cur_machine_force_netboot);                  m->force_netboot = parse_on_off(cur_machine_force_netboot);
518    
519                  if (!cur_machine_start_paused[0])                  if (!cur_machine_start_paused[0])
520                          strcpy(cur_machine_start_paused, "no");                          strlcpy(cur_machine_start_paused, "no",
521                                sizeof(cur_machine_start_paused));
522                  m->start_paused = parse_on_off(cur_machine_start_paused);                  m->start_paused = parse_on_off(cur_machine_start_paused);
523    
524                  /*  NOTE: Default nr of CPUs is 0:  */                  /*  NOTE: Default nr of CPUs is 0:  */
525                  if (!cur_machine_ncpus[0])                  if (!cur_machine_ncpus[0])
526                          strcpy(cur_machine_ncpus, "0");                          strlcpy(cur_machine_ncpus, "0",
527                                sizeof(cur_machine_ncpus));
528                  m->ncpus = atoi(cur_machine_ncpus);                  m->ncpus = atoi(cur_machine_ncpus);
529    
530                  if (cur_machine_n_gfx_cards[0])                  if (cur_machine_n_gfx_cards[0])
# Line 546  static void parse__machine(struct emul * Line 543  static void parse__machine(struct emul *
543    
544                  /*  NOTE: Default nr of CPUs is 0:  */                  /*  NOTE: Default nr of CPUs is 0:  */
545                  if (!cur_machine_memory[0])                  if (!cur_machine_memory[0])
546                          strcpy(cur_machine_memory, "0");                          strlcpy(cur_machine_memory, "0",
547                                sizeof(cur_machine_memory));
548                  m->physical_ram_in_mb = atoi(cur_machine_memory);                  m->physical_ram_in_mb = atoi(cur_machine_memory);
549    
550                  if (!cur_machine_x11_scaledown[0])                  if (!cur_machine_x11_scaledown[0])
# Line 554  static void parse__machine(struct emul * Line 552  static void parse__machine(struct emul *
552                  else {                  else {
553                          m->x11_scaledown = atoi(cur_machine_x11_scaledown);                          m->x11_scaledown = atoi(cur_machine_x11_scaledown);
554                          if (m->x11_scaledown < 0) {                          if (m->x11_scaledown < 0) {
555                                    m->x11_scaleup = 0 - m->x11_scaledown;
556                                    m->x11_scaledown = 1;
557                            }
558                            if (m->x11_scaledown < 1) {
559                                  fprintf(stderr, "Invalid scaledown value"                                  fprintf(stderr, "Invalid scaledown value"
560                                      " (%i)\n", m->x11_scaledown);                                      " (%i)\n", m->x11_scaledown);
561                                  exit(1);                                  exit(1);
# Line 616  static void parse__machine(struct emul * Line 618  static void parse__machine(struct emul *
618          WORD("bootname", cur_machine_bootname);          WORD("bootname", cur_machine_bootname);
619          WORD("bootarg", cur_machine_bootarg);          WORD("bootarg", cur_machine_bootarg);
620          WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi);          WORD("slow_serial_interrupts_hack_for_linux", cur_machine_slowsi);
         WORD("debugger_on_badaddr", cur_machine_debugger_on_badaddr);  
621          WORD("prom_emulation", cur_machine_prom_emulation);          WORD("prom_emulation", cur_machine_prom_emulation);
622          WORD("use_x11", cur_machine_use_x11);          WORD("use_x11", cur_machine_use_x11);
623          WORD("x11_scaledown", cur_machine_x11_scaledown);          WORD("x11_scaledown", cur_machine_x11_scaledown);
         WORD("bintrans", cur_machine_bintrans);  
         WORD("old_bintrans", cur_machine_old_bintrans);  
         WORD("bintrans_size", cur_machine_bintrans_size);  
624          WORD("byte_order", cur_machine_byte_order);          WORD("byte_order", cur_machine_byte_order);
625          WORD("random_mem_contents", cur_machine_random_mem);          WORD("random_mem_contents", cur_machine_random_mem);
626          WORD("use_random_bootstrap_cpu", cur_machine_random_cpu);          WORD("use_random_bootstrap_cpu", cur_machine_random_cpu);
# Line 727  static void parse__machine(struct emul * Line 725  static void parse__machine(struct emul *
725   *   *
726   *  Set up an emulation by parsing a config file.   *  Set up an emulation by parsing a config file.
727   */   */
728  void emul_parse_config(struct emul *e, FILE *f)  void emul_parse_config(struct emul *e, char *fname)
729  {  {
730          char word[500];          FILE *f = fopen(fname, "r");
731            char word[MAX_WORD_LEN];
732          int in_emul = 0;          int in_emul = 0;
733          int line = 1;          int line = 1;
734          int parsestate = PARSESTATE_NONE;          int parsestate = PARSESTATE_EMUL;
735    
736          /*  debug("emul_parse_config()\n");  */          /*  debug("emul_parse_config()\n");  */
737            if (f == NULL) {
738                    perror(fname);
739                    exit(1);
740            }
741    
742          while (!feof(f)) {          while (!feof(f)) {
743                  read_one_word(f, word, sizeof(word), &line,                  read_one_word(f, word, sizeof(word), &line,
# Line 745  void emul_parse_config(struct emul *e, F Line 748  void emul_parse_config(struct emul *e, F
748                  /*  debug("word = '%s'\n", word);  */                  /*  debug("word = '%s'\n", word);  */
749    
750                  switch (parsestate) {                  switch (parsestate) {
                 case PARSESTATE_NONE:  
                         parse__none(e, f, &in_emul, &line, &parsestate,  
                             word, sizeof(word));  
                         break;  
751                  case PARSESTATE_EMUL:                  case PARSESTATE_EMUL:
752                          parse__emul(e, f, &in_emul, &line, &parsestate,                          parse__emul(e, f, &in_emul, &line, &parsestate,
753                              word, sizeof(word));                              word, sizeof(word));
# Line 761  void emul_parse_config(struct emul *e, F Line 760  void emul_parse_config(struct emul *e, F
760                          parse__machine(e, f, &in_emul, &line, &parsestate,                          parse__machine(e, f, &in_emul, &line, &parsestate,
761                              word, sizeof(word));                              word, sizeof(word));
762                          break;                          break;
763                    case PARSESTATE_NONE:
764                            break;
765                  default:                  default:
766                          fatal("INTERNAL ERROR in emul_parse.c ("                          fatal("INTERNAL ERROR in emul_parse.c ("
767                              "parsestate %i is not imlemented yet?)\n",                              "parsestate %i is not imlemented yet?)\n",
# Line 769  void emul_parse_config(struct emul *e, F Line 770  void emul_parse_config(struct emul *e, F
770                  }                  }
771          }          }
772    
773          if (parsestate != PARSESTATE_NONE) {          if (parenthesis_level != 0) {
774                  fatal("EOF but not enough right parentheses?\n");                  fatal("EOF but not enough right parentheses?\n");
775                  exit(1);                  exit(1);
776          }          }
777    
778            fclose(f);
779  }  }
780    

Legend:
Removed from v.2  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26