Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Moved from flex to flexml.
authoralegrand <alegrand@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Wed, 5 Jan 2005 00:45:29 +0000 (00:45 +0000)
committeralegrand <alegrand@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Wed, 5 Jan 2005 00:45:29 +0000 (00:45 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@733 48e7efb5-ca39-0410-a469-dd3cf9ba447f

include/Makefile.am
src/Makefile.am
src/include/surf/surf_parse.h
src/include/surf/surfxml.h [new file with mode: 0644]
src/msg/deployment.c
src/surf/cpu.c
src/surf/network.c
src/surf/surfxml.dtd [new file with mode: 0644]
src/surf/surfxml.l [new file with mode: 0644]
testsuite/msg/msg_test.c

index 111ffc1..1206387 100644 (file)
@@ -15,6 +15,7 @@ nobase_include_HEADERS = \
        surf/trace_mgr.h \
        surf/surf.h \
        surf/surf_parse.h \
+       surf/surfxml.h \
        \
        msg/msg.h \
        msg/datatypes.h \
@@ -28,3 +29,5 @@ nobase_include_HEADERS = \
        amok/base.h \
        amok/bandwidth.h
 
+surf/surfxml.h: ../src/surf/surfxml.dtd
+       cd surf; flexml -H ../../src/surf/surfxml.dtd
index bf8a056..3fdf858 100644 (file)
@@ -28,7 +28,9 @@ EXTRA_DIST= \
        surf/surf_private.h \
        surf/cpu_private.h \
        surf/workstation_private.h \
-       surf/surf_parse.l \
+       surf/surf_parse.c \
+       surf/surfxml.l \
+       surf/surfxml.c \
        surf/network_private.h \
        \
        msg/private.h \
@@ -122,9 +124,14 @@ COMMON_S=\
 gras/DataDesc/ddt_parse.yy.c: gras/DataDesc/ddt_parse.yy.l
        @LEX@ -o$@ -Pgras_ddt_parse_ $^
 
-surf/surf_parse.c: surf/surf_parse.l
+surf/surf_parse.c: surf/surfxml.c
+
+surf/surfxml.c: surf/surfxml.l
        @LEX@ -o$@ -Psurf_parse_ $^
 
+surf/surfxml.l: surf/surfxml.dtd
+       cd surf; flexml -S surfxml.dtd
+
 libgras_la_SOURCES= $(COMMON_S) \
   gras/Transport/rl_transport.c  gras/Transport/transport_plugin_tcp.c  gras/Transport/transport_plugin_file.c      \
   \
index 284224f..7fa1e8b 100644 (file)
 
 #include "xbt/misc.h"
 #include "surf/trace_mgr.h"
-
-typedef enum {
-  TOKEN_EMPTY = 0,
-  TOKEN_LP = 512,
-  TOKEN_RP,
-  TOKEN_BEGIN_SECTION,
-  TOKEN_END_SECTION,
-  TOKEN_CLOSURE,
-  TOKEN_WORD,
-  TOKEN_NEWLINE,
-  TOKEN_ERROR
-} e_surf_token_t;
-
-#define MAX_STR_CONST 1024
-
-extern char *surf_parse_text;
-extern int surf_line_pos;
-extern int surf_char_pos;
-extern int surf_tok_num;
-
-e_surf_token_t surf_parse(void);
-void find_section(const char *file, const char *section_name);
-void close_section(const char *section_name);
-void surf_parse_double(double *value);
-void surf_parse_trace(tmgr_trace_t * trace);
-void surf_parse_deployment_line(char **host, int *argc, char ***argv);
-
-
-/* Should not be called if you use the previous "section" functions */
-void surf_parse_open(const char *file);
-void surf_parse_close(void);
+#include "surfxml.h"
+
+typedef   void (*void_f_void_t)(void);
+
+extern void_f_void_t STag_platform_description_fun;
+extern void_f_void_t ETag_platform_description_fun;
+extern void_f_void_t STag_cpu_fun;
+extern void_f_void_t ETag_cpu_fun;
+extern void_f_void_t STag_network_link_fun;
+extern void_f_void_t ETag_network_link_fun;
+extern void_f_void_t STag_route_fun;
+extern void_f_void_t ETag_route_fun;
+extern void_f_void_t STag_route_element_fun;
+extern void_f_void_t ETag_route_element_fun;
+extern void_f_void_t STag_process_fun;
+extern void_f_void_t ETag_process_fun;
+extern void_f_void_t STag_argument_fun;
+extern void_f_void_t ETag_argument_fun;
+
+
+void  surf_parse_open(const char *file);
+void  surf_parse_close(void);
+void  surf_parse_reset_parser(void);
+void surf_parse_get_double(double *value,const char *string);
+void surf_parse_get_trace(tmgr_trace_t *trace, const char *string);
 
 /* Prototypes of the functions offered by flex */
 int surf_parse_lex(void);
@@ -56,5 +50,4 @@ int surf_parse_get_debug(void);
 void surf_parse_set_debug(int bdebug);
 int surf_parse_lex_destroy(void);
 
-
 #endif
diff --git a/src/include/surf/surfxml.h b/src/include/surf/surfxml.h
new file mode 100644 (file)
index 0000000..426743e
--- /dev/null
@@ -0,0 +1,109 @@
+/* XML processor/application API for ../../src/surf/surfxml.dtd.
+ * Generated 2005/01/04 14:37:22.
+ *
+ * This program was generated with the FleXML XML processor generator,
+ * (Id: flexml.pl,v 1.29 2005/01/04 09:30:15 alegrand Exp).
+ * Copyright © 1999 Kristoffer Rose.  All rights reserved.
+ *
+ * You can redistribute and/or modify this program provided the following
+ * two conditions hold:
+ *
+ * 1. The program is distributed WITHOUT ANY WARRANTY from the author of
+ *    FleXML; without even the implied warranty of MERCHANTABILITY or
+ *    FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * 2. The program distribution conditions do not in any way affect the
+ *    distribution conditions of the FleXML system used to generate this
+ *    file or any version of FleXML derived from that system.
+ *
+ * Notice that these are explicit rights granted to you for files
+ * generated by the FleXML system.  For your rights in connection with
+ * the FleXML system itself please consult the GNU General Public License.
+ */
+
+#ifndef _FLEXML_surfxml_H
+#define _FLEXML_surfxml_H
+
+/* XML application entry points. */
+extern void STag_platform_description(void);
+extern void ETag_platform_description(void);
+extern void STag_cpu(void);
+extern void ETag_cpu(void);
+extern void STag_network_link(void);
+extern void ETag_network_link(void);
+extern void STag_route(void);
+extern void ETag_route(void);
+extern void STag_route_element(void);
+extern void ETag_route_element(void);
+extern void STag_process(void);
+extern void ETag_process(void);
+extern void STag_argument(void);
+extern void ETag_argument(void);
+
+/* XML application data. */
+typedef const char* AT_network_link_bandwidth;
+#define AU_network_link_bandwidth NULL
+typedef const char* AT_cpu_name;
+#define AU_cpu_name NULL
+typedef enum { AU_network_link_state, A_network_link_state_ON,A_network_link_state_OFF } AT_network_link_state;
+typedef const char* AT_argument_value;
+#define AU_argument_value NULL
+typedef const char* AT_cpu_availability_file;
+#define AU_cpu_availability_file NULL
+typedef const char* AT_process_host;
+#define AU_process_host NULL
+typedef const char* AT_route_src;
+#define AU_route_src NULL
+typedef const char* AT_network_link_latency_file;
+#define AU_network_link_latency_file NULL
+typedef const char* AT_cpu_availability;
+#define AU_cpu_availability NULL
+typedef const char* AT_network_link_name;
+#define AU_network_link_name NULL
+typedef const char* AT_route_element_name;
+#define AU_route_element_name NULL
+typedef const char* AT_cpu_power;
+#define AU_cpu_power NULL
+typedef const char* AT_process_function;
+#define AU_process_function NULL
+typedef enum { AU_cpu_state, A_cpu_state_ON,A_cpu_state_OFF } AT_cpu_state;
+typedef const char* AT_route_dst;
+#define AU_route_dst NULL
+typedef const char* AT_network_link_latency;
+#define AU_network_link_latency NULL
+typedef const char* AT_cpu_state_file;
+#define AU_cpu_state_file NULL
+typedef const char* AT_network_link_state_file;
+#define AU_network_link_state_file NULL
+typedef const char* AT_network_link_bandwidth_file;
+#define AU_network_link_bandwidth_file NULL
+
+/* FleXML-provided data. */
+extern const char* pcdata;
+extern AT_network_link_bandwidth A_network_link_bandwidth;
+extern AT_cpu_name A_cpu_name;
+extern AT_network_link_state A_network_link_state;
+extern AT_argument_value A_argument_value;
+extern AT_cpu_availability_file A_cpu_availability_file;
+extern AT_process_host A_process_host;
+extern AT_route_src A_route_src;
+extern AT_network_link_latency_file A_network_link_latency_file;
+extern AT_cpu_availability A_cpu_availability;
+extern AT_network_link_name A_network_link_name;
+extern AT_route_element_name A_route_element_name;
+extern AT_cpu_power A_cpu_power;
+extern AT_process_function A_process_function;
+extern AT_cpu_state A_cpu_state;
+extern AT_route_dst A_route_dst;
+extern AT_network_link_latency A_network_link_latency;
+extern AT_cpu_state_file A_cpu_state_file;
+extern AT_network_link_state_file A_network_link_state_file;
+extern AT_network_link_bandwidth_file A_network_link_bandwidth_file;
+
+/* XML application utilities. */
+extern int element_context(int);
+
+/* XML processor entry point. */
+extern int yylex(void);
+
+#endif
index b53e22e..9874ee1 100644 (file)
@@ -15,70 +15,53 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(deployment, msg,
 extern char *yytext;
 
 
+static int parse_argc = -1 ;
+static char **parse_argv = NULL;
+static m_process_code_t parse_code = NULL;
+static m_host_t parse_host = NULL;
+
+static void parse_process_init(void)
+{
+  parse_host = MSG_get_host_by_name(A_process_host);
+  xbt_assert1(parse_host, "Unknown host %s",A_process_host);
+  parse_code = MSG_get_registered_function(A_process_function);
+  xbt_assert1(parse_code, "Unknown function %s",A_process_function);
+  parse_argc = 0 ;
+  parse_argv = NULL;
+  parse_argc++;
+  parse_argv = xbt_realloc(parse_argv, (parse_argc) * sizeof(char *));
+  parse_argv[(parse_argc) - 1] = xbt_strdup(A_process_function);
+}
+
+static void parse_argument(void)
+{
+  parse_argc++;
+  parse_argv = xbt_realloc(parse_argv, (parse_argc) * sizeof(char *));
+  parse_argv[(parse_argc) - 1] = xbt_strdup(A_argument_value);
+}
+
+static void parse_process_finalize(void)
+{
+  MSG_process_create_with_arguments(parse_argv[0], parse_code, NULL, parse_host,
+                                   parse_argc,parse_argv);
+}
+
 /** \ingroup msg_easier_life
  * \brief An application deployer.
  *
  * Creates the process described in \a file.
- * @param file a file containing a simple description of the application.
- * The format of each line is the following : host_name function_name arguments
- * You can use C-style comments and C-style strings.
- * Here is a simple exemple
- * 
- \verbatim
-<DEPLOYMENT>
- // Here is the master
- the-doors.ens-lyon.fr  master "moby.cri2000.ens-lyon.fr" canaria.ens-lyon.fr popc.ens-lyon.fr
- // And here are the slaves
- moby.cri2000.ens-lyon.fr slave
- canaria.ens-lyon.fr slave
- popc.ens-lyon.fr slave 
-</DEPLOYMENT>
-\endverbatim
+ * @param file a file containing an XML description of the application.
  */
 void MSG_launch_application(const char *file) 
 {
-  char *host_name = NULL;
-  int argc = -1 ;
-  char **argv = NULL;
-  m_process_t process = NULL ;
-  m_host_t host = NULL;
-  m_process_code_t code = NULL;
-  e_surf_token_t token;
-
   MSG_global_init();
-  
-  find_section(file, "DEPLOYMENT");
-
-  while(1) {
-    token = surf_parse();
-
-    if (token == TOKEN_END_SECTION)
-      break;
-    if (token == TOKEN_NEWLINE)
-      continue;
-
-    if (token == TOKEN_WORD) {
-      surf_parse_deployment_line(&host_name,&argc,&argv);
-      xbt_assert0(argc,"No function to execute");
-
-      code = MSG_get_registered_function(argv[0]);
-      xbt_assert1(code, "Unknown function %s",argv[0]);
-
-      host = MSG_get_host_by_name(host_name);
-      xbt_assert1(host, "Unknown host %s",host_name);
-
-      process = MSG_process_create_with_arguments(argv[0], code, NULL, host,argc,argv);
-      argc=-1;
-      argv=NULL;
-      xbt_free(host_name); 
-    }
-    else {
-      CRITICAL1("Parse error line %d\n", surf_line_pos);
-      xbt_abort();
-    }
-  }
-
-  close_section("DEPLOYMENT");
+  surf_parse_reset_parser();
+  STag_process_fun = parse_process_init;
+  ETag_argument_fun = parse_argument;
+  ETag_process_fun = parse_process_finalize;
+  surf_parse_open(file);
+  surf_parse_lex();
+  surf_parse_close();
 }
 
 /** \ingroup msg_easier_life
index a3c4d94..84e72a6 100644 (file)
@@ -68,7 +68,6 @@ static cpu_t cpu_new(char *name, double power_scale,
 
 static void parse_cpu(void)
 {
-  e_surf_token_t token;
   char *name = NULL;
   double power_scale = 0.0;
   double power_initial = 0.0;
@@ -76,25 +75,16 @@ static void parse_cpu(void)
   e_surf_cpu_state_t state_initial = SURF_CPU_OFF;
   tmgr_trace_t state_trace = NULL;
 
-  name = xbt_strdup(surf_parse_text);
-
-  surf_parse_double(&power_scale);
-  surf_parse_double(&power_initial);
-  surf_parse_trace(&power_trace);
-
-  token = surf_parse();                /* state_initial */
-  xbt_assert1((token == TOKEN_WORD), "Parse error line %d", surf_line_pos);
-  if (strcmp(surf_parse_text, "ON") == 0)
-    state_initial = SURF_CPU_ON;
-  else if (strcmp(surf_parse_text, "OFF") == 0)
-    state_initial = SURF_CPU_OFF;
-  else {
-    CRITICAL2("Invalid cpu state (line %d): %s neq ON or OFF\n", surf_line_pos,
-             surf_parse_text);
-    xbt_abort();
-  }
+  name = xbt_strdup(A_cpu_name);
+  surf_parse_get_double(&power_scale,A_cpu_power);
+  surf_parse_get_double(&power_initial,A_cpu_availability);
+  surf_parse_get_trace(&power_trace,A_cpu_availability_file);
 
-  surf_parse_trace(&state_trace);
+  xbt_assert0((A_cpu_state==A_cpu_state_ON)||(A_cpu_state==A_cpu_state_OFF),
+             "Invalid state")
+  if (A_cpu_state==A_cpu_state_ON) state_initial = SURF_CPU_ON;
+  if (A_cpu_state==A_cpu_state_OFF) state_initial = SURF_CPU_OFF;
+  surf_parse_get_trace(&state_trace,A_cpu_state_file);
 
   cpu_new(name, power_scale, power_initial, power_trace, state_initial,
          state_trace);
@@ -102,27 +92,11 @@ static void parse_cpu(void)
 
 static void parse_file(const char *file)
 {
-  e_surf_token_t token;
-
-  find_section(file, "CPU");
-
-  while (1) {
-    token = surf_parse();
-
-    if (token == TOKEN_END_SECTION)
-      break;
-    if (token == TOKEN_NEWLINE)
-      continue;
-
-    if (token == TOKEN_WORD)
-      parse_cpu();
-    else {
-      CRITICAL1("Parse error line %d\n", surf_line_pos);
-      xbt_abort();
-    }
-  }
-
-  close_section("CPU");
+  surf_parse_reset_parser();
+  ETag_cpu_fun=parse_cpu;
+  surf_parse_open(file);
+  surf_parse_lex();
+  surf_parse_close();
 }
 
 static void *name_service(const char *name)
index 4377c0e..f6fa9e4 100644 (file)
@@ -77,7 +77,7 @@ static void network_card_free(void *nw_card)
   xbt_free(nw_card);
 }
 
-static int network_card_new(char *card_name)
+static int network_card_new(const char *card_name)
 {
   network_card_t card = NULL;
 
@@ -106,148 +106,86 @@ static void route_new(int src_id, int dst_id, char **links, int nb_link)
   xbt_free(links);
 }
 
-/*  
-   Semantic:  name       initial   bandwidth   initial   latency    initial     state
-                        bandwidth    trace     latency    trace      state      trace
-   
-   Token:   TOKEN_WORD TOKEN_WORD TOKEN_WORD TOKEN_WORD TOKEN_WORD TOKEN_WORD TOKEN_WORD
-   Type:     string      double      string    double     string     ON/OFF     string
-*/
 static void parse_network_link(void)
 {
-  e_surf_token_t token;
   char *name;
   double bw_initial;
   tmgr_trace_t bw_trace;
   double lat_initial;
   tmgr_trace_t lat_trace;
-  e_surf_network_link_state_t state_initial;
+  e_surf_network_link_state_t state_initial = SURF_NETWORK_LINK_ON;
   tmgr_trace_t state_trace;
 
-  name = xbt_strdup(surf_parse_text);
+  name = xbt_strdup(A_network_link_name);
+  surf_parse_get_double(&bw_initial,A_network_link_bandwidth);
+  surf_parse_get_trace(&bw_trace, A_network_link_bandwidth_file);
+  surf_parse_get_double(&lat_initial,A_network_link_latency);
+  surf_parse_get_trace(&lat_trace, A_network_link_latency_file);
 
-  surf_parse_double(&bw_initial);
-  surf_parse_trace(&bw_trace);
-  surf_parse_double(&lat_initial);
-  surf_parse_trace(&lat_trace);
-
-  token = surf_parse();                /* state_initial */
-  xbt_assert1((token == TOKEN_WORD), "Parse error line %d", surf_line_pos);
-  if (strcmp(surf_parse_text, "ON") == 0)
+  xbt_assert0((A_network_link_state==A_network_link_state_ON)||
+             (A_network_link_state==A_network_link_state_OFF),
+             "Invalid state")
+  if (A_network_link_state==A_network_link_state_ON) 
     state_initial = SURF_NETWORK_LINK_ON;
-  else if (strcmp(surf_parse_text, "OFF") == 0)
+  if (A_network_link_state==A_network_link_state_OFF) 
     state_initial = SURF_NETWORK_LINK_OFF;
-  else {
-    CRITICAL2("Invalid cpu state (line %d): %s neq ON or OFF\n", surf_line_pos,
-             surf_parse_text);
-    xbt_abort();
-  }
-
-  surf_parse_trace(&state_trace);
+  surf_parse_get_trace(&state_trace,A_network_link_state_file);
 
   network_link_new(name, bw_initial, bw_trace,
                   lat_initial, lat_trace, state_initial, state_trace);
 }
 
-/*  
-   Semantic:  source   destination           network
-                                              links
-   
-   Token:   TOKEN_WORD TOKEN_WORD TOKEN_LP TOKEN_WORD* TOKEN_RP
-   Type:     string       string             string
-*/
-static void parse_route(int fake)
+static int nb_link = 0;
+static char **link_name = NULL;
+static int src_id = -1;
+static int dst_id = -1;
+
+static void parse_route_set_endpoints(void)
 {
-  int src_id = -1;
-  int dst_id = -1;
-  int nb_link = 0;
-  char **link_name = NULL;
-  e_surf_token_t token;
-
-  src_id = network_card_new(surf_parse_text);
-
-  token = surf_parse();
-  xbt_assert1((token == TOKEN_WORD), "Parse error line %d", surf_line_pos);
-  dst_id = network_card_new(surf_parse_text);
-
-  token = surf_parse();
-  xbt_assert1((token == TOKEN_LP), "Parse error line %d", surf_line_pos);
-
-  while ((token = surf_parse()) == TOKEN_WORD) {
-    if (!fake) {
-      nb_link++;
-      link_name = xbt_realloc(link_name, (nb_link) * sizeof(char *));
-      link_name[(nb_link) - 1] = xbt_strdup(surf_parse_text);
-    }
-  }
-  xbt_assert1((token == TOKEN_RP), "Parse error line %d", surf_line_pos);
+  src_id = network_card_new(A_route_src);
+  dst_id = network_card_new(A_route_dst);
+  nb_link = 0;
+  link_name = NULL;
+}
+
+static void parse_route_elem(void)
+{
+  nb_link++;
+  link_name = xbt_realloc(link_name, (nb_link) * sizeof(char *));
+  link_name[(nb_link) - 1] = xbt_strdup(A_route_element_name);
+}
 
-  if (!fake)
-    route_new(src_id, dst_id, link_name, nb_link);
+static void parse_route_set_route(void)
+{
+  route_new(src_id, dst_id, link_name, nb_link);
 }
 
 static void parse_file(const char *file)
 {
-  e_surf_token_t token;
-
-  /* Figuring out the network links in the system */
-  find_section(file, "NETWORK");
-  while (1) {
-    token = surf_parse();
-
-    if (token == TOKEN_END_SECTION)
-      break;
-    if (token == TOKEN_NEWLINE)
-      continue;
-
-    if (token == TOKEN_WORD)
-      parse_network_link();
-    else {
-      CRITICAL1("Parse error line %d\n", surf_line_pos);
-      xbt_abort();
-    }
-  }
-  close_section("NETWORK");
+  /* Figuring out the network links */
+  surf_parse_reset_parser();
+  ETag_network_link_fun=parse_network_link;
+  surf_parse_open(file);
+  surf_parse_lex();
+  surf_parse_close();
 
   /* Figuring out the network cards used */
-  find_section(file, "ROUTE");
-  while (1) {
-    token = surf_parse();
-
-    if (token == TOKEN_END_SECTION)
-      break;
-    if (token == TOKEN_NEWLINE)
-      continue;
-
-    if (token == TOKEN_WORD)
-      parse_route(1);
-    else {
-      CRITICAL1("Parse error line %d\n", surf_line_pos);
-      xbt_abort();
-    }
-  }
-  close_section("ROUTE");
+  surf_parse_reset_parser();
+  STag_route_fun=parse_route_set_endpoints;
+  surf_parse_open(file);
+  surf_parse_lex();
+  surf_parse_close();
 
   create_routing_table();
 
   /* Building the routes */
-  find_section(file, "ROUTE");
-  while (1) {
-    token = surf_parse();
-
-    if (token == TOKEN_END_SECTION)
-      break;
-    if (token == TOKEN_NEWLINE)
-      continue;
-
-    if (token == TOKEN_WORD)
-      parse_route(0);
-    else {
-      CRITICAL1("Parse error line %d\n", surf_line_pos);
-      xbt_abort();
-    }
-  }
-  close_section("ROUTE");
+  surf_parse_reset_parser();
+  STag_route_fun=parse_route_set_endpoints;
+  ETag_route_element_fun=parse_route_elem;
+  ETag_route_fun=parse_route_set_route;
+  surf_parse_open(file);
+  surf_parse_lex();
+  surf_parse_close();
 }
 
 static void *name_service(const char *name)
diff --git a/src/surf/surfxml.dtd b/src/surf/surfxml.dtd
new file mode 100644 (file)
index 0000000..60619e1
--- /dev/null
@@ -0,0 +1,33 @@
+<!-- Small DTD for SURF based tools. -->
+<!ELEMENT platform_description ((cpu|network_link|route|process)*)>
+
+<!ELEMENT cpu EMPTY>
+<!ATTLIST cpu name CDATA #REQUIRED>
+<!ATTLIST cpu power CDATA #REQUIRED>
+<!ATTLIST cpu availability CDATA "1.0">
+<!ATTLIST cpu availability_file CDATA "">
+<!ATTLIST cpu state (ON|OFF) "ON">
+<!ATTLIST cpu state_file CDATA "">
+
+<!ELEMENT network_link EMPTY>
+<!ATTLIST network_link name CDATA #REQUIRED>
+<!ATTLIST network_link bandwidth CDATA  #REQUIRED>
+<!ATTLIST network_link bandwidth_file CDATA "">
+<!ATTLIST network_link latency CDATA "0.001">
+<!ATTLIST network_link latency_file CDATA "">
+<!ATTLIST network_link state (ON|OFF) "ON">
+<!ATTLIST network_link state_file CDATA "">
+
+<!ELEMENT route (route_element*)>
+<!ATTLIST route src CDATA #REQUIRED>
+<!ATTLIST route dst CDATA #REQUIRED>
+
+<!ELEMENT route_element EMPTY>
+<!ATTLIST route_element name CDATA #REQUIRED>
+
+<!ELEMENT process (argument*)>
+<!ATTLIST process host CDATA #REQUIRED>
+<!ATTLIST process function CDATA #REQUIRED>
+
+<!ELEMENT argument EMPTY>
+<!ATTLIST argument value CDATA #REQUIRED>
diff --git a/src/surf/surfxml.l b/src/surf/surfxml.l
new file mode 100644 (file)
index 0000000..f534db3
--- /dev/null
@@ -0,0 +1,741 @@
+/* Validating XML processor for surfxml.dtd.
+ * Generated 2005/01/04 14:37:23.
+ *
+ * This program was generated with the FleXML XML processor generator,
+ * (Id: flexml.pl,v 1.29 2005/01/04 09:30:15 alegrand Exp).
+ * Copyright © 1999 Kristoffer Rose.  All rights reserved.
+ *
+ * You can redistribute and/or modify this program provided the following
+ * two conditions hold:
+ *
+ * 1. The program is distributed WITHOUT ANY WARRANTY from the author of
+ *    FleXML; without even the implied warranty of MERCHANTABILITY or
+ *    FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * 2. The program distribution conditions do not in any way affect the
+ *    distribution conditions of the FleXML system used to generate this
+ *    file or any version of FleXML derived from that system.
+ *
+ * Notice that these are explicit rights granted to you for files
+ * generated by the FleXML system.  For your rights in connection with
+ * the FleXML system itself please consult the GNU General Public License.
+ */
+
+%{
+
+/* Version strings. */
+const char rcs_flexml_skeleton[] =
+ "$" "Id: skel,v 1.16 1999/12/09 04:01:51 krisrose Exp $";
+const char rcs_flexml[] =
+ "$" "Id: flexml.pl,v 1.29 2005/01/04 09:30:15 alegrand Exp $";
+
+/* ANSI headers. */
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+/* Generated definitions. */
+#define FLEXML_BUFFERSTACKSIZE 10000000
+
+/* XML processor api. */
+#include "surf/surfxml.h"
+
+/* FleXML-provided data. */
+const char* pcdata;
+AT_network_link_bandwidth A_network_link_bandwidth;
+AT_cpu_name A_cpu_name;
+AT_network_link_state A_network_link_state;
+AT_argument_value A_argument_value;
+AT_cpu_availability_file A_cpu_availability_file;
+AT_process_host A_process_host;
+AT_route_src A_route_src;
+AT_network_link_latency_file A_network_link_latency_file;
+AT_cpu_availability A_cpu_availability;
+AT_network_link_name A_network_link_name;
+AT_route_element_name A_route_element_name;
+AT_cpu_power A_cpu_power;
+AT_process_function A_process_function;
+AT_cpu_state A_cpu_state;
+AT_route_dst A_route_dst;
+AT_network_link_latency A_network_link_latency;
+AT_cpu_state_file A_cpu_state_file;
+AT_network_link_state_file A_network_link_state_file;
+AT_network_link_bandwidth_file A_network_link_bandwidth_file;
+
+/* XML state. */
+#ifdef FLEX_DEBUG
+# define ENTER(state)  debug_enter(state,#state)
+# define LEAVE         debug_leave()
+# define SET(state)    debug_set(state,#state)
+  static void debug_enter(int, const char*);
+  static void debug_leave(void);
+  static void debug_set(int, const char*);
+#else
+# define ENTER(state)  (yy_push_state(state))
+# define LEAVE         (yy_pop_state())
+# define SET(state)    BEGIN(state)
+#endif
+
+/* Generic actions. */
+#define SKIP   /*skip*/
+#define SUCCEED        return 0
+
+#define FAIL   return fail
+static int fail(const char*, ...);
+
+/* Text buffer stack handling. */
+char bufferstack[FLEXML_BUFFERSTACKSIZE];
+char* limit = bufferstack + FLEXML_BUFFERSTACKSIZE;
+typedef struct BufferLast_s {
+  struct BufferLast_s *old; char* saved; char new[1];
+} BufferLast;
+BufferLast* last = (BufferLast*)0;
+char* next = bufferstack;
+
+#define BUFFERSET(P)  (P = next)
+#define BUFFERPUTC(C) (assert(next<limit), *(next++) = (C))
+#define BUFFERDONE    (BUFFERPUTC('\0'))
+
+#define BUFFERLITERAL(C,P) bufferliteral(C,&(P),yytext)
+static void bufferliteral(char c, char** pp, char* text)
+{
+  char *s = strchr(text,c), *e = strrchr(text,c);
+  assert(s <= e); BUFFERSET(*pp);
+  while (++s<e) {
+    if (isspace(*s)) { BUFFERPUTC(' '); while (isspace(*s)) ++s; }
+    else BUFFERPUTC(*s);
+  } 
+  BUFFERDONE;
+}
+
+#ifdef FLEXML_HasMixed
+static void pushbuffer(char* p)
+{
+  BufferLast* l = (BufferLast*)next;
+  assert(next < limit);
+  l->old = last;
+  l->saved = p;
+  next = l->new;
+  last = l;
+}
+
+static char* popbuffer(void)
+{
+  BufferLast* l = last;
+  assert(last != (BufferLast*)0);
+  last = l->old;
+  next = (char*)l;
+  return l->saved;
+}
+#endif
+
+/* General internal entities are `unput' back onto the input stream... */
+#define ENTITYTEXT(T) \
+  { char *s = (T), *e = s+strlen(s);\
+    while (--e >= s) { unput(*e); }}
+%}
+
+/* Flex standard options. */
+%option stack
+%option noyy_top_state
+%option noinput
+%option noreject
+%option noyymore
+%option noyywrap
+
+/* Flex user-requested options. */
+%option nounput
+
+/* XML character classes (currently restricted to ASCII). */
+
+/* "Common syntactic structures." */
+S              [ \t\n\r\f]+
+s              [ \t\n\r\f]*
+
+/* "Names and Tokens." */
+NameChar       [A-Za-z0-9.:_-]
+Name           [A-Za-z_:]{NameChar}*
+Names          {Name}({S}{Name})*
+Nmtoken                ({NameChar})+
+Nmtokens       {Nmtoken}({S}{Nmtoken})*
+
+/* Miscellaneous. */
+VersionNum     [a-zA-Z0-9_.:-]+
+Eq             {s}"="{s}
+Literal                \'[^'']*\'|\"[^""]*\"
+
+/* Parser states (flex `exclusive start conditions'):
+ *
+ * PROLOG      the XML prolog of the document before <?xml...>
+ * DOCTYPE     the XML prolog of the document after <?xml...>
+ * EPILOG      after the root element
+ * INCOMMENT   inside an XML comment <!--....-->
+ * INPI                inside an XML PI <?...?>
+ * VALUE1      inside a '...'-delimited literal
+ * VALUE2      inside a "..."-delimited literal
+ * CDATA       inside a <![CDATA[...]]> section.
+ * ROOT_<tag>  expect root element <tag>
+ * AL_<tag>    inside the attribute list for <tag>
+ * IN_<tag>    inside a <tag> with element contents (ready for end tag)
+ * IMPOSSIBLE  dummy to permit disabling rules; must be last
+ */
+%x PROLOG DOCTYPE EPILOG INCOMMENT INPI VALUE1 VALUE2 CDATA
+%x ROOT_platform_description AL_platform_description S_platform_description S_platform_description_1 S_platform_description_2 E_platform_description
+%x ROOT_cpu AL_cpu E_cpu
+%x ROOT_network_link AL_network_link E_network_link
+%x ROOT_route AL_route S_route S_route_1 S_route_2 E_route
+%x ROOT_route_element AL_route_element E_route_element
+%x ROOT_process AL_process S_process S_process_1 S_process_2 E_process
+%x ROOT_argument AL_argument E_argument
+%x IMPOSSIBLE
+
+%{
+/* State names. */
+const char* *statenames=NULL;
+%}
+
+%%
+
+ /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */
+ SET(PROLOG);
+  /* FleXML_init */
+  if(!statenames) statenames=calloc(IMPOSSIBLE,sizeof(char*));
+  statenames[PROLOG] = NULL;
+  statenames[DOCTYPE] = NULL;
+  statenames[EPILOG] = NULL;
+  statenames[INCOMMENT] = NULL;
+  statenames[INPI] = NULL;
+  statenames[VALUE1] = NULL;
+  statenames[VALUE2] = NULL;
+  statenames[CDATA] = NULL;
+  statenames[ROOT_platform_description] = NULL;
+  statenames[AL_platform_description] = NULL;
+  statenames[S_platform_description] = "platform_description";
+  statenames[S_platform_description_1] = "platform_description";
+  statenames[S_platform_description_2] = "platform_description";
+  statenames[E_platform_description] = "platform_description";
+  statenames[ROOT_cpu] = NULL;
+  statenames[AL_cpu] = NULL;
+  statenames[E_cpu] = "cpu";
+  statenames[ROOT_network_link] = NULL;
+  statenames[AL_network_link] = NULL;
+  statenames[E_network_link] = "network_link";
+  statenames[ROOT_route] = NULL;
+  statenames[AL_route] = NULL;
+  statenames[S_route] = "route";
+  statenames[S_route_1] = "route";
+  statenames[S_route_2] = "route";
+  statenames[E_route] = "route";
+  statenames[ROOT_route_element] = NULL;
+  statenames[AL_route_element] = NULL;
+  statenames[E_route_element] = "route_element";
+  statenames[ROOT_process] = NULL;
+  statenames[AL_process] = NULL;
+  statenames[S_process] = "process";
+  statenames[S_process_1] = "process";
+  statenames[S_process_2] = "process";
+  statenames[E_process] = "process";
+  statenames[ROOT_argument] = NULL;
+  statenames[AL_argument] = NULL;
+  statenames[E_argument] = "argument";
+
+ /* COMMENTS and PIs: handled uniformly for efficiency. */
+
+<ROOT_platform_description,AL_platform_description,S_platform_description,S_platform_description_1,S_platform_description_2,E_platform_description,ROOT_cpu,AL_cpu,E_cpu,ROOT_network_link,AL_network_link,E_network_link,ROOT_route,AL_route,S_route,S_route_1,S_route_2,E_route,ROOT_route_element,AL_route_element,E_route_element,ROOT_process,AL_process,S_process,S_process_1,S_process_2,E_process,ROOT_argument,AL_argument,E_argument,PROLOG,DOCTYPE,EPILOG>{
+ "<!--" ENTER(INCOMMENT);
+ "<?" ENTER(INPI);
+}
+<INCOMMENT>{
+ "-->"         LEAVE;
+ "--"          |
+ .             |
+ \n            SKIP;
+ <<EOF>>       fail("EOF in comment.");
+}
+<INPI>{
+ "?>"          LEAVE;
+ .             |
+ \n            SKIP;
+ <<EOF>>       fail("EOF in PI (processing instruction).");
+}
+
+ /* SPACES: skipped uniformly */
+
+<ROOT_platform_description,AL_platform_description,S_platform_description,S_platform_description_1,S_platform_description_2,E_platform_description,ROOT_cpu,AL_cpu,E_cpu,ROOT_network_link,AL_network_link,E_network_link,ROOT_route,AL_route,S_route,S_route_1,S_route_2,E_route,ROOT_route_element,AL_route_element,E_route_element,ROOT_process,AL_process,S_process,S_process_1,S_process_2,E_process,ROOT_argument,AL_argument,E_argument,PROLOG,DOCTYPE,EPILOG>{S} SKIP;
+
+ /* PROLOG: determine root element and process it. */
+
+<PROLOG>{
+ "<?xml"({S}version{Eq}(\'{VersionNum}\'|\"{VersionNum}\"))?"?>" SET(DOCTYPE);
+ "<?xml"[^>]*">" fail("Bad declaration %s.",yytext);
+}
+
+<PROLOG,DOCTYPE>{
+ "<!DOCTYPE"{S}"argument"{S}SYSTEM{S}("'surfxml.dtd'"|"\"surfxml.dtd\""){s}">" SET(ROOT_argument);
+ "<!DOCTYPE"{S}"route_element"{S}SYSTEM{S}("'surfxml.dtd'"|"\"surfxml.dtd\""){s}">" SET(ROOT_route_element);
+ "<!DOCTYPE"{S}"cpu"{S}SYSTEM{S}("'surfxml.dtd'"|"\"surfxml.dtd\""){s}">" SET(ROOT_cpu);
+ "<!DOCTYPE"{S}"route"{S}SYSTEM{S}("'surfxml.dtd'"|"\"surfxml.dtd\""){s}">" SET(ROOT_route);
+ "<!DOCTYPE"{S}"platform_description"{S}SYSTEM{S}("'surfxml.dtd'"|"\"surfxml.dtd\""){s}">" SET(ROOT_platform_description);
+ "<!DOCTYPE"{S}"network_link"{S}SYSTEM{S}("'surfxml.dtd'"|"\"surfxml.dtd\""){s}">" SET(ROOT_network_link);
+ "<!DOCTYPE"{S}"process"{S}SYSTEM{S}("'surfxml.dtd'"|"\"surfxml.dtd\""){s}">" SET(ROOT_process);
+ "<!"[^>-][^>]*">" fail("Bad declaration %s.",yytext);
+ .             fail("Unexpected character `%c' in prolog.", yytext[0]);
+ <<EOF>>       fail("EOF in prolog.");
+}
+
+ /* RULES DERIVED FROM DTD. */
+
+ /* <!-- Small DTD for SURF based tools. -->  */
+
+<ROOT_platform_description>"<platform_description"{s} {
+  ENTER(AL_platform_description);
+  }
+
+<AL_platform_description>{
+ ">" {
+  LEAVE; STag_platform_description();pcdata = NULL; ENTER(S_platform_description);
+ }
+ "/>" {
+  LEAVE; STag_platform_description(); pcdata = NULL; ETag_platform_description();
+  switch (YY_START) {
+   case ROOT_platform_description: SET(EPILOG); break;
+  }
+ }
+ .       fail("Unexpected character `%c' in attribute list of platform_description element.", yytext[0]);
+ {Name} fail("Bad attribute `%s' in `platform_description' element start tag.",yytext);
+ <<EOF>> fail("EOF in attribute list of `platform_description' element.");
+}
+
+<E_platform_description,S_platform_description_2,S_platform_description>{
+ "</platform_description"{s}">" {
+  LEAVE;
+  ETag_platform_description();
+  switch (YY_START) {
+   case ROOT_platform_description: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" fail("Unexpected end-tag `%s': `</platform_description>' expected.",yytext);
+ .       fail("Unexpected character `%c': `</platform_description>' expected.",yytext[0]);
+ <<EOF>> fail("Premature EOF: `</platform_description>' expected.");
+}
+
+<ROOT_cpu,S_platform_description_2,S_platform_description_1,S_platform_description>"<cpu"{s} {
+  A_cpu_name = NULL;
+  A_cpu_power = NULL;
+  A_cpu_availability = "1.0";
+  A_cpu_availability_file = NULL;
+  A_cpu_state = A_cpu_state_ON;
+  A_cpu_state_file = NULL;
+  ENTER(AL_cpu);
+  }
+
+<AL_cpu>{
+ "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_cpu_name);
+ "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_cpu_name);
+
+ "power"{Eq}\' ENTER(VALUE1); BUFFERSET(A_cpu_power);
+ "power"{Eq}\" ENTER(VALUE2); BUFFERSET(A_cpu_power);
+
+ "availability"{Eq}\' ENTER(VALUE1); BUFFERSET(A_cpu_availability);
+ "availability"{Eq}\" ENTER(VALUE2); BUFFERSET(A_cpu_availability);
+
+ "availability_file"{Eq}\' ENTER(VALUE1); BUFFERSET(A_cpu_availability_file);
+ "availability_file"{Eq}\" ENTER(VALUE2); BUFFERSET(A_cpu_availability_file);
+
+ "state"{Eq}"'ON'" |
+ "state"{Eq}"\"ON\"" A_cpu_state = A_cpu_state_ON;
+ "state"{Eq}"'OFF'" |
+ "state"{Eq}"\"OFF\"" A_cpu_state = A_cpu_state_OFF;
+
+ "state_file"{Eq}\' ENTER(VALUE1); BUFFERSET(A_cpu_state_file);
+ "state_file"{Eq}\" ENTER(VALUE2); BUFFERSET(A_cpu_state_file);
+
+ ">" {
+  if (!A_cpu_name) fail("Required attribute `name' not set for `cpu' element.");
+  if (!A_cpu_power) fail("Required attribute `power' not set for `cpu' element.");
+  LEAVE; STag_cpu();pcdata = NULL; ENTER(E_cpu);
+ }
+ "/>" {
+  if (!A_cpu_name) fail("Required attribute `name' not set for `cpu' element.");
+  if (!A_cpu_power) fail("Required attribute `power' not set for `cpu' element.");
+  LEAVE; STag_cpu(); pcdata = NULL; ETag_cpu();
+  switch (YY_START) {
+   case S_platform_description_2: case S_platform_description_1: case S_platform_description: SET(S_platform_description_2); break;
+   case ROOT_cpu: SET(EPILOG); break;
+  }
+ }
+ .       fail("Unexpected character `%c' in attribute list of cpu element.", yytext[0]);
+ {Name} fail("Bad attribute `%s' in `cpu' element start tag.",yytext);
+ <<EOF>> fail("EOF in attribute list of `cpu' element.");
+}
+
+<E_cpu>{
+ "</cpu"{s}">" {
+  LEAVE;
+  ETag_cpu();
+  switch (YY_START) {
+   case S_platform_description_2: case S_platform_description_1: case S_platform_description: SET(S_platform_description_2); break;
+   case ROOT_cpu: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" fail("Unexpected end-tag `%s': `</cpu>' expected.",yytext);
+ .       fail("Unexpected character `%c': `</cpu>' expected.",yytext[0]);
+ <<EOF>> fail("Premature EOF: `</cpu>' expected.");
+}
+
+<ROOT_network_link,S_platform_description_2,S_platform_description_1,S_platform_description>"<network_link"{s} {
+  A_network_link_name = NULL;
+  A_network_link_bandwidth = NULL;
+  A_network_link_bandwidth_file = NULL;
+  A_network_link_latency = "0.001";
+  A_network_link_latency_file = NULL;
+  A_network_link_state = A_network_link_state_ON;
+  A_network_link_state_file = NULL;
+  ENTER(AL_network_link);
+  }
+
+<AL_network_link>{
+ "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_network_link_name);
+ "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_network_link_name);
+
+ "bandwidth"{Eq}\' ENTER(VALUE1); BUFFERSET(A_network_link_bandwidth);
+ "bandwidth"{Eq}\" ENTER(VALUE2); BUFFERSET(A_network_link_bandwidth);
+
+ "bandwidth_file"{Eq}\' ENTER(VALUE1); BUFFERSET(A_network_link_bandwidth_file);
+ "bandwidth_file"{Eq}\" ENTER(VALUE2); BUFFERSET(A_network_link_bandwidth_file);
+
+ "latency"{Eq}\' ENTER(VALUE1); BUFFERSET(A_network_link_latency);
+ "latency"{Eq}\" ENTER(VALUE2); BUFFERSET(A_network_link_latency);
+
+ "latency_file"{Eq}\' ENTER(VALUE1); BUFFERSET(A_network_link_latency_file);
+ "latency_file"{Eq}\" ENTER(VALUE2); BUFFERSET(A_network_link_latency_file);
+
+ "state"{Eq}"'ON'" |
+ "state"{Eq}"\"ON\"" A_network_link_state = A_network_link_state_ON;
+ "state"{Eq}"'OFF'" |
+ "state"{Eq}"\"OFF\"" A_network_link_state = A_network_link_state_OFF;
+
+ "state_file"{Eq}\' ENTER(VALUE1); BUFFERSET(A_network_link_state_file);
+ "state_file"{Eq}\" ENTER(VALUE2); BUFFERSET(A_network_link_state_file);
+
+ ">" {
+  if (!A_network_link_name) fail("Required attribute `name' not set for `network_link' element.");
+  if (!A_network_link_bandwidth) fail("Required attribute `bandwidth' not set for `network_link' element.");
+  LEAVE; STag_network_link();pcdata = NULL; ENTER(E_network_link);
+ }
+ "/>" {
+  if (!A_network_link_name) fail("Required attribute `name' not set for `network_link' element.");
+  if (!A_network_link_bandwidth) fail("Required attribute `bandwidth' not set for `network_link' element.");
+  LEAVE; STag_network_link(); pcdata = NULL; ETag_network_link();
+  switch (YY_START) {
+   case S_platform_description_2: case S_platform_description_1: case S_platform_description: SET(S_platform_description_2); break;
+   case ROOT_network_link: SET(EPILOG); break;
+  }
+ }
+ .       fail("Unexpected character `%c' in attribute list of network_link element.", yytext[0]);
+ {Name} fail("Bad attribute `%s' in `network_link' element start tag.",yytext);
+ <<EOF>> fail("EOF in attribute list of `network_link' element.");
+}
+
+<E_network_link>{
+ "</network_link"{s}">" {
+  LEAVE;
+  ETag_network_link();
+  switch (YY_START) {
+   case S_platform_description_2: case S_platform_description_1: case S_platform_description: SET(S_platform_description_2); break;
+   case ROOT_network_link: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" fail("Unexpected end-tag `%s': `</network_link>' expected.",yytext);
+ .       fail("Unexpected character `%c': `</network_link>' expected.",yytext[0]);
+ <<EOF>> fail("Premature EOF: `</network_link>' expected.");
+}
+
+<ROOT_route,S_platform_description_2,S_platform_description_1,S_platform_description>"<route"{s} {
+  A_route_src = NULL;
+  A_route_dst = NULL;
+  ENTER(AL_route);
+  }
+
+<AL_route>{
+ "src"{Eq}\' ENTER(VALUE1); BUFFERSET(A_route_src);
+ "src"{Eq}\" ENTER(VALUE2); BUFFERSET(A_route_src);
+
+ "dst"{Eq}\' ENTER(VALUE1); BUFFERSET(A_route_dst);
+ "dst"{Eq}\" ENTER(VALUE2); BUFFERSET(A_route_dst);
+
+ ">" {
+  if (!A_route_src) fail("Required attribute `src' not set for `route' element.");
+  if (!A_route_dst) fail("Required attribute `dst' not set for `route' element.");
+  LEAVE; STag_route();pcdata = NULL; ENTER(S_route);
+ }
+ "/>" {
+  if (!A_route_src) fail("Required attribute `src' not set for `route' element.");
+  if (!A_route_dst) fail("Required attribute `dst' not set for `route' element.");
+  LEAVE; STag_route(); pcdata = NULL; ETag_route();
+  switch (YY_START) {
+   case S_platform_description_2: case S_platform_description_1: case S_platform_description: SET(S_platform_description_2); break;
+   case ROOT_route: SET(EPILOG); break;
+  }
+ }
+ .       fail("Unexpected character `%c' in attribute list of route element.", yytext[0]);
+ {Name} fail("Bad attribute `%s' in `route' element start tag.",yytext);
+ <<EOF>> fail("EOF in attribute list of `route' element.");
+}
+
+<S_route,S_route_2,E_route>{
+ "</route"{s}">" {
+  LEAVE;
+  ETag_route();
+  switch (YY_START) {
+   case S_platform_description_2: case S_platform_description_1: case S_platform_description: SET(S_platform_description_2); break;
+   case ROOT_route: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" fail("Unexpected end-tag `%s': `</route>' expected.",yytext);
+ .       fail("Unexpected character `%c': `</route>' expected.",yytext[0]);
+ <<EOF>> fail("Premature EOF: `</route>' expected.");
+}
+
+<ROOT_route_element,S_route_1,S_route,S_route_2>"<route_element"{s} {
+  A_route_element_name = NULL;
+  ENTER(AL_route_element);
+  }
+
+<AL_route_element>{
+ "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_route_element_name);
+ "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_route_element_name);
+
+ ">" {
+  if (!A_route_element_name) fail("Required attribute `name' not set for `route_element' element.");
+  LEAVE; STag_route_element();pcdata = NULL; ENTER(E_route_element);
+ }
+ "/>" {
+  if (!A_route_element_name) fail("Required attribute `name' not set for `route_element' element.");
+  LEAVE; STag_route_element(); pcdata = NULL; ETag_route_element();
+  switch (YY_START) {
+   case S_route_1: case S_route: case S_route_2: SET(S_route_2); break;
+   case ROOT_route_element: SET(EPILOG); break;
+  }
+ }
+ .       fail("Unexpected character `%c' in attribute list of route_element element.", yytext[0]);
+ {Name} fail("Bad attribute `%s' in `route_element' element start tag.",yytext);
+ <<EOF>> fail("EOF in attribute list of `route_element' element.");
+}
+
+<E_route_element>{
+ "</route_element"{s}">" {
+  LEAVE;
+  ETag_route_element();
+  switch (YY_START) {
+   case S_route_1: case S_route: case S_route_2: SET(S_route_2); break;
+   case ROOT_route_element: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" fail("Unexpected end-tag `%s': `</route_element>' expected.",yytext);
+ .       fail("Unexpected character `%c': `</route_element>' expected.",yytext[0]);
+ <<EOF>> fail("Premature EOF: `</route_element>' expected.");
+}
+
+<ROOT_process,S_platform_description_2,S_platform_description_1,S_platform_description>"<process"{s} {
+  A_process_host = NULL;
+  A_process_function = NULL;
+  ENTER(AL_process);
+  }
+
+<AL_process>{
+ "host"{Eq}\' ENTER(VALUE1); BUFFERSET(A_process_host);
+ "host"{Eq}\" ENTER(VALUE2); BUFFERSET(A_process_host);
+
+ "function"{Eq}\' ENTER(VALUE1); BUFFERSET(A_process_function);
+ "function"{Eq}\" ENTER(VALUE2); BUFFERSET(A_process_function);
+
+ ">" {
+  if (!A_process_host) fail("Required attribute `host' not set for `process' element.");
+  if (!A_process_function) fail("Required attribute `function' not set for `process' element.");
+  LEAVE; STag_process();pcdata = NULL; ENTER(S_process);
+ }
+ "/>" {
+  if (!A_process_host) fail("Required attribute `host' not set for `process' element.");
+  if (!A_process_function) fail("Required attribute `function' not set for `process' element.");
+  LEAVE; STag_process(); pcdata = NULL; ETag_process();
+  switch (YY_START) {
+   case S_platform_description_2: case S_platform_description_1: case S_platform_description: SET(S_platform_description_2); break;
+   case ROOT_process: SET(EPILOG); break;
+  }
+ }
+ .       fail("Unexpected character `%c' in attribute list of process element.", yytext[0]);
+ {Name} fail("Bad attribute `%s' in `process' element start tag.",yytext);
+ <<EOF>> fail("EOF in attribute list of `process' element.");
+}
+
+<S_process,E_process,S_process_2>{
+ "</process"{s}">" {
+  LEAVE;
+  ETag_process();
+  switch (YY_START) {
+   case S_platform_description_2: case S_platform_description_1: case S_platform_description: SET(S_platform_description_2); break;
+   case ROOT_process: SET(EPILOG); break;
+  }
+ }
+ "</"{Name}{s}">" fail("Unexpected end-tag `%s': `</process>' expected.",yytext);
+ .       fail("Unexpected character `%c': `</process>' expected.",yytext[0]);
+ <<EOF>> fail("Premature EOF: `</process>' expected.");
+}
+
+<ROOT_argument,S_process_1,S_process,S_process_2>"<argument"{s} {
+  A_argument_value = NULL;
+  ENTER(AL_argument);
+  }
+
+<AL_argument>{
+ "value"{Eq}\' ENTER(VALUE1); BUFFERSET(A_argument_value);
+ "value"{Eq}\" ENTER(VALUE2); BUFFERSET(A_argument_value);
+
+ ">" {
+  if (!A_argument_value) fail("Required attribute `value' not set for `argument' element.");
+  LEAVE; STag_argument();pcdata = NULL; ENTER(E_argument);
+ }
+ "/>" {
+  if (!A_argument_value) fail("Required attribute `value' not set for `argument' element.");
+  LEAVE; STag_argument(); pcdata = NULL; ETag_argument();
+  switch (YY_START) {
+   case ROOT_argument: SET(EPILOG); break;
+   case S_process_1: case S_process: case S_process_2: SET(S_process_2); break;
+  }
+ }
+ .       fail("Unexpected character `%c' in attribute list of argument element.", yytext[0]);
+ {Name} fail("Bad attribute `%s' in `argument' element start tag.",yytext);
+ <<EOF>> fail("EOF in attribute list of `argument' element.");
+}
+
+<E_argument>{
+ "</argument"{s}">" {
+  LEAVE;
+  ETag_argument();
+  switch (YY_START) {
+   case ROOT_argument: SET(EPILOG); break;
+   case S_process_1: case S_process: case S_process_2: SET(S_process_2); break;
+  }
+ }
+ "</"{Name}{s}">" fail("Unexpected end-tag `%s': `</argument>' expected.",yytext);
+ .       fail("Unexpected character `%c': `</argument>' expected.",yytext[0]);
+ <<EOF>> fail("Premature EOF: `</argument>' expected.");
+}
+
+ /* EPILOG: after the root element. */
+
+<EPILOG>{
+ .             fail("Unexpected character `%c' after document.", yytext[0]);
+ <<EOF>>       SUCCEED;
+}
+
+ /* CHARACTER DATA. */
+
+<IMPOSSIBLE,VALUE1,VALUE2>{
+ /* Non-defined standard entities... */
+"&amp;"  BUFFERPUTC('&');
+"&lt;"   BUFFERPUTC('<');
+"&gt;"   BUFFERPUTC('>');
+"&apos;" BUFFERPUTC('\'');
+"&quot;" BUFFERPUTC('"');
+
+ /* Character entities. */
+ "&#"[[:digit:]]+";"   BUFFERPUTC((unsigned char)atoi(yytext+2));
+ "&#x"[[:xdigit:]]+";" BUFFERPUTC((unsigned char)strtol(yytext+3,NULL,16));
+}
+
+<IMPOSSIBLE,VALUE1,VALUE2,CDATA>{
+ "\n"          |
+ "\r"          |
+ "\r\n"                |
+ "\n\r"                BUFFERPUTC('\n');
+}
+
+<IMPOSSIBLE>{
+ "<![CDATA["   ENTER(CDATA);
+ "]""]>"               fail("Unexpected `]""]>' in character data.");
+}
+
+<VALUE1>{
+ \'            BUFFERDONE; LEAVE;
+ <<EOF>>       fail("EOF in literal (\"'\" expected).");
+}
+
+<VALUE2>{
+ \"            BUFFERDONE; LEAVE;
+ <<EOF>>       fail("EOF in literal (`\"' expected).");
+}
+
+<IMPOSSIBLE,VALUE1,VALUE2>{
+ [^<&]         BUFFERPUTC(yytext[0]);
+ [<&]          fail("Spurious `%c' in character data.",yytext[0]);
+}
+
+<CDATA>{
+ "]""]>"               LEAVE;
+ "]""]"                BUFFERPUTC(yytext[0]); BUFFERPUTC(yytext[1]);
+ .             BUFFERPUTC(yytext[0]);
+ <<EOF>>       fail("EOF in CDATA section.");
+}
+
+ /* Impossible rules to avoid warnings from flex(1). */
+
+<INITIAL,IMPOSSIBLE>{
+ .|[\n] fail("The Impossible Happened: INITIAL or IMPOSSIBLE state entered?");
+}
+
+%%
+
+/* Element context stack lookup. */
+int element_context(int i)
+{
+  return (0<i && i<yy_start_stack_depth
+         ? yy_start_stack[yy_start_stack_ptr - i]
+         : 0);
+}
+
+#ifdef FLEX_DEBUG
+void print_yy_stack(char* fmt, ...)
+{
+  int i = 0; va_list ap; va_start(ap, fmt);
+  vfprintf(stderr, fmt, ap);
+  for (i=1; i<yy_start_stack_ptr; i++)
+    fprintf(stderr, "%s/", statenames[yy_start_stack[i] ]);
+  fprintf(stderr,"%s\n", statenames[YY_START]);
+  va_end(ap);
+}
+
+static void debug_enter(int state, const char* statename) {
+  yy_push_state(state);
+  if (yy_flex_debug) print_yy_stack("--ENTER(%s) : ",statename);
+}
+
+static void debug_leave(void) {
+  if (yy_flex_debug) print_yy_stack("--LEAVE : ");
+  yy_pop_state();
+}
+
+static void debug_set(int state, const char* statename) {
+  BEGIN(state);
+  if (yy_flex_debug) print_yy_stack("--SET(%s) : ",statename);
+}
+#endif
+
+
+static int fail(const char* fmt, ...)
+{
+  va_list ap; va_start(ap, fmt);
+#ifdef FLEXML_yylineno
+  fprintf(stderr, "Invalid XML (XML input line %d, state %d): ", yylineno, YY_START);
+#else
+  fprintf(stderr, "Invalid XML (state %d): ",YY_START);
+#endif
+  vfprintf(stderr, fmt, ap);
+  fprintf(stderr, "\n");
+  va_end(ap);
+  return 1;
+}
index 56195fb..c5c9d18 100644 (file)
@@ -190,7 +190,7 @@ void test_all(const char *platform_file,const char *application_file, double sha
 
 int main(int argc, char *argv[])
 {
-  test_all("msg_platform.txt","msg_deployment.txt",-.1);
+  test_all("msg_platform.xml","msg_deployment.xml",-.1);
 /*   test_all("msg_platform.txt","msg_deployment.txt",.1); */
   return (0);
 }