/* Validating XML processor for octave.dtd.
 * Generated 2004/02/13 14:47:24.
 *
 * This program was generated with the FleXML XML processor generator,
 * (Id: flexml.pl,v 1.28 2003/02/12 02:55:41 krisrose 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.28 2003/02/12 02:55:41 krisrose 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 100000

/* XML application entry points. */
static void STag_octave(void);
static void ETag_octave(void);
static void STag_scalar(void);
static void ETag_scalar(void);
static void STag_complex(void);
static void ETag_complex(void);
static void STag_string(void);
static void ETag_string(void);
static void STag_array(void);
static void ETag_array(void);
static void STag_matrix(void);
static void ETag_matrix(void);
static void STag_structure(void);
static void ETag_structure(void);
static void STag_list(void);
static void ETag_list(void);
static void STag_cell(void);
static void ETag_cell(void);

/* XML application data. */
typedef char* AT_list_length;
#define AU_list_length NULL
typedef char* AT_matrix_rows;
#define AU_matrix_rows NULL
typedef char* AT_matrix_name;
#define AU_matrix_name NULL
typedef char* AT_cell_columns;
#define AU_cell_columns NULL
typedef char* AT_scalar_name;
#define AU_scalar_name NULL
typedef char* AT_array_name;
#define AU_array_name NULL
typedef char* AT_complex_name;
#define AU_complex_name NULL
typedef char* AT_matrix_columns;
#define AU_matrix_columns NULL
typedef char* AT_cell_name;
#define AU_cell_name NULL
typedef char* AT_string_length;
#define AU_string_length NULL
typedef char* AT_list_name;
#define AU_list_name NULL
typedef enum { AU_scalar_value, A_scalar_value_undefined,A_scalar_value_true,A_scalar_value_false,A_scalar_value_inf,A_scalar_value_neginf,A_scalar_value_na,A_scalar_value_nan } AT_scalar_value;
typedef char* AT_structure_name;
#define AU_structure_name NULL
typedef char* AT_cell_rows;
#define AU_cell_rows NULL
typedef char* AT_array_rows;
#define AU_array_rows NULL
typedef char* AT_string_name;
#define AU_string_name NULL

/* FleXML-provided data. */
static char* pcdata;
static AT_list_length A_list_length;
static AT_matrix_rows A_matrix_rows;
static AT_matrix_name A_matrix_name;
static AT_cell_columns A_cell_columns;
static AT_scalar_name A_scalar_name;
static AT_array_name A_array_name;
static AT_complex_name A_complex_name;
static AT_matrix_columns A_matrix_columns;
static AT_cell_name A_cell_name;
static AT_string_length A_string_length;
static AT_list_name A_list_name;
static AT_scalar_value A_scalar_value;
static AT_structure_name A_structure_name;
static AT_cell_rows A_cell_rows;
static AT_array_rows A_array_rows;
static AT_string_name A_string_name;

/* 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, char*);
  static void debug_leave(void);
  static void debug_set(int, 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_octave AL_octave S_octave E_octave
%x ROOT_scalar AL_scalar IN_scalar
%x ROOT_complex AL_complex S_complex S_complex_1 E_complex
%x ROOT_string AL_string IN_string
%x ROOT_array AL_array S_array S_array_1 S_array_2 S_array_3 E_array
%x ROOT_matrix AL_matrix S_matrix S_matrix_1 S_matrix_2 E_matrix
%x ROOT_structure AL_structure IN_structure
%x ROOT_list AL_list IN_list
%x ROOT_cell AL_cell IN_cell
%x IMPOSSIBLE

%{
/* State names. */
char* statenames[IMPOSSIBLE];

