Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Extending the dtd
[simgrid.git] / src / xbt / graphxml.l
1 /* Validating XML processor for graphxml.dtd.
2  * Generated 2006/03/28 12:29:32.
3  *
4  * This program was generated with the FleXML XML processor generator.
5  * FleXML is Copyright © 1999-2005 Kristoffer Rose.  All rights reserved.
6  * (Id: flexml.pl,v 1.47 2006/03/21 11:12:57 legranda Exp).
7  * 
8  * There are two, intertwined parts to this program, part A and part B.
9  *
10  * Part A
11  * ------
12  * 
13  * Some parts, here collectively called "Part A", are found in the 
14  * FleXML package.  They are Copyright © 1999-2005 Kristoffer Rose. 
15  * All rights reserved.
16  *
17  * You can redistribute, use, perform, display and/or modify "Part A"
18  * provided the following two conditions hold:
19  *
20  * 1. The program is distributed WITHOUT ANY WARRANTY from the author of
21  *    FleXML; without even the implied warranty of MERCHANTABILITY or
22  *    FITNESS FOR A PARTICULAR PURPOSE.
23  *
24  * 2. The program distribution conditions do not in any way affect the
25  *    distribution conditions of the FleXML system used to generate this
26  *    file or any version of FleXML derived from that system.
27  *
28  * Notice that these are explicit rights granted to you for files
29  * generated by the FleXML system.  For your rights in connection with
30  * the FleXML system itself please consult the GNU General Public License.
31  * 
32  * Part B
33  * ------
34  * 
35  * The other parts, here collectively called "Part B", and which came 
36  * from the DTD used by FleXML to generate this program, can be 
37  * distributed (or not, as the case may be) under the terms of whoever
38  * wrote them, provided these terms respect and obey the two conditions 
39  * above under the heading "Part A".
40  *
41  * The author of and contributors to FleXML specifically disclaim
42  * any copyright interest in "Part B", unless "Part B" was written 
43  * by the author of or contributors to FleXML.
44  * 
45  */
46
47 %{
48
49 /* Version strings. */
50 const char rcs_graphxml_flexml_skeleton[] =
51  "$" "Id: skel,v 1.28 2006/03/21 12:04:13 legranda Exp $";
52 const char rcs_graphxml_flexml[] =
53  "$" "Id: flexml.pl,v 1.47 2006/03/21 11:12:57 legranda Exp $";
54
55 /* ANSI headers. */
56 #include <unistd.h>
57 #include <stdio.h>
58 #include <string.h>
59 #include <assert.h>
60 #include <stdarg.h>
61 #include <ctype.h>
62
63 /* Generated definitions. */
64 #define FLEXML_yylineno
65 #define FLEXML_BUFFERSTACKSIZE 1000000
66
67 /* XML processor api. */
68 /* FleXML-provided data. */
69 const char* pcdata;
70 AT_graphxml_node_name A_graphxml_node_name;
71 AT_graphxml_edge_source A_graphxml_edge_source;
72 AT_graphxml_node_position_y A_graphxml_node_position_y;
73 AT_graphxml_node_position_x A_graphxml_node_position_x;
74 AT_graphxml_edge_data A_graphxml_edge_data;
75 AT_graphxml_edge_target A_graphxml_edge_target;
76 AT_graphxml_graph_isDirected A_graphxml_graph_isDirected;
77 AT_graphxml_node_label A_graphxml_node_label;
78 AT_graphxml_node_data A_graphxml_node_data;
79 AT_graphxml_edge_label A_graphxml_edge_label;
80 AT_graphxml_edge_length A_graphxml_edge_length;
81 AT_graphxml_edge_name A_graphxml_edge_name;
82
83 /* XML state. */
84 #ifdef FLEX_DEBUG
85 # define ENTER(state)   debug_enter(state,#state)
86 # define LEAVE          debug_leave()
87 # define SET(state)     debug_set(state,#state)
88   static void debug_enter(int, const char*);
89   static void debug_leave(void);
90   static void debug_set(int, const char*);
91 #else
92 # define ENTER(state)   (yy_push_state(state))
93 # define LEAVE          (yy_pop_state())
94 # define SET(state)     BEGIN(state)
95 #endif
96
97 /* Generic actions. */
98 #define SKIP    /*skip*/
99 #define SUCCEED        CLEANUP; return 0
100
101 #define FAIL    return fail
102 static int fail(const char*, ...);
103 const char * graphxml_parse_err_msg(void);
104
105 /* Cleanup */
106 static void cleanup(void);
107 #define CLEANUP  cleanup()
108
109 /* Text buffer stack handling. */
110 char bufferstack[FLEXML_BUFFERSTACKSIZE];
111 static char* limit = bufferstack + FLEXML_BUFFERSTACKSIZE;
112 typedef struct BufferLast_s {
113   struct BufferLast_s *old; char* saved; char new1[1];
114 } BufferLast;
115 #ifdef FLEXML_HasMixed
116 static BufferLast* last = (BufferLast*)0;
117 #endif
118 static char* next = bufferstack;
119
120 #define BUFFERSET(P)  (P = next)
121 #define BUFFERPUTC(C) (assert(next<limit), *(next++) = (C))
122 #define BUFFERDONE    (BUFFERPUTC('\0'))
123
124 #define BUFFERLITERAL(C,P) bufferliteral(C,&(P),yytext)
125 static void bufferliteral(char c, const char** pp, char* text)
126 {
127   char *s = strchr(text,c), *e = strrchr(text,c);
128   assert(s <= e); BUFFERSET(*pp);
129   while (++s<e) {
130     if (isspace(*s)) { BUFFERPUTC(' '); while (isspace(*s)) ++s; }
131     else BUFFERPUTC(*s);
132   }
133   BUFFERDONE;
134 }
135
136 #ifdef FLEXML_HasMixed
137 static void pushbuffer(char* p)
138 {
139   BufferLast* l = (BufferLast*)next;
140   assert(next < limit);
141   l->old = last;
142   l->saved = p;
143   next = l->new1;
144   last = l;
145 }
146
147 static char* popbuffer(void)
148 {
149   BufferLast* l = last;
150   assert(last != (BufferLast*)0);
151   last = l->old;
152   next = (char*)l;
153   return l->saved;
154 }
155 #endif
156
157 /* General internal entities are `unput' back onto the input stream... */
158 #define ENTITYTEXT(T) \
159   { char *s = (T), *e = s+strlen(s);\
160     while (--e >= s) { unput(*e); }}
161 %}
162
163 /* Flex standard options. */
164 %option stack
165 %option noyy_top_state
166 %option noinput
167 %option noreject
168 %option noyymore
169 %option noyywrap
170
171 /* Flex user-requested options. */
172 %option yylineno
173 %option nounput
174
175 /* XML character classes (currently restricted to ASCII). */
176
177 /* "Common syntactic structures." */
178 S               [ \t\n\r\f]+
179 s               [ \t\n\r\f]*
180
181 /* "Names and Tokens." */
182 NameChar        [A-Za-z0-9.:_-]
183 Name            [A-Za-z_:]{NameChar}*
184 Names           {Name}({S}{Name})*
185 Nmtoken         ({NameChar})+
186 Nmtokens        {Nmtoken}({S}{Nmtoken})*
187
188 /* Miscellaneous. */
189 VersionNum      [a-zA-Z0-9_.:-]+
190 Eq              {s}"="{s}
191 Literal         \'[^'']*\'|\"[^""]*\"
192
193 /* Parser states (flex `exclusive start conditions'):
194  *
195  * PROLOG       the XML prolog of the document before <?xml...>
196  * DOCTYPE      the XML prolog of the document after <?xml...>
197  * EPILOG       after the root element
198  * INCOMMENT    inside an XML comment <!--....-->
199  * INPI         inside an XML PI <?...?>
200  * VALUE1       inside a '...'-delimited literal
201  * VALUE2       inside a "..."-delimited literal
202  * CDATA        inside a <![CDATA[...] ]> section.
203  * ROOT_<tag>   expect root element <tag>
204  * AL_<tag>     inside the attribute list for <tag>
205  * IN_<tag>     inside a <tag> with element contents (ready for end tag)
206  * IMPOSSIBLE   dummy to permit disabling rules; must be last
207  */
208 %x PROLOG DOCTYPE EPILOG INCOMMENT INPI VALUE1 VALUE2 CDATA
209 %x ROOT_graphxml_graph AL_graphxml_graph S_graphxml_graph S_graphxml_graph_1 S_graphxml_graph_2 S_graphxml_graph_3 S_graphxml_graph_4 S_graphxml_graph_5 E_graphxml_graph
210 %x ROOT_graphxml_node AL_graphxml_node E_graphxml_node
211 %x ROOT_graphxml_edge AL_graphxml_edge E_graphxml_edge
212 %x IMPOSSIBLE
213
214 %{
215 /* State names. */
216 const char* *graphxml_statenames=NULL;
217 %}
218
219 %%
220
221  /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */
222  SET(PROLOG);
223   /* FleXML_init */
224   next = bufferstack;
225   if(!graphxml_statenames) {graphxml_statenames= (const char **)calloc(IMPOSSIBLE,sizeof(char*));
226   graphxml_statenames[PROLOG] = NULL;
227   graphxml_statenames[DOCTYPE] = NULL;
228   graphxml_statenames[EPILOG] = NULL;
229   graphxml_statenames[INCOMMENT] = NULL;
230   graphxml_statenames[INPI] = NULL;
231   graphxml_statenames[VALUE1] = NULL;
232   graphxml_statenames[VALUE2] = NULL;
233   graphxml_statenames[CDATA] = NULL;
234   graphxml_statenames[ROOT_graphxml_graph] = NULL;
235   graphxml_statenames[AL_graphxml_graph] = NULL;
236   graphxml_statenames[S_graphxml_graph] = "graph";
237   graphxml_statenames[S_graphxml_graph_1] = "graph";
238   graphxml_statenames[S_graphxml_graph_2] = "graph";
239   graphxml_statenames[S_graphxml_graph_3] = "graph";
240   graphxml_statenames[S_graphxml_graph_4] = "graph";
241   graphxml_statenames[S_graphxml_graph_5] = "graph";
242   graphxml_statenames[E_graphxml_graph] = "graph";
243   graphxml_statenames[ROOT_graphxml_node] = NULL;
244   graphxml_statenames[AL_graphxml_node] = NULL;
245   graphxml_statenames[E_graphxml_node] = "node";
246   graphxml_statenames[ROOT_graphxml_edge] = NULL;
247   graphxml_statenames[AL_graphxml_edge] = NULL;
248   graphxml_statenames[E_graphxml_edge] = "edge";
249   }
250
251  /* COMMENTS and PIs: handled uniformly for efficiency. */
252
253 <ROOT_graphxml_graph,AL_graphxml_graph,S_graphxml_graph,S_graphxml_graph_1,S_graphxml_graph_2,S_graphxml_graph_3,S_graphxml_graph_4,S_graphxml_graph_5,E_graphxml_graph,ROOT_graphxml_node,AL_graphxml_node,E_graphxml_node,ROOT_graphxml_edge,AL_graphxml_edge,E_graphxml_edge,PROLOG,DOCTYPE,EPILOG>{
254  "<!--" ENTER(INCOMMENT);
255  "<?" ENTER(INPI);
256 }
257 <INCOMMENT>{
258  "-->"          LEAVE;
259  "--"           |
260  .              |
261  \n             SKIP;
262  <<EOF>>        FAIL("EOF in comment.");
263 }
264 <INPI>{
265  "?>"           LEAVE;
266  .              |
267  \n             SKIP;
268  <<EOF>>        FAIL("EOF in PI (processing instruction).");
269 }
270
271  /* SPACES: skipped uniformly */
272
273 <ROOT_graphxml_graph,AL_graphxml_graph,S_graphxml_graph,S_graphxml_graph_1,S_graphxml_graph_2,S_graphxml_graph_3,S_graphxml_graph_4,S_graphxml_graph_5,E_graphxml_graph,ROOT_graphxml_node,AL_graphxml_node,E_graphxml_node,ROOT_graphxml_edge,AL_graphxml_edge,E_graphxml_edge,PROLOG,DOCTYPE,EPILOG>{S} SKIP;
274
275  /* PROLOG: determine root element and process it. */
276
277 <PROLOG>{
278  "<?xml"({S}version{Eq}(\'{VersionNum}\'|\"{VersionNum}\"))?({S}encoding{Eq}(\'[^']*\'|\"[^"]*\"))?"?>" SET(DOCTYPE); 
279  "<?xml"[^>]*">" FAIL("Bad declaration %s.",yytext);
280 }
281
282 <PROLOG,DOCTYPE>{
283  "<!DOCTYPE"{S}"edge"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_graphxml_edge);
284  "<!DOCTYPE"{S}"node"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_graphxml_node);
285  "<!DOCTYPE"{S}"graph"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_graphxml_graph);
286  "<!"[^>-][^>]*">" FAIL("Bad declaration %s.",yytext);
287  .              FAIL("Unexpected character `%c' in prolog.", yytext[0]);
288  <<EOF>>        FAIL("EOF in prolog.");
289 }
290
291  /* RULES DERIVED FROM DTD. */
292
293  /* <!-- Small DTD for xbt graphs. -->  */
294
295  /*     isDirected (true|false) "true"
296   * >  */
297
298 <ROOT_graphxml_graph>"<graph"{s} {
299   A_graphxml_graph_isDirected = A_graphxml_graph_isDirected_true;
300   ENTER(AL_graphxml_graph);
301   }
302
303 <AL_graphxml_graph>{
304  "isDirected"{Eq}"'true'" |
305  "isDirected"{Eq}"\"true\"" A_graphxml_graph_isDirected = A_graphxml_graph_isDirected_true;
306  "isDirected"{Eq}"'false'" |
307  "isDirected"{Eq}"\"false\"" A_graphxml_graph_isDirected = A_graphxml_graph_isDirected_false;
308
309  ">" {
310   LEAVE; STag_graphxml_graph();pcdata = NULL; ENTER(S_graphxml_graph);
311  }
312  "/>" {
313   LEAVE; STag_graphxml_graph(); pcdata = NULL; ETag_graphxml_graph();
314   switch (YY_START) {
315    case ROOT_graphxml_graph: SET(EPILOG); break;
316   }
317  }
318  .       FAIL("Unexpected character `%c' in attribute list of graph element.", yytext[0]);
319  {Name} FAIL("Bad attribute `%s' in `graph' element start tag.",yytext);
320  <<EOF>> FAIL("EOF in attribute list of `graph' element.");
321 }
322
323 <S_graphxml_graph_1,E_graphxml_graph,S_graphxml_graph_3,S_graphxml_graph_5,S_graphxml_graph>{
324  "</graph"{s}">" {
325   LEAVE;
326   ETag_graphxml_graph();
327   switch (YY_START) {
328    case ROOT_graphxml_graph: SET(EPILOG); break;
329   }
330  }
331  "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</graph>' expected.",yytext);
332  .       FAIL("Unexpected character `%c': `</graph>' expected.",yytext[0]);
333  <<EOF>> FAIL("Premature EOF: `</graph>' expected.");
334 }
335
336  /*     label           CDATA                ""
337   *     name            CDATA                #REQUIRED
338   *     data            CDATA                ""
339   *     position_x          CDATA                "-1.0"
340   *     position_y          CDATA                "-1.0"
341   * >  */
342
343 <ROOT_graphxml_node,S_graphxml_graph_2,S_graphxml_graph_3,S_graphxml_graph>"<node"{s} {
344   A_graphxml_node_label = NULL;
345   A_graphxml_node_name = NULL;
346   A_graphxml_node_data = NULL;
347   A_graphxml_node_position_x = "-1.0";
348   A_graphxml_node_position_y = "-1.0";
349   ENTER(AL_graphxml_node);
350   }
351
352 <AL_graphxml_node>{
353  "label"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_node_label);
354  "label"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_node_label);
355
356  "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_node_name);
357  "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_node_name);
358
359  "data"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_node_data);
360  "data"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_node_data);
361
362  "position_x"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_node_position_x);
363  "position_x"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_node_position_x);
364
365  "position_y"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_node_position_y);
366  "position_y"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_node_position_y);
367
368  ">" {
369   if (!A_graphxml_node_name) FAIL("Required attribute `name' not set for `node' element.");
370   LEAVE; STag_graphxml_node();pcdata = NULL; ENTER(E_graphxml_node);
371  }
372  "/>" {
373   if (!A_graphxml_node_name) FAIL("Required attribute `name' not set for `node' element.");
374   LEAVE; STag_graphxml_node(); pcdata = NULL; ETag_graphxml_node();
375   switch (YY_START) {
376    case S_graphxml_graph_2: case S_graphxml_graph_3: case S_graphxml_graph: SET(S_graphxml_graph_3); break;
377    case ROOT_graphxml_node: SET(EPILOG); break;
378   }
379  }
380  .       FAIL("Unexpected character `%c' in attribute list of node element.", yytext[0]);
381  {Name} FAIL("Bad attribute `%s' in `node' element start tag.",yytext);
382  <<EOF>> FAIL("EOF in attribute list of `node' element.");
383 }
384
385 <E_graphxml_node>{
386  "</node"{s}">" {
387   LEAVE;
388   ETag_graphxml_node();
389   switch (YY_START) {
390    case S_graphxml_graph_2: case S_graphxml_graph_3: case S_graphxml_graph: SET(S_graphxml_graph_3); break;
391    case ROOT_graphxml_node: SET(EPILOG); break;
392   }
393  }
394  "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</node>' expected.",yytext);
395  .       FAIL("Unexpected character `%c': `</node>' expected.",yytext[0]);
396  <<EOF>> FAIL("Premature EOF: `</node>' expected.");
397 }
398
399  /*     label           CDATA                ""
400   *     name            CDATA               #IMPLIED
401   *     source          CDATA               #REQUIRED
402   *     target          CDATA               #REQUIRED
403   *     length          CDATA               "-1.0"
404   *     data            CDATA               ""
405   * >  */
406
407 <ROOT_graphxml_edge,S_graphxml_graph_1,S_graphxml_graph_3,S_graphxml_graph_5,S_graphxml_graph_4,S_graphxml_graph>"<edge"{s} {
408   A_graphxml_edge_label = NULL;
409   A_graphxml_edge_name = NULL;
410   A_graphxml_edge_source = NULL;
411   A_graphxml_edge_target = NULL;
412   A_graphxml_edge_length = "-1.0";
413   A_graphxml_edge_data = NULL;
414   ENTER(AL_graphxml_edge);
415   }
416
417 <AL_graphxml_edge>{
418  "label"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_label);
419  "label"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_label);
420
421  "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_name);
422  "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_name);
423
424  "source"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_source);
425  "source"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_source);
426
427  "target"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_target);
428  "target"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_target);
429
430  "length"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_length);
431  "length"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_length);
432
433  "data"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_data);
434  "data"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_data);
435
436  ">" {
437   if (!A_graphxml_edge_source) FAIL("Required attribute `source' not set for `edge' element.");
438   if (!A_graphxml_edge_target) FAIL("Required attribute `target' not set for `edge' element.");
439   LEAVE; STag_graphxml_edge();pcdata = NULL; ENTER(E_graphxml_edge);
440  }
441  "/>" {
442   if (!A_graphxml_edge_source) FAIL("Required attribute `source' not set for `edge' element.");
443   if (!A_graphxml_edge_target) FAIL("Required attribute `target' not set for `edge' element.");
444   LEAVE; STag_graphxml_edge(); pcdata = NULL; ETag_graphxml_edge();
445   switch (YY_START) {
446    case S_graphxml_graph_1: case S_graphxml_graph_3: case S_graphxml_graph_5: case S_graphxml_graph_4: case S_graphxml_graph: SET(S_graphxml_graph_5); break;
447    case ROOT_graphxml_edge: SET(EPILOG); break;
448   }
449  }
450  .       FAIL("Unexpected character `%c' in attribute list of edge element.", yytext[0]);
451  {Name} FAIL("Bad attribute `%s' in `edge' element start tag.",yytext);
452  <<EOF>> FAIL("EOF in attribute list of `edge' element.");
453 }
454
455 <E_graphxml_edge>{
456  "</edge"{s}">" {
457   LEAVE;
458   ETag_graphxml_edge();
459   switch (YY_START) {
460    case S_graphxml_graph_1: case S_graphxml_graph_3: case S_graphxml_graph_5: case S_graphxml_graph_4: case S_graphxml_graph: SET(S_graphxml_graph_5); break;
461    case ROOT_graphxml_edge: SET(EPILOG); break;
462   }
463  }
464  "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</edge>' expected.",yytext);
465  .       FAIL("Unexpected character `%c': `</edge>' expected.",yytext[0]);
466  <<EOF>> FAIL("Premature EOF: `</edge>' expected.");
467 }
468
469  /* EPILOG: after the root element. */
470
471 <EPILOG>{
472  . {SET(PROLOG); yyless(0); CLEANUP; return -1;}
473  <<EOF>>        SUCCEED;
474 }
475
476  /* CHARACTER DATA. */
477
478 <IMPOSSIBLE,VALUE1,VALUE2>{
479  /* Non-defined standard entities... */
480 "&amp;"  BUFFERPUTC('&');
481 "&lt;"   BUFFERPUTC('<');
482 "&gt;"   BUFFERPUTC('>');
483 "&apos;" BUFFERPUTC('\'');
484 "&quot;" BUFFERPUTC('"');
485
486  /* Character entities. */
487  "&#"[[:digit:]]+";"    BUFFERPUTC((unsigned char)atoi(yytext+2));
488  "&#x"[[:xdigit:]]+";"  BUFFERPUTC((unsigned char)strtol(yytext+3,NULL,16));
489 }
490
491 <IMPOSSIBLE,VALUE1,VALUE2,CDATA>{
492  "\n"           |
493  "\r"           |
494  "\r\n"         |
495  "\n\r"         BUFFERPUTC('\n');
496 }
497
498 <IMPOSSIBLE>{
499  "<![CDATA["    ENTER(CDATA);
500  "]""]>"                FAIL("Unexpected `]""]>' in character data.");
501 }
502
503 <VALUE1>{
504  \'             BUFFERDONE; LEAVE;
505  <<EOF>>        FAIL("EOF in literal (\"'\" expected).");
506 }
507
508 <VALUE2>{
509  \"             BUFFERDONE; LEAVE;
510  <<EOF>>        FAIL("EOF in literal (`\"' expected).");
511 }
512
513 <IMPOSSIBLE,VALUE1,VALUE2>{
514  [^<&]          BUFFERPUTC(yytext[0]);
515  [<&]           FAIL("Spurious `%c' in character data.",yytext[0]);
516 }
517
518 <CDATA>{
519  "]""]>"                LEAVE;
520  /* "]""]"              BUFFERPUTC(yytext[0]); BUFFERPUTC(yytext[1]); */
521  .              BUFFERPUTC(yytext[0]);
522  <<EOF>>        FAIL("EOF in CDATA section.");
523 }
524
525  /* Impossible rules to avoid warnings from flex(1). */
526  /* Ideally, this should be replaced by code in flexml.pl that
527     generates just the states not covered by other rules. */
528 <*>{
529  .|[\n] FAIL("Syntax error on character `%c'.", yytext[0]);
530 }
531
532 %%
533
534 /* Element context stack lookup. */
535 int graphxml_element_context(int i)
536 {
537   return (0<i && i<yy_start_stack_depth
538           ? yy_start_stack[yy_start_stack_ptr - i]
539           : 0);
540 }
541
542 #ifdef FLEX_DEBUG
543 void print_yy_stack(char* fmt, ...)
544 {
545   int i = 0; va_list ap; va_start(ap, fmt);
546   vfprintf(stderr, fmt, ap);
547   for (i=1; i<yy_start_stack_ptr; i++)
548     fprintf(stderr, "%s/", graphxml_statenames[yy_start_stack[i] ]);
549   fprintf(stderr,"%s\n", graphxml_statenames[YY_START]);
550   va_end(ap);
551 }
552
553 static void debug_enter(int state, const char* statename) {
554   yy_push_state(state);
555   if (yy_flex_debug) print_yy_stack("--ENTER(%s) : ",statename);
556 }
557
558 static void debug_leave(void) {
559   if (yy_flex_debug) print_yy_stack("--LEAVE : ");
560   yy_pop_state();
561 }
562
563 static void debug_set(int state, const char* statename) {
564   BEGIN(state);
565   if (yy_flex_debug) print_yy_stack("--SET(%s) : ",statename);
566 }
567 #endif
568
569 enum {flexml_max_err_msg_size = 512};
570
571 static char flexml_err_msg[flexml_max_err_msg_size];
572 const char * graphxml_parse_err_msg()
573 {
574     return flexml_err_msg;
575 }
576
577 static void reset_graphxml_parse_err_msg()
578 {
579     flexml_err_msg[0] = '\0';
580 }
581
582
583 static void cleanup(void)
584 {
585     if (graphxml_statenames) {
586         free(graphxml_statenames);
587         graphxml_statenames = NULL;
588     }
589 }
590
591
592 static int fail(const char* fmt, ...)
593 {
594     int chars_left, used;
595     va_list ap; va_start(ap, fmt);
596 #ifdef FLEXML_yylineno
597     used = sprintf(flexml_err_msg,
598                    "Invalid XML (XML input line %d, state %d): ",
599                    yylineno, YY_START);
600 #else
601     used = sprintf(flexml_err_msg,
602                    "Invalid XML (state %d): ",
603                    YY_START);
604 #endif
605     chars_left = flexml_max_err_msg_size - used - 1;
606     vsnprintf(flexml_err_msg + used, chars_left, fmt, ap);
607     va_end(ap);
608
609 #ifndef FLEXML_quiet_parser
610     /* print directly to sdterr */
611     fprintf(stderr, "%s\n", flexml_err_msg);
612     flexml_err_msg[0] = '\0';
613 #endif
614
615     cleanup();
616
617     return 1;
618 }