Logo Search packages:      
Sourcecode: faumachine version File versions  Download package

generate_comps.c

/* $Id: generate_comps.c,v 1.32 2009-01-28 17:20:10 potyra Exp $ 
 *
 * Copyright (C) 2007-2009 FAUmachine Team <info@faumachine.org>.
 * This program is free software. You can redistribute it and/or modify it
 * under the terms of the GNU General Public License, either version 2 of
 * the License, or (at your option) any later version. See COPYING.
 */

#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "list.h"
#include "sigs_and_comps.h"

const char *progname;
const char *node_type;
int loglevel;

static const char *node_comp[1000];
static unsigned int node_comp_count;
static const char *node_sig[1000];
static unsigned int node_sig_count;

static const char *
type_trans(const char *type)
{
      /* This list should be empty...! FIXME */
      if (strcmp(type, "audio") == 0) {
            return "sound";
      } else if (strcmp(type, "character") == 0) {
            return "integer";
      } else if (strcmp(type, "ethbus") == 0) {
            return "eth";
      } else if (strcmp(type, "ext_audio") == 0) {
            return "sound";
      } else if (strcmp(type, "idebus") == 0) {
            return "ide_bus";
      } else if (strcmp(type, "isabus") == 0) {
            return "isa_bus";
      } else if (strcmp(type, "membus") == 0) {
            return "mem_bus";
      } else if (strcmp(type, "parallelbus") == 0) {
            return "parallel";
      } else if (strcmp(type, "powerboard") == 0) {
            return "power_board";
      } else if (strcmp(type, "powerdevice") == 0) {
            return "power_device";
      } else if (strcmp(type, "pcibus") == 0) {
            return "pci_bus";
      } else if (strcmp(type, "agpbus") == 0) {
            return "agp_bus";
      } else if (strcmp(type, "ps2bus") == 0) {
            return "ps2";
      } else if (strcmp(type, "scsibus") == 0) {
            return "scsi_bus";
      } else if (strcmp(type, "serialbus") == 0) {
            return "serial";
      } else if (strcmp(type, "shugartbus") == 0) {
            return "shugart_bus";
      } else if (strcmp(type, "soundbus") == 0) {
            return "sound";
      } else if (strcmp(type, "usbbus") == 0) {
            return "usb_bus";
      } else if (strcmp(type, "telephonebus") == 0) {
            return "telephone";
      } else {
            return type;
      }
}

static const char *
include(const char *type)
{
      static const struct {
            const char *type;
            const char *file;
      } table[] = {
            { "powerboard", "power" },
            { "powerdevice", "power" },
      };

      unsigned int i;

      for (i = 0; ; i++) {
            if (i == sizeof(table) / sizeof(table[0])) {
                  return type_trans(type);
            }
            if (strcmp(table[i].type, type) == 0) {
                  return table[i].file;
            }
      }
}