void FleXML_init(void)
{
  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_octave] = NULL;
  statenames[AL_octave] = NULL;
  statenames[S_octave] = "octave";
  statenames[E_octave] = "octave";
  statenames[ROOT_scalar] = NULL;
  statenames[AL_scalar] = NULL;
  statenames[IN_scalar] = "scalar";
  statenames[ROOT_complex] = NULL;
  statenames[AL_complex] = NULL;
  statenames[S_complex] = "complex";
  statenames[S_complex_1] = "complex";
  statenames[E_complex] = "complex";
  statenames[ROOT_string] = NULL;
  statenames[AL_string] = NULL;
  statenames[IN_string] = "string";
  statenames[ROOT_array] = NULL;
  statenames[AL_array] = NULL;
  statenames[S_array] = "array";
  statenames[S_array_1] = "array";
  statenames[S_array_2] = "array";
  statenames[S_array_3] = "array";
  statenames[E_array] = "array";
  statenames[ROOT_matrix] = NULL;
  statenames[AL_matrix] = NULL;
  statenames[S_matrix] = "matrix";
  statenames[S_matrix_1] = "matrix";
  statenames[S_matrix_2] = "matrix";
  statenames[E_matrix] = "matrix";
  statenames[ROOT_structure] = NULL;
  statenames[AL_structure] = NULL;
  statenames[IN_structure] = "structure";
  statenames[ROOT_list] = NULL;
  statenames[AL_list] = NULL;
  statenames[IN_list] = "list";
  statenames[ROOT_cell] = NULL;
  statenames[AL_cell] = NULL;
  statenames[IN_cell] = "cell";
}
%}

%%

 /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */
 SET(PROLOG); FleXML_init();

 /* COMMENTS and PIs: handled uniformly for efficiency. */

<ROOT_octave,AL_octave,S_octave,E_octave,ROOT_scalar,AL_scalar,IN_scalar,ROOT_complex,AL_complex,S_complex,S_complex_1,E_complex,ROOT_string,AL_string,IN_string,ROOT_array,AL_array,S_array,S_array_1,S_array_2,S_array_3,E_array,ROOT_matrix,AL_matrix,S_matrix,S_matrix_1,S_matrix_2,E_matrix,ROOT_structure,AL_structure,IN_structure,ROOT_list,AL_list,IN_list,ROOT_cell,AL_cell,IN_cell,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_octave,AL_octave,S_octave,E_octave,ROOT_scalar,AL_scalar,ROOT_complex,AL_complex,S_complex,S_complex_1,E_complex,ROOT_string,AL_string,ROOT_array,AL_array,S_array,S_array_1,S_array_2,S_array_3,E_array,ROOT_matrix,AL_matrix,S_matrix,S_matrix_1,S_matrix_2,E_matrix,ROOT_structure,AL_structure,ROOT_list,AL_list,ROOT_cell,AL_cell,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}"scalar"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_scalar);
 "<!DOCTYPE"{S}"octave"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_octave);
 "<!DOCTYPE"{S}"complex"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_complex);
 "<!DOCTYPE"{S}"string"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_string);
 "<!DOCTYPE"{S}"matrix"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_matrix);
 "<!DOCTYPE"{S}"array"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_array);
 "<!DOCTYPE"{S}"structure"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_structure);
 "<!DOCTYPE"{S}"cell"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_cell);
 "<!DOCTYPE"{S}"list"{S}SYSTEM{S}("'octave.dtd'"|"\"octave.dtd\""){s}">" SET(ROOT_list);
 "<!"[^>-][^>]*">" FAIL("Bad declaration %s.",yytext);
 . 		FAIL("Unexpected character `%c' in prolog.", yytext[0]);
 <<EOF>> 	FAIL("EOF in prolog.");
}

 /* RULES DERIVED FROM DTD. */

<ROOT_octave,IN_list,IN_structure,IN_cell>"<octave"{s} {
  ENTER(AL_octave);
  }

<AL_octave>{
 ">" {
  LEAVE; STag_octave(); pcdata = NULL; ENTER(S_octave);
 }
 "/>" FAIL("`octave' element cannot be empty.");
 .       FAIL("Unexpected character `%c' in attribute list of octave element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `octave' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `octave' element.");
}

