Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Enable surfxml to live with an other xml parser in the same C code. Now dtd should...
[simgrid.git] / src / xbt / graphxml.l
1 /* Validating XML processor for graphxml.dtd.
2  * Generated 2006/03/21 11:12: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.46 2006/03/21 08:24:12 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.27 2006/03/21 08:24:12 legranda Exp $";
52 const char rcs_graphxml_flexml[] =
53  "$" "Id: flexml.pl,v 1.46 2006/03/21 08:24:12 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_edge_target A_graphxml_edge_target;
71 AT_graphxml_node_name A_graphxml_node_name;
72 AT_graphxml_node_label A_graphxml_node_label;
73 AT_graphxml_edge_label A_graphxml_edge_label;
74 AT_graphxml_edge_source A_graphxml_edge_source;
75 AT_graphxml_edge_isDirected A_graphxml_edge_isDirected;
76 AT_graphxml_edge_name A_graphxml_edge_name;
77
78 /* XML state. */
79 #ifdef FLEX_DEBUG
80 # define ENTER(state)   debug_enter(state,#state)
81 # define LEAVE          debug_leave()
82 # define SET(state)     debug_set(state,#state)
83   static void debug_enter(int, const char*);
84   static void debug_leave(void);
85   static void debug_set(int, const char*);
86 #else
87 # define ENTER(state)   (yy_push_state(state))
88 # define LEAVE          (yy_pop_state())
89 # define SET(state)     BEGIN(state)
90 #endif
91
92 /* Generic actions. */
93 #define SKIP    /*skip*/
94 #define SUCCEED        CLEANUP; return 0
95
96 #define FAIL    return fail
97 static int fail(const char*, ...);
98 const char * graphxml_parse_err_msg(void);
99
100 /* Cleanup */
101 static void cleanup(void);
102 #define CLEANUP  cleanup()
103
104 /* Text buffer stack handling. */
105 char bufferstack[FLEXML_BUFFERSTACKSIZE];
106 static char* limit = bufferstack + FLEXML_BUFFERSTACKSIZE;
107 typedef struct BufferLast_s {
108   struct BufferLast_s *old; char* saved; char new1[1];
109 } BufferLast;
110 #ifdef FLEXML_HasMixed
111 static BufferLast* last = (BufferLast*)0;
112 #endif
113 static char* next = bufferstack;
114
115 #define BUFFERSET(P)  (P = next)
116 #define BUFFERPUTC(C) (assert(next<limit), *(next++) = (C))
117 #define BUFFERDONE    (BUFFERPUTC('\0'))
118
119 #define BUFFERLITERAL(C,P) bufferliteral(C,&(P),yytext)
120 static void bufferliteral(char c, const char** pp, char* text)
121 {
122   char *s = strchr(text,c), *e = strrchr(text,c);
123   assert(s <= e); BUFFERSET(*pp);
124   while (++s<e) {
125     if (isspace(*s)) { BUFFERPUTC(' '); while (isspace(*s)) ++s; }
126     else BUFFERPUTC(*s);
127   }
128   BUFFERDONE;
129 }
130
131 #ifdef FLEXML_HasMixed
132 static void pushbuffer(char* p)
133 {
134   BufferLast* l = (BufferLast*)next;
135   assert(next < limit);
136   l->old = last;
137   l->saved = p;
138   next = l->new1;
139   last = l;
140 }
141
142 static char* popbuffer(void)
143 {
144   BufferLast* l = last;
145   assert(last != (BufferLast*)0);
146   last = l->old;
147   next = (char*)l;
148   return l->saved;
149 }
150 #endif
151
152 /* General internal entities are `unput' back onto the input stream... */
153 #define ENTITYTEXT(T) \
154   { char *s = (T), *e = s+strlen(s);\
155     while (--e >= s) { unput(*e); }}
156 %}
157
158 /* Flex standard options. */
159 %option stack
160 %option noyy_top_state
161 %option noinput
162 %option noreject
163 %option noyymore
164 %option noyywrap
165
166 /* Flex user-requested options. */
167 %option yylineno
168 %option nounput
169
170 /* XML character classes (currently restricted to ASCII). */
171
172 /* "Common syntactic structures." */
173 S               [ \t\n\r\f]+
174 s               [ \t\n\r\f]*
175
176 /* "Names and Tokens." */
177 NameChar        [A-Za-z0-9.:_-]
178 Name            [A-Za-z_:]{NameChar}*
179 Names           {Name}({S}{Name})*
180 Nmtoken         ({NameChar})+
181 Nmtokens        {Nmtoken}({S}{Nmtoken})*
182
183 /* Miscellaneous. */
184 VersionNum      [a-zA-Z0-9_.:-]+
185 Eq              {s}"="{s}
186 Literal         \'[^'']*\'|\"[^""]*\"
187
188 /* Parser states (flex `exclusive start conditions'):
189  *
190  * PROLOG       the XML prolog of the document before <?xml...>
191  * DOCTYPE      the XML prolog of the document after <?xml...>
192  * EPILOG       after the root element
193  * INCOMMENT    inside an XML comment <!--....-->
194  * INPI         inside an XML PI <?...?>
195  * VALUE1       inside a '...'-delimited literal
196  * VALUE2       inside a "..."-delimited literal
197  * CDATA        inside a <![CDATA[...]]> section.
198  * ROOT_<tag>   expect root element <tag>
199  * AL_<tag>     inside the attribute list for <tag>
200  * IN_<tag>     inside a <tag> with element contents (ready for end tag)
201  * IMPOSSIBLE   dummy to permit disabling rules; must be last
202  */
203 %x PROLOG DOCTYPE EPILOG INCOMMENT INPI VALUE1 VALUE2 CDATA
204 %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
205 %x ROOT_graphxml_node AL_graphxml_node E_graphxml_node
206 %x ROOT_graphxml_edge AL_graphxml_edge E_graphxml_edge
207 %x IMPOSSIBLE
208
209 %{
210 /* State names. */
211 const char* *graphxml_statenames=NULL;
212 %}
213
214 %%
215
216  /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */
217  SET(PROLOG);
218   /* FleXML_init */
219   next = bufferstack;
220   if(!graphxml_statenames) {graphxml_statenames= (const char **)calloc(IMPOSSIBLE,sizeof(char*));
221   graphxml_statenames[PROLOG] = NULL;
222   graphxml_statenames[DOCTYPE] = NULL;
223   graphxml_statenames[EPILOG] = NULL;
224   graphxml_statenames[INCOMMENT] = NULL;
225   graphxml_statenames[INPI] = NULL;
226   graphxml_statenames[VALUE1] = NULL;
227   graphxml_statenames[VALUE2] = NULL;
228   graphxml_statenames[CDATA] = NULL;
229   graphxml_statenames[ROOT_graphxml_graph] = NULL;
230   graphxml_statenames[AL_graphxml_graph] = NULL;
231   graphxml_statenames[S_graphxml_graph] = "graph";
232   graphxml_statenames[S_graphxml_graph_1] = "graph";
233   graphxml_statenames[S_graphxml_graph_2] = "graph";
234   graphxml_statenames[S_graphxml_graph_3] = "graph";
235   graphxml_statenames[S_graphxml_graph_4] = "graph";
236   graphxml_statenames[S_graphxml_graph_5] = "graph";
237   graphxml_statenames[E_graphxml_graph] = "graph";
238   graphxml_statenames[ROOT_graphxml_node] = NULL;
239   graphxml_statenames[AL_graphxml_node] = NULL;
240   graphxml_statenames[E_graphxml_node] = "node";
241   graphxml_statenames[ROOT_graphxml_edge] = NULL;
242   graphxml_statenames[AL_graphxml_edge] = NULL;
243   graphxml_statenames[E_graphxml_edge] = "edge";
244   }
245
246  /* COMMENTS and PIs: handled uniformly for efficiency. */
247
248 <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>{
249  "<!--" ENTER(INCOMMENT);
250  "<?" ENTER(INPI);
251 }
252 <INCOMMENT>{
253  "-->"          LEAVE;
254  "--"           |
255  .              |
256  \n             SKIP;
257  <<EOF>>        FAIL("EOF in comment.");
258 }
259 <INPI>{
260  "?>"           LEAVE;
261  .              |
262  \n             SKIP;
263  <<EOF>>        FAIL("EOF in PI (processing instruction).");
264 }
265
266  /* SPACES: skipped uniformly */
267
268 <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;
269
270  /* PROLOG: determine root element and process it. */
271
272 <PROLOG>{
273  "<?xml"({S}version{Eq}(\'{VersionNum}\'|\"{VersionNum}\"))?({S}encoding{Eq}(\'[^']*\'|\"[^"]*\"))?"?>" SET(DOCTYPE); 
274  "<?xml"[^>]*">" FAIL("Bad declaration %s.",yytext);
275 }
276
277 <PROLOG,DOCTYPE>{
278  "<!DOCTYPE"{S}"edge"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_graphxml_edge);
279  "<!DOCTYPE"{S}"node"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_graphxml_node);
280  "<!DOCTYPE"{S}"graph"{S}SYSTEM{S}("'graphxml.dtd'"|"\"graphxml.dtd\""){s}">" SET(ROOT_graphxml_graph);
281  "<!"[^>-][^>]*">" FAIL("Bad declaration %s.",yytext);
282  .              FAIL("Unexpected character `%c' in prolog.", yytext[0]);
283  <<EOF>>        FAIL("EOF in prolog.");
284 }
285
286  /* RULES DERIVED FROM DTD. */
287
288  /* <!-- Small DTD for xbt graphs. -->  */
289
290 <ROOT_graphxml_graph>"<graph"{s} {
291   ENTER(AL_graphxml_graph);
292   }
293
294 <AL_graphxml_graph>{
295  ">" {
296   LEAVE; STag_graphxml_graph();pcdata = NULL; ENTER(S_graphxml_graph);
297  }
298  "/>" {
299   LEAVE; STag_graphxml_graph(); pcdata = NULL; ETag_graphxml_graph();
300   switch (YY_START) {
301    case ROOT_graphxml_graph: SET(EPILOG); break;
302   }
303  }
304  .       FAIL("Unexpected character `%c' in attribute list of graph element.", yytext[0]);
305  {Name} FAIL("Bad attribute `%s' in `graph' element start tag.",yytext);
306  <<EOF>> FAIL("EOF in attribute list of `graph' element.");
307 }
308
309 <S_graphxml_graph_1,E_graphxml_graph,S_graphxml_graph_3,S_graphxml_graph_5,S_graphxml_graph>{
310  "</graph"{s}">" {
311   LEAVE;
312   ETag_graphxml_graph();
313   switch (YY_START) {
314    case ROOT_graphxml_graph: SET(EPILOG); break;
315   }
316  }
317  "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</graph>' expected.",yytext);
318  .       FAIL("Unexpected character `%c': `</graph>' expected.",yytext[0]);
319  <<EOF>> FAIL("Premature EOF: `</graph>' expected.");
320 }
321
322  /*     label           CDATA                ""
323   *     name            CDATA                #REQUIRED
324   * >  */
325
326 <ROOT_graphxml_node,S_graphxml_graph_2,S_graphxml_graph_3,S_graphxml_graph>"<node"{s} {
327   A_graphxml_node_label = NULL;
328   A_graphxml_node_name = NULL;
329   ENTER(AL_graphxml_node);
330   }
331
332 <AL_graphxml_node>{
333  "label"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_node_label);
334  "label"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_node_label);
335
336  "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_node_name);
337  "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_node_name);
338
339  ">" {
340   if (!A_graphxml_node_name) FAIL("Required attribute `name' not set for `node' element.");
341   LEAVE; STag_graphxml_node();pcdata = NULL; ENTER(E_graphxml_node);
342  }
343  "/>" {
344   if (!A_graphxml_node_name) FAIL("Required attribute `name' not set for `node' element.");
345   LEAVE; STag_graphxml_node(); pcdata = NULL; ETag_graphxml_node();
346   switch (YY_START) {
347    case S_graphxml_graph_2: case S_graphxml_graph_3: case S_graphxml_graph: SET(S_graphxml_graph_3); break;
348    case ROOT_graphxml_node: SET(EPILOG); break;
349   }
350  }
351  .       FAIL("Unexpected character `%c' in attribute list of node element.", yytext[0]);
352  {Name} FAIL("Bad attribute `%s' in `node' element start tag.",yytext);
353  <<EOF>> FAIL("EOF in attribute list of `node' element.");
354 }
355
356 <E_graphxml_node>{
357  "</node"{s}">" {
358   LEAVE;
359   ETag_graphxml_node();
360   switch (YY_START) {
361    case S_graphxml_graph_2: case S_graphxml_graph_3: case S_graphxml_graph: SET(S_graphxml_graph_3); break;
362    case ROOT_graphxml_node: SET(EPILOG); break;
363   }
364  }
365  "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</node>' expected.",yytext);
366  .       FAIL("Unexpected character `%c': `</node>' expected.",yytext[0]);
367  <<EOF>> FAIL("Premature EOF: `</node>' expected.");
368 }
369
370  /*     label           CDATA                ""
371   *     name       CDATA        #IMPLIED
372   *     source     CDATA        #REQUIRED
373   *     target     CDATA        #REQUIRED
374   *     isDirected (true|false) "true"
375   * >  */
376
377 <ROOT_graphxml_edge,S_graphxml_graph_1,S_graphxml_graph_3,S_graphxml_graph_5,S_graphxml_graph_4,S_graphxml_graph>"<edge"{s} {
378   A_graphxml_edge_label = NULL;
379   A_graphxml_edge_name = NULL;
380   A_graphxml_edge_source = NULL;
381   A_graphxml_edge_target = NULL;
382   A_graphxml_edge_isDirected = A_graphxml_edge_isDirected_true;
383   ENTER(AL_graphxml_edge);
384   }
385
386 <AL_graphxml_edge>{
387  "label"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_label);
388  "label"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_label);
389
390  "name"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_name);
391  "name"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_name);
392
393  "source"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_source);
394  "source"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_source);
395
396  "target"{Eq}\' ENTER(VALUE1); BUFFERSET(A_graphxml_edge_target);
397  "target"{Eq}\" ENTER(VALUE2); BUFFERSET(A_graphxml_edge_target);
398
399  "isDirected"{Eq}"'true'" |
400  "isDirected"{Eq}"\"true\"" A_graphxml_edge_isDirected = A_graphxml_edge_isDirected_true;
401  "isDirected"{Eq}"'false'" |
402  "isDirected"{Eq}"\"false\"" A_graphxml_edge_isDirected = A_graphxml_edge_isDirected_false;
403
404  ">" {
405   if (!A_graphxml_edge_source) FAIL("Required attribute `source' not set for `edge' element.");
406   if (!A_graphxml_edge_target) FAIL("Required attribute `target' not set for `edge' element.");
407   LEAVE; STag_graphxml_edge();pcdata = NULL; ENTER(E_graphxml_edge);
408  }
409  "/>" {
410   if (!A_graphxml_edge_source) FAIL("Required attribute `source' not set for `edge' element.");
411   if (!A_graphxml_edge_target) FAIL("Required attribute `target' not set for `edge' element.");
412   LEAVE; STag_graphxml_edge(); pcdata = NULL; ETag_graphxml_edge();
413   switch (YY_START) {
414    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;
415    case ROOT_graphxml_edge: SET(EPILOG); break;
416   }
417  }
418  .       FAIL("Unexpected character `%c' in attribute list of edge element.", yytext[0]);
419  {Name} FAIL("Bad attribute `%s' in `edge' element start tag.",yytext);
420  <<EOF>> FAIL("EOF in attribute list of `edge' element.");
421 }
422
423 <E_graphxml_edge>{
424  "</edge"{s}">" {
425   LEAVE;
426   ETag_graphxml_edge();
427   switch (YY_START) {
428    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;
429    case ROOT_graphxml_edge: SET(EPILOG); break;
430   }
431  }
432  "</"{Name}{s}">" FAIL("Unexpected end-tag `%s': `</edge>' expected.",yytext);
433  .       FAIL("Unexpected character `%c': `</edge>' expected.",yytext[0]);
434  <<EOF>> FAIL("Premature EOF: `</edge>' expected.");
435 }
436
437  /* EPILOG: after the root element. */
438
439 <EPILOG>{
440  . {SET(PROLOG); yyless(0); CLEANUP; return -1;}
441  <<EOF>>        SUCCEED;
442 }
443
444  /* CHARACTER DATA. */
445
446 <IMPOSSIBLE,VALUE1,VALUE2>{
447  /* Non-defined standard entities... */
448 "&amp;"  BUFFERPUTC('&');
449 "&lt;"   BUFFERPUTC('<');
450 "&gt;"   BUFFERPUTC('>');
451 "&apos;" BUFFERPUTC('\'');
452 "&quot;" BUFFERPUTC('"');
453
454  /* Character entities. */
455  "&#"[[:digit:]]+";"    BUFFERPUTC((unsigned char)atoi(yytext+2));
456  "&#x"[[:xdigit:]]+";"  BUFFERPUTC((unsigned char)strtol(yytext+3,NULL,16));
457 }
458
459 <IMPOSSIBLE,VALUE1,VALUE2,CDATA>{
460  "\n"           |
461  "\r"           |
462  "\r\n"         |
463  "\n\r"         BUFFERPUTC('\n');
464 }
465
466 <IMPOSSIBLE>{
467  "<![CDATA["    ENTER(CDATA);
468  "]""]>"                FAIL("Unexpected `]""]>' in character data.");
469 }
470
471 <VALUE1>{
472  \'             BUFFERDONE; LEAVE;
473  <<EOF>>        FAIL("EOF in literal (\"'\" expected).");
474 }
475
476 <VALUE2>{
477  \"             BUFFERDONE; LEAVE;
478  <<EOF>>        FAIL("EOF in literal (`\"' expected).");
479 }
480
481 <IMPOSSIBLE,VALUE1,VALUE2>{
482  [^<&]          BUFFERPUTC(yytext[0]);
483  [<&]           FAIL("Spurious `%c' in character data.",yytext[0]);
484 }
485
486 <CDATA>{
487  "]""]>"                LEAVE;
488  /* "]""]"              BUFFERPUTC(yytext[0]); BUFFERPUTC(yytext[1]); */
489  .              BUFFERPUTC(yytext[0]);
490  <<EOF>>        FAIL("EOF in CDATA section.");
491 }
492
493  /* Impossible rules to avoid warnings from flex(1). */
494  /* Ideally, this should be replaced by code in flexml.pl that
495     generates just the states not covered by other rules. */
496 <*>{
497  .|[\n] FAIL("Syntax error on character `%c'.", yytext[0]);
498 }
499
500 %%
501
502 /* Element context stack lookup. */
503 int graphxml_element_context(int i)
504 {
505   return (0<i && i<yy_start_stack_depth
506           ? yy_start_stack[yy_start_stack_ptr - i]
507           : 0);
508 }
509
510 #ifdef FLEX_DEBUG
511 void print_yy_stack(char* fmt, ...)
512 {
513   int i = 0; va_list ap; va_start(ap, fmt);
514   vfprintf(stderr, fmt, ap);
515   for (i=1; i<yy_start_stack_ptr; i++)
516     fprintf(stderr, "%s/", graphxml_statenames[yy_start_stack[i] ]);
517   fprintf(stderr,"%s\n", graphxml_statenames[YY_START]);
518   va_end(ap);
519 }
520
521 static void debug_enter(int state, const char* statename) {
522   yy_push_state(state);
523   if (yy_flex_debug) print_yy_stack("--ENTER(%s) : ",statename);
524 }
525
526 static void debug_leave(void) {
527   if (yy_flex_debug) print_yy_stack("--LEAVE : ");
528   yy_pop_state();
529 }
530
531 static void debug_set(int state, const char* statename) {
532   BEGIN(state);
533   if (yy_flex_debug) print_yy_stack("--SET(%s) : ",statename);
534 }
535 #endif
536
537 enum {flexml_max_err_msg_size = 512};
538
539 static char flexml_err_msg[flexml_max_err_msg_size];
540 const char * graphxml_parse_err_msg()
541 {
542     return flexml_err_msg;
543 }
544
545 static void reset_graphxml_parse_err_msg()
546 {
547     flexml_err_msg[0] = '\0';
548 }
549
550
551 static void cleanup(void)
552 {
553     if (graphxml_statenames) {
554         free(graphxml_statenames);
555         graphxml_statenames = NULL;
556     }
557 }
558
559
560 static int fail(const char* fmt, ...)
561 {
562     int chars_left, used;
563     va_list ap; va_start(ap, fmt);
564 #ifdef FLEXML_yylineno
565     used = sprintf(flexml_err_msg,
566                    "Invalid XML (XML input line %d, state %d): ",
567                    yylineno, YY_START);
568 #else
569     used = sprintf(flexml_err_msg,
570                    "Invalid XML (state %d): ",
571                    YY_START);
572 #endif
573     chars_left = flexml_max_err_msg_size - used - 1;
574     vsnprintf(flexml_err_msg + used, chars_left, fmt, ap);
575     va_end(ap);
576
577 #ifndef FLEXML_quiet_parser
578     /* print directly to sdterr */
579     fprintf(stderr, "%s\n", flexml_err_msg);
580     flexml_err_msg[0] = '\0';
581 #endif
582
583     cleanup();
584
585     return 1;
586 }