static void
generate_h(const char *comp_name)
{
      const char *incfile[100];
      unsigned int incfile_count;
      char path[1024];
      FILE *fp;
      struct list_header *ports;
      struct list_dnode *port;
      struct list_header *faults;
      struct list_dnode *fault;
      unsigned int i;

      sprintf(path, "simulator/%s.h", comp_name);
      fp = fopen(path, "r");
      if (! fp) {
            sprintf(path, "%s.h", comp_name);
            fp = fopen(path, "r");
      }
      if (! fp) {
            fprintf(stderr, "WARNING: %s: %s.\n", path, strerror(errno));
      } else {
            fclose(fp);
      }

      /* Build include file list. */
      incfile_count = 0;

      /* Ports */
      ports = sac_comp_port_names(comp_name);
      list_Foreach(ports, port) {
            const char *port_name = (const char *) port->data;
            const char *port_type = sac_comp_port_type(comp_name, port_name);
            const char *inc;

            inc = include(port_type);

            for (i = 0; ; i++) {
                  if (i == incfile_count) {
                        incfile[incfile_count] = inc;
                        incfile_count++;
                        break;
                  }
                  if (strcmp(incfile[i], inc) == 0) {
                        break;
                  }
            }
      }
      sac_free_list(ports);
      assert(1 <= incfile_count);

      /* Sort include file list. */
      for (;;) {
            int done;

            done = 1;
            for (i = 0; i < incfile_count - 1; i++) {
                  if (0 < strcmp(incfile[i], incfile[i + 1])) {
                        const char *tmp;

                        tmp = incfile[i];
                        incfile[i] = incfile[i + 1];
                        incfile[i + 1] = tmp;
                        done = 0;
                  }
            }
            if (done) {
                  break;
            }
      }

      /* Faults */
      faults = sac_comp_fault_names(comp_name);
      list_Foreach(faults, fault) {
            for (i = 0; ; i++) {
                  if (i == incfile_count) {
                        incfile[incfile_count] = "fault";
                        incfile_count++;
                        break;
                  }
                  if (strcmp(incfile[i], "fault") == 0) {
                        break;
                  }
            }
      }
      sac_free_list(faults);

      sprintf(path, "simulator/%s.h.tmp", comp_name);
      fp = fopen(path, "w");
      if (! fp) {
            sprintf(path, "%s.h.tmp", comp_name);
            fp = fopen(path, "w");
      }
      assert(fp);

      fprintf(fp, "/*\n");
      fprintf(fp, " * Generated by %s.\n", progname);
      fprintf(fp, " */\n");
      fprintf(fp, "\n");
      for (i = 0; i < incfile_count; i++) {
            fprintf(fp, "#include \"sig_%s.h\"\n", incfile[i]);
      }
      fprintf(fp, "\n");
      fprintf(fp, "extern void\n");
      fprintf(fp, "%s_init(\n", comp_name);
      fprintf(fp, "\tunsigned int nr");
      ports = sac_comp_port_names(comp_name);
      list_Foreach(ports, port) {
            const char *port_name = (const char *) port->data;

            fprintf(fp, ",\n");
            fprintf(fp, "\tstruct sig_%s *port_%s",
                  type_trans(sac_comp_port_type(comp_name, port_name)),
                  port_name);
      }
      sac_free_list(ports);
      faults = sac_comp_fault_names(comp_name);
      list_Foreach(faults, fault) {
            const char *fault_name = (const char *) fault->data;

            fprintf(fp, ",\n");
            fprintf(fp, "\tstruct sig_fault *fault_%s", fault_name);
      }
      sac_free_list(faults);
      fprintf(fp, "\n);\n");
      fprintf(fp, "\n");
      fprintf(fp, "extern void\n");
      fprintf(fp, "%s_create(const char *dir, unsigned int nr);\n", comp_name);
      fprintf(fp, "extern void\n");
      fprintf(fp, "%s_destroy(unsigned int nr);\n", comp_name);

      fclose(fp);
}

