head	1.16;
access;
symbols;
locks; strict;
comment	@# @;


1.16
date	99.12.09.04.01.51;	author krisrose;	state Exp;
branches;
next	1.15;

1.15
date	99.12.06.21.08.09;	author krisrose;	state Exp;
branches;
next	1.14;

1.14
date	99.12.03.23.24.40;	author krisrose;	state Exp;
branches;
next	1.13;

1.13
date	99.12.03.02.08.56;	author krisrose;	state Exp;
branches;
next	1.12;

1.12
date	99.12.01.03.41.19;	author krisrose;	state Exp;
branches;
next	1.11;

1.11
date	99.11.30.18.28.23;	author krisrose;	state Exp;
branches;
next	1.10;

1.10
date	99.11.29.16.09.02;	author krisrose;	state Exp;
branches;
next	1.9;

1.9
date	99.11.25.18.42.03;	author krisrose;	state Exp;
branches;
next	1.8;

1.8
date	99.11.25.03.01.47;	author krisrose;	state Exp;
branches;
next	1.7;

1.7
date	99.11.23.10.10.36;	author krisrose;	state Exp;
branches;
next	;


desc
@Moved from flexml.skel
@


1.16
log
@Ready for Xtech2000 submission.
@
text
@/* Flex(1) XML processor skeleton scanner (in -*-C-*-).
 * Copyright  1999 Kristoffer Rose.  All rights reserved.
 * 
 * This file is part of the FleXML XML processor generator system.
 * Copyright  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.15 1999/12/06 21:08:09 krisrose Exp krisrose $";
FLEXML_VERSION

/* ANSI headers. */
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <ctype.h>

/* 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, 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. */
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 <?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
FLEXML_START_CONDITIONS
%x IMPOSSIBLE

FLEXML_EXTRA_DEFINITIONS

%%

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

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

<FLEXML_COMMENTS,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 */

<FLEXML_NON_MIXED,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>{
FLEXML_DOCTYPES
 "<!"[^>-][^>]*">" FAIL("Bad declaration %s.",yytext);
 . 		FAIL("Unexpected character `%c' in prolog.", yytext[0]);
 <<EOF>> 	FAIL("EOF in prolog.");
}

 /* RULES DERIVED FROM DTD. */
FLEXML_RULES

 /* EPILOG: after the root element. */

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

 /* CHARACTER DATA. */

<FLEXML_MIXED,VALUE1,VALUE2>{
FLEXML_ENTITIES

 /* Character entities. */
 "&#"[[:digit:]]+";"	BUFFERPUTC((unsigned char)atoi(yytext+2));
 "&#x"[[:xdigit:]]+";"	BUFFERPUTC((unsigned char)strtol(yytext+3,NULL,16));
}

<FLEXML_MIXED,VALUE1,VALUE2,CDATA>{
 "\n"		|
 "\r"		|
 "\r\n"		|
 "\n\r"		BUFFERPUTC('\n');
}

<FLEXML_MIXED>{
 "<![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).");
}

<FLEXML_MIXED,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;
}
@


1.15
log
@Releasing.
@
text
@d21 2
a22 1
 * Note: FleXML depends on the following line.
d28 1
a28 1
 "$Id: skel,v 1.14 1999/12/03 23:24:40 krisrose Exp krisrose $";
@


1.14
log
@Can now generate validating processors for XHTML!
@
text
@d27 1
a27 1
 "$Id: skel,v 1.13 1999/12/03 02:08:56 krisrose Exp krisrose $";
d42 1
a42 1
#ifdef DEBUG
d59 2
a60 4
#ifndef FLEXML_NOFAIL
# define FAIL	return fail
  static int fail(const char*, ...);
#endif
d277 1
a277 1
#ifdef DEBUG
a304 1
#ifndef FLEXML_NOFAIL
a317 1
#endif
@


1.13
log
@Compiles xhtml.dtd!
@
text
@d27 1
a27 1
 "$Id: skel,v 1.12 1999/12/01 03:41:19 krisrose Exp krisrose $";
d150 2
a151 1
 * COMMENT	inside an XML comment <!--....-->
d160 1
a160 1
%x PROLOG DOCTYPE EPILOG COMMENT VALUE1 VALUE2 CDATA
d171 1
a171 1
 /* COMMENTS: handled uniformly for efficiency. */
