diff options
| author | Martin Quinson <mquinson@debian.org> | 2006-09-16 00:44:05 +0200 |
|---|---|---|
| committer | git-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com> | 2006-11-08 08:03:05 +0000 |
| commit | 36cf2640230d902a3fcea52df5a81be46bfc7761 (patch) | |
| tree | 15846901f66328ba9ef61159fcbda33ff41394bd | |
| parent | 9ee068e3d78ff23ca29089f3b8f481d507b57441 (diff) | |
| parent | 77afe1cb483c1750ec235404549d32d3f4c017af (diff) | |
1.7-1 (patches applied)applied/1.7-1applied/ubuntu/gutsy-develapplied/ubuntu/gutsyapplied/ubuntu/feisty-develapplied/ubuntu/feisty
Imported using git-ubuntu import.
62 files changed, 2614 insertions, 332 deletions
diff --git a/EnlargeFlex.patch b/EnlargeFlex.patch deleted file mode 100644 index e665d5a..0000000 --- a/EnlargeFlex.patch +++ /dev/null @@ -1,92 +0,0 @@ -This patch, relative to the flex-2.5.4a sources, permits really large -NFA and DFAs when flex is passed the -Ca option (since in that case it -does not affect performance in any way). - -Note: The patch is ALREADY applied in the Debian GNU/Linux package -since flex-2.5.4a-6. - -$Id: EnlargeFlex.patch,v 1.2 1999/12/13 15:57:18 krisrose Exp $ -Copyright � 1999 Kristoffer Rose; placed in the public domain. - -diff -ur flex-2.5.4a/MISC/texinfo/flex.texi.orig flex-2.5.4a/MISC/texinfo/flex.texi ---- flex-2.5.4a/MISC/texinfo/flex.texi.orig Sun Jul 27 04:47:21 1997 -+++ flex-2.5.4a/MISC/texinfo/flex.texi Fri Dec 3 18:59:51 1999 -@@ -2152,8 +2152,10 @@ - aligned for memory access and computation. On some - RISC architectures, fetching and manipulating - long-words is more efficient than with smaller-sized --units such as shortwords. This option can double --the size of the tables used by your scanner. -+units such as shortwords. This option can quadruple -+the size of the tables used by your scanner. It has the -+side effect of permitting much larger scanners, however, -+if you need this. - - @samp{-Ce} directs @code{flex} to construct @dfn{equivalence classes}, - i.e., sets of characters which have identical -diff -ur flex-2.5.4a/flexdef.h.orig flex-2.5.4a/flexdef.h ---- flex-2.5.4a/flexdef.h.orig Sun Jul 27 04:42:50 1997 -+++ flex-2.5.4a/flexdef.h Fri Dec 3 18:46:36 1999 -@@ -214,11 +214,12 @@ - - /* Maximum number of NFA states. */ - #define MAXIMUM_MNS 31999 -+#define MAXIMUM_MNS_LONG 3999999 - - /* Enough so that if it's subtracted from an NFA state number, the result - * is guaranteed to be negative. - */ --#define MARKER_DIFFERENCE (MAXIMUM_MNS+2) -+#define MARKER_DIFFERENCE (maximum_mns+2) - - /* Maximum number of nxt/chk pairs for non-templates. */ - #define INITIAL_MAX_XPAIRS 2000 -@@ -457,6 +458,7 @@ - - - /* Variables for nfa machine data: -+ * maximum_mns - maximal number of NFA states supported by tables - * current_mns - current maximum on number of NFA states - * num_rules - number of the last accepting state; also is number of - * rules created so far -@@ -485,7 +487,7 @@ - * rule_useful - true if we've determined that the rule can be matched - */ - --extern int current_mns, current_max_rules; -+extern int maximum_mns, current_mns, current_max_rules; - extern int num_rules, num_eof_rules, default_rule, lastnfa; - extern int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; - extern int *accptnum, *assoc_rule, *state_type; -diff -ur flex-2.5.4a/main.c.orig flex-2.5.4a/main.c ---- flex-2.5.4a/main.c.orig Sun Jul 27 04:32:19 1997 -+++ flex-2.5.4a/main.c Fri Dec 3 18:57:27 1999 -@@ -70,7 +70,7 @@ - int do_stdinit, use_stdout; - int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; - int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; --int current_mns, current_max_rules; -+int maximum_mns, current_mns, current_max_rules; - int num_rules, num_eof_rules, default_rule, lastnfa; - int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; - int *accptnum, *assoc_rule, *state_type; -@@ -1056,6 +1056,7 @@ - - void set_up_initial_allocations() - { -+ maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS); - current_mns = INITIAL_MNS; - firstst = allocate_integer_array( current_mns ); - lastst = allocate_integer_array( current_mns ); -diff -ur flex-2.5.4a/nfa.c.orig flex-2.5.4a/nfa.c ---- flex-2.5.4a/nfa.c.orig Sun Jul 27 04:32:19 1997 -+++ flex-2.5.4a/nfa.c Fri Dec 3 18:44:33 1999 -@@ -595,7 +595,7 @@ - { - if ( ++lastnfa >= current_mns ) - { -- if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS ) -+ if ( (current_mns += MNS_INCREMENT) >= maximum_mns ) - lerrif( - _( "input rules are too complicated (>= %d NFA states)" ), - current_mns ); @@ -1,8 +1,8 @@ # Make(1) rules for FleXML XML processor generator system. -# Copyright � 1999 Kristoffer Rose. All rights reserved. +# Copyright (c) 1999 Kristoffer Rose. All rights reserved. # # This file is part of the FleXML XML processor generator system. -# Copyright � 1999 Kristoffer Rose. All rights reserved. +# 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 @@ -18,7 +18,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # Temple Place, Suite 330, Boston, MA 02111-1307 USA. -# $Id: Makefile,v 1.39 2006/03/21 13:16:08 mquinson Exp $ +# $Id: Makefile,v 1.42 2006/08/23 16:23:59 mquinson Exp $ # SUFF (defined in Makefile.defs) is the versioning suffix added to binaries and # resource files. To get rid of it (and do a non-versioned install, @@ -34,7 +34,7 @@ BINS = $(FLEXML) LIBS = $(FLEXML_ACT) DATA = skel MANS = flexml.1 -DOCS = README NOTES TODO flexml-act.dtd EnlargeFlex.patch +DOCS = README NOTES TODO flexml-act.dtd HTMLS = FleXML.html paper.html SRC = $(STUFF) $(DATA) $(DOCS) $(HTMLS) @@ -70,7 +70,7 @@ dist: clean mkdir $(FLEXML_DISTDIR) cp $(STUFF) $(DATA) $(DOCS) $(HTMLS) flexml-act-bootstrap.c \ $(FLEXML_DISTDIR) - cp -r examples $(FLEXML_DISTDIR) + cp -r examples testbed $(FLEXML_DISTDIR) find $(FLEXML_DISTDIR) -name CVS | xargs rm -rf find $(FLEXML_DISTDIR) -name .cvsignore | xargs rm -rf tar cvfz $(FLEXML_DISTDIR).tar.gz $(FLEXML_DISTDIR) @@ -131,8 +131,8 @@ index.html: FleXML.html # TESTS. -clean::; make -C examples $@ -test::; make -C examples $@ +clean::; make -C examples $@; make -C testbed $@ +test::; make -C examples $@; make -C testbed $@ # END. diff --git a/Makefile.defs b/Makefile.defs index 7d4ce78..5e15481 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -6,7 +6,7 @@ #SUFF ?=-$(VER) SUFF ?= -VER = 1.4.1 +VER = 1.7 # SETUP. @@ -38,6 +38,7 @@ POD2MAN = $(PERL_DIR)/pod2man POD2HTML = $(PERL_DIR)/pod2html FLEX = /usr/bin/flex +SYMLINK = ln -s # Build compilation setup. CC = gcc -Wall -ansi -pedantic @@ -1,5 +1,5 @@ # FleXML fast XML scanner framework -# Copyright � 1999 Kristoffer Rose. All rights reserved. +# Copyright (c) 1999 Kristoffer Rose. All rights reserved. # # Description: Notes for FleXML scanner generator # Author: Kristoffer Rose @@ -20,7 +20,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# $Id: NOTES,v 1.2 1999/11/22 18:41:48 krisrose Exp $ +# $Id: NOTES,v 1.3 2006/07/18 18:21:13 mquinson Exp $ GUIDELINES FOR WRITING A flex(1) SCANNER FOR SIMPLE XML FORMATS. @@ -13,11 +13,8 @@ change the setup; similarly you will probably have to change executable. The toolkit produces scanners for flex(1) which you should thus -install. In order to be able to handle large DTDs (such as XHTML) you -will have to apply `EnlargeFlex.patch' (and use the -Ca option). - -Note: Debian flex has this patch applied since version 2.5.4a-6. +install. Enjoy, - Kristoffer H�gsbro Rose + Kristoffer Rose pgp f-p: A4D3 5BD7 3EC5 7CA2 924E D21D 126B B8E0 <krisrose@debian.org> @@ -1,7 +1,7 @@ -1. Make text buffer dynamically allocated. +1. -- this space intentionally left blank -- 2. Rework scanner to get rid of *all* flex dummy rule fallbacks. 3. ID type attributes should be validated for uniqueness. 4. IDREF and IDREFS attributes should be validated. -5. ENTITY and ENTITIES attribute types should be supported. +5. ENTITY and ENTITIES attribute types should be validated. 6. The xml:spaces pragma attrbute should be supported. -7. Make the pcdata buffer act more like a traditional parser stack. + diff --git a/debian/changelog b/debian/changelog index d202770..eb802aa 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,69 @@ +flexml (1.7-1) unstable; urgency=low + + [William Dowling] + * Change the static buffstack into two dynamically allocated stacks. + This get rids of any stack size limitation; + This also solves #1529930 (parsing mixed content fails on sparc/solaris, + which were caused by misaligned pointers) + * Fix #1538171: Only display the stacknames when they are defined (they + are not in the prolog) + * Fix a bufferstack memleak. This fixes both leaks of attributes and leaks + of pcdata. People using large XML files shouldn't have to use insane + buffsizes anymore. + * Fix bug #1558023 'REQUIRED attributes not validated correctly'. + * Add -i command-line param to #include given file in output .l. + * Add a proper regression testing infrastructure and some test cases. + + -- Martin Quinson <mquinson@debian.org> Sat, 16 Sep 2006 00:44:05 +0200 + +flexml (1.5.3-1) unstable; urgency=low + + * New option: --sysid to override the system id + * Kill any non ascii char from the distrib. They were latin1, I use utf8 + so they annoyed me for not much benefit. I could have switched to utf8, + but it would have annoyed other people, I'm sure. + * Kill the EnlargeFlex.patch: was integrated into flex a few ages ago. + + -- Martin Quinson <mquinson@debian.org> Tue, 18 Jul 2006 19:40:36 +0200 + +flexml (1.5.2-1) unstable; urgency=low + + * Bug fix: do find the skeleton file in installed distributions + + -- Martin Quinson <mquinson@debian.org> Tue, 18 Jul 2006 14:06:50 +0200 + +flexml (1.5.1-1) unstable; urgency=low + + * Tests used to rely on wget to fetch a dtd. Include this in the tarball + instead. + + -- Martin Quinson <mquinson@debian.org> Thu, 13 Jul 2006 21:47:45 +0200 + +flexml (1.5-1) unstable; urgency=low + + [William Dowling] + * Fix bug 1498401 "Parser loops on empty entity expansion" (l. 251); + * Fix bug 1498407 "Cannot have ELEMENT with same name as ATTLIST" (ll. 674-5); + * Fix bug 1498418 "ENTITY attribute type unimplemented." (ll. 842-51). + + [Martin Quinson] + (upstream) + * Switch to Getopt::Long (I hope I didn't break anything) + * Add long version of each command line option + * Allow to override the scanner, header, application names using an + optionnal argument along to -S -H -A options. + (debian package) + * Switch to debhelper level 5 (at least try to, change seem to be ignored) + * Run the test suite in the process of package building + + -- Martin Quinson <mquinson@debian.org> Thu, 13 Jul 2006 20:27:50 +0200 + flexml (1.4.1-1) unstable; urgency=low * More fixes to get several parsers in the same C code: - pass bufferstack to static too - prefix the pcdata variable (WARNING: go fix your code using it) - Interesingly enough, this seems to be needed on Mac OSX somehow + This seems to be needed with gcc 4.x -- Martin Quinson <mquinson@debian.org> Sat, 22 Apr 2006 01:29:23 +0200 diff --git a/debian/compat b/debian/compat index b8626c4..7ed6ff8 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -4 +5 diff --git a/debian/docs b/debian/docs index 1f1fe8c..10ce222 100644 --- a/debian/docs +++ b/debian/docs @@ -1,4 +1,3 @@ README -EnlargeFlex.patch NOTES TODO diff --git a/debian/rules b/debian/rules index c03982b..5b956ec 100755 --- a/debian/rules +++ b/debian/rules @@ -12,6 +12,7 @@ build: build-stamp build-stamp: dh_testdir $(MAKE) SUFF= + $(MAKE) test SUFF= touch build-stamp clean: @@ -27,7 +28,6 @@ install: build dh_clean -k dh_installdirs $(MAKE) install DESTDIR=`pwd`/debian/tmp SUFF= - rm debian/tmp/usr/share/doc/flexml/EnlargeFlex.patch touch install-stamp # Build architecture-independent files here. diff --git a/examples/FleXML.xml b/examples/FleXML.xml index 3fd8357..88ba334 100644 --- a/examples/FleXML.xml +++ b/examples/FleXML.xml @@ -1,6 +1,6 @@ <!DOCTYPE html PUBLIC "-//IETF//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<!--$Id: FleXML.xml,v 1.1 2005/03/18 22:02:50 wdowling Exp $--> +<!--$Id: FleXML.xml,v 1.2 2006/07/18 18:21:13 mquinson Exp $--> <html> <head> <title>FleXML - XML Processor Generator</title> @@ -175,7 +175,7 @@ `copyleft'). </p> <hr /> - <address>Copyright � + <address>Copyright (c) <a href="mailto:Kristoffer.Rose@ens-lyon.fr">Kristoffer Rose</a>. <!-- Created: Thu Dec 9 08:09:41 CET 1999 --> <!-- hhmts start --> diff --git a/examples/Makefile b/examples/Makefile index 42148db..0606531 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,8 +1,8 @@ # Make(1) rules for FleXML XML processor generator system. -# Copyright � 1999 Kristoffer Rose. All rights reserved. +# Copyright (c) 1999 Kristoffer Rose. All rights reserved. # # This file is part of the FleXML XML processor generator system. -# Copyright � 1999 Kristoffer Rose. All rights reserved. +# 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 @@ -18,7 +18,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # Temple Place, Suite 330, Boston, MA 02111-1307 USA. -# $Id: Makefile,v 1.5 2006/03/21 13:11:27 mquinson Exp $ +# $Id: Makefile,v 1.8 2006/08/28 20:50:38 wdowling Exp $ # FILES. @@ -30,7 +30,7 @@ ACT=../flexml-act SAMPS = my.dtd my-show.act my-joke.xml my-joke2.xml my-joke3.xml \ tricky.dtd tricky.act tricky.xml \ - test.html + test.html xhtml1-transitional.dtd SRC = $(SAMPS) ALL = $(SAMPS) @@ -115,9 +115,6 @@ clean::; $(RM) tricky.[lco] tricky # Complex example: application to print XHTML <a href=...> values. -xhtml1-transitional.dtd: - wget 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd' - xhtml1-transitional.l xhtml1-transitional.h: xhtml1-transitional.dtd $(FLEXML_PROG) -rhtml \ -p "-//IETF//DTD XHTML 1.0 Transitional//EN" \ @@ -127,6 +124,9 @@ xhtml1-transitional.l xhtml1-transitional.h: xhtml1-transitional.dtd xhtml1-transitional.c: xhtml1-transitional.l $(FLEX) -B -s -v -Ca -oxhtml1-transitional.c xhtml1-transitional.l +# turn off the -O2 when building this -- it takes too long to run +xhtml1-transitional.o: CFLAGS = -g + xhtml1-transitional.o: xhtml1-transitional.c xhtml1-transitional.h xhtml-href.c: xhtml-href.act xhtml1-transitional.dtd @@ -138,7 +138,7 @@ test:: xhtml-href FleXML.xml if ./xhtml-href <test.html ; then echo "TEST PASSED"; else echo "TEST FAILED"; fi if ./xhtml-href < FleXML.xml ; then echo "TEST PASSED"; else echo "TEST FAILED"; fi -clean::; $(RM) xhtml1-*.dtd xhtml1-*.[lhco] xhtml-href.[co] xhtml-href +clean::; $(RM) xhtml1-*.[lhco] xhtml-href.[co] xhtml-href # END. diff --git a/examples/xhtml1-transitional.dtd b/examples/xhtml1-transitional.dtd new file mode 100644 index 0000000..9448c25 --- /dev/null +++ b/examples/xhtml1-transitional.dtd @@ -0,0 +1,1201 @@ +<!-- + Extensible HTML version 1.0 Transitional DTD + + This is the same as HTML 4 Transitional except for + changes due to the differences between XML and SGML. + + Namespace = http://www.w3.org/1999/xhtml + + For further information, see: http://www.w3.org/TR/xhtml1 + + Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio), + All Rights Reserved. + + This DTD module is identified by the PUBLIC and SYSTEM identifiers: + + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" + + $Revision: 1.1 $ + $Date: 2006/07/13 19:57:04 $ + +--> + +<!--================ Character mnemonic entities =========================--> + +<!ENTITY % HTMLlat1 PUBLIC + "-//W3C//ENTITIES Latin 1 for XHTML//EN" + "xhtml-lat1.ent"> +%HTMLlat1; + +<!ENTITY % HTMLsymbol PUBLIC + "-//W3C//ENTITIES Symbols for XHTML//EN" + "xhtml-symbol.ent"> +%HTMLsymbol; + +<!ENTITY % HTMLspecial PUBLIC + "-//W3C//ENTITIES Special for XHTML//EN" + "xhtml-special.ent"> +%HTMLspecial; + +<!--================== Imported Names ====================================--> + +<!ENTITY % ContentType "CDATA"> + <!-- media type, as per [RFC2045] --> + +<!ENTITY % ContentTypes "CDATA"> + <!-- comma-separated list of media types, as per [RFC2045] --> + +<!ENTITY % Charset "CDATA"> + <!-- a character encoding, as per [RFC2045] --> + +<!ENTITY % Charsets "CDATA"> + <!-- a space separated list of character encodings, as per [RFC2045] --> + +<!ENTITY % LanguageCode "NMTOKEN"> + <!-- a language code, as per [RFC3066] --> + +<!ENTITY % Character "CDATA"> + <!-- a single character, as per section 2.2 of [XML] --> + +<!ENTITY % Number "CDATA"> + <!-- one or more digits --> + +<!ENTITY % LinkTypes "CDATA"> + <!-- space-separated list of link types --> + +<!ENTITY % MediaDesc "CDATA"> + <!-- single or comma-separated list of media descriptors --> + +<!ENTITY % URI "CDATA"> + <!-- a Uniform Resource Identifier, see [RFC2396] --> + +<!ENTITY % UriList "CDATA"> + <!-- a space separated list of Uniform Resource Identifiers --> + +<!ENTITY % Datetime "CDATA"> + <!-- date and time information. ISO date format --> + +<!ENTITY % Script "CDATA"> + <!-- script expression --> + +<!ENTITY % StyleSheet "CDATA"> + <!-- style sheet data --> + +<!ENTITY % Text "CDATA"> + <!-- used for titles etc. --> + +<!ENTITY % FrameTarget "NMTOKEN"> + <!-- render in this frame --> + +<!ENTITY % Length "CDATA"> + <!-- nn for pixels or nn% for percentage length --> + +<!ENTITY % MultiLength "CDATA"> + <!-- pixel, percentage, or relative --> + +<!ENTITY % Pixels "CDATA"> + <!-- integer representing length in pixels --> + +<!-- these are used for image maps --> + +<!ENTITY % Shape "(rect|circle|poly|default)"> + +<!ENTITY % Coords "CDATA"> + <!-- comma separated list of lengths --> + +<!-- used for object, applet, img, input and iframe --> +<!ENTITY % ImgAlign "(top|middle|bottom|left|right)"> + +<!-- a color using sRGB: #RRGGBB as Hex values --> +<!ENTITY % Color "CDATA"> + +<!-- There are also 16 widely known color names with their sRGB values: + + Black = #000000 Green = #008000 + Silver = #C0C0C0 Lime = #00FF00 + Gray = #808080 Olive = #808000 + White = #FFFFFF Yellow = #FFFF00 + Maroon = #800000 Navy = #000080 + Red = #FF0000 Blue = #0000FF + Purple = #800080 Teal = #008080 + Fuchsia= #FF00FF Aqua = #00FFFF +--> + +<!--=================== Generic Attributes ===============================--> + +<!-- core attributes common to most elements + id document-wide unique id + class space separated list of classes + style associated style info + title advisory title/amplification +--> +<!ENTITY % coreattrs + "id ID #IMPLIED + class CDATA #IMPLIED + style %StyleSheet; #IMPLIED + title %Text; #IMPLIED" + > + +<!-- internationalization attributes + lang language code (backwards compatible) + xml:lang language code (as per XML 1.0 spec) + dir direction for weak/neutral text +--> +<!ENTITY % i18n + "lang %LanguageCode; #IMPLIED + xml:lang %LanguageCode; #IMPLIED + dir (ltr|rtl) #IMPLIED" + > + +<!-- attributes for common UI events + onclick a pointer button was clicked + ondblclick a pointer button was double clicked + onmousedown a pointer button was pressed down + onmouseup a pointer button was released + onmousemove a pointer was moved onto the element + onmouseout a pointer was moved away from the element + onkeypress a key was pressed and released + onkeydown a key was pressed down + onkeyup a key was released +--> +<!ENTITY % events + "onclick %Script; #IMPLIED + ondblclick %Script; #IMPLIED + onmousedown %Script; #IMPLIED + onmouseup %Script; #IMPLIED + onmouseover %Script; #IMPLIED + onmousemove %Script; #IMPLIED + onmouseout %Script; #IMPLIED + onkeypress %Script; #IMPLIED + onkeydown %Script; #IMPLIED + onkeyup %Script; #IMPLIED" + > + +<!-- attributes for elements that can get the focus + accesskey accessibility key character + tabindex position in tabbing order + onfocus the element got the focus + onblur the element lost the focus +--> +<!ENTITY % focus + "accesskey %Character; #IMPLIED + tabindex %Number; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED" + > + +<!ENTITY % attrs "%coreattrs; %i18n; %events;"> + +<!-- text alignment for p, div, h1-h6. The default is + align="left" for ltr headings, "right" for rtl --> + +<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED"> + +<!--=================== Text Elements ====================================--> + +<!ENTITY % special.extra + "object | applet | img | map | iframe"> + +<!ENTITY % special.basic + "br | span | bdo"> + +<!ENTITY % special + "%special.basic; | %special.extra;"> + +<!ENTITY % fontstyle.extra "big | small | font | basefont"> + +<!ENTITY % fontstyle.basic "tt | i | b | u + | s | strike "> + +<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;"> + +<!ENTITY % phrase.extra "sub | sup"> +<!ENTITY % phrase.basic "em | strong | dfn | code | q | + samp | kbd | var | cite | abbr | acronym"> + +<!ENTITY % phrase "%phrase.basic; | %phrase.extra;"> + +<!ENTITY % inline.forms "input | select | textarea | label | button"> + +<!-- these can occur at block or inline level --> +<!ENTITY % misc.inline "ins | del | script"> + +<!-- these can only occur at block level --> +<!ENTITY % misc "noscript | %misc.inline;"> + +<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;"> + +<!-- %Inline; covers inline or "text-level" elements --> +<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*"> + +<!--================== Block level elements ==============================--> + +<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> +<!ENTITY % lists "ul | ol | dl | menu | dir"> +<!ENTITY % blocktext "pre | hr | blockquote | address | center | noframes"> + +<!ENTITY % block + "p | %heading; | div | %lists; | %blocktext; | isindex |fieldset | table"> + +<!-- %Flow; mixes block and inline and is used for list items etc. --> +<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*"> + +<!--================== Content models for exclusions =====================--> + +<!-- a elements use %Inline; excluding a --> + +<!ENTITY % a.content + "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*"> + +<!-- pre uses %Inline excluding img, object, applet, big, small, + font, or basefont --> + +<!ENTITY % pre.content + "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; | + %inline.forms; | %misc.inline;)*"> + +<!-- form uses %Flow; excluding form --> + +<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*"> + +<!-- button uses %Flow; but excludes a, form, form controls, iframe --> + +<!ENTITY % button.content + "(#PCDATA | p | %heading; | div | %lists; | %blocktext; | + table | br | span | bdo | object | applet | img | map | + %fontstyle; | %phrase; | %misc;)*"> + +<!--================ Document Structure ==================================--> + +<!-- the namespace URI designates the document profile --> + +<!ELEMENT html (head, body)> +<!ATTLIST html + %i18n; + id ID #IMPLIED + xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml' + > + +<!--================ Document Head =======================================--> + +<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*"> + +<!-- content model is %head.misc; combined with a single + title and an optional base element in any order --> + +<!ELEMENT head (%head.misc;, + ((title, %head.misc;, (base, %head.misc;)?) | + (base, %head.misc;, (title, %head.misc;))))> + +<!ATTLIST head + %i18n; + id ID #IMPLIED + profile %URI; #IMPLIED + > + +<!-- The title element is not considered part of the flow of text. + It should be displayed, for example as the page header or + window title. Exactly one title is required per document. + --> +<!ELEMENT title (#PCDATA)> +<!ATTLIST title + %i18n; + id ID #IMPLIED + > + +<!-- document base URI --> + +<!ELEMENT base EMPTY> +<!ATTLIST base + id ID #IMPLIED + href %URI; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- generic metainformation --> +<!ELEMENT meta EMPTY> +<!ATTLIST meta + %i18n; + id ID #IMPLIED + http-equiv CDATA #IMPLIED + name CDATA #IMPLIED + content CDATA #REQUIRED + scheme CDATA #IMPLIED + > + +<!-- + Relationship values can be used in principle: + + a) for document specific toolbars/menus when used + with the link element in document head e.g. + start, contents, previous, next, index, end, help + b) to link to a separate style sheet (rel="stylesheet") + c) to make a link to a script (rel="script") + d) by stylesheets to control how collections of + html nodes are rendered into printed documents + e) to make a link to a printable version of this document + e.g. a PostScript or PDF version (rel="alternate" media="print") +--> + +<!ELEMENT link EMPTY> +<!ATTLIST link + %attrs; + charset %Charset; #IMPLIED + href %URI; #IMPLIED + hreflang %LanguageCode; #IMPLIED + type %ContentType; #IMPLIED + rel %LinkTypes; #IMPLIED + rev %LinkTypes; #IMPLIED + media %MediaDesc; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- style info, which may include CDATA sections --> +<!ELEMENT style (#PCDATA)> +<!ATTLIST style + %i18n; + id ID #IMPLIED + type %ContentType; #REQUIRED + media %MediaDesc; #IMPLIED + title %Text; #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!-- script statements, which may include CDATA sections --> +<!ELEMENT script (#PCDATA)> +<!ATTLIST script + id ID #IMPLIED + charset %Charset; #IMPLIED + type %ContentType; #REQUIRED + language CDATA #IMPLIED + src %URI; #IMPLIED + defer (defer) #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!-- alternate content container for non script-based rendering --> + +<!ELEMENT noscript %Flow;> +<!ATTLIST noscript + %attrs; + > + +<!--======================= Frames =======================================--> + +<!-- inline subwindow --> + +<!ELEMENT iframe %Flow;> +<!ATTLIST iframe + %coreattrs; + longdesc %URI; #IMPLIED + name NMTOKEN #IMPLIED + src %URI; #IMPLIED + frameborder (1|0) "1" + marginwidth %Pixels; #IMPLIED + marginheight %Pixels; #IMPLIED + scrolling (yes|no|auto) "auto" + align %ImgAlign; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + > + +<!-- alternate content container for non frame-based rendering --> + +<!ELEMENT noframes %Flow;> +<!ATTLIST noframes + %attrs; + > + +<!--=================== Document Body ====================================--> + +<!ELEMENT body %Flow;> +<!ATTLIST body + %attrs; + onload %Script; #IMPLIED + onunload %Script; #IMPLIED + background %URI; #IMPLIED + bgcolor %Color; #IMPLIED + text %Color; #IMPLIED + link %Color; #IMPLIED + vlink %Color; #IMPLIED + alink %Color; #IMPLIED + > + +<!ELEMENT div %Flow;> <!-- generic language/style container --> +<!ATTLIST div + %attrs; + %TextAlign; + > + +<!--=================== Paragraphs =======================================--> + +<!ELEMENT p %Inline;> +<!ATTLIST p + %attrs; + %TextAlign; + > + +<!--=================== Headings =========================================--> + +<!-- + There are six levels of headings from h1 (the most important) + to h6 (the least important). +--> + +<!ELEMENT h1 %Inline;> +<!ATTLIST h1 + %attrs; + %TextAlign; + > + +<!ELEMENT h2 %Inline;> +<!ATTLIST h2 + %attrs; + %TextAlign; + > + +<!ELEMENT h3 %Inline;> +<!ATTLIST h3 + %attrs; + %TextAlign; + > + +<!ELEMENT h4 %Inline;> +<!ATTLIST h4 + %attrs; + %TextAlign; + > + +<!ELEMENT h5 %Inline;> +<!ATTLIST h5 + %attrs; + %TextAlign; + > + +<!ELEMENT h6 %Inline;> +<!ATTLIST h6 + %attrs; + %TextAlign; + > + +<!--=================== Lists ============================================--> + +<!-- Unordered list bullet styles --> + +<!ENTITY % ULStyle "(disc|square|circle)"> + +<!-- Unordered list --> + +<!ELEMENT ul (li)+> +<!ATTLIST ul + %attrs; + type %ULStyle; #IMPLIED + compact (compact) #IMPLIED + > + +<!-- Ordered list numbering style + + 1 arabic numbers 1, 2, 3, ... + a lower alpha a, b, c, ... + A upper alpha A, B, C, ... + i lower roman i, ii, iii, ... + I upper roman I, II, III, ... + + The style is applied to the sequence number which by default + is reset to 1 for the first list item in an ordered list. +--> +<!ENTITY % OLStyle "CDATA"> + +<!-- Ordered (numbered) list --> + +<!ELEMENT ol (li)+> +<!ATTLIST ol + %attrs; + type %OLStyle; #IMPLIED + compact (compact) #IMPLIED + start %Number; #IMPLIED + > + +<!-- single column list (DEPRECATED) --> +<!ELEMENT menu (li)+> +<!ATTLIST menu + %attrs; + compact (compact) #IMPLIED + > + +<!-- multiple column list (DEPRECATED) --> +<!ELEMENT dir (li)+> +<!ATTLIST dir + %attrs; + compact (compact) #IMPLIED + > + +<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" --> +<!ENTITY % LIStyle "CDATA"> + +<!-- list item --> + +<!ELEMENT li %Flow;> +<!ATTLIST li + %attrs; + type %LIStyle; #IMPLIED + value %Number; #IMPLIED + > + +<!-- definition lists - dt for term, dd for its definition --> + +<!ELEMENT dl (dt|dd)+> +<!ATTLIST dl + %attrs; + compact (compact) #IMPLIED + > + +<!ELEMENT dt %Inline;> +<!ATTLIST dt + %attrs; + > + +<!ELEMENT dd %Flow;> +<!ATTLIST dd + %attrs; + > + +<!--=================== Address ==========================================--> + +<!-- information on author --> + +<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*> +<!ATTLIST address + %attrs; + > + +<!--=================== Horizontal Rule ==================================--> + +<!ELEMENT hr EMPTY> +<!ATTLIST hr + %attrs; + align (left|center|right) #IMPLIED + noshade (noshade) #IMPLIED + size %Pixels; #IMPLIED + width %Length; #IMPLIED + > + +<!--=================== Preformatted Text ================================--> + +<!-- content is %Inline; excluding + "img|object|applet|big|small|sub|sup|font|basefont" --> + +<!ELEMENT pre %pre.content;> +<!ATTLIST pre + %attrs; + width %Number; #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!--=================== Block-like Quotes ================================--> + +<!ELEMENT blockquote %Flow;> +<!ATTLIST blockquote + %attrs; + cite %URI; #IMPLIED + > + +<!--=================== Text alignment ===================================--> + +<!-- center content --> +<!ELEMENT center %Flow;> +<!ATTLIST center + %attrs; + > + +<!--=================== Inserted/Deleted Text ============================--> + +<!-- + ins/del are allowed in block and inline content, but its + inappropriate to include block content within an ins element + occurring in inline content. +--> +<!ELEMENT ins %Flow;> +<!ATTLIST ins + %attrs; + cite %URI; #IMPLIED + datetime %Datetime; #IMPLIED + > + +<!ELEMENT del %Flow;> +<!ATTLIST del + %attrs; + cite %URI; #IMPLIED + datetime %Datetime; #IMPLIED + > + +<!--================== The Anchor Element ================================--> + +<!-- content is %Inline; except that anchors shouldn't be nested --> + +<!ELEMENT a %a.content;> +<!ATTLIST a + %attrs; + %focus; + charset %Charset; #IMPLIED + type %ContentType; #IMPLIED + name NMTOKEN #IMPLIED + href %URI; #IMPLIED + hreflang %LanguageCode; #IMPLIED + rel %LinkTypes; #IMPLIED + rev %LinkTypes; #IMPLIED + shape %Shape; "rect" + coords %Coords; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!--===================== Inline Elements ================================--> + +<!ELEMENT span %Inline;> <!-- generic language/style container --> +<!ATTLIST span + %attrs; + > + +<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride --> +<!ATTLIST bdo + %coreattrs; + %events; + lang %LanguageCode; #IMPLIED + xml:lang %LanguageCode; #IMPLIED + dir (ltr|rtl) #REQUIRED + > + +<!ELEMENT br EMPTY> <!-- forced line break --> +<!ATTLIST br + %coreattrs; + clear (left|all|right|none) "none" + > + +<!ELEMENT em %Inline;> <!-- emphasis --> +<!ATTLIST em %attrs;> + +<!ELEMENT strong %Inline;> <!-- strong emphasis --> +<!ATTLIST strong %attrs;> + +<!ELEMENT dfn %Inline;> <!-- definitional --> +<!ATTLIST dfn %attrs;> + +<!ELEMENT code %Inline;> <!-- program code --> +<!ATTLIST code %attrs;> + +<!ELEMENT samp %Inline;> <!-- sample --> +<!ATTLIST samp %attrs;> + +<!ELEMENT kbd %Inline;> <!-- something user would type --> +<!ATTLIST kbd %attrs;> + +<!ELEMENT var %Inline;> <!-- variable --> +<!ATTLIST var %attrs;> + +<!ELEMENT cite %Inline;> <!-- citation --> +<!ATTLIST cite %attrs;> + +<!ELEMENT abbr %Inline;> <!-- abbreviation --> +<!ATTLIST abbr %attrs;> + +<!ELEMENT acronym %Inline;> <!-- acronym --> +<!ATTLIST acronym %attrs;> + +<!ELEMENT q %Inline;> <!-- inlined quote --> +<!ATTLIST q + %attrs; + cite %URI; #IMPLIED + > + +<!ELEMENT sub %Inline;> <!-- subscript --> +<!ATTLIST sub %attrs;> + +<!ELEMENT sup %Inline;> <!-- superscript --> +<!ATTLIST sup %attrs;> + +<!ELEMENT tt %Inline;> <!-- fixed pitch font --> +<!ATTLIST tt %attrs;> + +<!ELEMENT i %Inline;> <!-- italic font --> +<!ATTLIST i %attrs;> + +<!ELEMENT b %Inline;> <!-- bold font --> +<!ATTLIST b %attrs;> + +<!ELEMENT big %Inline;> <!-- bigger font --> +<!ATTLIST big %attrs;> + +<!ELEMENT small %Inline;> <!-- smaller font --> +<!ATTLIST small %attrs;> + +<!ELEMENT u %Inline;> <!-- underline --> +<!ATTLIST u %attrs;> + +<!ELEMENT s %Inline;> <!-- strike-through --> +<!ATTLIST s %attrs;> + +<!ELEMENT strike %Inline;> <!-- strike-through --> +<!ATTLIST strike %attrs;> + +<!ELEMENT basefont EMPTY> <!-- base font size --> +<!ATTLIST basefont + id ID #IMPLIED + size CDATA #REQUIRED + color %Color; #IMPLIED + face CDATA #IMPLIED + > + +<!ELEMENT font %Inline;> <!-- local change to font --> +<!ATTLIST font + %coreattrs; + %i18n; + size CDATA #IMPLIED + color %Color; #IMPLIED + face CDATA #IMPLIED + > + +<!--==================== Object ======================================--> +<!-- + object is used to embed objects as part of HTML pages. + param elements should precede other content. Parameters + can also be expressed as attribute/value pairs on the + object element itself when brevity is desired. +--> + +<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*> +<!ATTLIST object + %attrs; + declare (declare) #IMPLIED + classid %URI; #IMPLIED + codebase %URI; #IMPLIED + data %URI; #IMPLIED + type %ContentType; #IMPLIED + codetype %ContentType; #IMPLIED + archive %UriList; #IMPLIED + standby %Text; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + usemap %URI; #IMPLIED + name NMTOKEN #IMPLIED + tabindex %Number; #IMPLIED + align %ImgAlign; #IMPLIED + border %Pixels; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!-- + param is used to supply a named property value. + In XML it would seem natural to follow RDF and support an + abbreviated syntax where the param elements are replaced + by attribute value pairs on the object start tag. +--> +<!ELEMENT param EMPTY> +<!ATTLIST param + id ID #IMPLIED + name CDATA #REQUIRED + value CDATA #IMPLIED + valuetype (data|ref|object) "data" + type %ContentType; #IMPLIED + > + +<!--=================== Java applet ==================================--> +<!-- + One of code or object attributes must be present. + Place param elements before other content. +--> +<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*> +<!ATTLIST applet + %coreattrs; + codebase %URI; #IMPLIED + archive CDATA #IMPLIED + code CDATA #IMPLIED + object CDATA #IMPLIED + alt %Text; #IMPLIED + name NMTOKEN #IMPLIED + width %Length; #REQUIRED + height %Length; #REQUIRED + align %ImgAlign; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!--=================== Images ===========================================--> + +<!-- + To avoid accessibility problems for people who aren't + able to see the image, you should provide a text + description using the alt and longdesc attributes. + In addition, avoid the use of server-side image maps. +--> + +<!ELEMENT img EMPTY> +<!ATTLIST img + %attrs; + src %URI; #REQUIRED + alt %Text; #REQUIRED + name NMTOKEN #IMPLIED + longdesc %URI; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + usemap %URI; #IMPLIED + ismap (ismap) #IMPLIED + align %ImgAlign; #IMPLIED + border %Length; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!-- usemap points to a map element which may be in this document + or an external document, although the latter is not widely supported --> + +<!--================== Client-side image maps ============================--> + +<!-- These can be placed in the same document or grouped in a + separate document although this isn't yet widely supported --> + +<!ELEMENT map ((%block; | form | %misc;)+ | area+)> +<!ATTLIST map + %i18n; + %events; + id ID #REQUIRED + class CDATA #IMPLIED + style %StyleSheet; #IMPLIED + title %Text; #IMPLIED + name CDATA #IMPLIED + > + +<!ELEMENT area EMPTY> +<!ATTLIST area + %attrs; + %focus; + shape %Shape; "rect" + coords %Coords; #IMPLIED + href %URI; #IMPLIED + nohref (nohref) #IMPLIED + alt %Text; #REQUIRED + target %FrameTarget; #IMPLIED + > + +<!--================ Forms ===============================================--> + +<!ELEMENT form %form.content;> <!-- forms shouldn't be nested --> + +<!ATTLIST form + %attrs; + action %URI; #REQUIRED + method (get|post) "get" + name NMTOKEN #IMPLIED + enctype %ContentType; "application/x-www-form-urlencoded" + onsubmit %Script; #IMPLIED + onreset %Script; #IMPLIED + accept %ContentTypes; #IMPLIED + accept-charset %Charsets; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- + Each label must not contain more than ONE field + Label elements shouldn't be nested. +--> +<!ELEMENT label %Inline;> +<!ATTLIST label + %attrs; + for IDREF #IMPLIED + accesskey %Character; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED + > + +<!ENTITY % InputType + "(text | password | checkbox | + radio | submit | reset | + file | hidden | image | button)" + > + +<!-- the name attribute is required for all but submit & reset --> + +<!ELEMENT input EMPTY> <!-- form control --> +<!ATTLIST input + %attrs; + %focus; + type %InputType; "text" + name CDATA #IMPLIED + value CDATA #IMPLIED + checked (checked) #IMPLIED + disabled (disabled) #IMPLIED + readonly (readonly) #IMPLIED + size CDATA #IMPLIED + maxlength %Number; #IMPLIED + src %URI; #IMPLIED + alt CDATA #IMPLIED + usemap %URI; #IMPLIED + onselect %Script; #IMPLIED + onchange %Script; #IMPLIED + accept %ContentTypes; #IMPLIED + align %ImgAlign; #IMPLIED + > + +<!ELEMENT select (optgroup|option)+> <!-- option selector --> +<!ATTLIST select + %attrs; + name CDATA #IMPLIED + size %Number; #IMPLIED + multiple (multiple) #IMPLIED + disabled (disabled) #IMPLIED + tabindex %Number; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED + onchange %Script; #IMPLIED + > + +<!ELEMENT optgroup (option)+> <!-- option group --> +<!ATTLIST optgroup + %attrs; + disabled (disabled) #IMPLIED + label %Text; #REQUIRED + > + +<!ELEMENT option (#PCDATA)> <!-- selectable choice --> +<!ATTLIST option + %attrs; + selected (selected) #IMPLIED + disabled (disabled) #IMPLIED + label %Text; #IMPLIED + value CDATA #IMPLIED + > + +<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field --> +<!ATTLIST textarea + %attrs; + %focus; + name CDATA #IMPLIED + rows %Number; #REQUIRED + cols %Number; #REQUIRED + disabled (disabled) #IMPLIED + readonly (readonly) #IMPLIED + onselect %Script; #IMPLIED + onchange %Script; #IMPLIED + > + +<!-- + The fieldset element is used to group form fields. + Only one legend element should occur in the content + and if present should only be preceded by whitespace. +--> +<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*> +<!ATTLIST fieldset + %attrs; + > + +<!ENTITY % LAlign "(top|bottom|left|right)"> + +<!ELEMENT legend %Inline;> <!-- fieldset label --> +<!ATTLIST legend + %attrs; + accesskey %Character; #IMPLIED + align %LAlign; #IMPLIED + > + +<!-- + Content is %Flow; excluding a, form, form controls, iframe +--> +<!ELEMENT button %button.content;> <!-- push button --> +<!ATTLIST button + %attrs; + %focus; + name CDATA #IMPLIED + value CDATA #IMPLIED + type (button|submit|reset) "submit" + disabled (disabled) #IMPLIED + > + +<!-- single-line text input control (DEPRECATED) --> +<!ELEMENT isindex EMPTY> +<!ATTLIST isindex + %coreattrs; + %i18n; + prompt %Text; #IMPLIED + > + +<!--======================= Tables =======================================--> + +<!-- Derived from IETF HTML table standard, see [RFC1942] --> + +<!-- + The border attribute sets the thickness of the frame around the + table. The default units are screen pixels. + + The frame attribute specifies which parts of the frame around + the table should be rendered. The values are not the same as + CALS to avoid a name clash with the valign attribute. +--> +<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)"> + +<!-- + The rules attribute defines which rules to draw between cells: + + If rules is absent then assume: + "none" if border is absent or border="0" otherwise "all" +--> + +<!ENTITY % TRules "(none | groups | rows | cols | all)"> + +<!-- horizontal placement of table relative to document --> +<!ENTITY % TAlign "(left|center|right)"> + +<!-- horizontal alignment attributes for cell contents + + char alignment char, e.g. char=':' + charoff offset for alignment char +--> +<!ENTITY % cellhalign + "align (left|center|right|justify|char) #IMPLIED + char %Character; #IMPLIED + charoff %Length; #IMPLIED" + > + +<!-- vertical alignment attributes for cell contents --> +<!ENTITY % cellvalign + "valign (top|middle|bottom|baseline) #IMPLIED" + > + +<!ELEMENT table + (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> +<!ELEMENT caption %Inline;> +<!ELEMENT thead (tr)+> +<!ELEMENT tfoot (tr)+> +<!ELEMENT tbody (tr)+> +<!ELEMENT colgroup (col)*> +<!ELEMENT col EMPTY> +<!ELEMENT tr (th|td)+> +<!ELEMENT th %Flow;> +<!ELEMENT td %Flow;> + +<!ATTLIST table + %attrs; + summary %Text; #IMPLIED + width %Length; #IMPLIED + border %Pixels; #IMPLIED + frame %TFrame; #IMPLIED + rules %TRules; #IMPLIED + cellspacing %Length; #IMPLIED + cellpadding %Length; #IMPLIED + align %TAlign; #IMPLIED + bgcolor %Color; #IMPLIED + > + +<!ENTITY % CAlign "(top|bottom|left|right)"> + +<!ATTLIST caption + %attrs; + align %CAlign; #IMPLIED + > + +<!-- +colgroup groups a set of col elements. It allows you to group +several semantically related columns together. +--> +<!ATTLIST colgroup + %attrs; + span %Number; "1" + width %MultiLength; #IMPLIED + %cellhalign; + %cellvalign; + > + +<!-- + col elements define the alignment properties for cells in + one or more columns. + + The width attribute specifies the width of the columns, e.g. + + width=64 width in screen pixels + width=0.5* relative width of 0.5 + + The span attribute causes the attributes of one + col element to apply to more than one column. +--> +<!ATTLIST col + %attrs; + span %Number; "1" + width %MultiLength; #IMPLIED + %cellhalign; + %cellvalign; + > + +<!-- + Use thead to duplicate headers when breaking table + across page boundaries, or for static headers when + tbody sections are rendered in scrolling panel. + + Use tfoot to duplicate footers when breaking table + across page boundaries, or for static footers when + tbody sections are rendered in scrolling panel. + + Use multiple tbody sections when rules are needed + between groups of table rows. +--> +<!ATTLIST thead + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tfoot + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tbody + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tr + %attrs; + %cellhalign; + %cellvalign; + bgcolor %Color; #IMPLIED + > + +<!-- Scope is simpler than headers attribute for common tables --> +<!ENTITY % Scope "(row|col|rowgroup|colgroup)"> + +<!-- th is for headers, td for data and for cells acting as both --> + +<!ATTLIST th + %attrs; + abbr %Text; #IMPLIED + axis CDATA #IMPLIED + headers IDREFS #IMPLIED + scope %Scope; #IMPLIED + rowspan %Number; "1" + colspan %Number; "1" + %cellhalign; + %cellvalign; + nowrap (nowrap) #IMPLIED + bgcolor %Color; #IMPLIED + width %Length; #IMPLIED + height %Length; #IMPLIED + > + +<!ATTLIST td + %attrs; + abbr %Text; #IMPLIED + axis CDATA #IMPLIED + headers IDREFS #IMPLIED + scope %Scope; #IMPLIED + rowspan %Number; "1" + colspan %Number; "1" + %cellhalign; + %cellvalign; + nowrap (nowrap) #IMPLIED + bgcolor %Color; #IMPLIED + width %Length; #IMPLIED + height %Length; #IMPLIED + > + diff --git a/flexml-act-bootstrap.c b/flexml-act-bootstrap.c index 963d0b0..e1a8584 100644 --- a/flexml-act-bootstrap.c +++ b/flexml-act-bootstrap.c @@ -1,8 +1,8 @@ /* Flex(1) XML processor action language application. - * Copyright � 1999 Kristoffer Rose. All rights reserved. + * Copyright (c) 1999 Kristoffer Rose. All rights reserved. * * This file is part of the FleXML XML processor generator system. - * Copyright � 1999 Kristoffer Rose. All rights reserved. + * 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 @@ -24,6 +24,7 @@ #include <unistd.h> #include "flexml-act.h" +extern char *bufferstack; extern FILE* yyin; extern int yylineno; extern int yylex(void); diff --git a/flexml-act.dtd b/flexml-act.dtd index 54aeb5f..a65a696 100644 --- a/flexml-act.dtd +++ b/flexml-act.dtd @@ -1,9 +1,9 @@ <!-- Flex(1) XML processor action file DTD. - $Id: flexml-act.dtd,v 1.7 1999/11/30 18:28:23 krisrose Exp $ - Copyright � 1999 Kristoffer Rose. All rights reserved. + $Id: flexml-act.dtd,v 1.8 2006/07/18 18:21:13 mquinson Exp $ + Copyright (c) 1999 Kristoffer Rose. All rights reserved. This file is part of the FleXML XML processor generator system. - Copyright � 1999 Kristoffer Rose. All rights reserved. + 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 @@ -1,10 +1,11 @@ #!/usr/bin/env perl # Flex(1) XML processor scanner generator. -# Copyright � 1999 Kristoffer Rose. All rights reserved. +# Copyright (C) 1999 Kristoffer Rose. All rights reserved. # # This file is part of the FleXML XML processor generator system. -# Copyright � 1999 Kristoffer Rose. All rights reserved. +# Copyright (C) 1999 Kristoffer Rose. All rights reserved. +# Copyright (C) 2003-2006 Martin Quinson. 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 @@ -22,12 +23,12 @@ use warnings; -my $Id = '$Id: flexml.pl,v 1.48 2006/03/21 13:09:12 mquinson Exp $ '; +my $Id = '$Id: flexml.pl,v 1.61 2006/09/13 16:34:33 wdowling Exp $ '; $Id =~ s/\s*\$\s*//go; # IMPORTS. -use Getopt::Std; +use Getopt::Long; use LWP::UserAgent; use Carp qw/cluck confess/; @@ -41,10 +42,11 @@ use vars qw/ $HEADER /; # generated XML processor API header use vars qw/ $ACTIONS /; # the actions file use vars qw/ $APPLICATION /; # generated XML application +$SKELETON = "./skel"; # default value + # OPTIONS (and other globals). my $Use; # usage string -my %opt = (); # options my $debug; # -d option flag my $verbose; # -v option flag @@ -53,9 +55,19 @@ my $nofail; # -X option flag my $quiet_parser; # -q option flag my $uri; # -u option uri my $pubid; # -p option string -my $stacksize; # -b option flag -my $tagprefix; # -P option flag -my $actbin; # -T option content +my $sysid; # --sysid option string +my $stacksize=100000; # -b option flag +my $tagprefix=""; # -P option flag +my $actbin="./flexml-act"; # -T option content +my $init_header=""; # -i option string + +my $header; # -H option flag/content +my $dummy; # -D option flag/content +my $standalone; # -A option flag/content +my $scanner; # -S option flag/content +my $actions; # -a option content + +my $dryrun; # -n option flag my $dtd; # DTD file name (or URI) my $dtdrevision; # DTD version pruned from file @@ -166,7 +178,8 @@ sub redistribute { # Print C comment with generated file "license". my ($pre) = @_; print <<EOT; $pre This program was generated with the FleXML XML processor generator. -$pre FleXML is Copyright � 1999-2005 Kristoffer Rose. All rights reserved. +$pre FleXML is Copyright (C) 1999-2005 Kristoffer Rose. All rights reserved. +$pre FleXML is Copyright (C) 2003-2006 Martin Quinson. All rights reserved. $pre ($Id). $pre $pre There are two, intertwined parts to this program, part A and part B. @@ -175,8 +188,8 @@ $pre Part A $pre ------ $pre $pre Some parts, here collectively called "Part A", are found in the -$pre FleXML package. They are Copyright � 1999-2005 Kristoffer Rose. -$pre All rights reserved. +$pre FleXML package. They are Copyright (C) 1999-2005 Kristoffer Rose +$pre and Copyright (C) 2003-2006 Martin Quinson. All rights reserved. $pre $pre You can redistribute, use, perform, display and/or modify "Part A" $pre provided the following two conditions hold: @@ -234,12 +247,22 @@ sub api_types { # Print XML application interface types. sub api_data { # Print XML application interface parameters. - my ($pre) = @_; + my ($pre) = @_; # pre should be a storage class spec like 'static' or 'extern' print "/* FleXML-provided data. */\n"; - print $pre . "const char* ${tagprefix}pcdata;\n"; + print $pre . "int ${tagprefix}pcdata_ix;\n"; + print "extern char *${tagprefix}bufferstack;\n"; + print "#define ${tagprefix}pcdata (${tagprefix}bufferstack + ${tagprefix}pcdata_ix)\n"; + for (keys %atttype) { if (m.($Nmtoken)[/]($Nmtoken).xo) { - print $pre . "AT_${tagprefix}$ctag{$1}_$catt{$2} A_${tagprefix}$ctag{$1}_$catt{$2};\n"; + print $pre . "AT_${tagprefix}$ctag{$1}_$catt{$2} AX_${tagprefix}$ctag{$1}_$catt{$2};\n"; + print "#define A_${tagprefix}$ctag{$1}_$catt{$2} "; + if ($enumtype{$_}) { + print "AX_${tagprefix}$ctag{$1}_$catt{$2}\n"; + } + else { + print "(${tagprefix}bufferstack + AX_${tagprefix}$ctag{$1}_$catt{$2})\n"; + } } } } @@ -248,7 +271,7 @@ sub api_data { # Print XML application interface parameters. sub expandparametersat { # Expand parameter entities in $_ at $place. my ($place) = @_; while ( m/$place\s*%($Name);/ ) { - if ($parameter{$1}) { + if (defined $parameter{$1}) { s/$place(\s*)%($Name);/ ' '. $1 . $parameter{$2} . ' ' /xe; } } @@ -300,6 +323,16 @@ sub geturl { # Insert contents of URL into input stream at current point # } } +# add attribute to list of all default attributes +my @default_attributes; +my $next_att_loc = 1; +sub add_def_att { + my ($att) = @_; + my $retval = $next_att_loc; + push @default_attributes, ($att); + $next_att_loc += length($att) + 1; + return $retval; +} sub nextline { # return one input line @@ -487,49 +520,71 @@ sub analysechildren { # Analyse DTD children specification; return # Parse options. -$Use = "Usage: flexml [-ASHDvdqnLXV] [-s skel] [-T actbin] [-p pubid] [-u uri]\n" - . " [-b stack_size] [-r roottags] [-a actions] [-P prefix] name[.dtd]"; - -getopts('ASHDvdnLXVqp:b:P:s:T:u:r:a:', \%opt); +$Use = "Usage: flexml [-ASHDvdqnLXV] [-s skel] [-T actbin] [--sysid sysid] " + . "[-p pubid] [-u uri] [-i init_header]\n" + . " [-b stack_increment] [-r roottags] [-a actions] [-P prefix] name[.dtd]"; -# Version! -print "FleXML version $Id.\n" if $opt{V} or $opt{v}; -exit 0 if $opt{V}; +sub show_version { -# Debugging? -$debug = $opt{d}; -$verbose = $opt{v}; + exit 0; +} + +Getopt::Long::Configure ("bundling"); +GetOptions( + # Debugging and verbosity + "debug|d" => \$debug, + "verbose|v" => \$verbose, + "quiet|q" => \$quiet_parser, + + # Version! + "version|V" => sub { print "FleXML version $Id.\n"; exit 0; }, -# Line numbers? -$lineno = $opt{L}; + # dry-run ? + "dry-run|n" => \$dryrun, -# Quiet parser? -$quiet_parser = $opt{q}; + # Line numbers? + "lineno|L" => \$lineno, -# Exit without fail message? -$nofail = $opt{X}; + # Exit without fail message? + "nofail|X" => \$nofail, -# Specific root tags? -if ($opt{r}) { - for (split ',',$opt{r}) { $roottags{$_} = 'true'; } -} + # Specific root tags? + "root-tags|r=s" => sub { + for (split ',',$_[1]) { $roottags{$_} = 'true'; } + }, -# Specific stack size? -$stacksize = ($opt{'b'} ? $opt{'b'} : 100000); + # Specific stack size? + "stack-increment|b=s" => \$stacksize, + + # Specific tagprefix? + "tag-prefix|P=s" => sub { $tagprefix = $_[1]."_" }, + + # Specific actbin? (internal use) + "act-bin|T=s" => \$actbin, + + # Set skeleton scanner file name and check it is readable (if needed). + "skel|s=s" => sub { + $SKELETON = $_[1]; + die "$0: No skeleton file $SKELETON.\n" if not -r $SKELETON and $_[1]; + }, + + # Set document type URI and PUBID. + "uri|u=s" => \$uri, + "pubid|p=s" => \$pubid, + "sysid=s" => \$sysid, -# Specific tagprefix? -$tagprefix = ($opt{'P'} ? $opt{'P'}."_" : ""); + # name of header file to be included in initial section of generated .l file + "init_header|i=s" => \$init_header, -# Specific actbin? -$actbin = ($opt{'T'} ? $opt{'T'} : "./flexml-act"); - -# Set skeleton scanner file name and check it is readable (if needed). -$SKELETON = ($opt{'s'} ? $opt{'s'} : './skel'); -die "$0: No skeleton file $SKELETON.\n" if not -r $SKELETON and $opt{S}; + # What to generate + "header|H:s" => sub { $header = $_[1] || 'true' }, + "dummy|D:s" => sub { $dummy = $_[1] || 'true' }, + "stand-alone|A" => \$standalone, + "scanner|S:s" => sub { $scanner = $_[1] || 'true' }, + "actions|a=s" => \$actions + ); -# Set document type URI and PUBID. -$uri = $opt{u} if $opt{u}; -$pubid = $opt{p} if $opt{p}; +print "FleXML version $Id.\n" if $verbose; # Set DTD file name...and extract prefix for later my $prefix = $ARGV[0]; @@ -546,30 +601,30 @@ else { # Selection options: If none of -SHDA specified then default to -SH. # Furthermore -a implies -D. -$opt{S} = $opt{H} = 'true' unless ($opt{S} or $opt{H} or $opt{D} or $opt{A}); -$opt{D} ||= $opt{a} unless $opt{A}; +$scanner = $header = 'true' unless ($scanner or $header or $dummy or $standalone); +$dummy ||= $actions unless $standalone; # Set default (DTD-based) output file names. -$SCANNER = "$prefix.l"; -$HEADER = "$prefix.h"; -$APPLICATION = "$prefix-dummy.c"; +$SCANNER = (!defined($scanner)) || $scanner eq 'true' ? "$prefix.l" : $scanner; +$HEADER = (!defined($header)) || $header eq 'true' ? "$prefix.h" : $header; +$APPLICATION = (!defined($dummy)) || $dummy eq 'true' ? "$prefix-dummy.c" : $dummy; # Set actions=based output file names, if any. -if ($ACTIONS = $opt{a}) { - $opt{a} =~ s/\.[a-z]+$//; - $APPLICATION = "$opt{a}.c"; +if ($ACTIONS = $actions) { + $actions =~ s/\.[a-z]+$//; + $APPLICATION = "$actions.c"; } # Stand-alone applications... -if ($opt{A}) { - die "$0: -A conflicts with -SHD.\n" if ($opt{S} or $opt{H} or $opt{D}); +if ($standalone) { + die "$0: -A conflicts with -SHD.\n" if ($scanner or $header or $dummy); $SCANNER = $APPLICATION; $SCANNER =~ s/\.c$/.l/; } # Dry-run? -if ($opt{n}) { - $opt{A} = $opt{S} = $opt{H} = $opt{D} = undef; +if ($dryrun) { + $standalone = $scanner = $header = $dummy = undef; } @@ -672,11 +727,12 @@ while (@inputs) { # While there are lines... # strip off the matched code from the beginning of $_ $_ = $'; #' + # place the newly found tag into the list of tags @tags + die place()."Repeated element $tag.\n" if exists $source{$tag}; + # ????? - most of the time $orig is undef $source{$tag} = "$orig"; - # place the newly found tag into the list of tags @tags - die place()."Repeated element $tag.\n" if $ctag{$tag}; push @tags, $tag; # Create C-friendly tag names. @@ -815,12 +871,12 @@ while (@inputs) { # While there are lines... } # ...and string/token types. else { - $typeof{"$tag/$attribute"} = 'const char*'; + $typeof{"$tag/$attribute"} = 'int'; if ($default) { - $initof{"$tag/$attribute"} = "\"$default\""; + $initof{"$tag/$attribute"} = add_def_att($default); } else { - $initof{"$tag/$attribute"} = 'NULL'; + $initof{"$tag/$attribute"} = '0'; } # Special treatment of token types. @@ -839,10 +895,15 @@ while (@inputs) { # While there are lines... $literaltype{"$tag/$attribute"} = '{Nmtokens}'; } elsif ( $type eq 'ENTITY' ) { - die place()."ENTITY attribute type unimplemented.\n"; + #die place()."ENTITY attribute type unimplemented.\n"; + $literaltype{"$tag/$attribute"} = '{Name}'; + print STDERR place()."Warning: attribute type `$type' not validated.\n"; } elsif ( $type eq 'ENTITIES' ) { - die place()."ENTITIES attribute type unimplemented.\n"; + #die place()."ENTITIES attribute type unimplemented.\n"; + $literaltype{"$tag/$attribute"} = '{Names}'; + print STDERR place()."Warning: attribute type `$type' not validated.\n"; + } elsif ( $type ne 'CDATA' ) { die place()."Unknown AttType `$type'.\n"; @@ -980,7 +1041,7 @@ if (not %roottags) { } # Handling prefix -if($opt{P}) { +if(length($tagprefix)) { my($h,$k); my(@hashlist) = (\%states,\%emptytrans,\%instates,\%startstate, \%endstates,\%exittrans); @@ -1016,7 +1077,32 @@ if ($debug) { return $out; } - print '%opt = (' . printhash(\%opt) . ")\n"; + # display the options we got + print "debug=".($debug||'undef')."\n"; + print "verbose=".($verbose||'undef')."\n"; + print "quiet=".($quiet_parser||'undef')."\n"; + + print "dry-run=".($dryrun||'undef')."\n"; + print "lineno=".($lineno||'undef')."\n"; + + print "nofail=".($nofail||'undef')."\n"; + + print "stack-increment=".($stacksize||'undef')."\n"; + print "tag-prefix=".($tagprefix||'undef')."\n"; + + print "act-bin=".($actbin||'undef')."\n"; + + print "skel=".($SKELETON||'undef')."\n"; + + print "uri=".($uri||'undef')."\n"; + print "pubid=".($pubid||'undef')."\n\n"; + print "sysid=".($sysid||'undef')."\n\n"; + + print "header=".($header||'undef')."\n"; + print "dummy=".($dummy||'undef')."\n"; + print "stand-alone=".($standalone||'undef')."\n"; + print "scanner=".($scanner||'undef')."\n"; + print "actions=".($actions||'undef')."\n\n"; print '%source = (' . printhash(\%source) . ")\n"; print "\n"; @@ -1065,7 +1151,7 @@ if ($debug) { # WRITE API HEADER (if requested). -if ($opt{H}) { +if ($header) { print STDOUT "Generating XML processor header in `$HEADER'.\n" if $verbose; @@ -1112,10 +1198,10 @@ if ($opt{H}) { # WRITE XML PROCESSOR (if requested). -if ($opt{S} or $opt{A}) { +if ($scanner or $standalone) { print STDOUT "Writing XML processor" - . ($opt{a} || $opt{A} ? " and application" : "") + . ($actions || $standalone ? " and application" : "") . " onto `$SCANNER'.\n" if $verbose; open SCANNER, "+>$SCANNER"|| die "$0: cannot write $SCANNER: $!\n"; @@ -1154,11 +1240,14 @@ if ($opt{S} or $opt{A}) { print "#define FLEXML_yylineno\n" if $lineno; print "#define FLEXML_NOFAIL\n" if $nofail; print "#define FLEXML_quiet_parser\n" if $quiet_parser; - print "#define FLEXML_HasMixed\n" if %inmixed; + print "#ifndef FLEXML_BUFFERSTACKSIZE\n"; print "#define FLEXML_BUFFERSTACKSIZE $stacksize\n"; + print "#endif\n"; + print "#define FLEXML_NEED_BUFFERLIT\n" + if (scalar(%literaltype) or ($#default_attributes >= 0)); print "\n"; - if ($opt{A}) { + if ($standalone) { api_functions('static ',';'); print "\n"; api_types(); @@ -1168,11 +1257,18 @@ if ($opt{S} or $opt{A}) { else { print "/* XML processor api. */\n"; print "#include \"$HEADER\"\n\n" - if ($opt{H}); + if ($header); api_data(''); } } + elsif ( /^FLEXML_INCLUDE_INIT_HEADER$/ ) { + if ($init_header) { + print "/* User-supplied header */\n"; + print "#include \"$init_header\"\n"; + } + } + elsif ( /^FLEXML_FLEX_OPTIONS$/ ) { print "%option yylineno\n" if $lineno; @@ -1203,7 +1299,10 @@ if ($opt{S} or $opt{A}) { my ($state, $tag); print " /* FleXML_init */\n"; - print " next = bufferstack;\n"; + print " bnext = inext = 1;\n"; + for my $att (@default_attributes) { + print " ${tagprefix}bufferliteral('\\0', &bnext, \"$att\");\n"; + } print " if(!${tagprefix}statenames) {${tagprefix}statenames= (const char **)calloc(IMPOSSIBLE,sizeof(char*));\n"; for ('PROLOG','DOCTYPE','EPILOG','INCOMMENT','INPI','VALUE1','VALUE2','CDATA') { print " ${tagprefix}statenames[$_] = NULL;\n"; @@ -1220,8 +1319,9 @@ if ($opt{S} or $opt{A}) { } elsif ( /^FLEXML_DOCTYPES$/ ) { - my $sysid = ( $uri ? "(\"'$uri'\"|\"\\\"$uri\\\"\")" - : "(\"'$dtd'\"|\"\\\"$dtd\\\"\")" ); + $sysid = $sysid ? "(\"'$sysid'\"|\"\\\"$sysid\\\"\")" + : ( $uri ? "(\"'$uri'\"|\"\\\"$uri\\\"\")" + : "(\"'$dtd'\"|\"\\\"$dtd\\\"\")" ); for (keys %roottags) { my $c = $ctag{$_}; @@ -1268,11 +1368,6 @@ if ($opt{S} or $opt{A}) { } $exitswitch .= " }\n"; } - - - - - # Start or empty tag: initialise attribute list. print "\n"; @@ -1288,9 +1383,9 @@ if ($opt{S} or $opt{A}) { print ">\"<$tag\"{s} {\n"; for my $attribute (@myattributes) { - print " A_${tagprefix}${myctag}_$catt{$attribute} = " . $initof{"$tag/$attribute"} . ";\n"; + print " AX_${tagprefix}${myctag}_$catt{$attribute} = " . $initof{"$tag/$attribute"} . ";\n"; } - print " ENTER(AL_${tagprefix}$myctag);\n"; + print " ENTER(AL_${tagprefix}$myctag); pushbuffer(0);\n"; print " }\n"; # print " . FAIL(\"Unexpected character `%c': `<$tag' expected.\",yytext[0]);\n"; @@ -1333,23 +1428,23 @@ if ($opt{S} or $opt{A}) { print " \"$attribute\"{Eq}\"'" . $attdef{"$tag/$attribute"} . "'\"" . " |\n" . " \"$attribute\"{Eq}\"\\\"" . $attdef{"$tag/$attribute"} . "\\\"\"" - . " A_${tagprefix}${myctag}_$catt{$attribute}" + . " AX_${tagprefix}${myctag}_$catt{$attribute}" . " = " . $initof{"$tag/$attribute"} . ";\n"; } elsif ($type = $literaltype{"$tag/$attribute"}) { # - (non-fixed) literal-type attribute: scan literal string directly, or - print " \"$attribute\"{Eq}\'$type\' BUFFERLITERAL('\\\'',A_${tagprefix}${myctag}_$catt{$attribute});\n"; + print " \"$attribute\"{Eq}\'$type\' BUFFERLITERAL('\\\'',AX_${tagprefix}${myctag}_$catt{$attribute});\n"; - print " \"$attribute\"{Eq}\\\"$type\\\" BUFFERLITERAL('\"',A_${tagprefix}${myctag}_$catt{$attribute});\n"; + print " \"$attribute\"{Eq}\\\"$type\\\" BUFFERLITERAL('\"',AX_${tagprefix}${myctag}_$catt{$attribute});\n"; } else { # - (non-fixed non-literal) attribute: scan string with entity expansion. - print " \"$attribute\"{Eq}\\' ENTER(VALUE1); BUFFERSET(A_${tagprefix}${myctag}_$catt{$attribute});\n"; - print " \"$attribute\"{Eq}\\\" ENTER(VALUE2); BUFFERSET(A_${tagprefix}${myctag}_$catt{$attribute});\n"; + print " \"$attribute\"{Eq}\\' ENTER(VALUE1); BUFFERSET(AX_${tagprefix}${myctag}_$catt{$attribute});\n"; + print " \"$attribute\"{Eq}\\\" ENTER(VALUE2); BUFFERSET(AX_${tagprefix}${myctag}_$catt{$attribute});\n"; } print "\n"; @@ -1360,13 +1455,13 @@ if ($opt{S} or $opt{A}) { print " \">\" {\n"; for my $attribute (@myattributes) { if ($required{"$tag/$attribute"}) { - print " if (!A_${tagprefix}$ctag{$tag}_" . variablify($attribute) . ")" + print " if (!AX_${tagprefix}$ctag{$tag}_" . variablify($attribute) . ")" . " FAIL(\"Required attribute `$attribute' not set for `$tag' element.\");\n"; } } print " LEAVE; STag_${tagprefix}$myctag();" - . (%inmixed ? ' pushbuffer('."${tagprefix}".'pcdata);' : '') - . ($mixed{$tag} ? 'BUFFERSET('."${tagprefix}".'pcdata)' : "${tagprefix}".'pcdata = NULL'). ";" + . (%inmixed ? ' pushbuffer('."${tagprefix}".'pcdata_ix);' : '') + . ($mixed{$tag} ? 'pushbuffer('."${tagprefix}".'pcdata_ix); BUFFERSET('."${tagprefix}".'pcdata_ix);' : "${tagprefix}".'pcdata_ix = 0'). ";" . " ENTER($startstate{$tag});\n"; print " }\n"; # @@ -1375,16 +1470,16 @@ if ($opt{S} or $opt{A}) { print " \"/>\" {\n"; for my $attribute (@myattributes) { if ($required{"$tag/$attribute"}) { - print " if (!A_${tagprefix}$ctag{$tag}_" . variablify($attribute) . ")" + print " if (!AX_${tagprefix}$ctag{$tag}_" . variablify($attribute) . ")" . " FAIL(\"Required attribute `$attribute' not set for `$tag' element.\");\n"; } } print " LEAVE; STag_${tagprefix}$myctag();" - . (%inmixed ? ' pushbuffer('."${tagprefix}".'pcdata);' : '') - . " ${tagprefix}".'pcdata = ' . ($mixed{$tag} ? '""' : 'NULL') . ';' + . (%inmixed ? ' pushbuffer('."${tagprefix}".'pcdata_ix);' : '') + . " ${tagprefix}".'pcdata_ix = 0;' . " ETag_${tagprefix}$myctag();" - . (%inmixed ? " ${tagprefix}".'pcdata = popbuffer();' : '') - . "\n"; + . (%inmixed ? " ${tagprefix}".'pcdata_ix = popbuffer();' : '') + . " popbuffer(); /* attribute */\n"; # print $exitswitch; print " }\n"; @@ -1408,7 +1503,9 @@ if ($opt{S} or $opt{A}) { print " LEAVE;\n"; print " BUFFERDONE;\n" if $mixed{$tag}; print " ETag_${tagprefix}$myctag();\n"; - print " ${tagprefix}pcdata = popbuffer();\n" if %inmixed; + print " ${tagprefix}pcdata_ix = popbuffer();\n" if $mixed{$tag}; + print " ${tagprefix}pcdata_ix = popbuffer();\n" if %inmixed; + print " popbuffer(); /* attribute */\n"; print $exitswitch; print " }\n"; @@ -1505,13 +1602,15 @@ if ($opt{S} or $opt{A}) { s/element_context/${tagprefix}element_context/g; s/parse_err_msg/${tagprefix}parse_err_msg/g; s/rcs_flexml_skeleton/rcs_${tagprefix}flexml_skeleton/g; + s/bufferliteral/${tagprefix}bufferliteral/g; + s/bufferstack/${tagprefix}bufferstack/g; print; } } close SKELETON || die "$0: Cannot close $SKELETON: $!\n"; - unless ($opt{A}) { + unless ($standalone) { close SCANNER || die "$0: Cannot close $SCANNER: $!\n"; } } @@ -1521,10 +1620,10 @@ if ($opt{S} or $opt{A}) { # WRITE APPLICATION. -if ($opt{D}) { +if ($dummy) { print STDOUT "Writing XML" - . ($opt{a} ? "" : " dummy") + . ($actions ? "" : " dummy") . " application onto `$APPLICATION'.\n" if $verbose; open APPLICATION, "+>$APPLICATION" || die "$0: Cannot write $APPLICATION: $!\n"; @@ -1546,7 +1645,7 @@ if ($opt{D}) { } -if ($opt{D} or $opt{A}) { +if ($dummy or $standalone) { # Get requested actions. if ($ACTIONS) { @@ -1589,23 +1688,17 @@ if ($opt{D} or $opt{A}) { if ($tag) { while ( s/\{($Name)\}/A_${tagprefix}$ctag{$tag}_$catt{$1}/x ) { - die "\"$ACTIONS\", line $lineno: Attributes only allowed in start tag.\n" - if not $isstart; die "\"$ACTIONS\", line $lineno: Unknown attribute `$1' for <$tag>.\n" if not $atttype{"$tag/$1"}; } while ( s/\{[!]($Name)\}/AU_${tagprefix}$ctag{$tag}_$catt{$1}/x ) { - die "\"$ACTIONS\", line $lineno: Attributes only allowed in start tag.\n" - if not $isstart; die "\"$ACTIONS\", line $lineno: Unknown attribute `$1' for <$tag>.\n" if not $atttype{"$tag/$1"}; } while ( s|\{($Name)=($Name)\}| "A_${tagprefix}$ctag{$tag}_$catt{$1}_" . variablify($2); |xe ) { - die "\"$ACTIONS\", line $lineno: Attributes only allowed in start tag.\n" - if not $isstart; my ($att,$elt) = ($1,$2); die "\"$ACTIONS\", line $lineno: Unknown attribute $1 for <$tag>.\n" if not $atttype{"$tag/$1"}; @@ -1623,6 +1716,7 @@ if ($opt{D} or $opt{A}) { die "\"$ACTIONS\", line $lineno: Malformed annotation `$&' in <$tag> action.\n" if m|\{[^;\s]+\}|o; } + print STDERR "Action: $_" if $debug; print $_; } @@ -1635,10 +1729,10 @@ if ($opt{D} or $opt{A}) { } -if ($opt{D}) { +if ($dummy) { close APPLICATION || die "$0: Cannot close $APPLICATION: $!\n"; } -elsif ($opt{A}) { +elsif ($standalone) { close SCANNER || die "$0: Cannot close $SCANNER: $!\n"; } @@ -1656,6 +1750,7 @@ B<flexml> [B<-ASHDvdnLXV>] [B<-s>I<skel>] [B<-p>I<pubid>] +[B<-i>I<init_header>] [B<-u>I<uri>] [B<-r>I<rootags>] [B<-a>I<actions>] @@ -1700,102 +1795,114 @@ I<Flexml> takes the following options. =over 4 -=item B<-A> +=item B<--stand-alone>, B<-A> Generate a I<stand-alone> scanner application. If combined with B<-a>I<actions> then the application will be named as I<actions> with the extension replaced by F<.l>, otherwise it will be in I<name>F<.l>. Conflicts with B<-S>, B<-H>, and B<-D>. -=item B<-a> I<actions> +=item B<--actions> I<actions>, B<-a> I<actions> Uses the I<actions> file to produce an XML application in the file with the same name as I<actions> after replacing the extension with F<.c>. If combined with B<-A> then instead the stand-alone application will include the action functions. -=item B<-D> +=item B<--dummy> B<[>I<app_name>B<]>, B<-D> B<[>I<app_name>B<]> -Generate a dummy application I<name>F<-dummy.c> with just empty -functions to be called by the XML processor. If combined with -B<-a>I<actions> then the application will insert the specified -actions and be named as I<actions> with the extension replaced by -F<.c>. Conflicts with B<-A>; implied by B<-a> unless either of -B<-SHD> is specified. +Generate a dummy application with just empty functions to be called by the +XML processor. If I<app_name> is not specified on the command line, it +defaults to I<name>F<-dummy.c>. If combined with B<-a> I<actions> then the +application will insert the specified actions and be named as I<actions> +with the extension replaced by F<.c>. Conflicts with B<-A>; implied by +B<-a> unless either of B<-SHD> is specified. -=item B<-d> +=item B<--debug>, B<-d> Turns on debug mode in the flex scanner and also prints out the details of the DTD analysis performed by I<flexml>. -=item B<-H> +=item B<--header> B<[>I<header_name>B<]>, B<-H> B<[>I<header_name>B<]> -Generate the header file I<name>F<.h>. Conflicts with B<-A>; on by +Generate the header file. If the I<header_name> is not specified on the +command line, defaults to I<name>F<.h>. Conflicts with B<-A>; on by default if none of B<-SHD> specified. -=item B<-L> +=item B<--lineno>, B<-L> Makes the XML processor (as produced by I<flex>(1)) count the lines in the input and keep it available to XML application actions in the integer C<yylineno>. (This is off by default as the performance overhead is significant.) -=item B<-q> +=item B<--quiet>, B<-q> Prevents the XML processor (as produced by I<flex>(1)) from reporting the error it runs into on stderr. Instead, users will have to pool for error messages with the parse_err_msg() function. By default, error messages are written on stderr. -=item B<-n> +=item B<--dry-run>, B<-n> "Dry-run": do not produce any of the output files. -=item B<-p> I<pubid> +=item B<--pubid> I<pubid>, B<-p> I<pubid> Sets the document type to be C<PUBLIC> with the identifier I<pubid> instead of C<SYSTEM>, the default. -=item B<-r> I<roottags> +=item B<--init_header> I<init_header>, B<-i> I<init_header> + +Puts a line containing C<#include "init_header"> in the C<%{...%}> section +at the top of the generated .l file. This may be useful for making various +flex C<#define>s, for example C<YY_INPUT> or C<YY_DECL>. + +=item B<--sysid>=I<sysid> + +Overrides the C<SYSTEM> id of the accepted DTD. Sometimes usefull when your +dtd is placed in a subdirectory. + +=item B<--root-tags> I<roottags>, B<-r> I<roottags> Restricts the XML processor to validate only documents with one of the root elements listed in the comma-separated I<roottags>. -=item B<-S> +=item B<--scanner> B<[>I<scanner_name>B<]>, B<-S> B<[>I<scanner_name>B<]> -Generate the scanner I<name>F<.l>. Conflicts with B<-A>; on by -default if none of B<-SHD> specified. +Generate the scanner. If I<scanner_name> is not given on command line, it +defaults to I<name>F<.l>. Conflicts with B<-A>; on by default if none of +B<-SHD> specified. -=item B<-s> I<skel> +=item B<--skel> I<skel>, B<-s> I<skel> Use the skeleton scanner I<skel> instead of the default. -=item B<-T> I<flexml-act> +=item B<--act-bin> I<flexml-act>, B<-T> I<flexml-act> This is an internal option mainly used to test versions of flexml not installed yet. -=item B<-b> I<stack_size> +=item B<--stack-increment> I<stack_increment>, B<-b> I<stack_increment> -Sets the FLEXML_BUFFERSTACKSIZE to stack_size (100000 by default). Use -this option when you get an error like "Assertion `next<limit' -failed". +Sets the FLEXML_BUFFERSTACKSIZE to stack_increment (100000 by default). This +controls how much the data stack grows in each realloc(). -=item B<-p> I<STRING> +=item B<--tag-prefix> I<STRING>, B<-O> I<STRING> Use STRING to differentiate multiple versions of flexml in the same C -code. +code, just like the -P flex argument. -=item B<-u> I<uri> +=item B<--uri> I<uri>, B<-u> I<uri> Sets the URI of the DTD, used in the C<DOCTYPE> header, to the specified I<uri> (the default is the DTD name). -=item B<-v> +=item B<--verbose>, B<-v> Be verbose: echo each DTD declaration (after parameter expansion). -=item B<-V> +=item B<--version>, B<-V> Print the version of I<flexml> and exit. @@ -1946,11 +2053,6 @@ in particular C<xml:spaces> should be supported. =item * -The XML processor currently uses a fixed-size buffer to read -C<pcdata>. It should not. - -=item * - The DTD parser is presently a perl hack so it may parse some DTDs badly; in particular the expansion of parameter entities may not conform fully to the XML specification. @@ -1984,7 +2086,7 @@ REC-xml-1998-0210). =head1 AUTHOR -I<Flexml> was written by Kristoffer H�gsbro Rose, +I<Flexml> was written by Kristoffer Rose, E<lt>C<krisrose@debian.org>E<gt>. =head1 COPYRIGHT @@ -4,7 +4,7 @@ <html> <head> <title>Generating Fast Validating XML Processors</title> - <!--$Id: paper.html,v 1.12 2005/04/06 10:12:27 mquinson Exp $--> + <!--$Id: paper.html,v 1.13 2006/07/18 18:21:13 mquinson Exp $--> <style type="text/css"> <!-- BODY { BACKGROUND-COLOR: #ffffff; FONT-FAMILY: arial, times new roman, sans-serif; } @@ -385,7 +385,7 @@ gcc -Wall -ansi -pedantic xhtml-href.o xhtml1-transitional.o -o xhtml-href <p> This is useful for XML applications that are meant to process a large number of documents in a fixed format. One such - application is the NTSys �-payment transaction server which is + application is the NTSys u-payment transaction server which is implemented as an Apache module where performance is of premium importance. Using FleXML permits a highly modular development of modules for the various transaction types based on a common @@ -445,7 +445,7 @@ gcc -Wall -ansi -pedantic xhtml-href.o xhtml1-transitional.o -o xhtml-href </dl> <hr> - <address>Copyright � + <address>Copyright (c) <a href="mailto:krisrose@debian.org">Kristoffer Rose</a>. <!-- Created: Thu Dec 9 08:09:41 CET 1999 --> <!-- hhmts start -->Last modified: Tue Feb 11 13:56:40 EST 2003 <!-- hhmts end --> @@ -1,8 +1,8 @@ /* Flex(1) XML processor skeleton scanner (in -*-C-*-). - * Copyright � 1999 Kristoffer Rose. All rights reserved. + * Copyright (C) 1999 Kristoffer Rose. All rights reserved. * * This file is part of the FleXML XML processor generator system. - * Copyright � 1999 Kristoffer Rose. All rights reserved. + * 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 @@ -25,7 +25,7 @@ /* Version strings. */ const char rcs_flexml_skeleton[] = - "$Id: skel,v 1.28 2006/03/21 12:04:13 legranda Exp $"; + "$Id: skel,v 1.38 2006/09/12 18:05:45 wdowling Exp $"; FLEXML_VERSION /* ANSI headers. */ @@ -36,6 +36,10 @@ FLEXML_VERSION #include <stdarg.h> #include <ctype.h> +#ifndef FLEXML_INDEXSTACKSIZE +#define FLEXML_INDEXSTACKSIZE 1000 +#endif + /* Generated definitions. */ FLEXML_DEFINITIONS @@ -59,64 +63,99 @@ FLEXML_DEFINITIONS #define FAIL return fail static int fail(const char*, ...); -const char * parse_err_msg(void); + +enum {flexml_max_err_msg_size = 512}; +static char flexml_err_msg[flexml_max_err_msg_size]; +const char * parse_err_msg() +{ + return flexml_err_msg; +} +static void reset_parse_err_msg() +{ + flexml_err_msg[0] = '\0'; +} /* Cleanup */ static void cleanup(void); #define CLEANUP cleanup() /* Text buffer stack handling. */ -static char bufferstack[FLEXML_BUFFERSTACKSIZE]; -static char* limit = bufferstack + FLEXML_BUFFERSTACKSIZE; -typedef struct BufferLast_s { - struct BufferLast_s *old; char* saved; char new1[1]; -} BufferLast; -#ifdef FLEXML_HasMixed -static BufferLast* last = (BufferLast*)0; -#endif -static char* next = bufferstack; +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 = next) -#define BUFFERPUTC(C) (assert(next<limit), *(next++) = (C)) +#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) -static void bufferliteral(char c, const char** pp, char* text) +#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() +{ + 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() +{ + 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) { - char *s = strchr(text,c), *e = strrchr(text,c); + const char *s = (c ? strchr(text,c) : text-1), *e = strrchr(text,c); assert(s <= e); BUFFERSET(*pp); while (++s<e) { - if (isspace(*s)) { BUFFERPUTC(' '); while (isspace(*s)) ++s; } + if (isspace(*s) && c) { BUFFERPUTC(' '); while (isspace(*s)) ++s; } else BUFFERPUTC(*s); } BUFFERDONE; } +#endif -#ifdef FLEXML_HasMixed -static void pushbuffer(char* p) +static void pushbuffer(int p) { - BufferLast* l = (BufferLast*)next; - assert(next < limit); - l->old = last; - l->saved = p; - next = l->new1; - last = l; + ck_ilimit(); + indexstack[inext++] = p; + indexstack[inext++] = bnext; } -static char* popbuffer(void) +static int popbuffer(void) { - BufferLast* l = last; - assert(last != (BufferLast*)0); - last = l->old; - next = (char*)l; - return l->saved; + assert(inext >= 2); + bnext = indexstack[--inext]; + return indexstack[--inext]; } -#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); }} + +FLEXML_INCLUDE_INIT_HEADER + %} /* Flex standard options. */ @@ -173,6 +212,22 @@ FLEXML_EXTRA_DEFINITIONS /* Bypass Flex's default INITIAL state and begin by parsing the XML prolog. */ SET(PROLOG); + 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. */ @@ -289,19 +344,39 @@ 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]); + if (statenames) { + 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); } +void print_bufferstack() +{ + int i; + fputs("Buffer: ", stderr); + for (i = 0; i < blimit; i++) { + if ( bufferstack[i] == '\377' ) break; + putc(bufferstack[i], stderr); + } + putc('\n', stderr); +} + static void debug_enter(int state, const char* statename) { yy_push_state(state); - if (yy_flex_debug) print_yy_stack("--ENTER(%s) : ",statename); + if (yy_flex_debug) { + print_yy_stack("--ENTER(%s) : ",statename); + print_bufferstack(); + } } static void debug_leave(void) { - if (yy_flex_debug) print_yy_stack("--LEAVE : "); + if (yy_flex_debug) { + print_yy_stack("--LEAVE : "); + print_bufferstack(); + } yy_pop_state(); } @@ -311,19 +386,6 @@ static void debug_set(int state, const char* statename) { } #endif -enum {flexml_max_err_msg_size = 512}; - -static char flexml_err_msg[flexml_max_err_msg_size]; -const char * parse_err_msg() -{ - return flexml_err_msg; -} - -static void reset_parse_err_msg() -{ - flexml_err_msg[0] = '\0'; -} - static void cleanup(void) { @@ -331,6 +393,11 @@ static void cleanup(void) free(statenames); statenames = NULL; } + free(bufferstack); + bufferstack = NULL; + + free(indexstack); + indexstack = NULL; } diff --git a/testbed/.#Makefile.1.1 b/testbed/.#Makefile.1.1 new file mode 100644 index 0000000..39d4539 --- /dev/null +++ b/testbed/.#Makefile.1.1 @@ -0,0 +1,138 @@ +# $Source: /cvsroot/flexml/flexml/testbed/Makefile,v $ + +# regression testbed Makefile + +##################################################### +# Fixed definitions -- do not modify for new tests +##################################################### + +include ../Makefile.defs + +MAKEUTILS_DIR = . + +# If UNIT_TESTS is test_foo +# and test_foo_out is bar baz +# Then the created files (that need to be deleted by 'make clean' +# will be +# test_foo foo.std{err,out} foo.std{err,out}.diff bar baz bar.diff baz.diff +TEST_INTERMEDIATES = \ + $(UNIT_TESTS) \ + $(UNIT_TESTS:test_%=%.stdout) $(UNIT_TESTS:test_%=%.stdout.diff) \ + $(UNIT_TESTS:test_%=.test_%.stdout.expected) \ + $(UNIT_TESTS:test_%=%.stderr) $(UNIT_TESTS:test_%=%.stderr.diff) \ + $(UNIT_TESTS:test_%=.test_%.stderr.expected) \ + $(foreach var,$(UNIT_TESTS:%=%_out),$(foreach o,$($(var)),$o $(o).diff)) + +# Compares test.out.std[out,err] with expected values +COMPARE_OUT = $(MAKEUTILS_DIR)/CompareOut.pl + +CC = /usr/bin/gcc-3.3 -Wall -ansi +CFLAGS = -O2 -g +#FLEXDEBUG = -d + +FLEXML = /proj/flexml/flexml-from-cvs-20060821/flexml -s /proj/flexml/flexml-from-cvs-20060821/skel + +.PHONY : test +.PHONY : clean + +##################################################### +# test definitions -- add new tests here +##################################################### + +EXES = mixed1 mixed-stratt +INTERMEDIATES = $(EXES) $(EXES:%=%.c) $(EXES:%=%.l) + +UNIT_TESTS = \ + test_mixed1 \ + test_mixed-stratt + + +test : $(UNIT_TESTS) + +# Test mixed1 +test_mixed1_cmd = ./mixed1 < mixed1.in +test_mixed1_deps = mixed1 mixed1.in + +# Test mixed-stratt (mixed content + string attribute) +test_mixed-stratt_cmd = ./mixed-stratt < mixed-stratt.in +test_mixed-stratt_deps = mixed-stratt mixed-stratt.in + +##################################################### +# test build rules -- add new build rules here +##################################################### + + +mixed1: mixed1.dtd mixed1.act + $(FLEXML) -b 1000 -A -amixed1.act mixed1.dtd + $(FLEX) -s -L -t mixed1.l > mixed1.c + $(CC) $(CFLAGS) -o $@ mixed1.c + +mixed-stratt: mixed-stratt.dtd mixed-stratt.act + $(FLEXML) -b 1000 -A -amixed-stratt.act mixed-stratt.dtd + $(FLEX) -s -L -t mixed-stratt.l > mixed-stratt.c + $(CC) $(CFLAGS) -o $@ mixed-stratt.c + + +##################################################### +# test infrastructure -- do not modify for new tests +##################################################### + +clean : + rm -f $(TEST_INTERMEDIATES) $(INTERMEDIATES) + +# When we are building test_foo, the variable $(TEST_BASE) is "foo" +test_% : TEST_BASE = $(@:test_%=%) + +ifndef distribute_deps +# This will take a target and dependency list, and evaluate each dependency +# individually. This only needs to be used on dependency lists that are to +# be in an $(eval ...) function. This is a work-around for a bug in GNU Make +# 3.80, which fails when $(eval)'ing dependency lists longer than about 160 +# characters. +# 1. target +# 2. dependency list +define distribute_deps +$(foreach dep,$(2),$(eval $(1) : $(dep))) +endef +endif + +define unit_test_deps_t +$(1) : .$(1).stdout.expected +$(1) : .$(1).stderr.expected +$$(call distribute_deps,$(1),$($(1)_deps)) +endef + +$(foreach test,$(UNIT_TESTS),$(eval $(call unit_test_deps_t,$(test)))) + + +# To build .test_foo.std{err,out}.expected -- +# If foo.std{err,out}.expected exists, symlink to it +# Else, .test_foo.std{err,out}.expected is a new empty file +# These rules are invoked from rules in the Extradeps section. +# They must be two separate rules (else 'make test' not idempotent +# -- see bug #105) +.test_%.stderr.expected: + @if [ -f $(@:.test_%=%) ]; \ + then $(SYMLINK) $(@:.test_%=%) $@; \ + else touch $@; \ + fi +.test_%.stdout.expected: + @if [ -f $(@:.test_%=%) ]; \ + then $(SYMLINK) $(@:.test_%=%) $@; \ + else touch $@; \ + fi + + +# Unit test rule. Expects: +# UNIT_TESTS = test_foo test_bar (test_ prefix is necessary) +# test_foo_cmd = command to run +# test_foo_deps = dependencies (i.e. inputs to the test, and the executable) +# test_foo_out = files and directories created by running the command +# with corresponding .expected files for comparison + +$(UNIT_TESTS) : + @$(test_$(@:test_%=%)_cmd) > $(@:test_%=%).stdout \ + 2>$(@:test_%=%).stderr || true + @$(PERL) $(COMPARE_OUT) -p '$($(@)_diff_prog)' -- \ + $($(@)_diff_opts) $(@:test_%=%) $($(@)_out) | tee $@ + diff --git a/testbed/CompareOut.pl b/testbed/CompareOut.pl new file mode 100755 index 0000000..a30da20 --- /dev/null +++ b/testbed/CompareOut.pl @@ -0,0 +1,84 @@ +#!/usr/bin/env perl + +# Assume ARGV is ($basename @REST). Print "passed" or "failed" based on the +# following comparisons: + +# Compare $basename.stderr with $basename.stderr.expected +# pass if no difference or +# $basename.stderr is empty and $basename.stderr.expected doesn't exist; +# Compare $basename.stdout with $basename.stdout.expected +# pass if no difference or +# $basename.stdout is empty and $basename.stdout.expected doesn't exist; +# For each file $foo in @REST +# Compare $foo with $foo.expected +# pass if no difference; + + +# Print "passed" if all tests pass, otherwise print +# "failed <file-that-failed>" + +# NOTES +# In order to compare directories, GNU diff must be used. There +# should probably be a test to ensure this. + +# $Id: CompareOut.pl,v 1.2 2006/08/21 17:33:13 wdowling Exp $ +# $Source: /cvsroot/flexml/flexml/testbed/CompareOut.pl,v $ + +use strict; +use Getopt::Std; + +my %args; +getopts('p:', \%args); + +my $diff_prog = $args{'p'} || 'diff'; + +my $diff_opt = ""; +if ($ARGV[0] =~ /^-/) { + $diff_opt = shift; +} + +my $basename = shift; + +my $diff_cmd = "$diff_prog $diff_opt"; + +my $retcode; +my $fail_file; +my $made_stdout = 0; +my $made_stderr = 0; + +# Compare basename.stderr to basename.stderr.expected +if (! -f "$basename.stderr.expected") { + system("touch $basename.stderr.expected"); + $made_stderr = 1; +} + +$retcode = + system("$diff_cmd $basename.stderr $basename.stderr.expected " . + "> $basename.stderr.diff 2>/dev/null"); +system("rm -f $basename.stderr.expected") if $made_stderr; + +$fail_file = "$basename.stderr" if $retcode; + +# Compare basename.stdout to basename.stdout.expected +if ($retcode == 0) { + if (! -f "$basename.stdout.expected") { + system("touch $basename.stdout.expected"); + $made_stdout = 1; + } + + $retcode = + system("$diff_cmd $basename.stdout $basename.stdout.expected " . + "> $basename.stdout.diff 2>/dev/null"); + system("rm -f $basename.stdout.expected") if $made_stdout; + + $fail_file = "$basename.stdout" if $retcode; +} + +while (($retcode == 0) && @ARGV) { + my $file = shift; + # compare file with file.expected + $retcode = system("$diff_cmd $file $file.expected >$file.diff 2>/dev/null"); + $fail_file = $file if $retcode; +} + +print ($retcode ? "failed $fail_file\n" : "passed $basename\n"); diff --git a/testbed/Makefile b/testbed/Makefile new file mode 100644 index 0000000..9410be0 --- /dev/null +++ b/testbed/Makefile @@ -0,0 +1,200 @@ +# $Source: /cvsroot/flexml/flexml/testbed/Makefile,v $ + +# regression testbed Makefile + +##################################################### +# Fixed definitions -- do not modify for new tests +##################################################### + +include ../Makefile.defs + +MAKEUTILS_DIR = . + +# If UNIT_TESTS is test_foo +# and test_foo_out is bar baz +# Then the created files (that need to be deleted by 'make clean' +# will be +# test_foo foo.std{err,out} foo.std{err,out}.diff bar baz bar.diff baz.diff +TEST_INTERMEDIATES = \ + $(UNIT_TESTS) \ + $(UNIT_TESTS:test_%=%.stdout) $(UNIT_TESTS:test_%=%.stdout.diff) \ + $(UNIT_TESTS:test_%=.test_%.stdout.expected) \ + $(UNIT_TESTS:test_%=%.stderr) $(UNIT_TESTS:test_%=%.stderr.diff) \ + $(UNIT_TESTS:test_%=.test_%.stderr.expected) \ + $(foreach var,$(UNIT_TESTS:%=%_out),$(foreach o,$($(var)),$o $(o).diff)) + +# Compares test.out.std[out,err] with expected values +COMPARE_OUT = $(MAKEUTILS_DIR)/CompareOut.pl + +#CC = /usr/bin/gcc-3.3 -Wall +#CFLAGS = -O2 -g +#FLEXDEBUG = -d + +FLEXML = ../flexml -s ../skel -T../flexml-act + +.PHONY : test +.PHONY : clean + +##################################################### +# test definitions -- add new tests here +##################################################### + +EXES = \ + biparser \ + init_header \ + missing-att \ + mixed-enumatt \ + mixed-enumatt2 \ + mixed-stratt \ + mixed-stratt-def \ + mixed1 \ + multi-parser-run + + +INTERMEDIATES = $(EXES) $(EXES:%=%.c) $(EXES:%=%.l) + +# leave this alphabetically sorted for easy scanning +UNIT_TESTS = \ + test_biparser \ + test_init_header \ + test_missing-att \ + test_mixed-enumatt \ + test_mixed-enumatt2 \ + test_mixed-stratt \ + test_mixed-stratt-def \ + test_mixed1 \ + test_multi-parser-run + +test : $(UNIT_TESTS) + +# Test init_header +test_init_header_cmd = ./init_header < init_header.in +test_init_header_deps = init_header init_header.in + +# Test missing REQUIRED attribute +test_missing-att_cmd = ./missing-att < missing-att.in +test_missing-att_deps = missing-att missing-att.in + +# Test mixed1 +test_mixed1_cmd = ./mixed1 < mixed1.in +test_mixed1_deps = mixed1 mixed1.in + +# Test mixed-enumatt (mixed content + enumerated attribute) +test_mixed-enumatt_cmd = ./mixed-enumatt < mixed-enumatt.in +test_mixed-enumatt_deps = mixed-enumatt mixed-enumatt.in + +# Test mixed-enumatt2 (mixed content + enumerated attribute, eval'ed in end tag) +test_mixed-enumatt2_cmd = ./mixed-enumatt2 < mixed-enumatt2.in +test_mixed-enumatt2_deps = mixed-enumatt2 mixed-enumatt2.in + +# Test mixed-stratt (mixed content + string attribute) +test_mixed-stratt_cmd = ./mixed-stratt < mixed-stratt.in +test_mixed-stratt_deps = mixed-stratt mixed-stratt.in + +# Test mixed-stratt (mixed content + default string attribute) +test_mixed-stratt-def_cmd = ./mixed-stratt-def < mixed-stratt-def.in +test_mixed-stratt-def_deps = mixed-stratt-def mixed-stratt-def.in + +# Test multi-parser-run (Run the parser several times on "different" files) +test_multi-parser-run_cmd = ./multi-parser-run multi-parser-run.in +test_multi-parser-run_deps = multi-parser-run multi-parser-run.in + +# Test biparser (Have two parsers in the same code) +test_biparser_cmd = ./biparser biparser-one.in biparser-two.in +test_biparser_deps = biparser biparser-one.in biparser-two.in + +biparser: biparser-one.dtd biparser-two.dtd biparser.precious.c + for n in one two ; do \ + $(FLEXML) -P$$n -H biparser-$$n.h -L biparser-$$n.dtd; \ + $(FLEXML) -P$$n -S biparser-$$n.l -L biparser-$$n.dtd; \ + $(FLEX) -s -L -P$${n}_ -obiparser-$$n.c biparser-$$n.l; \ + done + $(CC) $(CFLAGS) -o biparser \ + biparser-one.c biparser-two.c \ + biparser.precious.c +CLEANFILES+= biparser-one.h biparser-one.l biparser-one.c \ + biparser-two.h biparser-two.l biparser-two.c + +init_header : init_header.act init_header.dtd init_header.h + $(FLEXML) -b 1000 -A -i$@.h -a$@.act $@.dtd + $(FLEX) -s -L -o$@.c $@.l + $(CC) $(CFLAGS) -o $@ $@.c + +% : %.dtd %.act + $(FLEXML) -b 1000 -A -a$@.act $@.dtd + $(FLEX) -s -L -o$@.c $@.l + $(CC) $(CFLAGS) -o $@ $@.c + +############################################################## +# test build rules -- add override build rules here if needed +############################################################## + +#mixed1: mixed1.dtd mixed1.act +# $(FLEXML) -b 500 -A -amixed1.act mixed1.dtd +# $(FLEX) -s -L -o mixed1.c mixed1.l > mixed1.c +# $(CC) $(CFLAGS) -o $@ mixed1.c + + +##################################################### +# test infrastructure -- do not modify for new tests +##################################################### + +clean : + rm -f $(TEST_INTERMEDIATES) $(INTERMEDIATES) $(CLEANFILES) + +# When we are building test_foo, the variable $(TEST_BASE) is "foo" +test_% : TEST_BASE = $(@:test_%=%) + +ifndef distribute_deps +# This will take a target and dependency list, and evaluate each dependency +# individually. This only needs to be used on dependency lists that are to +# be in an $(eval ...) function. This is a work-around for a bug in GNU Make +# 3.80, which fails when $(eval)'ing dependency lists longer than about 160 +# characters. +# 1. target +# 2. dependency list +define distribute_deps +$(foreach dep,$(2),$(eval $(1) : $(dep))) +endef +endif + +define unit_test_deps_t +$(1) : .$(1).stdout.expected +$(1) : .$(1).stderr.expected +$$(call distribute_deps,$(1),$($(1)_deps)) +endef + +$(foreach test,$(UNIT_TESTS),$(eval $(call unit_test_deps_t,$(test)))) + + +# To build .test_foo.std{err,out}.expected -- +# If foo.std{err,out}.expected exists, symlink to it +# Else, .test_foo.std{err,out}.expected is a new empty file +# These rules are invoked from rules in the Extradeps section. +# They must be two separate rules (else 'make test' not idempotent +# -- see bug #105) +.test_%.stderr.expected: + @if [ -f $(@:.test_%=%) ]; \ + then $(SYMLINK) $(@:.test_%=%) $@; \ + else touch $@; \ + fi +.test_%.stdout.expected: + @if [ -f $(@:.test_%=%) ]; \ + then $(SYMLINK) $(@:.test_%=%) $@; \ + else touch $@; \ + fi + + +# Unit test rule. Expects: +# UNIT_TESTS = test_foo test_bar (test_ prefix is necessary) +# test_foo_cmd = command to run +# test_foo_deps = dependencies (i.e. inputs to the test, and the executable) +# test_foo_out = files and directories created by running the command +# with corresponding .expected files for comparison + +$(UNIT_TESTS) : + @$(test_$(@:test_%=%)_cmd) > $(@:test_%=%).stdout \ + 2>$(@:test_%=%).stderr || true + @$(PERL) $(COMPARE_OUT) -p '$($(@)_diff_prog)' -- \ + $($(@)_diff_opts) $(@:test_%=%) $($(@)_out) | tee $@ + diff --git a/testbed/biparser-one.dtd b/testbed/biparser-one.dtd new file mode 100644 index 0000000..abf24ac --- /dev/null +++ b/testbed/biparser-one.dtd @@ -0,0 +1,2 @@ +<!ELEMENT foo (#PCDATA|bar)*> +<!ELEMENT bar (#PCDATA)> diff --git a/testbed/biparser-one.in b/testbed/biparser-one.in new file mode 100644 index 0000000..1cfc6b8 --- /dev/null +++ b/testbed/biparser-one.in @@ -0,0 +1,2 @@ +<!DOCTYPE foo SYSTEM "biparser-one.dtd"> +<foo>012<bar>456789ab</bar>cdefghijklmn</foo> diff --git a/testbed/biparser-two.dtd b/testbed/biparser-two.dtd new file mode 100644 index 0000000..9d2bfab --- /dev/null +++ b/testbed/biparser-two.dtd @@ -0,0 +1,3 @@ +<!ELEMENT toto (#PCDATA|tutu)*> +<!ELEMENT tutu (#PCDATA)> + diff --git a/testbed/biparser-two.in b/testbed/biparser-two.in new file mode 100644 index 0000000..37b210b --- /dev/null +++ b/testbed/biparser-two.in @@ -0,0 +1,2 @@ +<!DOCTYPE toto SYSTEM "biparser-two.dtd"> +<toto>012<tutu>456789ab</tutu>cdefghijklmn</toto> diff --git a/testbed/biparser.precious.c b/testbed/biparser.precious.c new file mode 100644 index 0000000..6a0cc3f --- /dev/null +++ b/testbed/biparser.precious.c @@ -0,0 +1,69 @@ +#include <stdio.h> + +#include "biparser-one.h" +#include "biparser-two.h" + +/* XML application entry points. + Should be generated from two action files, but I wasn't succesfull in that area yet [Mt] */ +void STag_one_foo(void) {} +void ETag_one_foo(void) {printf("foo pcdata: %s\n", one_pcdata);} +void STag_one_bar(void) {} +void ETag_one_bar(void) {printf("bar pcdata: %s\n", one_pcdata);} + +void STag_two_toto(void) {} +void ETag_two_toto(void) {printf("toto pcdata: %s\n", two_pcdata);} +void STag_two_tutu(void) {} +void ETag_two_tutu(void) {printf("tutu pcdata: %s\n", two_pcdata);} + +/* Parsers control. + Should probably be added to the .h */ +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int one_lex (void); +extern void one_restart (FILE *input_file ); +extern void one__switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE one__create_buffer (FILE *file,int size ); +extern void one__delete_buffer (YY_BUFFER_STATE b ); +extern void one__flush_buffer (YY_BUFFER_STATE b ); +extern void one_push_buffer_state (YY_BUFFER_STATE new_buffer ); +extern void one_pop_buffer_state (void ); + +extern int two_lex (void); +extern void two_restart (FILE *input_file ); +extern void two__switch_to_buffer (YY_BUFFER_STATE new_buffer ); +extern YY_BUFFER_STATE two__create_buffer (FILE *file,int size ); +extern void two__delete_buffer (YY_BUFFER_STATE b ); +extern void two__flush_buffer (YY_BUFFER_STATE b ); +extern void two_push_buffer_state (YY_BUFFER_STATE new_buffer ); +extern void two_pop_buffer_state (void ); + + +int main(int argc, char **argv) { + FILE *infile; + YY_BUFFER_STATE buff; + int retval; + + printf("Parse biparser-one.in\n"); + infile=fopen("biparser-one.in","r"); + buff=one__create_buffer(infile,10); + one__switch_to_buffer(buff); + retval = one_lex(); + one__delete_buffer(buff); + fclose(infile); + + printf("Parse biparser-two.in\n"); + infile=fopen("biparser-two.in","r"); + buff=two__create_buffer(infile,10); + two__switch_to_buffer(buff); + retval = two_lex() || retval; + two__delete_buffer(buff); + fclose(infile); + + return retval; +} + + + diff --git a/testbed/biparser.stdout.expected b/testbed/biparser.stdout.expected new file mode 100644 index 0000000..d0efb8b --- /dev/null +++ b/testbed/biparser.stdout.expected @@ -0,0 +1,6 @@ +Parse biparser-one.in +bar pcdata: 456789ab +foo pcdata: 012cdefghijklmn +Parse biparser-two.in +tutu pcdata: 456789ab +toto pcdata: 012cdefghijklmn diff --git a/testbed/core b/testbed/core Binary files differnew file mode 100644 index 0000000..c6d2199 --- /dev/null +++ b/testbed/core diff --git a/testbed/init_header.act b/testbed/init_header.act new file mode 100644 index 0000000..ae0855c --- /dev/null +++ b/testbed/init_header.act @@ -0,0 +1,27 @@ +<!DOCTYPE actions SYSTEM "flexml-act.dtd"> +<actions> + +<top><![CDATA[ +#include <stdio.h> +]]></top> + +<end tag='bar'><![CDATA[ + printf("bar pcdata: %s\n", {#PCDATA}); +]]></end> + + +<end tag='foo'><![CDATA[ + printf("foo pcdata: %s\nparam was %d\n", {#PCDATA}, static_lexer_param); +]]></end> + + +<main><![CDATA[ +int main(int argc, char **argv) +{ + int retval = lexer(7); + printf("retval = %d\n", retval); + return retval; +} +]]></main> + +</actions> diff --git a/testbed/init_header.dtd b/testbed/init_header.dtd new file mode 100644 index 0000000..dd51f3b --- /dev/null +++ b/testbed/init_header.dtd @@ -0,0 +1,4 @@ + +<!ELEMENT foo (#PCDATA|bar)*> +<!ELEMENT bar (#PCDATA)> +<!-- <!ATTLIST bar batt CDATA #REQUIRED> --> diff --git a/testbed/init_header.h b/testbed/init_header.h new file mode 100644 index 0000000..80beccf --- /dev/null +++ b/testbed/init_header.h @@ -0,0 +1,3 @@ +/* header file to be included at end of generated %{ ... %} section */ +#define YY_DECL static int static_lexer_param; int lexer(int lexer_param) +#define YY_USER_INIT static_lexer_param = lexer_param; diff --git a/testbed/init_header.in b/testbed/init_header.in new file mode 100644 index 0000000..051a356 --- /dev/null +++ b/testbed/init_header.in @@ -0,0 +1,2 @@ +<!DOCTYPE foo SYSTEM "init_header.dtd"> +<foo>012<bar>456789ab</bar>cdefghijklmn</foo> diff --git a/testbed/init_header.stdout.expected b/testbed/init_header.stdout.expected new file mode 100644 index 0000000..7d60070 --- /dev/null +++ b/testbed/init_header.stdout.expected @@ -0,0 +1,4 @@ +bar pcdata: 456789ab +foo pcdata: 012cdefghijklmn +param was 7 +retval = 0 diff --git a/testbed/missing-att.act b/testbed/missing-att.act new file mode 100644 index 0000000..0afbd24 --- /dev/null +++ b/testbed/missing-att.act @@ -0,0 +1,32 @@ +<!DOCTYPE actions SYSTEM "flexml-act.dtd"> +<actions> + +<top><![CDATA[ +#include <stdio.h> +]]></top> + +<start tag='bar'><![CDATA[ + printf("bar att: %s\n", {batt}); +]]></start> + + +<end tag='bar'><![CDATA[ + printf("bar pcdata: %s\n", {#PCDATA}); +]]></end> + + +<end tag='foo'><![CDATA[ + printf("foo pcdata: %s\n", {#PCDATA}); +]]></end> + + +<main><![CDATA[ +int main(int argc, char **argv) +{ + int retval = yylex(); + printf("retval = %d\n", retval); + return retval; +} +]]></main> + +</actions> diff --git a/testbed/missing-att.dtd b/testbed/missing-att.dtd new file mode 100644 index 0000000..2ec03fa --- /dev/null +++ b/testbed/missing-att.dtd @@ -0,0 +1,4 @@ +<!-- test mixed content elements with string sttributes --> +<!ELEMENT foo (#PCDATA|bar)*> +<!ELEMENT bar (#PCDATA)> +<!ATTLIST bar batt CDATA #REQUIRED> diff --git a/testbed/missing-att.in b/testbed/missing-att.in new file mode 100644 index 0000000..970ec5f --- /dev/null +++ b/testbed/missing-att.in @@ -0,0 +1,2 @@ +<!DOCTYPE foo SYSTEM "missing-att.dtd"> +<foo>012<bar>456789ab</bar>cdefghijklmn</foo> diff --git a/testbed/missing-att.stderr.expected b/testbed/missing-att.stderr.expected new file mode 100644 index 0000000..05a0230 --- /dev/null +++ b/testbed/missing-att.stderr.expected @@ -0,0 +1 @@ +Invalid XML (state 13): Required attribute `batt' not set for `bar' element. diff --git a/testbed/missing-att.stdout.expected b/testbed/missing-att.stdout.expected new file mode 100644 index 0000000..a086c81 --- /dev/null +++ b/testbed/missing-att.stdout.expected @@ -0,0 +1 @@ +retval = 1 diff --git a/testbed/mixed-enumatt.act b/testbed/mixed-enumatt.act new file mode 100644 index 0000000..5b22569 --- /dev/null +++ b/testbed/mixed-enumatt.act @@ -0,0 +1,53 @@ +<!DOCTYPE actions SYSTEM "flexml-act.dtd"> +<actions> + +<top><![CDATA[ +#include <stdio.h> +]]></top> + +<start tag='reqatt'><![CDATA[ + printf("reqatt att: (%s)\n", + {att} == {att=val1} ? "val1" : + {att} == {att=val2} ? "val2" : + {att} == {!att} ? "no att given" : "error in attribute"); +]]></start> +<start tag='defatt'><![CDATA[ + printf("defatt att: (%s)\n", + {att} == {att=val1} ? "val1" : + {att} == {att=val2} ? "val2" : + {att} == {!att} ? "no att given" : "error in attribute"); +]]></start> +<start tag='optatt'><![CDATA[ + printf("optatt att: (%s)\n", + {att} == {att=val1} ? "val1" : + {att} == {att=val2} ? "val2" : + {att} == {!att} ? "no att given" : "error in attribute"); +]]></start> + + +<end tag='reqatt'><![CDATA[ + printf("reqatt pcdata: %s\n", {#PCDATA}); +]]></end> +<end tag='defatt'><![CDATA[ + printf("defatt pcdata: %s\n", {#PCDATA}); +]]></end> +<end tag='optatt'><![CDATA[ + printf("optatt pcdata: %s\n", {#PCDATA}); +]]></end> + + +<end tag='foo'><![CDATA[ + printf("foo pcdata: %s\n", {#PCDATA}); +]]></end> + + +<main><![CDATA[ +int main(int argc, char **argv) +{ + int retval = yylex(); + printf("retval = %d\n", retval); + return retval; +} +]]></main> + +</actions> diff --git a/testbed/mixed-enumatt.dtd b/testbed/mixed-enumatt.dtd new file mode 100644 index 0000000..c82c098 --- /dev/null +++ b/testbed/mixed-enumatt.dtd @@ -0,0 +1,8 @@ + +<!ELEMENT foo (#PCDATA|reqatt|defatt|optatt)*> +<!ELEMENT reqatt (#PCDATA)> +<!ATTLIST reqatt att (val1 | val2 ) #REQUIRED> +<!ELEMENT defatt (#PCDATA)> +<!ATTLIST defatt att (val1 | val2 ) 'val2'> +<!ELEMENT optatt (#PCDATA)> +<!ATTLIST optatt att (val1 | val2 ) #IMPLIED> diff --git a/testbed/mixed-enumatt.in b/testbed/mixed-enumatt.in new file mode 100644 index 0000000..51f55b4 --- /dev/null +++ b/testbed/mixed-enumatt.in @@ -0,0 +1,8 @@ +<!DOCTYPE foo SYSTEM "mixed-enumatt.dtd"> +<foo>foo start data + <reqatt att="val1">reqatt data</reqatt> + <defatt att="val1">defatt data</defatt> + <defatt>defatt data</defatt> + <optatt att="val1">optatt data</optatt> + <optatt>optatt data</optatt> +foo end data.</foo> diff --git a/testbed/mixed-enumatt.stdout.expected b/testbed/mixed-enumatt.stdout.expected new file mode 100644 index 0000000..db43a9d --- /dev/null +++ b/testbed/mixed-enumatt.stdout.expected @@ -0,0 +1,18 @@ +reqatt att: (val1) +reqatt pcdata: reqatt data +defatt att: (val1) +defatt pcdata: defatt data +defatt att: (val2) +defatt pcdata: defatt data +optatt att: (val1) +optatt pcdata: optatt data +optatt att: (no att given) +optatt pcdata: optatt data +foo pcdata: foo start data + + + + + +foo end data. +retval = 0 diff --git a/testbed/mixed-enumatt2.act b/testbed/mixed-enumatt2.act new file mode 100644 index 0000000..6ec197d --- /dev/null +++ b/testbed/mixed-enumatt2.act @@ -0,0 +1,47 @@ +<!DOCTYPE actions SYSTEM "flexml-act.dtd"> +<actions> + +<top><![CDATA[ +#include <stdio.h> +]]></top> + +<end tag='reqatt'><![CDATA[ + printf("reqatt pcdata: %s\n", {#PCDATA}); + printf("reqatt att: (%s)\n", + {att} == {att=val1} ? "val1" : + {att} == {att=val2} ? "val2" : + {att} == {!att} ? "no att given" : "error in attribute"); +]]></end> +<end tag='defatt'><![CDATA[ + printf("defatt pcdata: %s\n", {#PCDATA}); + printf("defatt att: (%s)\n", + {att} == {att=val1} ? "val1" : + {att} == {att=val2} ? "val2" : + {att} == {!att} ? "no att given" : "error in attribute"); + +]]></end> +<end tag='optatt'><![CDATA[ + printf("optatt pcdata: %s\n", {#PCDATA}); + printf("optatt att: (%s)\n", + {att} == {att=val1} ? "val1" : + {att} == {att=val2} ? "val2" : + {att} == {!att} ? "no att given" : "error in attribute"); + +]]></end> + + +<end tag='foo'><![CDATA[ + printf("foo pcdata: %s\n", {#PCDATA}); +]]></end> + + +<main><![CDATA[ +int main(int argc, char **argv) +{ + int retval = yylex(); + printf("retval = %d\n", retval); + return retval; +} +]]></main> + +</actions> diff --git a/testbed/mixed-enumatt2.dtd b/testbed/mixed-enumatt2.dtd new file mode 100644 index 0000000..c82c098 --- /dev/null +++ b/testbed/mixed-enumatt2.dtd @@ -0,0 +1,8 @@ + +<!ELEMENT foo (#PCDATA|reqatt|defatt|optatt)*> +<!ELEMENT reqatt (#PCDATA)> +<!ATTLIST reqatt att (val1 | val2 ) #REQUIRED> +<!ELEMENT defatt (#PCDATA)> +<!ATTLIST defatt att (val1 | val2 ) 'val2'> +<!ELEMENT optatt (#PCDATA)> +<!ATTLIST optatt att (val1 | val2 ) #IMPLIED> diff --git a/testbed/mixed-enumatt2.in b/testbed/mixed-enumatt2.in new file mode 100644 index 0000000..fd90810 --- /dev/null +++ b/testbed/mixed-enumatt2.in @@ -0,0 +1,8 @@ +<!DOCTYPE foo SYSTEM "mixed-enumatt2.dtd"> +<foo>foo start data + <reqatt att="val1">reqatt data</reqatt> + <defatt att="val1">defatt data</defatt> + <defatt>defatt data</defatt> + <optatt att="val1">optatt data</optatt> + <optatt>optatt data</optatt> +foo end data.</foo> diff --git a/testbed/mixed-enumatt2.stdout.expected b/testbed/mixed-enumatt2.stdout.expected new file mode 100644 index 0000000..0e5c5b5 --- /dev/null +++ b/testbed/mixed-enumatt2.stdout.expected @@ -0,0 +1,18 @@ +reqatt pcdata: reqatt data +reqatt att: (val1) +defatt pcdata: defatt data +defatt att: (val1) +defatt pcdata: defatt data +defatt att: (val2) +optatt pcdata: optatt data +optatt att: (val1) +optatt pcdata: optatt data +optatt att: (no att given) +foo pcdata: foo start data + + + + + +foo end data. +retval = 0 diff --git a/testbed/mixed-stratt-def.act b/testbed/mixed-stratt-def.act new file mode 100644 index 0000000..2f6a9ea --- /dev/null +++ b/testbed/mixed-stratt-def.act @@ -0,0 +1,33 @@ +<!DOCTYPE actions SYSTEM "flexml-act.dtd"> +<actions> + +<top><![CDATA[ +#include <stdio.h> +]]></top> + +<start tag='bar'><![CDATA[ + printf("bar batt: (%s) batt2: (%s) batt3: (%s)\n", + {batt}, {batt2}, {batt3}); +]]></start> + + +<end tag='bar'><![CDATA[ + printf("bar pcdata: %s\n", {#PCDATA}); +]]></end> + + +<end tag='foo'><![CDATA[ + printf("foo pcdata: %s\n", {#PCDATA}); +]]></end> + + +<main><![CDATA[ +int main(int argc, char **argv) +{ + int retval = yylex(); + printf("retval = %d\n", retval); + return retval; +} +]]></main> + +</actions> diff --git a/testbed/mixed-stratt-def.dtd b/testbed/mixed-stratt-def.dtd new file mode 100644 index 0000000..55b67c7 --- /dev/null +++ b/testbed/mixed-stratt-def.dtd @@ -0,0 +1,7 @@ +<!-- test mixed content elements with default string sttributes --> +<!ELEMENT foo (#PCDATA|bar)*> +<!ELEMENT bar (#PCDATA)> +<!ATTLIST bar batt CDATA 'default value' + batt2 CDATA 'second default value' + batt3 CDATA 'third default value' +> diff --git a/testbed/mixed-stratt-def.in b/testbed/mixed-stratt-def.in new file mode 100644 index 0000000..9f5846d --- /dev/null +++ b/testbed/mixed-stratt-def.in @@ -0,0 +1,6 @@ +<!DOCTYPE foo SYSTEM "mixed-stratt-def.dtd"> +<foo>012 + <bar>bar data 1</bar> + <bar batt2=' non-default 2'>bar data 2</bar> + <bar batt3 = "non-default with single-quote(')">bar data 3</bar> + cdefghijklmn</foo> diff --git a/testbed/mixed-stratt-def.stdout.expected b/testbed/mixed-stratt-def.stdout.expected new file mode 100644 index 0000000..17e021b --- /dev/null +++ b/testbed/mixed-stratt-def.stdout.expected @@ -0,0 +1,12 @@ +bar batt: (default value) batt2: (second default value) batt3: (third default value) +bar pcdata: bar data 1 +bar batt: (default value) batt2: ( non-default 2) batt3: (third default value) +bar pcdata: bar data 2 +bar batt: (default value) batt2: (second default value) batt3: (non-default with single-quote(')) +bar pcdata: bar data 3 +foo pcdata: 012 + + + + cdefghijklmn +retval = 0 diff --git a/testbed/mixed-stratt.act b/testbed/mixed-stratt.act new file mode 100644 index 0000000..0afbd24 --- /dev/null +++ b/testbed/mixed-stratt.act @@ -0,0 +1,32 @@ +<!DOCTYPE actions SYSTEM "flexml-act.dtd"> +<actions> + +<top><![CDATA[ +#include <stdio.h> +]]></top> + +<start tag='bar'><![CDATA[ + printf("bar att: %s\n", {batt}); +]]></start> + + +<end tag='bar'><![CDATA[ + printf("bar pcdata: %s\n", {#PCDATA}); +]]></end> + + +<end tag='foo'><![CDATA[ + printf("foo pcdata: %s\n", {#PCDATA}); +]]></end> + + +<main><![CDATA[ +int main(int argc, char **argv) +{ + int retval = yylex(); + printf("retval = %d\n", retval); + return retval; +} +]]></main> + +</actions> diff --git a/testbed/mixed-stratt.dtd b/testbed/mixed-stratt.dtd new file mode 100644 index 0000000..2ec03fa --- /dev/null +++ b/testbed/mixed-stratt.dtd @@ -0,0 +1,4 @@ +<!-- test mixed content elements with string sttributes --> +<!ELEMENT foo (#PCDATA|bar)*> +<!ELEMENT bar (#PCDATA)> +<!ATTLIST bar batt CDATA #REQUIRED> diff --git a/testbed/mixed-stratt.in b/testbed/mixed-stratt.in new file mode 100644 index 0000000..22d9e90 --- /dev/null +++ b/testbed/mixed-stratt.in @@ -0,0 +1,2 @@ +<!DOCTYPE foo SYSTEM "mixed-stratt.dtd"> +<foo>012<bar batt="batt1">456789ab</bar>cdefghijklmn</foo> diff --git a/testbed/mixed-stratt.stdout.expected b/testbed/mixed-stratt.stdout.expected new file mode 100644 index 0000000..a476ed7 --- /dev/null +++ b/testbed/mixed-stratt.stdout.expected @@ -0,0 +1,4 @@ +bar att: batt1 +bar pcdata: 456789ab +foo pcdata: 012cdefghijklmn +retval = 0 diff --git a/testbed/mixed1.act b/testbed/mixed1.act new file mode 100644 index 0000000..7cafafa --- /dev/null +++ b/testbed/mixed1.act @@ -0,0 +1,27 @@ +<!DOCTYPE actions SYSTEM "flexml-act.dtd"> +<actions> + +<top><![CDATA[ +#include <stdio.h> +]]></top> + +<end tag='bar'><![CDATA[ + printf("bar pcdata: %s\n", {#PCDATA}); +]]></end> + + +<end tag='foo'><![CDATA[ + printf("foo pcdata: %s\n", {#PCDATA}); +]]></end> + + +<main><![CDATA[ +int main(int argc, char **argv) +{ + int retval = yylex(); + printf("retval = %d\n", retval); + return retval; +} +]]></main> + +</actions> diff --git a/testbed/mixed1.dtd b/testbed/mixed1.dtd new file mode 100644 index 0000000..dd51f3b --- /dev/null +++ b/testbed/mixed1.dtd @@ -0,0 +1,4 @@ + +<!ELEMENT foo (#PCDATA|bar)*> +<!ELEMENT bar (#PCDATA)> +<!-- <!ATTLIST bar batt CDATA #REQUIRED> --> diff --git a/testbed/mixed1.in b/testbed/mixed1.in new file mode 100644 index 0000000..c9045bc --- /dev/null +++ b/testbed/mixed1.in @@ -0,0 +1,2 @@ +<!DOCTYPE foo SYSTEM "mixed1.dtd"> +<foo>012<bar>456789ab</bar>cdefghijklmn</foo> diff --git a/testbed/mixed1.stdout.expected b/testbed/mixed1.stdout.expected new file mode 100644 index 0000000..1c29c6a --- /dev/null +++ b/testbed/mixed1.stdout.expected @@ -0,0 +1,3 @@ +bar pcdata: 456789ab +foo pcdata: 012cdefghijklmn +retval = 0 diff --git a/testbed/multi-parser-run.act b/testbed/multi-parser-run.act new file mode 100644 index 0000000..7e71408 --- /dev/null +++ b/testbed/multi-parser-run.act @@ -0,0 +1,38 @@ +<!DOCTYPE actions SYSTEM "flexml-act.dtd"> +<actions> + +<top><![CDATA[ +#include <stdio.h> +]]></top> + +<start tag='foo'><![CDATA[ + printf("foo attributes name='%s' toz='%s' gaz='%s'\n", {name}, {toz}, {gaz}); +]]></start> + +<start tag='bar'><![CDATA[ + printf("bar attributes name='%s'\n", {name}); +]]></start> + +<main><![CDATA[ +int main(int argc, char **argv) { + FILE *infile; + YY_BUFFER_STATE buff; + int retval; + + int i; + + for (i=0; i<3; i++) { + printf("Run %d\n",i); + infile=fopen(argv[1],"r"); + buff=yy_create_buffer(infile,10); + yy_switch_to_buffer(buff); + retval = yylex(); + yy_delete_buffer(buff); + fclose(infile); + } + + return retval; +} +]]></main> + +</actions> diff --git a/testbed/multi-parser-run.dtd b/testbed/multi-parser-run.dtd new file mode 100644 index 0000000..a97c9a3 --- /dev/null +++ b/testbed/multi-parser-run.dtd @@ -0,0 +1,7 @@ +<!ELEMENT foo (bar)*> +<!ATTLIST foo name CDATA #REQUIRED> +<!ATTLIST foo toz CDATA "0.0"> +<!ATTLIST foo gaz CDATA "0.0"> + +<!ELEMENT bar EMPTY> +<!ATTLIST bar name CDATA #REQUIRED> diff --git a/testbed/multi-parser-run.in b/testbed/multi-parser-run.in new file mode 100644 index 0000000..ede99c0 --- /dev/null +++ b/testbed/multi-parser-run.in @@ -0,0 +1,2 @@ +<!DOCTYPE foo SYSTEM "multi-parser-run.dtd"> +<foo name="toto"><bar name="tutu"/> </foo> diff --git a/testbed/multi-parser-run.stdout.expected b/testbed/multi-parser-run.stdout.expected new file mode 100644 index 0000000..3b16573 --- /dev/null +++ b/testbed/multi-parser-run.stdout.expected @@ -0,0 +1,9 @@ +Run 0 +foo attributes name='toto' toz='0.0' gaz='0.0' +bar attributes name='tutu' +Run 1 +foo attributes name='toto' toz='0.0' gaz='0.0' +bar attributes name='tutu' +Run 2 +foo attributes name='toto' toz='0.0' gaz='0.0' +bar attributes name='tutu' |