static void
generate_gen_c(const char *comp_name)
{
      char path[1024];
      FILE *fp;
      struct list_header *generics;
      struct list_dnode *generic;
      struct list_header *ports;
      struct list_dnode *port;
      struct list_header *faults;
      struct list_dnode *fault;

      sprintf(path, "simulator/%s.c", comp_name);
      fp = fopen(path, "r");
      if (! fp) {
            sprintf(path, "%s.c", comp_name);
            fp = fopen(path, "r");
      }
      if (! fp) {
            fprintf(stderr, "WARNING: %s: %s.\n", path, strerror(errno));
      } else {
            fclose(fp);
      }

      sprintf(path, "simulator/%s.c.tmp", comp_name);
      fp = fopen(path, "w");
      if (! fp) {
            sprintf(path, "%s.c.tmp", comp_name);
            fp = fopen(path, "w");
      }
      assert(fp);

      /*
       * Header
       */
      fprintf(fp, "/*\n");
      fprintf(fp, " * Generated by %s.\n", progname);
      fprintf(fp, " */\n");
      fprintf(fp, "\n");
      fprintf(fp, "#include \"config.h\"\n");
      fprintf(fp, "\n");
      fprintf(fp, "#include <assert.h>\n");
      fprintf(fp, "#include <stdio.h>\n");
      fprintf(fp, "\n");
      fprintf(fp, "#include \"glue-shm.h\"\n");
      fprintf(fp, "\n");
      fprintf(fp, "#include \"%s.h\"\n", comp_name);
      fprintf(fp, "\n");
      fprintf(fp, "#define COMP \"%s\"\n", comp_name);

      fprintf(fp, "\n");

      /*
       * cpssp Structure
       */
      fprintf(fp, "struct cpssp {\n");
      fprintf(fp, "\t/* Config */\n");
      generics = sac_comp_generic_names(comp_name);
      list_Foreach(generics, generic) {
            const char *generic_name = (const char *) generic->data;

            fprintf(fp, "\t%s %s;\n",
                  type_trans(sac_comp_generic_type(comp_name, generic_name)),
                  generic_name);
      }
      sac_free_list(generics);
      fprintf(fp, "\n");
      fprintf(fp, "\t/* Ports */\n");
      ports = sac_comp_port_names(comp_name);
      list_Foreach(ports, port) {
            const char *port_name = (const char *) port->data;

            fprintf(fp, "\tstruct sig_%s *port_%s;\n",
                  type_trans(sac_comp_port_type(comp_name, port_name)),
                  port_name);
      }
      sac_free_list(ports);
      fprintf(fp, "\n");
      fprintf(fp, "\t/* Signals */\n");
      fprintf(fp, "\n");
      fprintf(fp, "\t/* State */\n");
      fprintf(fp, "\n");
      fprintf(fp, "\t/* Processes */\n");
      fprintf(fp, "\n");
      fprintf(fp, "\t/* FILL ME */\n");
      fprintf(fp, "};\n");

      fprintf(fp, "\n");

      /*
       * *_init Function
       */
      fprintf(fp, "void\n");
      fprintf(fp, "%s_init(\n", comp_name);
      fprintf(fp, "\tunsigned int nr");
      ports = sac_comp_port_names(comp_name);
      list_Foreach(ports, port) {
            const char *port_name = (const char *) port->data;

            fprintf(fp, ",\n");
            fprintf(fp, "\tstruct sig_%s *port_%s",
                  type_trans(sac_comp_port_type(comp_name, port_name)),
                  port_name);
      }
      sac_free_list(ports);
      faults = sac_comp_fault_names(comp_name);
      list_Foreach(faults, fault) {
            const char *fault_name = (const char *) fault->data;

            fprintf(fp, ",\n");
            fprintf(fp, "\tstruct sig_fault *fault_%s", fault_name);
      }
      sac_free_list(faults);
      fprintf(fp, "\n)\n");
      fprintf(fp, "{\n");
      fprintf(fp, "\tstruct cpssp *cpssp;\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tcpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);\n");
      fprintf(fp, "\n");
      fprintf(fp, "\t/* FILL ME */\n");
      fprintf(fp, "}\n");

      fprintf(fp, "\n");

      /*
       * *_create Function
       */
      fprintf(fp, "void\n");
      fprintf(fp, "%s_create(const char *dir, unsigned int nr)\n", comp_name);
      fprintf(fp, "{\n");
      fprintf(fp, "\tstruct cpssp *cpssp;\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tshm_create(COMP, nr, sizeof(*cpssp));\n");
      fprintf(fp, "\tcpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);\n");
      fprintf(fp, "\n");
      fprintf(fp, "\t/* FILL ME */\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tshm_unmap(cpssp, sizeof(*cpssp));\n");
      fprintf(fp, "}\n");

      fprintf(fp, "\n");

      /*
       * *_destroy Function
       */
      fprintf(fp, "void\n");
      fprintf(fp, "%s_destroy(unsigned int nr)\n", comp_name);
      fprintf(fp, "{\n");
      fprintf(fp, "\tstruct cpssp *cpssp;\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tcpssp = shm_map(COMP, nr, sizeof(*cpssp), 0);\n");
      fprintf(fp, "\n");
      fprintf(fp, "\t/* FILL ME */\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tshm_unmap(cpssp, sizeof(*cpssp));\n");
      fprintf(fp, "\tshm_destroy(COMP, nr);\n");
      fprintf(fp, "}\n");

      fclose(fp);
}

