From 9696c1a327d9f7439c42d72097c9eec20afb3c4a Mon Sep 17 00:00:00 2001 From: alegrand Date: Wed, 5 Jan 2005 00:45:29 +0000 Subject: [PATCH] Moved from flex to flexml. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@733 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- include/Makefile.am | 3 + src/Makefile.am | 11 +- src/include/surf/surf_parse.h | 57 ++- src/include/surf/surfxml.h | 109 +++++ src/msg/deployment.c | 95 ++--- src/surf/cpu.c | 54 +-- src/surf/network.c | 166 +++----- src/surf/surfxml.dtd | 33 ++ src/surf/surfxml.l | 741 ++++++++++++++++++++++++++++++++++ testsuite/msg/msg_test.c | 2 +- 10 files changed, 1026 insertions(+), 245 deletions(-) create mode 100644 src/include/surf/surfxml.h create mode 100644 src/surf/surfxml.dtd create mode 100644 src/surf/surfxml.l diff --git a/include/Makefile.am b/include/Makefile.am index 111ffc1dd6..1206387168 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -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 diff --git a/src/Makefile.am b/src/Makefile.am index bf8a056a36..3fdf85877e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ \ diff --git a/src/include/surf/surf_parse.h b/src/include/surf/surf_parse.h index 284224fc05..7fa1e8b4c9 100644 --- a/src/include/surf/surf_parse.h +++ b/src/include/surf/surf_parse.h @@ -10,37 +10,31 @@ #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 index 0000000000..426743e30d --- /dev/null +++ b/src/include/surf/surfxml.h @@ -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 diff --git a/src/msg/deployment.c b/src/msg/deployment.c index b53e22e025..9874ee1ea2 100644 --- a/src/msg/deployment.c +++ b/src/msg/deployment.c @@ -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 - - // 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 - -\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 diff --git a/src/surf/cpu.c b/src/surf/cpu.c index a3c4d94c64..84e72a6002 100644 --- a/src/surf/cpu.c +++ b/src/surf/cpu.c @@ -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) diff --git a/src/surf/network.c b/src/surf/network.c index 4377c0ef5e..f6fa9e450d 100644 --- a/src/surf/network.c +++ b/src/surf/network.c @@ -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 index 0000000000..60619e145d --- /dev/null +++ b/src/surf/surfxml.dtd @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/surf/surfxml.l b/src/surf/surfxml.l new file mode 100644 index 0000000000..f534db341f --- /dev/null +++ b/src/surf/surfxml.l @@ -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 +#include +#include +#include +#include +#include + +/* 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(nextold = 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 + * DOCTYPE the XML prolog of the document after + * 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 section. + * ROOT_ expect root element + * AL_ inside the attribute list for + * IN_ inside a 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. */ + +{ + "" LEAVE; + "--" | + . | + \n SKIP; + <> fail("EOF in comment."); +} +{ + "?>" LEAVE; + . | + \n SKIP; + <> fail("EOF in PI (processing instruction)."); +} + + /* SPACES: skipped uniformly */ + +{S} SKIP; + + /* PROLOG: determine root element and process it. */ + +{ + "" SET(DOCTYPE); + "]*">" fail("Bad declaration %s.",yytext); +} + +{ + "" SET(ROOT_argument); + "" SET(ROOT_route_element); + "" SET(ROOT_cpu); + "" SET(ROOT_route); + "" SET(ROOT_platform_description); + "" SET(ROOT_network_link); + "" SET(ROOT_process); + "-][^>]*">" fail("Bad declaration %s.",yytext); + . fail("Unexpected character `%c' in prolog.", yytext[0]); + <> fail("EOF in prolog."); +} + + /* RULES DERIVED FROM DTD. */ + + /* */ + +"{ + ">" { + 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); + <> fail("EOF in attribute list of `platform_description' element."); +} + +{ + "" { + LEAVE; + ETag_platform_description(); + switch (YY_START) { + case ROOT_platform_description: SET(EPILOG); break; + } + } + "" fail("Unexpected end-tag `%s': `' expected.",yytext); + . fail("Unexpected character `%c': `' expected.",yytext[0]); + <> fail("Premature EOF: `' expected."); +} + +"{ + "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); + <> fail("EOF in attribute list of `cpu' element."); +} + +{ + "" { + 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; + } + } + "" fail("Unexpected end-tag `%s': `' expected.",yytext); + . fail("Unexpected character `%c': `' expected.",yytext[0]); + <> fail("Premature EOF: `' expected."); +} + +"{ + "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); + <> fail("EOF in attribute list of `network_link' element."); +} + +{ + "" { + 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; + } + } + "" fail("Unexpected end-tag `%s': `' expected.",yytext); + . fail("Unexpected character `%c': `' expected.",yytext[0]); + <> fail("Premature EOF: `' expected."); +} + +"{ + "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); + <> fail("EOF in attribute list of `route' element."); +} + +{ + "" { + 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; + } + } + "" fail("Unexpected end-tag `%s': `' expected.",yytext); + . fail("Unexpected character `%c': `' expected.",yytext[0]); + <> fail("Premature EOF: `' expected."); +} + +"{ + "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); + <> fail("EOF in attribute list of `route_element' element."); +} + +{ + "" { + 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; + } + } + "" fail("Unexpected end-tag `%s': `' expected.",yytext); + . fail("Unexpected character `%c': `' expected.",yytext[0]); + <> fail("Premature EOF: `' expected."); +} + +"{ + "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); + <> fail("EOF in attribute list of `process' element."); +} + +{ + "" { + 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; + } + } + "" fail("Unexpected end-tag `%s': `' expected.",yytext); + . fail("Unexpected character `%c': `' expected.",yytext[0]); + <> fail("Premature EOF: `' expected."); +} + +"{ + "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); + <> fail("EOF in attribute list of `argument' element."); +} + +{ + "" { + 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; + } + } + "" fail("Unexpected end-tag `%s': `' expected.",yytext); + . fail("Unexpected character `%c': `' expected.",yytext[0]); + <> fail("Premature EOF: `' expected."); +} + + /* EPILOG: after the root element. */ + +{ + . fail("Unexpected character `%c' after document.", yytext[0]); + <> SUCCEED; +} + + /* CHARACTER DATA. */ + +{ + /* Non-defined standard entities... */ +"&" BUFFERPUTC('&'); +"<" BUFFERPUTC('<'); +">" BUFFERPUTC('>'); +"'" BUFFERPUTC('\''); +""" BUFFERPUTC('"'); + + /* Character entities. */ + "&#"[[:digit:]]+";" BUFFERPUTC((unsigned char)atoi(yytext+2)); + "&#x"[[:xdigit:]]+";" BUFFERPUTC((unsigned char)strtol(yytext+3,NULL,16)); +} + +{ + "\n" | + "\r" | + "\r\n" | + "\n\r" BUFFERPUTC('\n'); +} + +{ + "" fail("Unexpected `]""]>' in character data."); +} + +{ + \' BUFFERDONE; LEAVE; + <> fail("EOF in literal (\"'\" expected)."); +} + +{ + \" BUFFERDONE; LEAVE; + <> fail("EOF in literal (`\"' expected)."); +} + +{ + [^<&] BUFFERPUTC(yytext[0]); + [<&] fail("Spurious `%c' in character data.",yytext[0]); +} + +{ + "]""]>" LEAVE; + "]""]" BUFFERPUTC(yytext[0]); BUFFERPUTC(yytext[1]); + . BUFFERPUTC(yytext[0]); + <> fail("EOF in CDATA section."); +} + + /* Impossible rules to avoid warnings from flex(1). */ + +{ + .|[\n] fail("The Impossible Happened: INITIAL or IMPOSSIBLE state entered?"); +} + +%% + +/* Element context stack lookup. */ +int element_context(int i) +{ + return (0