<E_octave>{
 "</octave"{s}">" {
  LEAVE;
  ETag_octave();
  switch (YY_START) {
   case ROOT_octave: SET(EPILOG); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</octave>' expected.",yytext);
 .       FAIL("Unexpected character `%c': `</octave>' expected.",yytext[0]);
 <<EOF>> FAIL("Premature EOF: `</octave>' expected.");
}

 /* 	value (undefined | true | false | inf | neginf | na | nan) "undefined"
  * 	name CDATA #IMPLIED>  */

<ROOT_scalar,IN_list,S_matrix_2,IN_cell,S_octave,S_complex,S_matrix_1,S_complex_1,S_matrix,IN_structure>"<scalar"{s} {
  A_scalar_value = A_scalar_value_undefined;
  A_scalar_name = NULL;
  ENTER(AL_scalar);
  }

<AL_scalar>{
 "value"{Eq}"'undefined'" |
 "value"{Eq}"\"undefined\"" A_scalar_value = A_scalar_value_undefined;
 "value"{Eq}"'true'" |
 "value"{Eq}"\"true\"" A_scalar_value = A_scalar_value_true;
 "value"{Eq}"'false'" |
 "value"{Eq}"\"false\"" A_scalar_value = A_scalar_value_false;
 "value"{Eq}"'inf'" |
 "value"{Eq}"\"inf\"" A_scalar_value = A_scalar_value_inf;
 "value"{Eq}"'neginf'" |
 "value"{Eq}"\"neginf\"" A_scalar_value = A_scalar_value_neginf;
 "value"{Eq}"'na'" |
 "value"{Eq}"\"na\"" A_scalar_value = A_scalar_value_na;
 "value"{Eq}"'nan'" |
 "value"{Eq}"\"nan\"" A_scalar_value = A_scalar_value_nan;

 "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_scalar_name);
 "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_scalar_name);

 ">" {
  LEAVE; STag_scalar(); pcdata = BUFFERSET(pcdata); ENTER(IN_scalar);
 }
 "/>" {
  LEAVE; STag_scalar(); pcdata = ""; ETag_scalar();
  switch (YY_START) {
   case S_complex_1: SET(E_complex); break;
   case S_octave: SET(E_octave); break;
   case S_complex: SET(S_complex_1); break;
   case S_matrix_1: case S_matrix: case S_matrix_2: SET(S_matrix_2); break;
   case ROOT_scalar: SET(EPILOG); break;
  }
 }
 .       FAIL("Unexpected character `%c' in attribute list of scalar element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `scalar' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `scalar' element.");
}

<IN_scalar>{
 "</scalar"{s}">" {
  LEAVE;
  BUFFERDONE;
  ETag_scalar();
  switch (YY_START) {
   case S_complex_1: SET(E_complex); break;
   case S_octave: SET(E_octave); break;
   case S_complex: SET(S_complex_1); break;
   case S_matrix_1: case S_matrix: case S_matrix_2: SET(S_matrix_2); break;
   case ROOT_scalar: SET(EPILOG); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</scalar>' expected.",yytext);
 <<EOF>> FAIL("Premature EOF: `</scalar>' expected.");
}

<ROOT_complex,IN_list,S_matrix_2,IN_cell,S_octave,S_matrix_1,S_matrix,IN_structure>"<complex"{s} {
  A_complex_name = NULL;
  ENTER(AL_complex);
  }

<AL_complex>{
 "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_complex_name);
 "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_complex_name);

 ">" {
  LEAVE; STag_complex(); pcdata = NULL; ENTER(S_complex);
 }
 "/>" FAIL("`complex' element cannot be empty.");
 .       FAIL("Unexpected character `%c' in attribute list of complex element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `complex' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `complex' element.");
}

<E_complex>{
 "</complex"{s}">" {
  LEAVE;
  ETag_complex();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case S_matrix_1: case S_matrix: case S_matrix_2: SET(S_matrix_2); break;
   case ROOT_complex: SET(EPILOG); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</complex>' expected.",yytext);
 .       FAIL("Unexpected character `%c': `</complex>' expected.",yytext[0]);
 <<EOF>> FAIL("Premature EOF: `</complex>' expected.");
}

 /* 	length CDATA #REQUIRED
  * 	name CDATA #IMPLIED>  */

<ROOT_string,S_array,IN_list,S_array_1,IN_cell,S_octave,S_array_2,S_array_3,IN_structure>"<string"{s} {
  A_string_length = NULL;
  A_string_name = NULL;
  ENTER(AL_string);
  }

<AL_string>{
 "length"{Eq}\' ENTER(VALUE1); BUFFERSET(A_string_length);
 "length"{Eq}\" ENTER(VALUE2); BUFFERSET(A_string_length);

 "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_string_name);
 "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_string_name);

 ">" {
  if (!A_string_length) FAIL("Required attribute `length' not set for `string' element.");
  LEAVE; STag_string(); pcdata = BUFFERSET(pcdata); ENTER(IN_string);
 }
 "/>" {
  if (!A_string_length) FAIL("Required attribute `length' not set for `string' element.");
  LEAVE; STag_string(); pcdata = ""; ETag_string();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case S_array_2: case S_array_3: case S_array_1: SET(S_array_3); break;
   case ROOT_string: SET(EPILOG); break;
   case S_array: SET(S_array_1); break;
  }
 }
 .       FAIL("Unexpected character `%c' in attribute list of string element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `string' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `string' element.");
}

<IN_string>{
 "</string"{s}">" {
  LEAVE;
  BUFFERDONE;
  ETag_string();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case S_array_2: case S_array_3: case S_array_1: SET(S_array_3); break;
   case ROOT_string: SET(EPILOG); break;
   case S_array: SET(S_array_1); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</string>' expected.",yytext);
 <<EOF>> FAIL("Premature EOF: `</string>' expected.");
}

 /* 	rows CDATA #REQUIRED
  * 	name CDATA #IMPLIED>  */

<ROOT_array,IN_list,IN_cell,S_octave,IN_structure>"<array"{s} {
  A_array_rows = NULL;
  A_array_name = NULL;
  ENTER(AL_array);
  }

<AL_array>{
 "rows"{Eq}\' ENTER(VALUE1); BUFFERSET(A_array_rows);
 "rows"{Eq}\" ENTER(VALUE2); BUFFERSET(A_array_rows);

 "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_array_name);
 "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_array_name);

 ">" {
  if (!A_array_rows) FAIL("Required attribute `rows' not set for `array' element.");
  LEAVE; STag_array(); pcdata = NULL; ENTER(S_array);
 }
 "/>" FAIL("`array' element cannot be empty.");
 .       FAIL("Unexpected character `%c' in attribute list of array element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `array' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `array' element.");
}

<S_array_3,E_array>{
 "</array"{s}">" {
  LEAVE;
  ETag_array();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case ROOT_array: SET(EPILOG); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</array>' expected.",yytext);
 .       FAIL("Unexpected character `%c': `</array>' expected.",yytext[0]);
 <<EOF>> FAIL("Premature EOF: `</array>' expected.");
}

 /* 	rows CDATA #REQUIRED
  * 	columns  CDATA #REQUIRED
  * 	name CDATA #IMPLIED>  */

<ROOT_matrix,IN_list,IN_cell,IN_structure>"<matrix"{s} {
  A_matrix_rows = NULL;
  A_matrix_columns = NULL;
  A_matrix_name = NULL;
  ENTER(AL_matrix);
  }

<AL_matrix>{
 "rows"{Eq}\' ENTER(VALUE1); BUFFERSET(A_matrix_rows);
 "rows"{Eq}\" ENTER(VALUE2); BUFFERSET(A_matrix_rows);

 "columns"{Eq}\' ENTER(VALUE1); BUFFERSET(A_matrix_columns);
 "columns"{Eq}\" ENTER(VALUE2); BUFFERSET(A_matrix_columns);

 "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_matrix_name);
 "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_matrix_name);

 ">" {
  if (!A_matrix_rows) FAIL("Required attribute `rows' not set for `matrix' element.");
  if (!A_matrix_columns) FAIL("Required attribute `columns' not set for `matrix' element.");
  LEAVE; STag_matrix(); pcdata = NULL; ENTER(S_matrix);
 }
 "/>" {
  if (!A_matrix_rows) FAIL("Required attribute `rows' not set for `matrix' element.");
  if (!A_matrix_columns) FAIL("Required attribute `columns' not set for `matrix' element.");
  LEAVE; STag_matrix(); pcdata = NULL; ETag_matrix();
  switch (YY_START) {
   case ROOT_matrix: SET(EPILOG); break;
  }
 }
 .       FAIL("Unexpected character `%c' in attribute list of matrix element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `matrix' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `matrix' element.");
}

<S_matrix,S_matrix_2,E_matrix>{
 "</matrix"{s}">" {
  LEAVE;
  ETag_matrix();
  switch (YY_START) {
   case ROOT_matrix: SET(EPILOG); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</matrix>' expected.",yytext);
 .       FAIL("Unexpected character `%c': `</matrix>' expected.",yytext[0]);
 <<EOF>> FAIL("Premature EOF: `</matrix>' expected.");
}

<ROOT_structure,IN_list,IN_cell,S_octave,IN_structure>"<structure"{s} {
  A_structure_name = NULL;
  ENTER(AL_structure);
  }

<AL_structure>{
 "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_structure_name);
 "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_structure_name);

 ">" {
  LEAVE; STag_structure(); pcdata = BUFFERSET(pcdata); ENTER(IN_structure);
 }
 "/>" {
  LEAVE; STag_structure(); pcdata = ""; ETag_structure();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case ROOT_structure: SET(EPILOG); break;
  }
 }
 .       FAIL("Unexpected character `%c' in attribute list of structure element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `structure' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `structure' element.");
}

<IN_structure>{
 "</structure"{s}">" {
  LEAVE;
  BUFFERDONE;
  ETag_structure();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case ROOT_structure: SET(EPILOG); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</structure>' expected.",yytext);
 <<EOF>> FAIL("Premature EOF: `</structure>' expected.");
}

 /* 	length CDATA #REQUIRED
  * 	name CDATA #IMPLIED>  */

<ROOT_list,IN_list,IN_cell,S_octave,IN_structure>"<list"{s} {
  A_list_length = NULL;
  A_list_name = NULL;
  ENTER(AL_list);
  }

<AL_list>{
 "length"{Eq}\' ENTER(VALUE1); BUFFERSET(A_list_length);
 "length"{Eq}\" ENTER(VALUE2); BUFFERSET(A_list_length);

 "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_list_name);
 "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_list_name);

 ">" {
  if (!A_list_length) FAIL("Required attribute `length' not set for `list' element.");
  LEAVE; STag_list(); pcdata = BUFFERSET(pcdata); ENTER(IN_list);
 }
 "/>" {
  if (!A_list_length) FAIL("Required attribute `length' not set for `list' element.");
  LEAVE; STag_list(); pcdata = ""; ETag_list();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case ROOT_list: SET(EPILOG); break;
  }
 }
 .       FAIL("Unexpected character `%c' in attribute list of list element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `list' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `list' element.");
}

<IN_list>{
 "</list"{s}">" {
  LEAVE;
  BUFFERDONE;
  ETag_list();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case ROOT_list: SET(EPILOG); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</list>' expected.",yytext);
 <<EOF>> FAIL("Premature EOF: `</list>' expected.");
}

 /* 	rows CDATA #REQUIRED
  * 	columns CDATA #REQUIRED
  * 	name CDATA #IMPLIED>  */

<ROOT_cell,IN_list,IN_cell,S_octave,IN_structure>"<cell"{s} {
  A_cell_rows = NULL;
  A_cell_columns = NULL;
  A_cell_name = NULL;
  ENTER(AL_cell);
  }

<AL_cell>{
 "rows"{Eq}\' ENTER(VALUE1); BUFFERSET(A_cell_rows);
 "rows"{Eq}\" ENTER(VALUE2); BUFFERSET(A_cell_rows);

 "columns"{Eq}\' ENTER(VALUE1); BUFFERSET(A_cell_columns);
 "columns"{Eq}\" ENTER(VALUE2); BUFFERSET(A_cell_columns);

 "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_cell_name);
 "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_cell_name);

 ">" {
  if (!A_cell_rows) FAIL("Required attribute `rows' not set for `cell' element.");
  if (!A_cell_columns) FAIL("Required attribute `columns' not set for `cell' element.");
  LEAVE; STag_cell(); pcdata = BUFFERSET(pcdata); ENTER(IN_cell);
 }
 "/>" {
  if (!A_cell_rows) FAIL("Required attribute `rows' not set for `cell' element.");
  if (!A_cell_columns) FAIL("Required attribute `columns' not set for `cell' element.");
  LEAVE; STag_cell(); pcdata = ""; ETag_cell();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case ROOT_cell: SET(EPILOG); break;
  }
 }
 .       FAIL("Unexpected character `%c' in attribute list of cell element.", yytext[0]);
 {Name} FAIL("Bad attribute `%s' in `cell' element start tag.",yytext);
 <<EOF>> FAIL("EOF in attribute list of `cell' element.");
}

<IN_cell>{
 "</cell"{s}">" {
  LEAVE;
  BUFFERDONE;
  ETag_cell();
  switch (YY_START) {
   case S_octave: SET(E_octave); break;
   case ROOT_cell: SET(EPILOG); break;
  }
 }
 "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</cell>' expected.",yytext);
 <<EOF>> FAIL("Premature EOF: `</cell>' expected.");
}

 /* EPILOG: after the root element. */

<EPILOG>{
 . 		FAIL("Unexpected character `%c' after document.", yytext[0]);
 <<EOF>> 	SUCCEED;
}

 /* CHARACTER DATA. */

<IN_scalar,IN_structure,IN_string,IN_cell,IN_list,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));
}

<IN_scalar,IN_structure,IN_string,IN_cell,IN_list,VALUE1,VALUE2,CDATA>{
 "\n"		|
 "\r"		|
 "\r\n"		|
 "\n\r"		BUFFERPUTC('\n');
}

<IN_scalar,IN_structure,IN_string,IN_cell,IN_list>{
 "<![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).");
}

<IN_scalar,IN_structure,IN_string,IN_cell,IN_list,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, 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, 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;
}

#line 30 "xmltree_read.act"

#include <stdlib.h>
#include "xmltree.h"

#define warning perror

element **current;
element *root;
list *lastlist;

void STag_octave(void)
{
#line 43 "xmltree_read.act"

root = new_element();
root->def_value = value_data;
current = &(root->child);

lastlist = new_list(lastlist);
lastlist->root = current;

} /* STag_octave */

void ETag_octave(void)
{
#line 52 "xmltree_read.act"

current = lastlist->root;
lastlist = pop_list(lastlist);
current = &((*current)->next);

} /* ETag_octave */

void STag_scalar(void)
{
#line 60 "xmltree_read.act"

*current = new_element();

if (A_scalar_name) {
  (*current)->name = (char *) malloc(strlen(A_scalar_name)+1);
  strcpy ((*current)->name, A_scalar_name);
}

(*current)->def_value = value_scalar;
switch (A_scalar_value) {
  case A_scalar_value_true: (*current)->const_value = const_true; break;
  case A_scalar_value_false: (*current)->const_value = const_false; break;
  case A_scalar_value_inf: (*current)->const_value = const_inf; break;
  case A_scalar_value_neginf: (*current)->const_value = const_neginf; break;
  case A_scalar_value_nan: (*current)->const_value = const_nan; break;
  case A_scalar_value_na: (*current)->const_value = const_na; break;
  default: (*current)->const_value = const_undef;
}

} /* STag_scalar */

void ETag_scalar(void)
{
#line 80 "xmltree_read.act"

if (((*current)->const_value == const_undef) && (pcdata))
  (*current)->scalar_value = strtod (pcdata, NULL);

(*(lastlist->root))->nb_elements++;

current = &((*current)->next);

} /* ETag_scalar */

void STag_string(void)
{
#line 91 "xmltree_read.act"

*current = new_element();

if (A_string_name) {
  (*current)->name = (char *) malloc(strlen(A_string_name)+1);
  strcpy ((*current)->name, A_string_name);
}

if (A_string_length)
  (*current)->length = strtol (A_string_length, NULL, 10);

(*current)->def_value = value_string;

} /* STag_string */

void ETag_string(void)
{
#line 105 "xmltree_read.act"

if (pcdata) {

  int len = strlen(pcdata);
  /* check length parameter */
  if ((*current)->length != len) {
    warning("incorrect length parameter for string\n");
    (*current)->length = len;
  }

  (*current)->string_value = (char *) malloc ((len+1) * sizeof(char));
  strcpy((*current)->string_value, pcdata);
}

(*(lastlist->root))->nb_elements++;

current = &((*current)->next);

} /* ETag_string */

void STag_complex(void)
{
#line 126 "xmltree_read.act"

*current = new_element();

if (A_complex_name) {
  (*current)->name = (char *) malloc(strlen(A_complex_name)+1);
  strcpy ((*current)->name, A_complex_name);
}

(*current)->def_value = value_complex;

lastlist = new_list(lastlist);
lastlist->root = current;
current = &((*current)->child);

} /* STag_complex */

void ETag_complex(void)
{
#line 141 "xmltree_read.act"

current = lastlist->root;
lastlist = pop_list(lastlist);

(*(lastlist->root))->nb_elements++;

current = &((*current)->next);

} /* ETag_complex */

void STag_array(void)
{
#line 152 "xmltree_read.act"

*current = new_element();

if (A_array_name) {
  (*current)->name = (char *) malloc(strlen(A_array_name)+1);
  strcpy ((*current)->name, A_array_name);
}

if (A_array_rows)
  (*current)->rows = strtol (A_array_rows, NULL, 10);

(*current)->def_value = value_array;

lastlist = new_list(lastlist);
lastlist->root = current;
current = &((*current)->child);

} /* STag_array */

void ETag_array(void)
{
#line 170 "xmltree_read.act"

/* check rows parameter */
if ((*(lastlist->root))->rows != (*(lastlist->root))->nb_elements) {
  warning("incorrect length parameter for array\n");
  (*(lastlist->root))->rows = (*(lastlist->root))->nb_elements;
}

current = lastlist->root;
lastlist = pop_list(lastlist);

(*(lastlist->root))->nb_elements++;

current = &((*current)->next);

} /* ETag_array */

void STag_matrix(void)
{
#line 187 "xmltree_read.act"

*current = new_element();

if (A_matrix_name) {
  (*current)->name = (char *) malloc(strlen(A_matrix_name)+1);
  strcpy ((*current)->name, A_matrix_name);
}

if (A_matrix_rows)
  (*current)->rows = strtol (A_matrix_rows, NULL, 10);

if (A_matrix_columns)
  (*current)->columns = strtol (A_matrix_columns, NULL, 10);

(*current)->def_value = value_matrix;

lastlist = new_list(lastlist);
lastlist->root = current;
current = &((*current)->child);

} /* STag_matrix */

void ETag_matrix(void)
{
#line 208 "xmltree_read.act"

/* check (rows, columns) parameters */
if ((*(lastlist->root))->rows * (*(lastlist->root))->columns != 
    (*(lastlist->root))->nb_elements) {
  warning("incorrect (rows, columns) parameters for matrix: reshaping matrix into vector\n");
  (*(lastlist->root))->rows = 1;
  (*(lastlist->root))->columns = (*(lastlist->root))->nb_elements;  
}

current = lastlist->root;
lastlist = pop_list(lastlist);

(*(lastlist->root))->nb_elements++;

current = &((*current)->next);

} /* ETag_matrix */

void STag_structure(void)
{
#line 227 "xmltree_read.act"

*current = new_element();

if (A_structure_name) {
  (*current)->name = (char *) malloc(strlen(A_structure_name)+1);
  strcpy ((*current)->name, A_structure_name);
}

(*current)->def_value = value_structure;

lastlist = new_list(lastlist);
lastlist->root = current;
current = &((*current)->child);

} /* STag_structure */

void ETag_structure(void)
{
#line 242 "xmltree_read.act"

/* no check possible (sic) */

current = lastlist->root;
lastlist = pop_list(lastlist);

(*(lastlist->root))->nb_elements++;

current = &((*current)->next);

} /* ETag_structure */

void STag_list(void)
{
#line 255 "xmltree_read.act"

*current = new_element();

if (A_list_name) {
  (*current)->name = (char *) malloc(strlen(A_list_name)+1);
  strcpy ((*current)->name, A_list_name);
}

if (A_list_length)
  (*current)->length = strtol (A_list_length, NULL, 10);

(*current)->def_value = value_list;

lastlist = new_list(lastlist);
lastlist->root = current;
current = &((*current)->child);

} /* STag_list */

void ETag_list(void)
{
#line 273 "xmltree_read.act"

/* check length parameter */
if ((*(lastlist->root))->length != (*(lastlist->root))->nb_elements) {
  warning("incorrect length parameter for list\n");
  (*(lastlist->root))->length = (*(lastlist->root))->nb_elements;
}

current = lastlist->root;
lastlist = pop_list(lastlist);

(*(lastlist->root))->nb_elements++;

current = &((*current)->next);

} /* ETag_list */

void STag_cell(void)
{
#line 290 "xmltree_read.act"

*current = new_element();

if (A_cell_name) {
  (*current)->name = (char *) malloc(strlen(A_cell_name)+1);
  strcpy ((*current)->name, A_cell_name);
}

if (A_cell_rows)
  (*current)->rows = strtol (A_cell_rows, NULL, 10);

if (A_cell_columns)
  (*current)->columns = strtol (A_cell_columns, NULL, 10);

(*current)->def_value = value_cell;

lastlist = new_list(lastlist);
lastlist->root = current;
current = &((*current)->child);

} /* STag_cell */

void ETag_cell(void)
{
#line 311 "xmltree_read.act"

/* check (rows, columns) parameters */
if ((*(lastlist->root))->rows * (*(lastlist->root))->columns != 
    (*(lastlist->root))->nb_elements) {
  warning("incorrect (rows, columns) parameters for cell: reshaping cell into list\n");
  (*(lastlist->root))->def_value = value_list;
  (*(lastlist->root))->length = (*(lastlist->root))->nb_elements;  
}

current = lastlist->root;
lastlist = pop_list(lastlist);

(*(lastlist->root))->nb_elements++;

current = &((*current)->next);

} /* ETag_cell */


#line 346 "xmltree_read.act"

element *read_xmltree (const char *file) {

  current = NULL;
  root = NULL;
  lastlist = NULL;

  xml_in = fopen(file, "r");
  if (!xml_in)
    perror("can't open file\n");

  xml_lex();
  fclose(xml_in);
  
  return root;
}


/* XML application entry points. */


syntax highlighted by Code2HTML, v. 0.9.1