static void
generate_setup_h(void)
{
      char path[1024];
      FILE *fp;
      unsigned int n;

      sprintf(path, "setup.h");
      fp = fopen(path, "r");
      if (! fp) {
            fprintf(stderr, "WARNING: %s: %s.\n", path, strerror(errno));
      } else {
            fclose(fp);
      }

      sprintf(path, "setup.h.tmp");
      fp = fopen(path, "w");
      assert(fp);

      fprintf(fp, "/* Generated by %s. */\n", progname);
      fprintf(fp, "\n");
      for (n = 0; n < node_comp_count; n++) {
            struct list_header *ports;
            struct list_dnode *port;
            struct list_header *faults;
            struct list_dnode *fault;

            fprintf(fp, "\tstruct {\n");
            fprintf(fp, "\t\tint available;\n");
            ports = sac_comp_port_names(node_comp[n]);
            list_Foreach(ports, port) {
                  const char *port_name = (const char *) port->data;

                  fprintf(fp, "\t\tunsigned int port_%s;\n", port_name);
            }
            sac_free_list(ports);
            faults = sac_comp_fault_names(node_comp[n]);
            list_Foreach(faults, fault) {
                  const char *fault_name = (const char *) fault->data;

                  fprintf(fp, "\t\tunsigned int fault_%s;\n", fault_name);
            }
            sac_free_list(faults);
            fprintf(fp, "\t} %s[20];\n", node_comp[n]);
      }

      fclose(fp);
}

static void
generate_setup_c(void)
{
      char path[1024];
      FILE *fp;
      unsigned int n;

      sprintf(path, "setup.c");
      fp = fopen(path, "r");
      if (! fp) {
            fprintf(stderr, "WARNING: %s: %s.\n", path, strerror(errno));
      } else {
            fclose(fp);
      }

      sprintf(path, "setup.c.tmp");
      fp = fopen(path, "w");
      assert(fp);

      fprintf(fp, "/* Generated by %s. */\n", progname);
      fprintf(fp, "\n");
      for (n = 0; n < node_comp_count; n++) {
            const char *comp_name = node_comp[n];
            struct list_header *ports;
            struct list_dnode *port;
            struct list_header *faults;
            struct list_dnode *fault;

            fprintf(fp, "\t\tfor (i = 0; i < sizeof(CONFIG->%s) / sizeof(CONFIG->%s[0]); i++) {\n", comp_name, comp_name);
            fprintf(fp, "\t\t\tcfg = cfg_open(dir, \"%s\", i, \"generics\");\n", comp_name);
            fprintf(fp, "\t\t\tif (! cfg) {\n");
            fprintf(fp, "\t\t\t\tCONFIG->%s[i].available = 0;\n", comp_name);
            fprintf(fp, "\t\t\t\tcontinue;\n");
            fprintf(fp, "\t\t\t}\n");
            fprintf(fp, "\t\t\tCONFIG->%s[i].available = 1;\n", comp_name);
            fprintf(fp, "\t\t\tcfg_close(cfg);\n");
            fprintf(fp, "\n");

            ports = sac_comp_port_names(comp_name);
            list_Foreach(ports, port) {
                  const char *port_name = (const char *) port->data;
                  const char *port_type = sac_comp_port_type(comp_name, port_name);

                  fprintf(fp, "\t\t\tportget(dir, %s, i, %s, %s);\n",
                              comp_name, port_name, type_trans(port_type));
            }
            sac_free_list(ports);
            faults = sac_comp_fault_names(comp_name);
            list_Foreach(faults, fault) {
                  const char *fault_name = (const char *) fault->data;

                  fprintf(fp, "\t\t\tfaultget(dir, %s, i, %s);\n",
                              comp_name, fault_name);
            }
            sac_free_list(faults);
            fprintf(fp, "\t\t}\n");
      }

      fclose(fp);
}