d173 5
a177 2
<FLEXML_COMMENTS,PROLOG,DOCTYPE,EPILOG>"<!--" ENTER(COMMENT);
<COMMENT>{
d180 2
a181 1
 .		SKIP;
d184 6
d193 1
a193 1
<FLEXML_NON_MIXED,COMMENT,PROLOG,DOCTYPE,EPILOG>{S} SKIP;
@


1.12
log
@Works (still needs testing, though... :).
@
text
@d27 1
a27 1
 "$Id: skel,v 1.11 1999/11/30 18:28:23 krisrose Exp krisrose $";
a42 1

d44 2
a46 2

# define LEAVE		debug_leave()
a47 2

# define SET(state)	debug_set(state,#state)
a48 1

d73 1
a73 1
#define BUFFERSET(P) (P = next)
d77 11
a87 8
#define BUFFERLITERAL(C,P) \
  { char *s = strchr(yytext,C), *e = strrchr(yytext,C); \
    assert(s <= e); BUFFERSET(P); \
    while (++s<e) { \
      if (isspace(*s)) { BUFFERPUTC(' '); while (isspace(*s)) ++s; } \
      else BUFFERPUTC(*s); \
    } \
    BUFFERDONE; }
a211 7

 /* Standard entities. */
 "&amp;" 	BUFFERPUTC('&');
 "&lt;" 	BUFFERPUTC('<');
 "&gt;" 	BUFFERPUTC('>');
 "&apos;" 	BUFFERPUTC('\'');
 "&quot;" 	BUFFERPUTC('\"');
@


1.11
log
@Full DTD parsing almost done...still some nitty-gritty, though.
@
text
@d27 1
a27 1
 "$Id: skel,v 1.10 1999/11/29 16:09:02 krisrose Exp krisrose $";
d43 10
a52 8
  int print_yy_stack(char*);
# define ENTER(state)	(yy_push_state(state),\
                         yy_flex_debug && print_yy_stack("--ENTER(" #state ") : "))

# define LEAVE		(yy_flex_debug && print_yy_stack("--LEAVE : "),\
                         yy_pop_state())
# define SET(state)	(BEGIN(state),\
                         yy_flex_debug && print_yy_stack("--SET(" #state ") : "))
a60 1
#define FAIL	return fail
d63 3
a65 7
static int fail(const char* fmt, ...)
{
  va_list ap; va_start(ap, fmt);
#ifdef FLEXML_yylineno
  fprintf(stderr, "Invalid XML (XML input line %d): ", yylineno);
#else
  fprintf(stderr, "Invalid XML: ");
a66 5
  vfprintf(stderr, fmt, ap);
  fprintf(stderr, "\n");
  va_end(ap);
  return 1;
}
a176 1
 {S}		|
d181 4
a194 1
 {S} 		SKIP;
a204 1
 {S} 		SKIP;
a257 1

d262 3
a264 1
<INITIAL,IMPOSSIBLE>"" FAIL("The Impossible Happened: INITIAL or IMPOSSIBLE state entered?");
a267 1

d277 1
a277 2
/* Print element context. */
int print_yy_stack(char* pre)
d279 2
a280 2
  int i = 0;
  fprintf(stderr,"%s",pre);
d284 33
@


1.10
log
@Full DTD parsing in progress...currently not working.
@
text
@d27 1
a27 1
 "$Id: skel,v 1.9 1999/11/25 18:42:03 krisrose Exp $";
d43 1
d98 1
a98 1
#ifdef FLEXML_inmixed
d166 1
a166 1
 * DISABLE	dummy to permit disabling rules; must be last
d170 1
a170 1
%x DISABLE
d270 1
a270 1
<INITIAL,DISABLE>"" FAIL("The Impossible Happened: INITIAL or DISABLE state entered?");
@


1.9
log
@Stand-alone mode added and documented; still technical section to write.
@
text
@d27 1
a27 1
 "$Id: skel,v 1.8 1999/11/25 03:01:47 krisrose Exp $";
d44 3
a46 2
                         yy_flex_debug && fprintf(stderr,"--ENTER(%s)\n",X##state))
# define LEAVE(state)	(yy_flex_debug && fprintf(stderr,"--LEAVE(%s)\n",X##state),\
d48 2
d52 2
a53 1
# define LEAVE(state)	(yy_pop_state())
a54 1
#define CHECKEPILOG(tag) if (YY_START == ROOT_##tag) BEGIN(EPILOG)
d164 2
a165 2
 * IN_<tag>	inside a <tag> with element contents
 * DISABLE	dummy to permit disabling rules
d167 1
a167 1
%x PROLOG DOCTYPE EPILOG COMMENT VALUE1 VALUE2 CDATA DISABLE
d169 3
d176 1
a176 1
 BEGIN(PROLOG);
d180 1
a180 1
<FLEXML_NORMAL,PROLOG,DOCTYPE,EPILOG>"<!--" ENTER(COMMENT);
d182 1
a182 1
 "-->"		LEAVE(COMMENT);
d192 1
a192 1
 "<?xml"({S}version{Eq}(\'{VersionNum}\'|\"{VersionNum}\"))?"?>" BEGIN(DOCTYPE);
d200 1
a200 1
 . 		FAIL("Unexpected character `%c' in prolog.", *yytext);
d211 1
a211 1
 . 		FAIL("Unexpected character `%c' after document.", *yytext);
d245 1
a245 1
 \'		BUFFERDONE; LEAVE(VALUE1);
d250 1
a250 1
 \"		BUFFERDONE; LEAVE(VALUE2);
d255 2
a256 2
 [^<&]		BUFFERPUTC(*yytext);
 [<&]		FAIL("Spurious `%c' in character data.",*yytext);
d260 1
a260 1
 "]]>"		LEAVE(CDATA);
d262 1
a262 1
 .		BUFFERPUTC(*yytext);
d269 1
a269 5
<INITIAL,DISABLE>{
  {S}		|
 .		|
 <<EOF>>	FAIL("The Impossible Happened: INITIAL or DISABLE state entered?");
}
a273 2
/* UTILITY FUNCTIONS. */

d281 12
@


1.8
log
@Almost ready...
@
text
@d1 1
a1 1
/* Flex(1) XML processor skeleton scanner.
d26 2
a27 2
const char* rcs_flexml_skeleton =
 "$Id: skel,v 1.7 1999/11/23 10:10:36 krisrose Exp krisrose $";
d38 2
a39 1
FLEXML_API
d61 3
d65 1
d72 3
a74 4
/* Text buffer stack. */
#define ROOTBUFFERSIZE 100000
static char rootbuffer[ROOTBUFFERSIZE];
static char* limit = rootbuffer + ROOTBUFFERSIZE;
d78 2
a79 2
static BufferLast* last = (BufferLast*)0;
static char* next = rootbuffer;
d94 2
a95 1
void pushbuffer(char* p)
d105 1
a105 1
char* popbuffer(void)
d113 1
d115 1
a115 2

/* General entities are `unput' back onto the input stream... */
d121 1
a121 2
/* Flex options. */
%option 8bit
d123 1
d128 2
d150 1
a150 3
/* "Attribute types." */

/* Exclusive parser states:
a151 1
 * INITIAL	initial state of scanner (not used)
d169 1
a169 1
 /* Bypass INITIAL state and begin by parsing the XML prolog. */
d172 11
d184 1
d192 1
a192 2
 "<!--"		ENTER(COMMENT);
 "<!"[^>]*">"	FAIL("Bad declaration %s.",yytext);
a203 1
 "<!--"		ENTER(COMMENT);
d209 1
a209 12
 /* COMMON SYNTAX. */

 /* Comments. */

<COMMENT>{
 "-->"		LEAVE(COMMENT);
 {S}		|
 .		SKIP;
 <<EOF>>	FAIL("EOF in comment.");
}

 /* Character data. */
a233 1
 "<!--"		ENTER(COMMENT);
d255 1
d258 1
d266 1
a266 1
   <<EOF>>	FAIL("Panic: INITIAL or DISABLE state entered?");
d271 10
a280 3
/* Local Variables: */
/* mode:c */
/* End: */
@


1.7
log
@checked in with -k by krisrose at 1999/11/24 16:44:43
@
text
@d27 1
a27 1
 "$Id: flexml.skel 1.7 1999/11/23 10:10:36 krisrose Exp krisrose $";
d42 4
a45 2
#define ENTER(state)	(yy_push_state(state),fprintf(stderr,"--ENTER(%s)\n",X##state))
#define LEAVE(state)	(fprintf(stderr,"--LEAVE(%s)\n",X##state),yy_pop_state())
d47 2
a48 2
#define ENTER(state)	(yy_push_state(state))
#define LEAVE(state)	(yy_pop_state())
d50 1
a50 1
#define CHECKEPILOG(tag) if (YY_START==ROOT_##tag) BEGIN(EPILOG)
a118 1
%option noyy_top_state
d141 1
a141 1
Literal		'[^'']*'|"[^""]*"
@
