/* Flex(1) XML processor skeleton scanner (in -*-C-*-). * Copyright (C) 1999 Kristoffer Rose. All rights reserved. * * This file is part of the FleXML XML processor generator system. * Copyright (C) 1999 Kristoffer Rose. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * Note: Files generated by the FleXML system have fewer restrictions on them * as explained in the header of each generated file. */ %{ /* Version strings. */ const char rcs_flexml_skeleton[] = "$Id: skel,v 1.3 2012/01/02 13:42:35 mikeaubury Exp $"; FLEXML_VERSION /* ANSI headers. */ #include #include #include #include #include #include #undef YY_INPUT #define YY_INPUT(b,r,ms) (r=my_yyinput(b,ms)) #ifndef FLEXML_INDEXSTACKSIZE #define FLEXML_INDEXSTACKSIZE 1000 #endif /* Generated definitions. */ FLEXML_DEFINITIONS /* 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 CLEANUP; return 0 #define FAIL return fail static int fail(const char*, ...); enum {flexml_max_err_msg_size = 512}; static char flexml_err_msg[flexml_max_err_msg_size]; const char * parse_err_msg(void) { return flexml_err_msg; } static void reset_parse_err_msg(void) { flexml_err_msg[0] = '\0'; } /* Cleanup */ static void cleanup(void); #define CLEANUP cleanup() /* Text buffer stack handling. */ char *bufferstack = NULL; static int blimit = FLEXML_BUFFERSTACKSIZE; static int bnext = 1; static int *indexstack = NULL; static int ilimit = FLEXML_INDEXSTACKSIZE; static int inext = 1; #define BUFFERSET(P) (P = bnext) #define BUFFERPUTC(C) (ck_blimit(), bufferstack[bnext++] = (C)) #define BUFFERDONE (BUFFERPUTC('\0')) #define BUFFERLITERAL(C, P) bufferliteral(C, &(P), yytext) /* after this is called, there are at least 2 slots left in the stack */ static int ck_blimit(void) { if (bnext >= blimit) { blimit += FLEXML_BUFFERSTACKSIZE + 2; { char *temp = (char *) realloc(bufferstack, blimit); assert(temp); bufferstack = temp; } } return 0; } /* after this is called, there are at least 2 slots left in the stack */ static int ck_ilimit(void) { if (inext >= ilimit) { ilimit += FLEXML_INDEXSTACKSIZE + 2; { int *temp = (int *) realloc(indexstack, ilimit); assert(temp); indexstack = temp; } } return 0; } #ifdef FLEXML_NEED_BUFFERLIT static void bufferliteral(char c, int* pp, const char* text) { const char *s = (c ? strchr(text,c) : text-1), *e = strrchr(text,c); assert(s <= e); BUFFERSET(*pp); while (++s= 2); bnext = indexstack[--inext]; return indexstack[--inext]; } /* 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); }} FLEXML_INCLUDE_INIT_HEADER %} /* Flex standard options. */ %option stack %option noyy_top_state %option noinput %option noreject %option noyymore %option noyywrap /* Flex user-requested options. */ FLEXML_FLEX_OPTIONS /* 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 FLEXML_START_CONDITIONS %x IMPOSSIBLE FLEXML_EXTRA_DEFINITIONS %% /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */ SET(ROOT_TRIGGERED); reset_parse_err_msg(); bufferstack = (char *) malloc(FLEXML_BUFFERSTACKSIZE); assert(bufferstack); #ifdef FLEX_DEBUG { int i; for (i = 0; i < blimit; i++) { bufferstack[i] = '\377'; } } #endif bufferstack[0] = '\0'; indexstack = (int *) malloc(FLEXML_INDEXSTACKSIZE * sizeof(int)); assert(indexstack); indexstack[0] = 0; FLEXML_EXTRA_DEFINITIONS_INIT /* 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); } { FLEXML_DOCTYPES "-][^>]*">" FAIL("Bad declaration %s.",yytext); . FAIL("Unexpected character `%c' in prolog.", yytext[0]); <> FAIL("EOF in prolog."); } /* RULES DERIVED FROM DTD. */ FLEXML_RULES /* EPILOG: after the root element. */ { . {SET(PROLOG); yyless(0); CLEANUP; return -1;} <> SUCCEED; } /* CHARACTER DATA. */ { FLEXML_ENTITIES /* 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). */ /* Ideally, this should be replaced by code in flexml.pl that generates just the states not covered by other rules. */ <*>{ .|[\n] FAIL("Syntax error on character `%c'.", yytext[0]); } %% /* Element context stack lookup. */ int element_context(int i) { return (0