static void
generate_system_c(void)
{
      char path[1024];
      FILE *fp;
      const char *incfile[100];
      unsigned int incfile_count;
      struct list_header *ports;
      struct list_dnode *port;
      struct list_header *faults;
      struct list_dnode *fault;
      unsigned int n;
      unsigned int i;

      sprintf(path, "system.c");
      fp = fopen(path, "r");
      if (! fp) {
            sprintf(path, "system.c");
            fp = fopen(path, "r");
      }
      if (! fp) {
            fprintf(stderr, "WARNING: %s: %s.\n", path, strerror(errno));
      } else {
            fclose(fp);
      }

      sprintf(path, "system.c.tmp");
      fp = fopen(path, "w");
      if (! fp) {
            sprintf(path, "system.c.tmp");
            fp = fopen(path, "w");
      }
      assert(fp);

      fprintf(fp, "/*\n");
      fprintf(fp, " * Generated by %s.\n", progname);
      fprintf(fp, " */\n");
      fprintf(fp, "\n");

      /* Create system's include list. */
      incfile_count = 0;
      for (n = 0; n < node_comp_count; n++) {
            ports = sac_comp_port_names(node_comp[n]);
            list_Foreach(ports, port) {
                  const char *port_name = (const char *) port->data;
                  const char *port_type = sac_comp_port_type(node_comp[n], port_name);
                  const char *inc;

                  inc = include(port_type);

                  for (i = 0; ; i++) {
                        if (i == incfile_count) {
                              incfile[incfile_count] = inc;
                              incfile_count++;
                              break;
                        }
                        if (strcmp(incfile[i], inc) == 0) {
                              break;
                        }
                  }
            }
            sac_free_list(ports);
      }
      assert(1 <= incfile_count);

        /* Sort include file list. */
        for (;;) {
                int done;

                done = 1;
                for (i = 0; i < incfile_count - 1; i++) {
                        if (0 < strcmp(incfile[i], incfile[i + 1])) {
                                const char *tmp;

                                tmp = incfile[i];
                                incfile[i] = incfile[i + 1];
                                incfile[i + 1] = tmp;
                                done = 0;
                        }
                }
                if (done) {
                        break;
                }
        }
      incfile[incfile_count++] = "fault";

      for (i = 0; i < incfile_count; i++) {
            fprintf(fp, "#include \"sig_%s.h\"\n", incfile[i]);
      }

      fprintf(fp, "\n");

      for (i = 0; i < incfile_count; i++) {
            fprintf(fp, "#include \"cim_%s.h\"\n", incfile[i]);
      }

      fprintf(fp, "\n");

      for (n = 0; n < node_comp_count; n++) {
            fprintf(fp, "#include \"simulator/%s.h\"\n", node_comp[n]);
      }

      fprintf(fp, "\n");

      /* Create system's 'init' function. */
      fprintf(fp, "void\n");
      fprintf(fp, "system_init(void)\n");
      fprintf(fp, "{\n");
      fprintf(fp, "\tstruct cpssp *cpssp;\n");
      fprintf(fp, "\tunsigned int nr;\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tcpssp = shm_map(\"system\", -1, sizeof(*cpssp))\n");
      fprintf(fp, "\t__cpssp = cpssp;\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tport_init()\n");
      fprintf(fp, "\n");
      for (n = 0; n < node_comp_count; n++) {
            const char *comp_name = node_comp[n];

            fprintf(fp, "\tfor (nr = 0; nr < sizeof(CONFIG->%s) / sizeof(CONFIG->%s[0]); nr++) {\n",
                        comp_name, comp_name);
            fprintf(fp, "\t\tif (! CONFIG->%s[nr].available) {\n",
                        comp_name);
            fprintf(fp, "\t\t\tcontinue;\n");
            fprintf(fp, "\t\t}\n");
            fprintf(fp, "\t\t%s_init(nr", comp_name);
            ports = sac_comp_port_names(comp_name);
            list_Foreach(ports, port) {
                  const char *port_name = (const char *) port->data;

                  fprintf(fp, ",\n");
                  fprintf(fp, "\t\t\tsig_init(CONFIG->%s[nr].port_%s)",
                        comp_name, port_name);
            }
            sac_free_list(ports);
            faults = sac_comp_fault_names(comp_name);
            list_Foreach(faults, fault) {
                  const char *fault_name = (const char *) fault->data;

                  fprintf(fp, ",\n");
                  fprintf(fp, "\t\t\tsig_init(CONFIG->%s[nr].fault_%s)",
                        comp_name, fault_name);
            }
            sac_free_list(faults);
            fprintf(fp, ");\n");
            fprintf(fp, "\t}\n");
      }
      fprintf(fp, "}\n");

      fprintf(fp, "\n");

      /* Create system's 'exit' function. */
      fprintf(fp, "void\n");
      fprintf(fp, "system_exit(void)\n");
      fprintf(fp, "{\n");
      fprintf(fp, "}\n");

      fprintf(fp, "\n");

      /* Create system's 'create' function. */
      fprintf(fp, "void\n");
      fprintf(fp, "system_create(void)\n");
      fprintf(fp, "{\n");
      fprintf(fp, "\tstruct cpssp *cpssp;\n");
      fprintf(fp, "\tunsigned int nr;\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tshm_create(\"system\", -1, sizeof(*cpssp));\n");
      fprintf(fp, "\tcpssp = shm_map(\"system\", -1, sizeof(*cpssp));\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tsig_create(cpssp);\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tport_create(cpssp);\n");
      fprintf(fp, "\n");
      for (n = 0; n < node_comp_count; n++) {
            const char *comp_name = node_comp[n];

            fprintf(fp, "\tfor (nr = 0; nr < sizeof(CONFIG->%s) / sizeof(CONFIG->%s[0]); nr++) {\n",
                        comp_name, comp_name);
            fprintf(fp, "\t\tif (! CONFIG->%s[nr].available) {\n",
                        comp_name);
            fprintf(fp, "\t\t\tcontinue;\n");
            fprintf(fp, "\t\t}\n");
            fprintf(fp, "\t\t%s_create(CONFIG->dir, nr);\n", comp_name);
            fprintf(fp, "\t}\n");
      }
      fprintf(fp, "\n");
      fprintf(fp, "\texpuser_create();\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tshm_unmap(cpssp, sizeof(*cpssp));\n");
      fprintf(fp, "}\n");

      fprintf(fp, "\n");

      /* Create system's 'destroy' function. */
      fprintf(fp, "void\n");
      fprintf(fp, "system_destroy(void)\n");
      fprintf(fp, "{\n");
      fprintf(fp, "\tstruct cpssp *cpssp;\n");
      fprintf(fp, "\tunsigned int nr;\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tcpssp = shm_map(\"system\", -1, sizeof(*cpssp));\n");
      fprintf(fp, "\n");
      fprintf(fp, "\texpuser_destroy();\n");
      fprintf(fp, "\n");
      for (n = 0; n < node_comp_count; n++) {
            const char *comp_name = node_comp[n];

            fprintf(fp, "\tfor (nr = 0; nr < sizeof(CONFIG->%s) / sizeof(CONFIG->%s[0]); nr++) {\n",
                        comp_name, comp_name);
            fprintf(fp, "\t\tif (! CONFIG->%s[nr].available) {\n",
                        comp_name);
            fprintf(fp, "\t\t\tcontinue;\n");
            fprintf(fp, "\t\t}\n");
            fprintf(fp, "\t\t%s_destroy(nr);\n", comp_name);
            fprintf(fp, "\t}\n");
      }
      fprintf(fp, "\n");
      fprintf(fp, "\tport_destroy(cpssp);\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tsig_destroy(cpssp);\n");
      fprintf(fp, "\n");
      fprintf(fp, "\tshm_unmap(cpssp, sizeof(*cpssp));\n");
      fprintf(fp, "\tshm_destroy(\"system\", -1);\n");
      fprintf(fp, "}\n");

      fclose(fp);

      fp = stdout;

      for (n = 0; n < node_comp_count; n++) {
            const char *comp_name = node_comp[n];

            ports = sac_comp_port_names(comp_name);
            list_Foreach(ports, port) {
                  const char *port_name = (const char *) port->data;

                  if (strncmp("audio_", port_name, 6) == 0
                   || strncmp("mech_", port_name, 5) == 0
                   || strncmp("opt_", port_name, 4) == 0
                   || strncmp("delta", port_name, 5) == 0
                   || strncmp("button", port_name, 6) == 0
                   || strncmp("press", port_name, 5) == 0
                   || strncmp("release", port_name, 7) == 0
                   || strncmp("change", port_name, 6) == 0) {
                        fprintf(fp, "%s %s\n", comp_name, port_name);
                  }
            }
            sac_free_list(ports);
      }
}

/*forward*/ static void
comp_add(
      struct list_header *sig_list,
      struct list_header *comp_list,
      const char *name
);

static void
sig_add(
      struct list_header *sig_list,
      struct list_header *comp_list,
      const char *name
)
{
      struct list_dnode *comp;
      unsigned int i;

      if (strchr(name, '(')
#if 0
       || ! sac_sig_connect_component(name)
#endif
      ) {
            return;
      }

      for (i = 0; ; i++) {
            if (i == node_sig_count) {
                  node_sig[i] = name;
                  node_sig_count++;
                  break;
            }
            if (strcmp(node_sig[i], name) == 0) {
                  return;
            }
      }

      list_Foreach(comp_list, comp) {
            const char *comp_name = (const char *) comp->data;
            struct list_header *port_list;
            struct list_dnode *port;

            port_list = sac_comp_port_names(comp_name);
            list_Foreach(port_list, port) {
                  const char *port_name = (const char *) port->data;

                  if (strcmp(sac_comp_port_type(comp_name, port_name),
                                    name) == 0) {
                        comp_add(sig_list, comp_list, comp_name);
                  }
            }
            sac_free_list(port_list);
      }
}

static void
comp_add(
      struct list_header *sig_list,
      struct list_header *comp_list,
      const char *name
)
{
      struct list_header *port_list;
      struct list_dnode *port;
      unsigned int i;

      if (strcmp(node_type, "node-pc") == 0) {
            if (strcmp(name, "serial_terminal") == 0) {
                  /* Hack... */
                  return;
            }
      } else if (strcmp(node_type, "node-vt102") == 0) {
            if (strncmp(name, "mb_", 3) == 0
             || strncmp(name, "isa_", 4) == 0
             || strncmp(name, "pci_", 4) == 0
             || strncmp(name, "floppy_", 7) == 0
             || strncmp(name, "ide_", 4) == 0
             || strncmp(name, "scsi_", 5) == 0
             || strcmp(name, "serial_terminal") == 0
             || strcmp(name, "keyboard") == 0
             || strcmp(name, "mouse") == 0) {
                  /* Hack... */
                  return;
            }
      }

      for (i = 0; ; i++) {
            if (i == node_comp_count) {
                  node_comp[i] = name;
                  node_comp_count++;
                  break;
            }
            if (strcmp(node_comp[i], name) == 0) {
                  return;
            }
      }

      port_list = sac_comp_port_names(name);
      list_Foreach(port_list, port) {
            const char *port_name = (const char *) port->data;

            sig_add(sig_list, comp_list,
                        sac_comp_port_type(name, port_name));
      }
      sac_free_list(port_list);
}

static void __attribute__((noreturn))
usage(int retval)
{
      fprintf(stderr, "Usage: %s <node_type>\n", progname);
      exit(retval);
}

int
main(int argc, char **argv)
{
      int c;
      struct list_header *sig_list;
      struct list_header *comp_list;
      struct list_dnode *dn;
      unsigned int n;

      /* Get program name. */
      progname = argv[0];

      /* Get options. */
      while ((c = getopt(argc, argv, "")) != -1) {
            switch (c) {
            default:
                  usage(1);
                  /*NOTREACHED*/
            }
      }
      argc -= optind;
      argv += optind;

      /* Get parameter. */
      if (argc <= 0) {
            usage(1);
      }
      node_type = *argv;
      argc--;
      argv++;

      if (argc != 0) {
            usage(1);
      }

      /* Do work. */
      sac_init("../lib/sigs_and_comps.spec");

      sig_list = sac_sig_list();
      comp_list = sac_comp_list();

      /* Generate list of components for <node_type>. */
      list_Foreach(comp_list, dn) {
            const char *comp_name = (const char *) dn->data;

            comp_add(sig_list, comp_list, comp_name);
      }

      /* Re-sort list according to sigs_and_comps.spec. */
      n = 0;
      list_Foreach(comp_list, dn) {
            const char *comp_name = (const char *) dn->data;
            unsigned int i;

            for (i = n; ; i++) {
                  if (i == node_comp_count) {
                        /* Not in list - skip. */
                        break;
                  }
                  if (strcmp(node_comp[i], comp_name) == 0) {
                        /* Move it to position 'n'. */
                        const char *tmp;

                        tmp = node_comp[n];
                        node_comp[n] = node_comp[i];
                        node_comp[i] = tmp;
                        n++;
                        break;
                  }
            }
      }

      for (n = 0; n < node_comp_count; n++) {
            generate_h(node_comp[n]);
            generate_gen_c(node_comp[n]);
      }

      generate_setup_h();
      generate_setup_c();
      generate_system_c();

      return 0;
}

Generated by  Doxygen 1.6.0   Back to index