New Upstream Release - html-xml-utils

Ready changes

Summary

Merged new upstream version: 8.6 (was: 8.3).

Resulting package

Built on 2023-05-24T05:35 (took 6m2s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases html-xml-utils-dbgsymapt install -t fresh-releases html-xml-utils

Lintian Result

Diff

diff --git a/ChangeLog b/ChangeLog
index e4c7708..69bdf2b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,135 @@
+2023-04-25  Bert Bos  <bert@nyx.sophia.w3.org>
+
+	* tests/select34.sh: Use "tr" instead of "xarg" to replace \0 by
+	\n. (The xargs command on BSD ignores empty input lines, the GNU
+	version does not.) Also use "printf" instead of "echo" to write to
+	the log file, because it seems to be more consistent between
+	different shells.
+
+2023-02-09  Bert Bos  <bert@nyx.sophia.w3.org>
+
+	* hxselect.c: Fixed a bug in parsing octal escapes in the
+	separator string (option -s). Patch provided by Jorrit Fahlke.
+
+2023-01-23  Bert Bos  <bert@w3.org>
+
+	* errexit.c: Removed. Consistently use err() and errx()
+	everywhere.
+
+	* hxwls.c, printlinks.c, hxcopy.c: Allow white space before and
+	after URLs in attributes. (Allowed by HTML5.)
+
+2022-04-01  Bert Bos  <bert@nyx.sophia.w3.org>
+
+	* hxselect.c: The :attr() pseudo-element was only matched if it
+	was on the first selector, not if it was on a subsequent selector
+	in a comma-separated list of selectors. (Found and fixed by Bas
+	Ploeger.)
+
+	* tests/select33.sh: Added test for multiple :attr()
+	selectors. (Contributed by Bas Ploeger.)
+
+2022-02-10  Bert Bos  <bert@w3.org>
+
+	* Rekleased version 8.3.
+
+	* dtd.hash: Make <head> rather than <body> the preferred parent
+	for <script>. Allow text in the <body> element, without requiring a
+	<p> or other element around it.
+
+	* tests/pipe5.sh, tests/pipe6.sh, tests/pipe7.sh: Added tests for
+	the -H option of hxpipe.
+
+	* hxpipe.c: Add option -H, which assumes the input is HTML and adds
+	implied tags and parses script and style elements as literal text.
+	hxpipe now outputs attributes in a normalized order
+	(alphabetical). Remove a redundant "if".
+
+2021-12-20  Bert Bos  <bert@w3.org>
+
+	* Released version 8.1.
+
+	* tests/select11.sh, tests/select12.sh, tests/select13.sh,
+	tests/select19.sh, tests/select21.sh: Added some text and
+	comments, to test that they are correctly skipped.
+
+	* tests/select31.sh, tests/select32.sh, Makefile.am: Added two
+	tests for the sibling selector (~).
+
+	* selmatch.c: Sibling selector failed to skip non-element nodes.
+
+2021-05-14  Bert Bos  <bert@w3.org>
+
+	* dict.c: Deleting an entry with dict_destroy() made entries with
+	the same hash value that were stored in subsequent slots
+	inaccessible. The dict_destroy() function isn't used in any of the
+	HTML-XML-utils, but other programs may borrow this module.
+
+2021-04-15  Bert Bos  <bert@w3.org>
+
+	* selector.c, selmatch.c: Also parse and process the experimental
+	":is()" and ":where()" pseudo-classes. Correct a bug in parsing
+	comma-separated selectors. Correct a bug in esc() that caused an
+	empty string to fail (e.g., in [alt=""]. (The function esc() is not
+	used, but could be used when debugging.)
+
+	* tests/select14.sh: Test ":empty" in combination with another
+	pseudo-class.
+
+	* Makefile.am: Added tests select26.sh, select27.sh, select28.sh,
+	select29.sh and select30.sh
+
+	* configure.ac: Added AC_SYS_LARGEFILE to enable seek() to seek
+	large files and the off_t type to be 64 bits on older, 32-bit
+	systems. Also check for limits.h.
+
+	* hxselect.1: Noted the known bug that case-insensitive selectors
+	(option -i) only work with ASCII characters.
+
+2020-08-04  Bert Bos  <bert@w3.org>
+
+	* unent.hash: gperf 3.1 generates size_t instead of unsigned int.
+
+	* Makefile.am: Call gperf on unent.hash with "-k 1-6" instead of
+	"-k 1,2,$ -D". Added test select25.sh.
+
+	* select25.sh: Test added. (Contributed by Hugo Peixoto.)
+
+	* selector.c: An attribute selector with an empty string such as
+	[foo=''], resulted in a NULL value instead of an empty string,
+	which led to a crash. (Found and fixed by Hugo Peixoto.)
+
+2019-10-05  Bert Bos  <bert@w3.org>
+
+	* Published version 7.8.
+
+	* textwrap.c, langinfo.c, hxnormalize.c: Added knowledge about
+	languages that do not use spaces between words. In such languages,
+	a newline should not be converted to a space in outc() in
+	textwrap.c, but only to a break opportunity.
+
+2019-08-28  Bert Bos  <bert@w3.org>
+
+	* hxtoc.c: The element to group headings in HTML5 is called
+	HGROUP, not HEADER. The heading of a section (SECTION, ARTICLE,
+	etc.) need not be the first element, there may be non-header
+	elements before it.
+
+	* hxwls.c: Print "longdesc", "classid" or "codebase" in the second
+	column for the corresponding attribute. Also recognize srcset
+	(somewhat).
+
+2018-08-03  Bert Bos  <bert@w3.org>
+
+	* hxnormalize.c: Added option -X to indicate the input is XML
+	instead of HTML. Handle conversion of CDATA elements to XML by
+	escaping < and & instead of adding <![CDATA[. Added corresponding
+	test normalize13.sh.
+
 2018-04-29  Bert Bos  <bert@w3.org>
 
+	* Released version 7.7.
+
 	* dtd.hash: Don't include the arguments in the forward declaration
 	of lookup_element(), because those arguments differ slightly
 	depending on which version of gperf is used to generate dtd.c:
diff --git a/Makefile.am b/Makefile.am
index bc44d5a..56e6e0f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright © 2000-2017 World Wide Web Consortium
+# Copyright © 2000-2018 World Wide Web Consortium
 # See http://www.w3.org/Consortium/Legal/copyright-software
 #
 # Author: Bert Bos <bert@w3.org>
@@ -39,89 +39,89 @@ AM_LFLAGS =		@lex_opt_flags@
 ACLOCAL_AMFLAGS =	-I m4
 
 EXPORTS =		dict.e heap.e types.e headers.e connectsock.e\
-			dtd.e errexit.e tree.e genid.e html.e url.e\
-			openurl.e scan.e textwrap.e unent.e class.e\
-			selector.e hash.e selmatch.e
+			dtd.e html.e scan.e tree.e genid.e url.e\
+			openurl.e textwrap.e unent.e class.e\
+			selector.e hash.e selmatch.e langinfo.e
 
-BUILT_SOURCES =		$(EXPORTS) scan.c html.c html.h dtd.c unent.c
+BUILT_SOURCES =		html.h $(EXPORTS) html.c scan.c dtd.c unent.c
 
 asc2xml_SOURCES =	asc2xml.c
-hxaddid_SOURCES =	hxaddid.c html.y scan.l dtd.c openurl.c errexit.c\
+hxaddid_SOURCES =	hxaddid.c html.y scan.l dtd.c openurl.c\
 			url.c connectsock.c heap.c tree.c types.c genid.c\
 			fopencookie.h\
 			class.c hash.c headers.c dict.c fopencookie.c
 cexport_SOURCES =	cexport.c
-hxcite_SOURCES =	heap.c errexit.c hxcite.c
-hxcount_SOURCES =	hxcount.c html.y scan.l types.c errexit.c heap.c\
+hxcite_SOURCES =	heap.c hxcite.c
+hxcount_SOURCES =	hxcount.c html.y scan.l types.c heap.c\
 			openurl.c url.c connectsock.c headers.c dict.c\
 			fopencookie.h fopencookie.c
 hxextract_SOURCES =	hxextract.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c class.c headers.c\
+			connectsock.c heap.c class.c headers.c\
 			dict.c types.c fopencookie.h fopencookie.c
 hxclean_SOURCES =	hxclean.c html.y tree.c types.c heap.c dtd.c\
-			scan.l errexit.c
-hxprune_SOURCES =	hxprune.c tree.c scan.l html.y errexit.c dtd.c\
+			scan.l
+hxprune_SOURCES =	hxprune.c tree.c scan.l html.y dtd.c\
 			heap.c types.c openurl.c url.c connectsock.c class.c\
 			headers.c dict.c fopencookie.h fopencookie.c
 hxincl_SOURCES =	hxincl.c scan.l html.y openurl.c url.c heap.c\
-			errexit.c connectsock.c types.c headers.c dict.c\
+			connectsock.c types.c headers.c dict.c\
 			fopencookie.h fopencookie.c
 hxindex_SOURCES =	hxindex.c scan.l html.y openurl.c url.c heap.c class.c\
-			errexit.c connectsock.c types.c tree.c genid.c dtd.c\
+			connectsock.c types.c tree.c genid.c dtd.c\
 			headers.c dict.c fopencookie.h fopencookie.c
-hxmkbib_SOURCES =	errexit.c heap.c hxmkbib.c hash.c
+hxmkbib_SOURCES =	heap.c hxmkbib.c hash.c
 hxmultitoc_SOURCES =	hxmultitoc.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c class.c headers.c\
+			connectsock.c heap.c class.c headers.c\
 			dict.c types.c fopencookie.h fopencookie.c
 hxnormalize_SOURCES =	hxnormalize.c html.y scan.l openurl.c url.c\
 			tree.c connectsock.c heap.c dtd.c types.c\
-			fopencookie.h\
-			textwrap.c errexit.c headers.c dict.c fopencookie.c
-hxnum_SOURCES =		hxnum.c html.y scan.l openurl.c url.c errexit.c\
+			fopencookie.h langinfo.c\
+			textwrap.c headers.c dict.c fopencookie.c
+hxnum_SOURCES =		hxnum.c html.y scan.l openurl.c url.c\
 			heap.c connectsock.c headers.c dict.c types.c class.c\
 			fopencookie.h fopencookie.c
-hxpipe_SOURCES =	hxpipe.c html.y scan.l types.c errexit.c heap.c\
+hxpipe_SOURCES =	hxpipe.c html.y scan.l types.c heap.c\
 			openurl.c url.c connectsock.c headers.c dict.c\
-			fopencookie.h fopencookie.c
-hxremove_SOURCES =	hxremove.c types.c errexit.c heap.c html.y scan.l\
+			dtd.c tree.c fopencookie.h fopencookie.c
+hxremove_SOURCES =	hxremove.c types.c heap.c html.y scan.l\
 			tree.c selector.c dtd.c selmatch.c
-hxselect_SOURCES =	hxselect.c types.c errexit.c heap.c html.y scan.l\
+hxselect_SOURCES =	hxselect.c types.c heap.c html.y scan.l\
 			tree.c selector.c dtd.c selmatch.c
 hxtabletrans_SOURCES =	hxtabletrans.c scan.l tree.c heap.c openurl.c html.y\
-			errexit.c dtd.c types.c dict.c connectsock.c\
+			dtd.c types.c dict.c connectsock.c\
 			headers.c url.c fopencookie.h fopencookie.c
-hxtoc_SOURCES =		html.y scan.l dtd.c openurl.c errexit.c url.c class.c\
+hxtoc_SOURCES =		html.y scan.l dtd.c openurl.c url.c class.c\
 			connectsock.c heap.c tree.c types.c genid.c hxtoc.c\
 			hash.c headers.c dict.c fopencookie.h fopencookie.c
 hxuncdata_SOURCES =	hxuncdata.c
 hxunent_SOURCES =	unent.c hxunentmain.c
-hxunpipe_SOURCES =	hxunpipe.c heap.c errexit.c openurl.c url.c\
+hxunpipe_SOURCES =	hxunpipe.c heap.c openurl.c url.c\
 			fopencookie.h\
 			connectsock.c headers.c dict.c types.c fopencookie.c
 hxunxmlns_SOURCES =	hxunxmlns.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c types.c headers.c\
+			connectsock.c heap.c types.c headers.c\
 			dict.c fopencookie.h fopencookie.c
 hxwls_SOURCES =		hxwls.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c types.c headers.c\
+			connectsock.c heap.c types.c headers.c\
 			dict.c fopencookie.h fopencookie.c unent.c
 hxxmlns_SOURCES =	hxxmlns.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c types.c headers.c\
+			connectsock.c heap.c types.c headers.c\
 			dict.c fopencookie.h fopencookie.c
 xml2asc_SOURCES =	xml2asc.c
-hxref_SOURCES =		html.y scan.l dtd.c openurl.c errexit.c url.c\
+hxref_SOURCES =		html.y scan.l dtd.c openurl.c url.c\
 			connectsock.c heap.c tree.c types.c genid.c hxref.c\
 			hash.c headers.c dict.c fopencookie.h fopencookie.c
-hxname2id_SOURCES =	html.y scan.l dtd.c openurl.c errexit.c url.c\
+hxname2id_SOURCES =	html.y scan.l dtd.c openurl.c url.c\
 			connectsock.c heap.c tree.c types.c hxname2id.c\
 			headers.c dict.c fopencookie.h fopencookie.c
-hxcopy_SOURCES =	html.y scan.l types.c url.c openurl.c errexit.c\
+hxcopy_SOURCES =	html.y scan.l types.c url.c openurl.c\
 			dict.c headers.c heap.c connectsock.c hxcopy.c\
 			fopencookie.h fopencookie.c
-hxnsxml_SOURCES =	hxnsxml.c html.y scan.l types.c errexit.c heap.c\
+hxnsxml_SOURCES =	hxnsxml.c html.y scan.l types.c heap.c\
 			openurl.c url.c connectsock.c headers.c dict.c\
 			fopencookie.h fopencookie.c
 hxprintlinks_SOURCES =	hxprintlinks.c openurl.c headers.c\
-			types.c heap.c errexit.c\
+			types.c heap.c\
 			dict.c html.y scan.l url.c connectsock.c\
 			fopencookie.h fopencookie.c
 
@@ -145,7 +145,7 @@ dtd.c: dtd.hash
 	gperf -a -c -C -o -t -p -T -k '1,2,$$' -N lookup_element $< >$@
 
 unent.c: unent.hash
-	gperf -a -c -C -o -t -p -k '1,2,$$' -D -N lookup_entity $< >$@
+	gperf -a -c -C -o -t -p -k 1-6 -N lookup_entity $< >$@
 
 scan.o: html.h html.e scan.c
 
@@ -180,11 +180,14 @@ TESTS = tests/addid1.sh tests/addid1.sh tests/ascxml.sh\
 	tests/normalize1.sh tests/normalize2.sh\
 	tests/normalize3.sh tests/normalize4.sh tests/normalize5.sh\
 	tests/normalize6.sh tests/normalize7.sh tests/normalize8.sh\
-	tests/normalize9.sh tests/normalize10.sh  tests/normalize11.sh\
-	tests/normalize12.sh\
+	tests/normalize9.sh tests/normalize10.sh tests/normalize11.sh\
+	tests/normalize12.sh tests/normalize13.sh tests/normalize14.sh\
+	tests/num1.sh tests/num2.sh tests/num3.sh tests/num4.sh\
+	tests/num5.sh tests/num6.sh\
 	tests/pipe1.sh tests/pipe2.sh tests/pipe3.sh tests/pipe4.sh\
+	tests/pipe5.sh tests/pipe6.sh tests/pipe7.sh\
 	tests/printlinks1.sh tests/printlinks2.sh tests/printlinks3.sh\
-	tests/printlinks4.sh tests/ref1.sh\
+	tests/printlinks4.sh tests/printlinks5.sh tests/ref1.sh\
 	tests/ref2.sh tests/ref3.sh tests/relurl1.sh tests/relurl2.sh\
 	tests/relurl3.sh tests/remove1.sh tests/remove2.sh\
 	tests/remove3.sh tests/remove4.sh tests/remove5.sh tests/remove6.sh\
@@ -197,9 +200,14 @@ TESTS = tests/addid1.sh tests/addid1.sh tests/ascxml.sh\
 	tests/select16.sh tests/select17.sh tests/select18.sh\
 	tests/select19.sh tests/select20.sh tests/select21.sh\
 	tests/select22.sh tests/select23.sh tests/select24.sh\
+	tests/select25.sh tests/select26.sh tests/select27.sh\
+	tests/select28.sh tests/select29.sh tests/select30.sh\
+	tests/select31.sh tests/select32.sh tests/select33.sh\
+	tests/select34.sh\
 	tests/tabletrans1.sh tests/tabletrans2.sh tests/tabletrans3.sh\
 	tests/tabletrans4.sh tests/tabletrans5.sh\
 	tests/toc1.sh tests/toc2.sh tests/toc3.sh tests/toc4.sh\
+	tests/toc5.sh tests/toc6.sh\
 	tests/uncdata1.sh\
 	tests/unent1.sh tests/unent2.sh tests/unent3.sh tests/unent4.sh\
 	tests/unent5.sh tests/unent6.sh\
@@ -207,7 +215,8 @@ TESTS = tests/addid1.sh tests/addid1.sh tests/ascxml.sh\
 	tests/unpipe2.sh tests/unpipe3.sh tests/unpipe4.sh tests/unpipe5.sh\
 	tests/unpipe6.sh\
 	tests/wls1.sh tests/wls2.sh\
-	tests/wls3.sh tests/wls4.sh tests/wls5.sh\
+	tests/wls3.sh tests/wls4.sh tests/wls5.sh tests/wls6.sh\
+	tests/wls7.sh\
 	tests/xmlasc1.sh tests/xmlasc2.sh tests/xmlasc3.sh\
 	tests/xmlasc4.sh tests/xmlasc5.sh tests/xmlasc6.sh\
 	tests/xmlasc7.sh tests/xmlns1.sh tests/xref1.sh tests/xref2.sh\
diff --git a/Makefile.in b/Makefile.in
index d57fb1e..eef741c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,7 @@
 
 @SET_MAKE@
 
-# Copyright © 2000-2017 World Wide Web Consortium
+# Copyright © 2000-2018 World Wide Web Consortium
 # See http://www.w3.org/Consortium/Legal/copyright-software
 #
 # Author: Bert Bos <bert@w3.org>
@@ -135,163 +135,156 @@ cexport_OBJECTS = $(am_cexport_OBJECTS)
 cexport_LDADD = $(LDADD)
 cexport_DEPENDENCIES = @LIBOBJS@
 am_hxaddid_OBJECTS = hxaddid.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
-	dtd.$(OBJEXT) openurl.$(OBJEXT) errexit.$(OBJEXT) \
-	url.$(OBJEXT) connectsock.$(OBJEXT) heap.$(OBJEXT) \
-	tree.$(OBJEXT) types.$(OBJEXT) genid.$(OBJEXT) class.$(OBJEXT) \
-	hash.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
-	fopencookie.$(OBJEXT)
+	dtd.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
+	connectsock.$(OBJEXT) heap.$(OBJEXT) tree.$(OBJEXT) \
+	types.$(OBJEXT) genid.$(OBJEXT) class.$(OBJEXT) hash.$(OBJEXT) \
+	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
 hxaddid_OBJECTS = $(am_hxaddid_OBJECTS)
 hxaddid_LDADD = $(LDADD)
 hxaddid_DEPENDENCIES = @LIBOBJS@
-am_hxcite_OBJECTS = heap.$(OBJEXT) errexit.$(OBJEXT) hxcite.$(OBJEXT)
+am_hxcite_OBJECTS = heap.$(OBJEXT) hxcite.$(OBJEXT)
 hxcite_OBJECTS = $(am_hxcite_OBJECTS)
 hxcite_LDADD = $(LDADD)
 hxcite_DEPENDENCIES = @LIBOBJS@
 am_hxclean_OBJECTS = hxclean.$(OBJEXT) html.$(OBJEXT) tree.$(OBJEXT) \
-	types.$(OBJEXT) heap.$(OBJEXT) dtd.$(OBJEXT) scan.$(OBJEXT) \
-	errexit.$(OBJEXT)
+	types.$(OBJEXT) heap.$(OBJEXT) dtd.$(OBJEXT) scan.$(OBJEXT)
 hxclean_OBJECTS = $(am_hxclean_OBJECTS)
 hxclean_LDADD = $(LDADD)
 hxclean_DEPENDENCIES = @LIBOBJS@
 am_hxcopy_OBJECTS = html.$(OBJEXT) scan.$(OBJEXT) types.$(OBJEXT) \
-	url.$(OBJEXT) openurl.$(OBJEXT) errexit.$(OBJEXT) \
-	dict.$(OBJEXT) headers.$(OBJEXT) heap.$(OBJEXT) \
-	connectsock.$(OBJEXT) hxcopy.$(OBJEXT) fopencookie.$(OBJEXT)
+	url.$(OBJEXT) openurl.$(OBJEXT) dict.$(OBJEXT) \
+	headers.$(OBJEXT) heap.$(OBJEXT) connectsock.$(OBJEXT) \
+	hxcopy.$(OBJEXT) fopencookie.$(OBJEXT)
 hxcopy_OBJECTS = $(am_hxcopy_OBJECTS)
 hxcopy_LDADD = $(LDADD)
 hxcopy_DEPENDENCIES = @LIBOBJS@
 am_hxcount_OBJECTS = hxcount.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
-	types.$(OBJEXT) errexit.$(OBJEXT) heap.$(OBJEXT) \
-	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
-	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	types.$(OBJEXT) heap.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
+	connectsock.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
+	fopencookie.$(OBJEXT)
 hxcount_OBJECTS = $(am_hxcount_OBJECTS)
 hxcount_LDADD = $(LDADD)
 hxcount_DEPENDENCIES = @LIBOBJS@
 am_hxextract_OBJECTS = hxextract.$(OBJEXT) html.$(OBJEXT) \
 	scan.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
-	connectsock.$(OBJEXT) heap.$(OBJEXT) errexit.$(OBJEXT) \
-	class.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
-	types.$(OBJEXT) fopencookie.$(OBJEXT)
+	connectsock.$(OBJEXT) heap.$(OBJEXT) class.$(OBJEXT) \
+	headers.$(OBJEXT) dict.$(OBJEXT) types.$(OBJEXT) \
+	fopencookie.$(OBJEXT)
 hxextract_OBJECTS = $(am_hxextract_OBJECTS)
 hxextract_LDADD = $(LDADD)
 hxextract_DEPENDENCIES = @LIBOBJS@
 am_hxincl_OBJECTS = hxincl.$(OBJEXT) scan.$(OBJEXT) html.$(OBJEXT) \
 	openurl.$(OBJEXT) url.$(OBJEXT) heap.$(OBJEXT) \
-	errexit.$(OBJEXT) connectsock.$(OBJEXT) types.$(OBJEXT) \
-	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	connectsock.$(OBJEXT) types.$(OBJEXT) headers.$(OBJEXT) \
+	dict.$(OBJEXT) fopencookie.$(OBJEXT)
 hxincl_OBJECTS = $(am_hxincl_OBJECTS)
 hxincl_LDADD = $(LDADD)
 hxincl_DEPENDENCIES = @LIBOBJS@
 am_hxindex_OBJECTS = hxindex.$(OBJEXT) scan.$(OBJEXT) html.$(OBJEXT) \
 	openurl.$(OBJEXT) url.$(OBJEXT) heap.$(OBJEXT) class.$(OBJEXT) \
-	errexit.$(OBJEXT) connectsock.$(OBJEXT) types.$(OBJEXT) \
-	tree.$(OBJEXT) genid.$(OBJEXT) dtd.$(OBJEXT) headers.$(OBJEXT) \
-	dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	connectsock.$(OBJEXT) types.$(OBJEXT) tree.$(OBJEXT) \
+	genid.$(OBJEXT) dtd.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
+	fopencookie.$(OBJEXT)
 hxindex_OBJECTS = $(am_hxindex_OBJECTS)
 hxindex_LDADD = $(LDADD)
 hxindex_DEPENDENCIES = @LIBOBJS@
-am_hxmkbib_OBJECTS = errexit.$(OBJEXT) heap.$(OBJEXT) \
-	hxmkbib.$(OBJEXT) hash.$(OBJEXT)
+am_hxmkbib_OBJECTS = heap.$(OBJEXT) hxmkbib.$(OBJEXT) hash.$(OBJEXT)
 hxmkbib_OBJECTS = $(am_hxmkbib_OBJECTS)
 hxmkbib_LDADD = $(LDADD)
 hxmkbib_DEPENDENCIES = @LIBOBJS@
 am_hxmultitoc_OBJECTS = hxmultitoc.$(OBJEXT) html.$(OBJEXT) \
 	scan.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
-	connectsock.$(OBJEXT) heap.$(OBJEXT) errexit.$(OBJEXT) \
-	class.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
-	types.$(OBJEXT) fopencookie.$(OBJEXT)
+	connectsock.$(OBJEXT) heap.$(OBJEXT) class.$(OBJEXT) \
+	headers.$(OBJEXT) dict.$(OBJEXT) types.$(OBJEXT) \
+	fopencookie.$(OBJEXT)
 hxmultitoc_OBJECTS = $(am_hxmultitoc_OBJECTS)
 hxmultitoc_LDADD = $(LDADD)
 hxmultitoc_DEPENDENCIES = @LIBOBJS@
 am_hxname2id_OBJECTS = html.$(OBJEXT) scan.$(OBJEXT) dtd.$(OBJEXT) \
-	openurl.$(OBJEXT) errexit.$(OBJEXT) url.$(OBJEXT) \
-	connectsock.$(OBJEXT) heap.$(OBJEXT) tree.$(OBJEXT) \
-	types.$(OBJEXT) hxname2id.$(OBJEXT) headers.$(OBJEXT) \
-	dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
+	heap.$(OBJEXT) tree.$(OBJEXT) types.$(OBJEXT) \
+	hxname2id.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
+	fopencookie.$(OBJEXT)
 hxname2id_OBJECTS = $(am_hxname2id_OBJECTS)
 hxname2id_LDADD = $(LDADD)
 hxname2id_DEPENDENCIES = @LIBOBJS@
 am_hxnormalize_OBJECTS = hxnormalize.$(OBJEXT) html.$(OBJEXT) \
 	scan.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) tree.$(OBJEXT) \
 	connectsock.$(OBJEXT) heap.$(OBJEXT) dtd.$(OBJEXT) \
-	types.$(OBJEXT) textwrap.$(OBJEXT) errexit.$(OBJEXT) \
+	types.$(OBJEXT) langinfo.$(OBJEXT) textwrap.$(OBJEXT) \
 	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
 hxnormalize_OBJECTS = $(am_hxnormalize_OBJECTS)
 hxnormalize_LDADD = $(LDADD)
 hxnormalize_DEPENDENCIES = @LIBOBJS@
 am_hxnsxml_OBJECTS = hxnsxml.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
-	types.$(OBJEXT) errexit.$(OBJEXT) heap.$(OBJEXT) \
-	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
-	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	types.$(OBJEXT) heap.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
+	connectsock.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
+	fopencookie.$(OBJEXT)
 hxnsxml_OBJECTS = $(am_hxnsxml_OBJECTS)
 hxnsxml_LDADD = $(LDADD)
 hxnsxml_DEPENDENCIES = @LIBOBJS@
 am_hxnum_OBJECTS = hxnum.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
-	openurl.$(OBJEXT) url.$(OBJEXT) errexit.$(OBJEXT) \
-	heap.$(OBJEXT) connectsock.$(OBJEXT) headers.$(OBJEXT) \
-	dict.$(OBJEXT) types.$(OBJEXT) class.$(OBJEXT) \
-	fopencookie.$(OBJEXT)
+	openurl.$(OBJEXT) url.$(OBJEXT) heap.$(OBJEXT) \
+	connectsock.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
+	types.$(OBJEXT) class.$(OBJEXT) fopencookie.$(OBJEXT)
 hxnum_OBJECTS = $(am_hxnum_OBJECTS)
 hxnum_LDADD = $(LDADD)
 hxnum_DEPENDENCIES = @LIBOBJS@
 am_hxpipe_OBJECTS = hxpipe.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
-	types.$(OBJEXT) errexit.$(OBJEXT) heap.$(OBJEXT) \
-	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
-	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	types.$(OBJEXT) heap.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
+	connectsock.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
+	dtd.$(OBJEXT) tree.$(OBJEXT) fopencookie.$(OBJEXT)
 hxpipe_OBJECTS = $(am_hxpipe_OBJECTS)
 hxpipe_LDADD = $(LDADD)
 hxpipe_DEPENDENCIES = @LIBOBJS@
 am_hxprintlinks_OBJECTS = hxprintlinks.$(OBJEXT) openurl.$(OBJEXT) \
 	headers.$(OBJEXT) types.$(OBJEXT) heap.$(OBJEXT) \
-	errexit.$(OBJEXT) dict.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
-	url.$(OBJEXT) connectsock.$(OBJEXT) fopencookie.$(OBJEXT)
+	dict.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) url.$(OBJEXT) \
+	connectsock.$(OBJEXT) fopencookie.$(OBJEXT)
 hxprintlinks_OBJECTS = $(am_hxprintlinks_OBJECTS)
 hxprintlinks_LDADD = $(LDADD)
 hxprintlinks_DEPENDENCIES = @LIBOBJS@
 am_hxprune_OBJECTS = hxprune.$(OBJEXT) tree.$(OBJEXT) scan.$(OBJEXT) \
-	html.$(OBJEXT) errexit.$(OBJEXT) dtd.$(OBJEXT) heap.$(OBJEXT) \
-	types.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
-	connectsock.$(OBJEXT) class.$(OBJEXT) headers.$(OBJEXT) \
-	dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	html.$(OBJEXT) dtd.$(OBJEXT) heap.$(OBJEXT) types.$(OBJEXT) \
+	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
+	class.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
+	fopencookie.$(OBJEXT)
 hxprune_OBJECTS = $(am_hxprune_OBJECTS)
 hxprune_LDADD = $(LDADD)
 hxprune_DEPENDENCIES = @LIBOBJS@
 am_hxref_OBJECTS = html.$(OBJEXT) scan.$(OBJEXT) dtd.$(OBJEXT) \
-	openurl.$(OBJEXT) errexit.$(OBJEXT) url.$(OBJEXT) \
-	connectsock.$(OBJEXT) heap.$(OBJEXT) tree.$(OBJEXT) \
-	types.$(OBJEXT) genid.$(OBJEXT) hxref.$(OBJEXT) hash.$(OBJEXT) \
-	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
+	heap.$(OBJEXT) tree.$(OBJEXT) types.$(OBJEXT) genid.$(OBJEXT) \
+	hxref.$(OBJEXT) hash.$(OBJEXT) headers.$(OBJEXT) \
+	dict.$(OBJEXT) fopencookie.$(OBJEXT)
 hxref_OBJECTS = $(am_hxref_OBJECTS)
 hxref_LDADD = $(LDADD)
 hxref_DEPENDENCIES = @LIBOBJS@
 am_hxremove_OBJECTS = hxremove.$(OBJEXT) types.$(OBJEXT) \
-	errexit.$(OBJEXT) heap.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
-	tree.$(OBJEXT) selector.$(OBJEXT) dtd.$(OBJEXT) \
-	selmatch.$(OBJEXT)
+	heap.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) tree.$(OBJEXT) \
+	selector.$(OBJEXT) dtd.$(OBJEXT) selmatch.$(OBJEXT)
 hxremove_OBJECTS = $(am_hxremove_OBJECTS)
 hxremove_LDADD = $(LDADD)
 hxremove_DEPENDENCIES = @LIBOBJS@
 am_hxselect_OBJECTS = hxselect.$(OBJEXT) types.$(OBJEXT) \
-	errexit.$(OBJEXT) heap.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
-	tree.$(OBJEXT) selector.$(OBJEXT) dtd.$(OBJEXT) \
-	selmatch.$(OBJEXT)
+	heap.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) tree.$(OBJEXT) \
+	selector.$(OBJEXT) dtd.$(OBJEXT) selmatch.$(OBJEXT)
 hxselect_OBJECTS = $(am_hxselect_OBJECTS)
 hxselect_LDADD = $(LDADD)
 hxselect_DEPENDENCIES = @LIBOBJS@
 am_hxtabletrans_OBJECTS = hxtabletrans.$(OBJEXT) scan.$(OBJEXT) \
 	tree.$(OBJEXT) heap.$(OBJEXT) openurl.$(OBJEXT) html.$(OBJEXT) \
-	errexit.$(OBJEXT) dtd.$(OBJEXT) types.$(OBJEXT) dict.$(OBJEXT) \
+	dtd.$(OBJEXT) types.$(OBJEXT) dict.$(OBJEXT) \
 	connectsock.$(OBJEXT) headers.$(OBJEXT) url.$(OBJEXT) \
 	fopencookie.$(OBJEXT)
 hxtabletrans_OBJECTS = $(am_hxtabletrans_OBJECTS)
 hxtabletrans_LDADD = $(LDADD)
 hxtabletrans_DEPENDENCIES = @LIBOBJS@
 am_hxtoc_OBJECTS = html.$(OBJEXT) scan.$(OBJEXT) dtd.$(OBJEXT) \
-	openurl.$(OBJEXT) errexit.$(OBJEXT) url.$(OBJEXT) \
-	class.$(OBJEXT) connectsock.$(OBJEXT) heap.$(OBJEXT) \
-	tree.$(OBJEXT) types.$(OBJEXT) genid.$(OBJEXT) hxtoc.$(OBJEXT) \
-	hash.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
-	fopencookie.$(OBJEXT)
+	openurl.$(OBJEXT) url.$(OBJEXT) class.$(OBJEXT) \
+	connectsock.$(OBJEXT) heap.$(OBJEXT) tree.$(OBJEXT) \
+	types.$(OBJEXT) genid.$(OBJEXT) hxtoc.$(OBJEXT) hash.$(OBJEXT) \
+	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
 hxtoc_OBJECTS = $(am_hxtoc_OBJECTS)
 hxtoc_LDADD = $(LDADD)
 hxtoc_DEPENDENCIES = @LIBOBJS@
@@ -304,32 +297,30 @@ hxunent_OBJECTS = $(am_hxunent_OBJECTS)
 hxunent_LDADD = $(LDADD)
 hxunent_DEPENDENCIES = @LIBOBJS@
 am_hxunpipe_OBJECTS = hxunpipe.$(OBJEXT) heap.$(OBJEXT) \
-	errexit.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
-	connectsock.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
-	types.$(OBJEXT) fopencookie.$(OBJEXT)
+	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
+	headers.$(OBJEXT) dict.$(OBJEXT) types.$(OBJEXT) \
+	fopencookie.$(OBJEXT)
 hxunpipe_OBJECTS = $(am_hxunpipe_OBJECTS)
 hxunpipe_LDADD = $(LDADD)
 hxunpipe_DEPENDENCIES = @LIBOBJS@
 am_hxunxmlns_OBJECTS = hxunxmlns.$(OBJEXT) html.$(OBJEXT) \
 	scan.$(OBJEXT) openurl.$(OBJEXT) url.$(OBJEXT) \
-	connectsock.$(OBJEXT) heap.$(OBJEXT) errexit.$(OBJEXT) \
-	types.$(OBJEXT) headers.$(OBJEXT) dict.$(OBJEXT) \
-	fopencookie.$(OBJEXT)
+	connectsock.$(OBJEXT) heap.$(OBJEXT) types.$(OBJEXT) \
+	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
 hxunxmlns_OBJECTS = $(am_hxunxmlns_OBJECTS)
 hxunxmlns_LDADD = $(LDADD)
 hxunxmlns_DEPENDENCIES = @LIBOBJS@
 am_hxwls_OBJECTS = hxwls.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
 	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
-	heap.$(OBJEXT) errexit.$(OBJEXT) types.$(OBJEXT) \
-	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT) \
-	unent.$(OBJEXT)
+	heap.$(OBJEXT) types.$(OBJEXT) headers.$(OBJEXT) \
+	dict.$(OBJEXT) fopencookie.$(OBJEXT) unent.$(OBJEXT)
 hxwls_OBJECTS = $(am_hxwls_OBJECTS)
 hxwls_LDADD = $(LDADD)
 hxwls_DEPENDENCIES = @LIBOBJS@
 am_hxxmlns_OBJECTS = hxxmlns.$(OBJEXT) html.$(OBJEXT) scan.$(OBJEXT) \
 	openurl.$(OBJEXT) url.$(OBJEXT) connectsock.$(OBJEXT) \
-	heap.$(OBJEXT) errexit.$(OBJEXT) types.$(OBJEXT) \
-	headers.$(OBJEXT) dict.$(OBJEXT) fopencookie.$(OBJEXT)
+	heap.$(OBJEXT) types.$(OBJEXT) headers.$(OBJEXT) \
+	dict.$(OBJEXT) fopencookie.$(OBJEXT)
 hxxmlns_OBJECTS = $(am_hxxmlns_OBJECTS)
 hxxmlns_LDADD = $(LDADD)
 hxxmlns_DEPENDENCIES = @LIBOBJS@
@@ -379,7 +370,35 @@ am__v_at_0 = @
 am__v_at_1 = 
 DEFAULT_INCLUDES = -I.@am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = $(DEPDIR)/malloc.Po $(DEPDIR)/realloc.Po \
+	$(DEPDIR)/strdup.Po $(DEPDIR)/strerror.Po $(DEPDIR)/strstr.Po \
+	$(DEPDIR)/tfind.Po $(DEPDIR)/tsearch.Po $(DEPDIR)/twalk.Po \
+	./$(DEPDIR)/asc2xml.Po ./$(DEPDIR)/cexport.Po \
+	./$(DEPDIR)/class.Po ./$(DEPDIR)/connectsock.Po \
+	./$(DEPDIR)/dict.Po ./$(DEPDIR)/dtd.Po \
+	./$(DEPDIR)/fopencookie.Po ./$(DEPDIR)/genid.Po \
+	./$(DEPDIR)/hash.Po ./$(DEPDIR)/headers.Po ./$(DEPDIR)/heap.Po \
+	./$(DEPDIR)/html.Po ./$(DEPDIR)/hxaddid.Po \
+	./$(DEPDIR)/hxcite.Po ./$(DEPDIR)/hxclean.Po \
+	./$(DEPDIR)/hxcopy.Po ./$(DEPDIR)/hxcount.Po \
+	./$(DEPDIR)/hxextract.Po ./$(DEPDIR)/hxincl.Po \
+	./$(DEPDIR)/hxindex.Po ./$(DEPDIR)/hxmkbib.Po \
+	./$(DEPDIR)/hxmultitoc.Po ./$(DEPDIR)/hxname2id.Po \
+	./$(DEPDIR)/hxnormalize.Po ./$(DEPDIR)/hxnsxml.Po \
+	./$(DEPDIR)/hxnum.Po ./$(DEPDIR)/hxpipe.Po \
+	./$(DEPDIR)/hxprintlinks.Po ./$(DEPDIR)/hxprune.Po \
+	./$(DEPDIR)/hxref.Po ./$(DEPDIR)/hxremove.Po \
+	./$(DEPDIR)/hxselect.Po ./$(DEPDIR)/hxtabletrans.Po \
+	./$(DEPDIR)/hxtoc.Po ./$(DEPDIR)/hxuncdata.Po \
+	./$(DEPDIR)/hxunentmain.Po ./$(DEPDIR)/hxunpipe.Po \
+	./$(DEPDIR)/hxunxmlns.Po ./$(DEPDIR)/hxwls.Po \
+	./$(DEPDIR)/hxxmlns.Po ./$(DEPDIR)/langinfo.Po \
+	./$(DEPDIR)/openurl.Po ./$(DEPDIR)/scan.Po \
+	./$(DEPDIR)/selector.Po ./$(DEPDIR)/selmatch.Po \
+	./$(DEPDIR)/textwrap.Po ./$(DEPDIR)/tree.Po \
+	./$(DEPDIR)/types.Po ./$(DEPDIR)/unent.Po ./$(DEPDIR)/url.Po \
+	./$(DEPDIR)/xml2asc.Po
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -437,8 +456,8 @@ man1dir = $(mandir)/man1
 NROFF = nroff
 MANS = $(man_MANS)
 DATA = $(doc_DATA)
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
-	$(LISP)config.h.in
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
+	config.h.in
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
 # *not* preserved.
@@ -614,6 +633,7 @@ am__set_TESTS_bases = \
   bases='$(TEST_LOGS)'; \
   bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
   bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
 RECHECK_LOGS = $(TEST_LOGS)
 TEST_SUITE_LOG = test-suite.log
 TEST_EXTENSIONS = @EXEEXT@ .test
@@ -654,6 +674,8 @@ am__post_remove_distdir = $(am__remove_distdir)
 DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 DIST_TARGETS = dist-gzip
+# Exists only to be overridden by the user if desired.
+AM_DISTCHECK_DVI_TARGET = dvi
 distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
   | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -789,111 +811,111 @@ AM_YFLAGS = -d
 AM_LFLAGS = @lex_opt_flags@
 ACLOCAL_AMFLAGS = -I m4
 EXPORTS = dict.e heap.e types.e headers.e connectsock.e\
-			dtd.e errexit.e tree.e genid.e html.e url.e\
-			openurl.e scan.e textwrap.e unent.e class.e\
-			selector.e hash.e selmatch.e
+			dtd.e html.e scan.e tree.e genid.e url.e\
+			openurl.e textwrap.e unent.e class.e\
+			selector.e hash.e selmatch.e langinfo.e
 
-BUILT_SOURCES = $(EXPORTS) scan.c html.c html.h dtd.c unent.c
+BUILT_SOURCES = html.h $(EXPORTS) html.c scan.c dtd.c unent.c
 asc2xml_SOURCES = asc2xml.c
-hxaddid_SOURCES = hxaddid.c html.y scan.l dtd.c openurl.c errexit.c\
+hxaddid_SOURCES = hxaddid.c html.y scan.l dtd.c openurl.c\
 			url.c connectsock.c heap.c tree.c types.c genid.c\
 			fopencookie.h\
 			class.c hash.c headers.c dict.c fopencookie.c
 
 cexport_SOURCES = cexport.c
-hxcite_SOURCES = heap.c errexit.c hxcite.c
-hxcount_SOURCES = hxcount.c html.y scan.l types.c errexit.c heap.c\
+hxcite_SOURCES = heap.c hxcite.c
+hxcount_SOURCES = hxcount.c html.y scan.l types.c heap.c\
 			openurl.c url.c connectsock.c headers.c dict.c\
 			fopencookie.h fopencookie.c
 
 hxextract_SOURCES = hxextract.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c class.c headers.c\
+			connectsock.c heap.c class.c headers.c\
 			dict.c types.c fopencookie.h fopencookie.c
 
 hxclean_SOURCES = hxclean.c html.y tree.c types.c heap.c dtd.c\
-			scan.l errexit.c
+			scan.l
 
-hxprune_SOURCES = hxprune.c tree.c scan.l html.y errexit.c dtd.c\
+hxprune_SOURCES = hxprune.c tree.c scan.l html.y dtd.c\
 			heap.c types.c openurl.c url.c connectsock.c class.c\
 			headers.c dict.c fopencookie.h fopencookie.c
 
 hxincl_SOURCES = hxincl.c scan.l html.y openurl.c url.c heap.c\
-			errexit.c connectsock.c types.c headers.c dict.c\
+			connectsock.c types.c headers.c dict.c\
 			fopencookie.h fopencookie.c
 
 hxindex_SOURCES = hxindex.c scan.l html.y openurl.c url.c heap.c class.c\
-			errexit.c connectsock.c types.c tree.c genid.c dtd.c\
+			connectsock.c types.c tree.c genid.c dtd.c\
 			headers.c dict.c fopencookie.h fopencookie.c
 
-hxmkbib_SOURCES = errexit.c heap.c hxmkbib.c hash.c
+hxmkbib_SOURCES = heap.c hxmkbib.c hash.c
 hxmultitoc_SOURCES = hxmultitoc.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c class.c headers.c\
+			connectsock.c heap.c class.c headers.c\
 			dict.c types.c fopencookie.h fopencookie.c
 
 hxnormalize_SOURCES = hxnormalize.c html.y scan.l openurl.c url.c\
 			tree.c connectsock.c heap.c dtd.c types.c\
-			fopencookie.h\
-			textwrap.c errexit.c headers.c dict.c fopencookie.c
+			fopencookie.h langinfo.c\
+			textwrap.c headers.c dict.c fopencookie.c
 
-hxnum_SOURCES = hxnum.c html.y scan.l openurl.c url.c errexit.c\
+hxnum_SOURCES = hxnum.c html.y scan.l openurl.c url.c\
 			heap.c connectsock.c headers.c dict.c types.c class.c\
 			fopencookie.h fopencookie.c
 
-hxpipe_SOURCES = hxpipe.c html.y scan.l types.c errexit.c heap.c\
+hxpipe_SOURCES = hxpipe.c html.y scan.l types.c heap.c\
 			openurl.c url.c connectsock.c headers.c dict.c\
-			fopencookie.h fopencookie.c
+			dtd.c tree.c fopencookie.h fopencookie.c
 
-hxremove_SOURCES = hxremove.c types.c errexit.c heap.c html.y scan.l\
+hxremove_SOURCES = hxremove.c types.c heap.c html.y scan.l\
 			tree.c selector.c dtd.c selmatch.c
 
-hxselect_SOURCES = hxselect.c types.c errexit.c heap.c html.y scan.l\
+hxselect_SOURCES = hxselect.c types.c heap.c html.y scan.l\
 			tree.c selector.c dtd.c selmatch.c
 
 hxtabletrans_SOURCES = hxtabletrans.c scan.l tree.c heap.c openurl.c html.y\
-			errexit.c dtd.c types.c dict.c connectsock.c\
+			dtd.c types.c dict.c connectsock.c\
 			headers.c url.c fopencookie.h fopencookie.c
 
-hxtoc_SOURCES = html.y scan.l dtd.c openurl.c errexit.c url.c class.c\
+hxtoc_SOURCES = html.y scan.l dtd.c openurl.c url.c class.c\
 			connectsock.c heap.c tree.c types.c genid.c hxtoc.c\
 			hash.c headers.c dict.c fopencookie.h fopencookie.c
 
 hxuncdata_SOURCES = hxuncdata.c
 hxunent_SOURCES = unent.c hxunentmain.c
-hxunpipe_SOURCES = hxunpipe.c heap.c errexit.c openurl.c url.c\
+hxunpipe_SOURCES = hxunpipe.c heap.c openurl.c url.c\
 			fopencookie.h\
 			connectsock.c headers.c dict.c types.c fopencookie.c
 
 hxunxmlns_SOURCES = hxunxmlns.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c types.c headers.c\
+			connectsock.c heap.c types.c headers.c\
 			dict.c fopencookie.h fopencookie.c
 
 hxwls_SOURCES = hxwls.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c types.c headers.c\
+			connectsock.c heap.c types.c headers.c\
 			dict.c fopencookie.h fopencookie.c unent.c
 
 hxxmlns_SOURCES = hxxmlns.c html.y scan.l openurl.c url.c\
-			connectsock.c heap.c errexit.c types.c headers.c\
+			connectsock.c heap.c types.c headers.c\
 			dict.c fopencookie.h fopencookie.c
 
 xml2asc_SOURCES = xml2asc.c
-hxref_SOURCES = html.y scan.l dtd.c openurl.c errexit.c url.c\
+hxref_SOURCES = html.y scan.l dtd.c openurl.c url.c\
 			connectsock.c heap.c tree.c types.c genid.c hxref.c\
 			hash.c headers.c dict.c fopencookie.h fopencookie.c
 
-hxname2id_SOURCES = html.y scan.l dtd.c openurl.c errexit.c url.c\
+hxname2id_SOURCES = html.y scan.l dtd.c openurl.c url.c\
 			connectsock.c heap.c tree.c types.c hxname2id.c\
 			headers.c dict.c fopencookie.h fopencookie.c
 
-hxcopy_SOURCES = html.y scan.l types.c url.c openurl.c errexit.c\
+hxcopy_SOURCES = html.y scan.l types.c url.c openurl.c\
 			dict.c headers.c heap.c connectsock.c hxcopy.c\
 			fopencookie.h fopencookie.c
 
-hxnsxml_SOURCES = hxnsxml.c html.y scan.l types.c errexit.c heap.c\
+hxnsxml_SOURCES = hxnsxml.c html.y scan.l types.c heap.c\
 			openurl.c url.c connectsock.c headers.c dict.c\
 			fopencookie.h fopencookie.c
 
 hxprintlinks_SOURCES = hxprintlinks.c openurl.c headers.c\
-			types.c heap.c errexit.c\
+			types.c heap.c\
 			dict.c html.y scan.l url.c connectsock.c\
 			fopencookie.h fopencookie.c
 
@@ -923,11 +945,14 @@ TESTS = tests/addid1.sh tests/addid1.sh tests/ascxml.sh\
 	tests/normalize1.sh tests/normalize2.sh\
 	tests/normalize3.sh tests/normalize4.sh tests/normalize5.sh\
 	tests/normalize6.sh tests/normalize7.sh tests/normalize8.sh\
-	tests/normalize9.sh tests/normalize10.sh  tests/normalize11.sh\
-	tests/normalize12.sh\
+	tests/normalize9.sh tests/normalize10.sh tests/normalize11.sh\
+	tests/normalize12.sh tests/normalize13.sh tests/normalize14.sh\
+	tests/num1.sh tests/num2.sh tests/num3.sh tests/num4.sh\
+	tests/num5.sh tests/num6.sh\
 	tests/pipe1.sh tests/pipe2.sh tests/pipe3.sh tests/pipe4.sh\
+	tests/pipe5.sh tests/pipe6.sh tests/pipe7.sh\
 	tests/printlinks1.sh tests/printlinks2.sh tests/printlinks3.sh\
-	tests/printlinks4.sh tests/ref1.sh\
+	tests/printlinks4.sh tests/printlinks5.sh tests/ref1.sh\
 	tests/ref2.sh tests/ref3.sh tests/relurl1.sh tests/relurl2.sh\
 	tests/relurl3.sh tests/remove1.sh tests/remove2.sh\
 	tests/remove3.sh tests/remove4.sh tests/remove5.sh tests/remove6.sh\
@@ -940,9 +965,14 @@ TESTS = tests/addid1.sh tests/addid1.sh tests/ascxml.sh\
 	tests/select16.sh tests/select17.sh tests/select18.sh\
 	tests/select19.sh tests/select20.sh tests/select21.sh\
 	tests/select22.sh tests/select23.sh tests/select24.sh\
+	tests/select25.sh tests/select26.sh tests/select27.sh\
+	tests/select28.sh tests/select29.sh tests/select30.sh\
+	tests/select31.sh tests/select32.sh tests/select33.sh\
+	tests/select34.sh\
 	tests/tabletrans1.sh tests/tabletrans2.sh tests/tabletrans3.sh\
 	tests/tabletrans4.sh tests/tabletrans5.sh\
 	tests/toc1.sh tests/toc2.sh tests/toc3.sh tests/toc4.sh\
+	tests/toc5.sh tests/toc6.sh\
 	tests/uncdata1.sh\
 	tests/unent1.sh tests/unent2.sh tests/unent3.sh tests/unent4.sh\
 	tests/unent5.sh tests/unent6.sh\
@@ -950,7 +980,8 @@ TESTS = tests/addid1.sh tests/addid1.sh tests/ascxml.sh\
 	tests/unpipe2.sh tests/unpipe3.sh tests/unpipe4.sh tests/unpipe5.sh\
 	tests/unpipe6.sh\
 	tests/wls1.sh tests/wls2.sh\
-	tests/wls3.sh tests/wls4.sh tests/wls5.sh\
+	tests/wls3.sh tests/wls4.sh tests/wls5.sh tests/wls6.sh\
+	tests/wls7.sh\
 	tests/xmlasc1.sh tests/xmlasc2.sh tests/xmlasc3.sh\
 	tests/xmlasc4.sh tests/xmlasc5.sh tests/xmlasc6.sh\
 	tests/xmlasc7.sh tests/xmlns1.sh tests/xref1.sh tests/xref2.sh\
@@ -983,8 +1014,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	    echo ' $(SHELL) ./config.status'; \
 	    $(SHELL) ./config.status;; \
 	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
 	esac;
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@@ -1224,65 +1255,71 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/malloc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/realloc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strdup.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strstr.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/tfind.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/tsearch.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/twalk.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asc2xml.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cexport.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/class.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connectsock.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtd.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errexit.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fopencookie.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genid.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/headers.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/html.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxaddid.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxcite.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxclean.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxcopy.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxcount.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxextract.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxincl.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxindex.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxmkbib.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxmultitoc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxname2id.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxnormalize.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxnsxml.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxnum.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxpipe.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxprintlinks.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxprune.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxref.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxremove.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxselect.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxtabletrans.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxtoc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxuncdata.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxunentmain.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxunpipe.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxunxmlns.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxwls.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxxmlns.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openurl.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selector.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selmatch.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textwrap.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/types.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unent.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/url.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml2asc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/malloc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/realloc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strdup.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strstr.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/tfind.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/tsearch.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/twalk.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asc2xml.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cexport.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/class.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connectsock.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dict.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtd.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fopencookie.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genid.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/headers.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/html.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxaddid.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxcite.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxclean.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxcopy.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxcount.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxextract.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxincl.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxindex.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxmkbib.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxmultitoc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxname2id.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxnormalize.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxnsxml.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxnum.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxpipe.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxprintlinks.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxprune.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxref.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxremove.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxselect.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxtabletrans.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxtoc.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxuncdata.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxunentmain.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxunpipe.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxunxmlns.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxwls.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hxxmlns.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/langinfo.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openurl.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selector.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selmatch.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textwrap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/types.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unent.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/url.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml2asc.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+	@$(MKDIR_P) $(@D)
+	@echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -1534,7 +1571,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
 	fi;								\
 	echo "$${col}$$br$${std}"; 					\
-	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}";	\
 	echo "$${col}$$br$${std}"; 					\
 	create_testsuite_report --maybe-color;				\
 	echo "$$col$$br$$std";						\
@@ -1547,7 +1584,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	fi;								\
 	$$success || exit 1
 
-check-TESTS:
+check-TESTS: 
 	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
 	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
 	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@@ -1960,6 +1997,62 @@ tests/normalize12.sh.log: tests/normalize12.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/normalize13.sh.log: tests/normalize13.sh
+	@p='tests/normalize13.sh'; \
+	b='tests/normalize13.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/normalize14.sh.log: tests/normalize14.sh
+	@p='tests/normalize14.sh'; \
+	b='tests/normalize14.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/num1.sh.log: tests/num1.sh
+	@p='tests/num1.sh'; \
+	b='tests/num1.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/num2.sh.log: tests/num2.sh
+	@p='tests/num2.sh'; \
+	b='tests/num2.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/num3.sh.log: tests/num3.sh
+	@p='tests/num3.sh'; \
+	b='tests/num3.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/num4.sh.log: tests/num4.sh
+	@p='tests/num4.sh'; \
+	b='tests/num4.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/num5.sh.log: tests/num5.sh
+	@p='tests/num5.sh'; \
+	b='tests/num5.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/num6.sh.log: tests/num6.sh
+	@p='tests/num6.sh'; \
+	b='tests/num6.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tests/pipe1.sh.log: tests/pipe1.sh
 	@p='tests/pipe1.sh'; \
 	b='tests/pipe1.sh'; \
@@ -1988,6 +2081,27 @@ tests/pipe4.sh.log: tests/pipe4.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/pipe5.sh.log: tests/pipe5.sh
+	@p='tests/pipe5.sh'; \
+	b='tests/pipe5.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/pipe6.sh.log: tests/pipe6.sh
+	@p='tests/pipe6.sh'; \
+	b='tests/pipe6.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/pipe7.sh.log: tests/pipe7.sh
+	@p='tests/pipe7.sh'; \
+	b='tests/pipe7.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tests/printlinks1.sh.log: tests/printlinks1.sh
 	@p='tests/printlinks1.sh'; \
 	b='tests/printlinks1.sh'; \
@@ -2016,6 +2130,13 @@ tests/printlinks4.sh.log: tests/printlinks4.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/printlinks5.sh.log: tests/printlinks5.sh
+	@p='tests/printlinks5.sh'; \
+	b='tests/printlinks5.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tests/ref1.sh.log: tests/ref1.sh
 	@p='tests/ref1.sh'; \
 	b='tests/ref1.sh'; \
@@ -2275,6 +2396,76 @@ tests/select24.sh.log: tests/select24.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select25.sh.log: tests/select25.sh
+	@p='tests/select25.sh'; \
+	b='tests/select25.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select26.sh.log: tests/select26.sh
+	@p='tests/select26.sh'; \
+	b='tests/select26.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select27.sh.log: tests/select27.sh
+	@p='tests/select27.sh'; \
+	b='tests/select27.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select28.sh.log: tests/select28.sh
+	@p='tests/select28.sh'; \
+	b='tests/select28.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select29.sh.log: tests/select29.sh
+	@p='tests/select29.sh'; \
+	b='tests/select29.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select30.sh.log: tests/select30.sh
+	@p='tests/select30.sh'; \
+	b='tests/select30.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select31.sh.log: tests/select31.sh
+	@p='tests/select31.sh'; \
+	b='tests/select31.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select32.sh.log: tests/select32.sh
+	@p='tests/select32.sh'; \
+	b='tests/select32.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select33.sh.log: tests/select33.sh
+	@p='tests/select33.sh'; \
+	b='tests/select33.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/select34.sh.log: tests/select34.sh
+	@p='tests/select34.sh'; \
+	b='tests/select34.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tests/tabletrans1.sh.log: tests/tabletrans1.sh
 	@p='tests/tabletrans1.sh'; \
 	b='tests/tabletrans1.sh'; \
@@ -2338,6 +2529,20 @@ tests/toc4.sh.log: tests/toc4.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/toc5.sh.log: tests/toc5.sh
+	@p='tests/toc5.sh'; \
+	b='tests/toc5.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/toc6.sh.log: tests/toc6.sh
+	@p='tests/toc6.sh'; \
+	b='tests/toc6.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tests/uncdata1.sh.log: tests/uncdata1.sh
 	@p='tests/uncdata1.sh'; \
 	b='tests/uncdata1.sh'; \
@@ -2464,6 +2669,20 @@ tests/wls5.sh.log: tests/wls5.sh
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/wls6.sh.log: tests/wls6.sh
+	@p='tests/wls6.sh'; \
+	b='tests/wls6.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tests/wls7.sh.log: tests/wls7.sh
+	@p='tests/wls7.sh'; \
+	b='tests/wls7.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 tests/xmlasc1.sh.log: tests/xmlasc1.sh
 	@p='tests/xmlasc1.sh'; \
 	b='tests/xmlasc1.sh'; \
@@ -2584,7 +2803,10 @@ tests/xref7.sh.log: tests/xref7.sh
 @am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
 @am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
-distdir: $(DISTFILES)
+distdir: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
 	$(am__remove_distdir)
 	test -d "$(distdir)" || mkdir "$(distdir)"
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -2624,7 +2846,7 @@ distdir: $(DISTFILES)
 	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
 	|| chmod -R a+r "$(distdir)"
 dist-gzip: distdir
-	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
 	$(am__post_remove_distdir)
 
 dist-bzip2: distdir
@@ -2639,6 +2861,10 @@ dist-xz: distdir
 	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
 	$(am__post_remove_distdir)
 
+dist-zstd: distdir
+	tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+	$(am__post_remove_distdir)
+
 dist-tarZ: distdir
 	@echo WARNING: "Support for distribution archives compressed with" \
 		       "legacy program 'compress' is deprecated." >&2
@@ -2650,7 +2876,7 @@ dist-shar: distdir
 	@echo WARNING: "Support for shar distribution archives is" \
 	               "deprecated." >&2
 	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
-	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
 
 dist-zip: distdir
@@ -2668,7 +2894,7 @@ dist dist-all:
 distcheck: dist
 	case '$(DIST_ARCHIVES)' in \
 	*.tar.gz*) \
-	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
 	*.tar.bz2*) \
 	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
 	*.tar.lz*) \
@@ -2678,9 +2904,11 @@ distcheck: dist
 	*.tar.Z*) \
 	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
 	*.shar.gz*) \
-	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
+	*.tar.zst*) \
+	  zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
@@ -2696,7 +2924,7 @@ distcheck: dist
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
 	    --srcdir=../.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
-	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
 	  && $(MAKE) $(AM_MAKEFLAGS) install \
 	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
@@ -2758,7 +2986,8 @@ installdirs:
 	done
 install: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) install-am
-install-exec: install-exec-am
+install-exec: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-exec-am
 install-data: install-data-am
 uninstall: uninstall-am
 
@@ -2802,7 +3031,65 @@ clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf $(DEPDIR) ./$(DEPDIR)
+		-rm -f $(DEPDIR)/malloc.Po
+	-rm -f $(DEPDIR)/realloc.Po
+	-rm -f $(DEPDIR)/strdup.Po
+	-rm -f $(DEPDIR)/strerror.Po
+	-rm -f $(DEPDIR)/strstr.Po
+	-rm -f $(DEPDIR)/tfind.Po
+	-rm -f $(DEPDIR)/tsearch.Po
+	-rm -f $(DEPDIR)/twalk.Po
+	-rm -f ./$(DEPDIR)/asc2xml.Po
+	-rm -f ./$(DEPDIR)/cexport.Po
+	-rm -f ./$(DEPDIR)/class.Po
+	-rm -f ./$(DEPDIR)/connectsock.Po
+	-rm -f ./$(DEPDIR)/dict.Po
+	-rm -f ./$(DEPDIR)/dtd.Po
+	-rm -f ./$(DEPDIR)/fopencookie.Po
+	-rm -f ./$(DEPDIR)/genid.Po
+	-rm -f ./$(DEPDIR)/hash.Po
+	-rm -f ./$(DEPDIR)/headers.Po
+	-rm -f ./$(DEPDIR)/heap.Po
+	-rm -f ./$(DEPDIR)/html.Po
+	-rm -f ./$(DEPDIR)/hxaddid.Po
+	-rm -f ./$(DEPDIR)/hxcite.Po
+	-rm -f ./$(DEPDIR)/hxclean.Po
+	-rm -f ./$(DEPDIR)/hxcopy.Po
+	-rm -f ./$(DEPDIR)/hxcount.Po
+	-rm -f ./$(DEPDIR)/hxextract.Po
+	-rm -f ./$(DEPDIR)/hxincl.Po
+	-rm -f ./$(DEPDIR)/hxindex.Po
+	-rm -f ./$(DEPDIR)/hxmkbib.Po
+	-rm -f ./$(DEPDIR)/hxmultitoc.Po
+	-rm -f ./$(DEPDIR)/hxname2id.Po
+	-rm -f ./$(DEPDIR)/hxnormalize.Po
+	-rm -f ./$(DEPDIR)/hxnsxml.Po
+	-rm -f ./$(DEPDIR)/hxnum.Po
+	-rm -f ./$(DEPDIR)/hxpipe.Po
+	-rm -f ./$(DEPDIR)/hxprintlinks.Po
+	-rm -f ./$(DEPDIR)/hxprune.Po
+	-rm -f ./$(DEPDIR)/hxref.Po
+	-rm -f ./$(DEPDIR)/hxremove.Po
+	-rm -f ./$(DEPDIR)/hxselect.Po
+	-rm -f ./$(DEPDIR)/hxtabletrans.Po
+	-rm -f ./$(DEPDIR)/hxtoc.Po
+	-rm -f ./$(DEPDIR)/hxuncdata.Po
+	-rm -f ./$(DEPDIR)/hxunentmain.Po
+	-rm -f ./$(DEPDIR)/hxunpipe.Po
+	-rm -f ./$(DEPDIR)/hxunxmlns.Po
+	-rm -f ./$(DEPDIR)/hxwls.Po
+	-rm -f ./$(DEPDIR)/hxxmlns.Po
+	-rm -f ./$(DEPDIR)/langinfo.Po
+	-rm -f ./$(DEPDIR)/openurl.Po
+	-rm -f ./$(DEPDIR)/scan.Po
+	-rm -f ./$(DEPDIR)/selector.Po
+	-rm -f ./$(DEPDIR)/selmatch.Po
+	-rm -f ./$(DEPDIR)/textwrap.Po
+	-rm -f ./$(DEPDIR)/tree.Po
+	-rm -f ./$(DEPDIR)/types.Po
+	-rm -f ./$(DEPDIR)/unent.Po
+	-rm -f ./$(DEPDIR)/url.Po
+	-rm -f ./$(DEPDIR)/xml2asc.Po
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-tags
@@ -2850,7 +3137,65 @@ installcheck-am:
 maintainer-clean: maintainer-clean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf $(DEPDIR) ./$(DEPDIR)
+		-rm -f $(DEPDIR)/malloc.Po
+	-rm -f $(DEPDIR)/realloc.Po
+	-rm -f $(DEPDIR)/strdup.Po
+	-rm -f $(DEPDIR)/strerror.Po
+	-rm -f $(DEPDIR)/strstr.Po
+	-rm -f $(DEPDIR)/tfind.Po
+	-rm -f $(DEPDIR)/tsearch.Po
+	-rm -f $(DEPDIR)/twalk.Po
+	-rm -f ./$(DEPDIR)/asc2xml.Po
+	-rm -f ./$(DEPDIR)/cexport.Po
+	-rm -f ./$(DEPDIR)/class.Po
+	-rm -f ./$(DEPDIR)/connectsock.Po
+	-rm -f ./$(DEPDIR)/dict.Po
+	-rm -f ./$(DEPDIR)/dtd.Po
+	-rm -f ./$(DEPDIR)/fopencookie.Po
+	-rm -f ./$(DEPDIR)/genid.Po
+	-rm -f ./$(DEPDIR)/hash.Po
+	-rm -f ./$(DEPDIR)/headers.Po
+	-rm -f ./$(DEPDIR)/heap.Po
+	-rm -f ./$(DEPDIR)/html.Po
+	-rm -f ./$(DEPDIR)/hxaddid.Po
+	-rm -f ./$(DEPDIR)/hxcite.Po
+	-rm -f ./$(DEPDIR)/hxclean.Po
+	-rm -f ./$(DEPDIR)/hxcopy.Po
+	-rm -f ./$(DEPDIR)/hxcount.Po
+	-rm -f ./$(DEPDIR)/hxextract.Po
+	-rm -f ./$(DEPDIR)/hxincl.Po
+	-rm -f ./$(DEPDIR)/hxindex.Po
+	-rm -f ./$(DEPDIR)/hxmkbib.Po
+	-rm -f ./$(DEPDIR)/hxmultitoc.Po
+	-rm -f ./$(DEPDIR)/hxname2id.Po
+	-rm -f ./$(DEPDIR)/hxnormalize.Po
+	-rm -f ./$(DEPDIR)/hxnsxml.Po
+	-rm -f ./$(DEPDIR)/hxnum.Po
+	-rm -f ./$(DEPDIR)/hxpipe.Po
+	-rm -f ./$(DEPDIR)/hxprintlinks.Po
+	-rm -f ./$(DEPDIR)/hxprune.Po
+	-rm -f ./$(DEPDIR)/hxref.Po
+	-rm -f ./$(DEPDIR)/hxremove.Po
+	-rm -f ./$(DEPDIR)/hxselect.Po
+	-rm -f ./$(DEPDIR)/hxtabletrans.Po
+	-rm -f ./$(DEPDIR)/hxtoc.Po
+	-rm -f ./$(DEPDIR)/hxuncdata.Po
+	-rm -f ./$(DEPDIR)/hxunentmain.Po
+	-rm -f ./$(DEPDIR)/hxunpipe.Po
+	-rm -f ./$(DEPDIR)/hxunxmlns.Po
+	-rm -f ./$(DEPDIR)/hxwls.Po
+	-rm -f ./$(DEPDIR)/hxxmlns.Po
+	-rm -f ./$(DEPDIR)/langinfo.Po
+	-rm -f ./$(DEPDIR)/openurl.Po
+	-rm -f ./$(DEPDIR)/scan.Po
+	-rm -f ./$(DEPDIR)/selector.Po
+	-rm -f ./$(DEPDIR)/selmatch.Po
+	-rm -f ./$(DEPDIR)/textwrap.Po
+	-rm -f ./$(DEPDIR)/tree.Po
+	-rm -f ./$(DEPDIR)/types.Po
+	-rm -f ./$(DEPDIR)/unent.Po
+	-rm -f ./$(DEPDIR)/url.Po
+	-rm -f ./$(DEPDIR)/xml2asc.Po
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -2871,27 +3216,28 @@ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
 
 uninstall-man: uninstall-man1
 
-.MAKE: all check check-am install install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \
-	check-am clean clean-binPROGRAMS clean-cscope clean-generic \
-	clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \
-	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
-	dist-xz dist-zip distcheck distclean distclean-compile \
-	distclean-generic distclean-hdr distclean-tags distcleancheck \
-	distdir distuninstallcheck dvi dvi-am html html-am info \
-	info-am install install-am install-binPROGRAMS \
-	install-binSCRIPTS install-data install-data-am \
-	install-docDATA install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-man install-man1 install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic pdf pdf-am ps ps-am recheck tags tags-am \
-	uninstall uninstall-am uninstall-binPROGRAMS \
-	uninstall-binSCRIPTS uninstall-docDATA uninstall-man \
-	uninstall-man1
+.MAKE: all check check-am install install-am install-exec \
+	install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles am--refresh check \
+	check-TESTS check-am clean clean-binPROGRAMS clean-cscope \
+	clean-generic clean-noinstPROGRAMS cscope cscopelist-am ctags \
+	ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \
+	dist-shar dist-tarZ dist-xz dist-zip dist-zstd distcheck \
+	distclean distclean-compile distclean-generic distclean-hdr \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-binSCRIPTS install-data \
+	install-data-am install-docDATA install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-man1 \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-binPROGRAMS uninstall-binSCRIPTS uninstall-docDATA \
+	uninstall-man uninstall-man1
 
 .PRECIOUS: Makefile
 
@@ -2910,7 +3256,7 @@ dtd.c: dtd.hash
 	gperf -a -c -C -o -t -p -T -k '1,2,$$' -N lookup_element $< >$@
 
 unent.c: unent.hash
-	gperf -a -c -C -o -t -p -k '1,2,$$' -D -N lookup_entity $< >$@
+	gperf -a -c -C -o -t -p -k 1-6 -N lookup_entity $< >$@
 
 scan.o: html.h html.e scan.c
 
diff --git a/TODO b/TODO
index 85c08da..99527db 100644
--- a/TODO
+++ b/TODO
@@ -15,4 +15,9 @@ sorted by name and http-equiv, link sorted by rel, style, script)
 
 Add ruby, rb, rp, rt and rtc to dtd.hash.
 
-Add MathML elements to dtd.hash.
\ No newline at end of file
+Add MathML elements to dtd.hash.
+
+An option to add <![CDATA[...]]> to CDATA sections or to escape <, >
+and & in such sections (only when output is XML).
+
+Properly parse the srcset attribute.
diff --git a/aclocal.m4 b/aclocal.m4
index 545482d..ac01f07 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,8 +20,685 @@ You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# iconv.m4 serial 19 (gettext-0.18.2)
-dnl Copyright (C) 2000-2002, 2007-2014, 2016 Free Software Foundation, Inc.
+# host-cpu-c-abi.m4 serial 13
+dnl Copyright (C) 2002-2020 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible and Sam Steingold.
+
+dnl Sets the HOST_CPU variable to the canonical name of the CPU.
+dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its
+dnl C language ABI (application binary interface).
+dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in
+dnl config.h.
+dnl
+dnl This canonical name can be used to select a particular assembly language
+dnl source file that will interoperate with C code on the given host.
+dnl
+dnl For example:
+dnl * 'i386' and 'sparc' are different canonical names, because code for i386
+dnl   will not run on SPARC CPUs and vice versa. They have different
+dnl   instruction sets.
+dnl * 'sparc' and 'sparc64' are different canonical names, because code for
+dnl   'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code
+dnl   contains 32-bit instructions, whereas 'sparc64' code contains 64-bit
+dnl   instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit
+dnl   mode, but not both.
+dnl * 'mips' and 'mipsn32' are different canonical names, because they use
+dnl   different argument passing and return conventions for C functions, and
+dnl   although the instruction set of 'mips' is a large subset of the
+dnl   instruction set of 'mipsn32'.
+dnl * 'mipsn32' and 'mips64' are different canonical names, because they use
+dnl   different sizes for the C types like 'int' and 'void *', and although
+dnl   the instruction sets of 'mipsn32' and 'mips64' are the same.
+dnl * The same canonical name is used for different endiannesses. You can
+dnl   determine the endianness through preprocessor symbols:
+dnl   - 'arm': test __ARMEL__.
+dnl   - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL.
+dnl   - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN.
+dnl * The same name 'i386' is used for CPUs of type i386, i486, i586
+dnl   (Pentium), AMD K7, Pentium II, Pentium IV, etc., because
+dnl   - Instructions that do not exist on all of these CPUs (cmpxchg,
+dnl     MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your
+dnl     assembly language source files use such instructions, you will
+dnl     need to make the distinction.
+dnl   - Speed of execution of the common instruction set is reasonable across
+dnl     the entire family of CPUs. If you have assembly language source files
+dnl     that are optimized for particular CPU types (like GNU gmp has), you
+dnl     will need to make the distinction.
+dnl   See <https://en.wikipedia.org/wiki/X86_instruction_listings>.
+AC_DEFUN([gl_HOST_CPU_C_ABI],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([gl_C_ASM])
+  AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi],
+    [case "$host_cpu" in
+
+changequote(,)dnl
+       i[34567]86 )
+changequote([,])dnl
+         gl_cv_host_cpu_c_abi=i386
+         ;;
+
+       x86_64 )
+         # On x86_64 systems, the C compiler may be generating code in one of
+         # these ABIs:
+         # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
+         # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
+         #   with native Windows (mingw, MSVC).
+         # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
+         # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#if (defined __x86_64__ || defined __amd64__ \
+                     || defined _M_X64 || defined _M_AMD64)
+                 int ok;
+                #else
+                 error fail
+                #endif
+              ]])],
+           [AC_COMPILE_IFELSE(
+              [AC_LANG_SOURCE(
+                 [[#if defined __ILP32__ || defined _ILP32
+                    int ok;
+                   #else
+                    error fail
+                   #endif
+                 ]])],
+              [gl_cv_host_cpu_c_abi=x86_64-x32],
+              [gl_cv_host_cpu_c_abi=x86_64])],
+           [gl_cv_host_cpu_c_abi=i386])
+         ;;
+
+changequote(,)dnl
+       alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] )
+changequote([,])dnl
+         gl_cv_host_cpu_c_abi=alpha
+         ;;
+
+       arm* | aarch64 )
+         # Assume arm with EABI.
+         # On arm64 systems, the C compiler may be generating code in one of
+         # these ABIs:
+         # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
+         # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
+         # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#ifdef __aarch64__
+                 int ok;
+                #else
+                 error fail
+                #endif
+              ]])],
+           [AC_COMPILE_IFELSE(
+              [AC_LANG_SOURCE(
+                [[#if defined __ILP32__ || defined _ILP32
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+                ]])],
+              [gl_cv_host_cpu_c_abi=arm64-ilp32],
+              [gl_cv_host_cpu_c_abi=arm64])],
+           [# Don't distinguish little-endian and big-endian arm, since they
+            # don't require different machine code for simple operations and
+            # since the user can distinguish them through the preprocessor
+            # defines __ARMEL__ vs. __ARMEB__.
+            # But distinguish arm which passes floating-point arguments and
+            # return values in integer registers (r0, r1, ...) - this is
+            # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which
+            # passes them in float registers (s0, s1, ...) and double registers
+            # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer
+            # sets the preprocessor defines __ARM_PCS (for the first case) and
+            # __ARM_PCS_VFP (for the second case), but older GCC does not.
+            echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c
+            # Look for a reference to the register d0 in the .s file.
+            AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1
+            if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then
+              gl_cv_host_cpu_c_abi=armhf
+            else
+              gl_cv_host_cpu_c_abi=arm
+            fi
+            rm -f conftest*
+           ])
+         ;;
+
+       hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
+         # On hppa, the C compiler may be generating 32-bit code or 64-bit
+         # code. In the latter case, it defines _LP64 and __LP64__.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#ifdef __LP64__
+                 int ok;
+                #else
+                 error fail
+                #endif
+              ]])],
+           [gl_cv_host_cpu_c_abi=hppa64],
+           [gl_cv_host_cpu_c_abi=hppa])
+         ;;
+
+       ia64* )
+         # On ia64 on HP-UX, the C compiler may be generating 64-bit code or
+         # 32-bit code. In the latter case, it defines _ILP32.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#ifdef _ILP32
+                 int ok;
+                #else
+                 error fail
+                #endif
+              ]])],
+           [gl_cv_host_cpu_c_abi=ia64-ilp32],
+           [gl_cv_host_cpu_c_abi=ia64])
+         ;;
+
+       mips* )
+         # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
+         # at 32.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
+                 int ok;
+                #else
+                 error fail
+                #endif
+              ]])],
+           [gl_cv_host_cpu_c_abi=mips64],
+           [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but
+            # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32.
+            # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but
+            # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32.
+            AC_COMPILE_IFELSE(
+              [AC_LANG_SOURCE(
+                 [[#if (_MIPS_SIM == _ABIN32)
+                    int ok;
+                   #else
+                    error fail
+                   #endif
+                 ]])],
+              [gl_cv_host_cpu_c_abi=mipsn32],
+              [gl_cv_host_cpu_c_abi=mips])])
+         ;;
+
+       powerpc* )
+         # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
+         # No need to distinguish them here; the caller may distinguish
+         # them based on the OS.
+         # On powerpc64 systems, the C compiler may still be generating
+         # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
+         # be generating 64-bit code.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#if defined __powerpc64__ || defined _ARCH_PPC64
+                 int ok;
+                #else
+                 error fail
+                #endif
+              ]])],
+           [# On powerpc64, there are two ABIs on Linux: The AIX compatible
+            # one and the ELFv2 one. The latter defines _CALL_ELF=2.
+            AC_COMPILE_IFELSE(
+              [AC_LANG_SOURCE(
+                 [[#if defined _CALL_ELF && _CALL_ELF == 2
+                    int ok;
+                   #else
+                    error fail
+                   #endif
+                 ]])],
+              [gl_cv_host_cpu_c_abi=powerpc64-elfv2],
+              [gl_cv_host_cpu_c_abi=powerpc64])
+           ],
+           [gl_cv_host_cpu_c_abi=powerpc])
+         ;;
+
+       rs6000 )
+         gl_cv_host_cpu_c_abi=powerpc
+         ;;
+
+       riscv32 | riscv64 )
+         # There are 2 architectures (with variants): rv32* and rv64*.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#if __riscv_xlen == 64
+                  int ok;
+                #else
+                  error fail
+                #endif
+              ]])],
+           [cpu=riscv64],
+           [cpu=riscv32])
+         # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
+         # Size of 'long' and 'void *':
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#if defined __LP64__
+                  int ok;
+                #else
+                  error fail
+                #endif
+              ]])],
+           [main_abi=lp64],
+           [main_abi=ilp32])
+         # Float ABIs:
+         # __riscv_float_abi_double:
+         #   'float' and 'double' are passed in floating-point registers.
+         # __riscv_float_abi_single:
+         #   'float' are passed in floating-point registers.
+         # __riscv_float_abi_soft:
+         #   No values are passed in floating-point registers.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#if defined __riscv_float_abi_double
+                  int ok;
+                #else
+                  error fail
+                #endif
+              ]])],
+           [float_abi=d],
+           [AC_COMPILE_IFELSE(
+              [AC_LANG_SOURCE(
+                 [[#if defined __riscv_float_abi_single
+                     int ok;
+                   #else
+                     error fail
+                   #endif
+                 ]])],
+              [float_abi=f],
+              [float_abi=''])
+           ])
+         gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}"
+         ;;
+
+       s390* )
+         # On s390x, the C compiler may be generating 64-bit (= s390x) code
+         # or 31-bit (= s390) code.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#if defined __LP64__ || defined __s390x__
+                  int ok;
+                #else
+                  error fail
+                #endif
+              ]])],
+           [gl_cv_host_cpu_c_abi=s390x],
+           [gl_cv_host_cpu_c_abi=s390])
+         ;;
+
+       sparc | sparc64 )
+         # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
+         # C compiler still generates 32-bit code.
+         AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE(
+              [[#if defined __sparcv9 || defined __arch64__
+                 int ok;
+                #else
+                 error fail
+                #endif
+              ]])],
+           [gl_cv_host_cpu_c_abi=sparc64],
+           [gl_cv_host_cpu_c_abi=sparc])
+         ;;
+
+       *)
+         gl_cv_host_cpu_c_abi="$host_cpu"
+         ;;
+     esac
+    ])
+
+  dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same.
+  HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'`
+  HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi"
+  AC_SUBST([HOST_CPU])
+  AC_SUBST([HOST_CPU_C_ABI])
+
+  # This was
+  #   AC_DEFINE_UNQUOTED([__${HOST_CPU}__])
+  #   AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__])
+  # earlier, but KAI C++ 3.2d doesn't like this.
+  sed -e 's/-/_/g' >> confdefs.h <<EOF
+#ifndef __${HOST_CPU}__
+#define __${HOST_CPU}__ 1
+#endif
+#ifndef __${HOST_CPU_C_ABI}__
+#define __${HOST_CPU_C_ABI}__ 1
+#endif
+EOF
+  AH_TOP([/* CPU and C ABI indicator */
+#ifndef __i386__
+#undef __i386__
+#endif
+#ifndef __x86_64_x32__
+#undef __x86_64_x32__
+#endif
+#ifndef __x86_64__
+#undef __x86_64__
+#endif
+#ifndef __alpha__
+#undef __alpha__
+#endif
+#ifndef __arm__
+#undef __arm__
+#endif
+#ifndef __armhf__
+#undef __armhf__
+#endif
+#ifndef __arm64_ilp32__
+#undef __arm64_ilp32__
+#endif
+#ifndef __arm64__
+#undef __arm64__
+#endif
+#ifndef __hppa__
+#undef __hppa__
+#endif
+#ifndef __hppa64__
+#undef __hppa64__
+#endif
+#ifndef __ia64_ilp32__
+#undef __ia64_ilp32__
+#endif
+#ifndef __ia64__
+#undef __ia64__
+#endif
+#ifndef __m68k__
+#undef __m68k__
+#endif
+#ifndef __mips__
+#undef __mips__
+#endif
+#ifndef __mipsn32__
+#undef __mipsn32__
+#endif
+#ifndef __mips64__
+#undef __mips64__
+#endif
+#ifndef __powerpc__
+#undef __powerpc__
+#endif
+#ifndef __powerpc64__
+#undef __powerpc64__
+#endif
+#ifndef __powerpc64_elfv2__
+#undef __powerpc64_elfv2__
+#endif
+#ifndef __riscv32__
+#undef __riscv32__
+#endif
+#ifndef __riscv64__
+#undef __riscv64__
+#endif
+#ifndef __riscv32_ilp32__
+#undef __riscv32_ilp32__
+#endif
+#ifndef __riscv32_ilp32f__
+#undef __riscv32_ilp32f__
+#endif
+#ifndef __riscv32_ilp32d__
+#undef __riscv32_ilp32d__
+#endif
+#ifndef __riscv64_ilp32__
+#undef __riscv64_ilp32__
+#endif
+#ifndef __riscv64_ilp32f__
+#undef __riscv64_ilp32f__
+#endif
+#ifndef __riscv64_ilp32d__
+#undef __riscv64_ilp32d__
+#endif
+#ifndef __riscv64_lp64__
+#undef __riscv64_lp64__
+#endif
+#ifndef __riscv64_lp64f__
+#undef __riscv64_lp64f__
+#endif
+#ifndef __riscv64_lp64d__
+#undef __riscv64_lp64d__
+#endif
+#ifndef __s390__
+#undef __s390__
+#endif
+#ifndef __s390x__
+#undef __s390x__
+#endif
+#ifndef __sh__
+#undef __sh__
+#endif
+#ifndef __sparc__
+#undef __sparc__
+#endif
+#ifndef __sparc64__
+#undef __sparc64__
+#endif
+])
+
+])
+
+
+dnl Sets the HOST_CPU_C_ABI_32BIT variable to 'yes' if the C language ABI
+dnl (application binary interface) is a 32-bit one, to 'no' if it is a 64-bit
+dnl one, or to 'unknown' if unknown.
+dnl This is a simplified variant of gl_HOST_CPU_C_ABI.
+AC_DEFUN([gl_HOST_CPU_C_ABI_32BIT],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_CACHE_CHECK([32-bit host C ABI], [gl_cv_host_cpu_c_abi_32bit],
+    [if test -n "$gl_cv_host_cpu_c_abi"; then
+       case "$gl_cv_host_cpu_c_abi" in
+         i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc)
+           gl_cv_host_cpu_c_abi_32bit=yes ;;
+         x86_64 | alpha | arm64 | hppa64 | ia64 | mips64 | powerpc64 | powerpc64-elfv2 | riscv*-lp64* | s390x | sparc64 )
+           gl_cv_host_cpu_c_abi_32bit=no ;;
+         *)
+           gl_cv_host_cpu_c_abi_32bit=unknown ;;
+       esac
+     else
+       case "$host_cpu" in
+
+         # CPUs that only support a 32-bit ABI.
+         arc \
+         | bfin \
+         | cris* \
+         | csky \
+         | epiphany \
+         | ft32 \
+         | h8300 \
+         | m68k \
+         | microblaze | microblazeel \
+         | nds32 | nds32le | nds32be \
+         | nios2 | nios2eb | nios2el \
+         | or1k* \
+         | or32 \
+         | sh | sh[1234] | sh[1234]e[lb] \
+         | tic6x \
+         | xtensa* )
+           gl_cv_host_cpu_c_abi_32bit=yes
+           ;;
+
+         # CPUs that only support a 64-bit ABI.
+changequote(,)dnl
+         alpha | alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] \
+         | mmix )
+changequote([,])dnl
+           gl_cv_host_cpu_c_abi_32bit=no
+           ;;
+
+changequote(,)dnl
+         i[34567]86 )
+changequote([,])dnl
+           gl_cv_host_cpu_c_abi_32bit=yes
+           ;;
+
+         x86_64 )
+           # On x86_64 systems, the C compiler may be generating code in one of
+           # these ABIs:
+           # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
+           # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
+           #   with native Windows (mingw, MSVC).
+           # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
+           # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#if (defined __x86_64__ || defined __amd64__ \
+                       || defined _M_X64 || defined _M_AMD64) \
+                      && !(defined __ILP32__ || defined _ILP32)
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=no],
+             [gl_cv_host_cpu_c_abi_32bit=yes])
+           ;;
+
+         arm* | aarch64 )
+           # Assume arm with EABI.
+           # On arm64 systems, the C compiler may be generating code in one of
+           # these ABIs:
+           # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
+           # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
+           # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#if defined __aarch64__ && !(defined __ILP32__ || defined _ILP32)
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=no],
+             [gl_cv_host_cpu_c_abi_32bit=yes])
+           ;;
+
+         hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
+           # On hppa, the C compiler may be generating 32-bit code or 64-bit
+           # code. In the latter case, it defines _LP64 and __LP64__.
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#ifdef __LP64__
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=no],
+             [gl_cv_host_cpu_c_abi_32bit=yes])
+           ;;
+
+         ia64* )
+           # On ia64 on HP-UX, the C compiler may be generating 64-bit code or
+           # 32-bit code. In the latter case, it defines _ILP32.
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#ifdef _ILP32
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=yes],
+             [gl_cv_host_cpu_c_abi_32bit=no])
+           ;;
+
+         mips* )
+           # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
+           # at 32.
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=no],
+             [gl_cv_host_cpu_c_abi_32bit=yes])
+           ;;
+
+         powerpc* )
+           # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
+           # No need to distinguish them here; the caller may distinguish
+           # them based on the OS.
+           # On powerpc64 systems, the C compiler may still be generating
+           # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
+           # be generating 64-bit code.
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#if defined __powerpc64__ || defined _ARCH_PPC64
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=no],
+             [gl_cv_host_cpu_c_abi_32bit=yes])
+           ;;
+
+         rs6000 )
+           gl_cv_host_cpu_c_abi_32bit=yes
+           ;;
+
+         riscv32 | riscv64 )
+           # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
+           # Size of 'long' and 'void *':
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#if defined __LP64__
+                    int ok;
+                  #else
+                    error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=no],
+             [gl_cv_host_cpu_c_abi_32bit=yes])
+           ;;
+
+         s390* )
+           # On s390x, the C compiler may be generating 64-bit (= s390x) code
+           # or 31-bit (= s390) code.
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#if defined __LP64__ || defined __s390x__
+                    int ok;
+                  #else
+                    error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=no],
+             [gl_cv_host_cpu_c_abi_32bit=yes])
+           ;;
+
+         sparc | sparc64 )
+           # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
+           # C compiler still generates 32-bit code.
+           AC_COMPILE_IFELSE(
+             [AC_LANG_SOURCE(
+                [[#if defined __sparcv9 || defined __arch64__
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+                ]])],
+             [gl_cv_host_cpu_c_abi_32bit=no],
+             [gl_cv_host_cpu_c_abi_32bit=yes])
+           ;;
+
+         *)
+           gl_cv_host_cpu_c_abi_32bit=unknown
+           ;;
+       esac
+     fi
+    ])
+
+  HOST_CPU_C_ABI_32BIT="$gl_cv_host_cpu_c_abi_32bit"
+])
+
+# iconv.m4 serial 21
+dnl Copyright (C) 2000-2002, 2007-2014, 2016-2020 Free Software Foundation,
+dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -189,15 +866,27 @@ AC_DEFUN([AM_ICONV_LINK],
 #endif
   /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
      provided.  */
-  if (/* Try standardized names.  */
-      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
-      /* Try IRIX, OSF/1 names.  */
-      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
-      /* Try AIX names.  */
-      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
-      /* Try HP-UX names.  */
-      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
-    result |= 16;
+  {
+    /* Try standardized names.  */
+    iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP");
+    /* Try IRIX, OSF/1 names.  */
+    iconv_t cd2 = iconv_open ("UTF-8", "eucJP");
+    /* Try AIX names.  */
+    iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP");
+    /* Try HP-UX names.  */
+    iconv_t cd4 = iconv_open ("utf8", "eucJP");
+    if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1)
+        && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1))
+      result |= 16;
+    if (cd1 != (iconv_t)(-1))
+      iconv_close (cd1);
+    if (cd2 != (iconv_t)(-1))
+      iconv_close (cd2);
+    if (cd3 != (iconv_t)(-1))
+      iconv_close (cd3);
+    if (cd4 != (iconv_t)(-1))
+      iconv_close (cd4);
+  }
   return result;
 ]])],
           [am_cv_func_iconv_works=yes], ,
@@ -280,20 +969,24 @@ size_t iconv();
     am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
     AC_MSG_RESULT([
          $am_cv_proto_iconv])
-    AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
-      [Define as const if the declaration of iconv() needs const.])
-    dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
-    m4_ifdef([gl_ICONV_H_DEFAULTS],
-      [AC_REQUIRE([gl_ICONV_H_DEFAULTS])
-       if test -n "$am_cv_proto_iconv_arg1"; then
-         ICONV_CONST="const"
-       fi
-      ])
+  else
+    dnl When compiling GNU libiconv on a system that does not have iconv yet,
+    dnl pick the POSIX compliant declaration without 'const'.
+    am_cv_proto_iconv_arg1=""
   fi
+  AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
+    [Define as const if the declaration of iconv() needs const.])
+  dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
+  m4_ifdef([gl_ICONV_H_DEFAULTS],
+    [AC_REQUIRE([gl_ICONV_H_DEFAULTS])
+     if test -n "$am_cv_proto_iconv_arg1"; then
+       ICONV_CONST="const"
+     fi
+    ])
 ])
 
-# lib-ld.m4 serial 6
-dnl Copyright (C) 1996-2003, 2009-2016 Free Software Foundation, Inc.
+# lib-ld.m4 serial 9
+dnl Copyright (C) 1996-2003, 2009-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -341,86 +1034,135 @@ if test "${PATH_SEPARATOR+set}" != set; then
        }
 fi
 
-ac_prog=ld
-if test "$GCC" = yes; then
-  # Check if gcc -print-prog-name=ld gives a path.
+if test -n "$LD"; then
+  AC_MSG_CHECKING([for ld])
+elif test "$GCC" = yes; then
   AC_MSG_CHECKING([for ld used by $CC])
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
-    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
-  *)
-    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
-  esac
-  case $ac_prog in
-    # Accept absolute paths.
-    [[\\/]]* | ?:[[\\/]]*)
-      re_direlt='/[[^/]][[^/]]*/\.\./'
-      # Canonicalize the pathname of ld
-      ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'`
-      while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do
-        ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
-      done
-      test -z "$LD" && LD="$ac_prog"
-      ;;
-  "")
-    # If it fails, then pretend we aren't using GCC.
-    ac_prog=ld
-    ;;
-  *)
-    # If it is relative, then search for the first ld in PATH.
-    with_gnu_ld=unknown
-    ;;
-  esac
 elif test "$with_gnu_ld" = yes; then
   AC_MSG_CHECKING([for GNU ld])
 else
   AC_MSG_CHECKING([for non-GNU ld])
 fi
-AC_CACHE_VAL([acl_cv_path_LD],
-[if test -z "$LD"; then
-  acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-  for ac_dir in $PATH; do
-    IFS="$acl_save_ifs"
-    test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      acl_cv_path_LD="$ac_dir/$ac_prog"
-      # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some variants of GNU ld only accept -v.
-      # Break only if it was the GNU/non-GNU ld that we prefer.
-      case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in
-      *GNU* | *'with BFD'*)
-        test "$with_gnu_ld" != no && break
-        ;;
-      *)
-        test "$with_gnu_ld" != yes && break
-        ;;
+if test -n "$LD"; then
+  # Let the user override the test with a path.
+  :
+else
+  AC_CACHE_VAL([acl_cv_path_LD],
+  [
+    acl_cv_path_LD= # Final result of this test
+    ac_prog=ld # Program to search in $PATH
+    if test "$GCC" = yes; then
+      # Check if gcc -print-prog-name=ld gives a path.
+      case $host in
+        *-*-mingw*)
+          # gcc leaves a trailing carriage return which upsets mingw
+          acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+        *)
+          acl_output=`($CC -print-prog-name=ld) 2>&5` ;;
+      esac
+      case $acl_output in
+        # Accept absolute paths.
+        [[\\/]]* | ?:[[\\/]]*)
+          re_direlt='/[[^/]][[^/]]*/\.\./'
+          # Canonicalize the pathname of ld
+          acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'`
+          while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do
+            acl_output=`echo $acl_output | sed "s%$re_direlt%/%"`
+          done
+          # Got the pathname. No search in PATH is needed.
+          acl_cv_path_LD="$acl_output"
+          ac_prog=
+          ;;
+        "")
+          # If it fails, then pretend we aren't using GCC.
+          ;;
+        *)
+          # If it is relative, then search for the first ld in PATH.
+          with_gnu_ld=unknown
+          ;;
       esac
     fi
-  done
-  IFS="$acl_save_ifs"
-else
-  acl_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$acl_cv_path_LD"
+    if test -n "$ac_prog"; then
+      # Search for $ac_prog in $PATH.
+      acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+      for ac_dir in $PATH; do
+        IFS="$acl_save_ifs"
+        test -z "$ac_dir" && ac_dir=.
+        if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+          acl_cv_path_LD="$ac_dir/$ac_prog"
+          # Check to see if the program is GNU ld.  I'd rather use --version,
+          # but apparently some variants of GNU ld only accept -v.
+          # Break only if it was the GNU/non-GNU ld that we prefer.
+          case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in
+            *GNU* | *'with BFD'*)
+              test "$with_gnu_ld" != no && break
+              ;;
+            *)
+              test "$with_gnu_ld" != yes && break
+              ;;
+          esac
+        fi
+      done
+      IFS="$acl_save_ifs"
+    fi
+    case $host in
+      *-*-aix*)
+        AC_COMPILE_IFELSE(
+          [AC_LANG_SOURCE(
+             [[#if defined __powerpc64__ || defined _ARCH_PPC64
+                int ok;
+               #else
+                error fail
+               #endif
+             ]])],
+          [# The compiler produces 64-bit code. Add option '-b64' so that the
+           # linker groks 64-bit object files.
+           case "$acl_cv_path_LD " in
+             *" -b64 "*) ;;
+             *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;;
+           esac
+          ], [])
+        ;;
+      sparc64-*-netbsd*)
+        AC_COMPILE_IFELSE(
+          [AC_LANG_SOURCE(
+             [[#if defined __sparcv9 || defined __arch64__
+                int ok;
+               #else
+                error fail
+               #endif
+             ]])],
+          [],
+          [# The compiler produces 32-bit code. Add option '-m elf32_sparc'
+           # so that the linker groks 32-bit object files.
+           case "$acl_cv_path_LD " in
+             *" -m elf32_sparc "*) ;;
+             *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;;
+           esac
+          ])
+        ;;
+    esac
+  ])
+  LD="$acl_cv_path_LD"
+fi
 if test -n "$LD"; then
   AC_MSG_RESULT([$LD])
 else
   AC_MSG_RESULT([no])
+  AC_MSG_ERROR([no acceptable ld found in \$PATH])
 fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
 AC_LIB_PROG_LD_GNU
 ])
 
-# lib-link.m4 serial 26 (gettext-0.18.2)
-dnl Copyright (C) 2001-2016 Free Software Foundation, Inc.
+# lib-link.m4 serial 31
+dnl Copyright (C) 2001-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 dnl From Bruno Haible.
 
-AC_PREREQ([2.54])
+AC_PREREQ([2.61])
 
 dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
 dnl the libraries corresponding to explicit and implicit dependencies.
@@ -538,8 +1280,8 @@ dnl   acl_hardcode_direct,
 dnl   acl_hardcode_minus_L.
 AC_DEFUN([AC_LIB_RPATH],
 [
-  dnl Tell automake >= 1.10 to complain if config.rpath is missing.
-  m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+  dnl Complain if config.rpath is missing.
+  AC_REQUIRE_AUX_FILE([config.rpath])
   AC_REQUIRE([AC_PROG_CC])                dnl we use $CC, $GCC, $LDFLAGS
   AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD, $with_gnu_ld
   AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host
@@ -601,17 +1343,17 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
   pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-],
                                      [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])])
   pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
-  dnl Autoconf >= 2.61 supports dots in --with options.
-  pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)])
   dnl By default, look in $includedir and $libdir.
   use_additional=yes
   AC_LIB_WITH_FINAL_PREFIX([
     eval additional_includedir=\"$includedir\"
     eval additional_libdir=\"$libdir\"
+    eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\"
+    eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\"
   ])
-  AC_ARG_WITH(P_A_C_K[-prefix],
-[[  --with-]]P_A_C_K[[-prefix[=DIR]  search for ]PACKLIBS[ in DIR/include and DIR/lib
-  --without-]]P_A_C_K[[-prefix     don't search for ]PACKLIBS[ in includedir and libdir]],
+  AC_ARG_WITH(PACK[-prefix],
+[[  --with-]]PACK[[-prefix[=DIR]  search for ]PACKLIBS[ in DIR/include and DIR/lib
+  --without-]]PACK[[-prefix     don't search for ]PACKLIBS[ in includedir and libdir]],
 [
     if test "X$withval" = "Xno"; then
       use_additional=no
@@ -620,17 +1362,23 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
         AC_LIB_WITH_FINAL_PREFIX([
           eval additional_includedir=\"$includedir\"
           eval additional_libdir=\"$libdir\"
+          eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\"
+          eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\"
         ])
       else
         additional_includedir="$withval/include"
         additional_libdir="$withval/$acl_libdirstem"
-        if test "$acl_libdirstem2" != "$acl_libdirstem" \
-           && ! test -d "$withval/$acl_libdirstem"; then
-          additional_libdir="$withval/$acl_libdirstem2"
-        fi
+        additional_libdir2="$withval/$acl_libdirstem2"
+        additional_libdir3="$withval/$acl_libdirstem3"
       fi
     fi
 ])
+  if test "X$additional_libdir2" = "X$additional_libdir"; then
+    additional_libdir2=
+  fi
+  if test "X$additional_libdir3" = "X$additional_libdir"; then
+    additional_libdir3=
+  fi
   dnl Search the library and its dependencies in $additional_libdir and
   dnl $LDFLAGS. Using breadth-first-seach.
   LIB[]NAME=
@@ -686,48 +1434,54 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
             shrext=
           fi
           if test $use_additional = yes; then
-            dir="$additional_libdir"
-            dnl The same code as in the loop below:
-            dnl First look for a shared library.
-            if test -n "$acl_shlibext"; then
-              if test -f "$dir/$libname$shrext"; then
-                found_dir="$dir"
-                found_so="$dir/$libname$shrext"
-              else
-                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
-                  ver=`(cd "$dir" && \
-                        for f in "$libname$shrext".*; do echo "$f"; done \
-                        | sed -e "s,^$libname$shrext\\\\.,," \
-                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
-                        | sed 1q ) 2>/dev/null`
-                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
-                    found_dir="$dir"
-                    found_so="$dir/$libname$shrext.$ver"
+            for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do
+              if test "X$found_dir" = "X"; then
+                eval dir=\$$additional_libdir_variable
+                if test -n "$dir"; then
+                  dnl The same code as in the loop below:
+                  dnl First look for a shared library.
+                  if test -n "$acl_shlibext"; then
+                    if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then
+                      found_dir="$dir"
+                      found_so="$dir/$libname$shrext"
+                    else
+                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                        ver=`(cd "$dir" && \
+                              for f in "$libname$shrext".*; do echo "$f"; done \
+                              | sed -e "s,^$libname$shrext\\\\.,," \
+                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                              | sed 1q ) 2>/dev/null`
+                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then
+                          found_dir="$dir"
+                          found_so="$dir/$libname$shrext.$ver"
+                        fi
+                      else
+                        eval library_names=\"$acl_library_names_spec\"
+                        for f in $library_names; do
+                          if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then
+                            found_dir="$dir"
+                            found_so="$dir/$f"
+                            break
+                          fi
+                        done
+                      fi
+                    fi
                   fi
-                else
-                  eval library_names=\"$acl_library_names_spec\"
-                  for f in $library_names; do
-                    if test -f "$dir/$f"; then
+                  dnl Then look for a static library.
+                  if test "X$found_dir" = "X"; then
+                    if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then
                       found_dir="$dir"
-                      found_so="$dir/$f"
-                      break
+                      found_a="$dir/$libname.$acl_libext"
                     fi
-                  done
+                  fi
+                  if test "X$found_dir" != "X"; then
+                    if test -f "$dir/$libname.la"; then
+                      found_la="$dir/$libname.la"
+                    fi
+                  fi
                 fi
               fi
-            fi
-            dnl Then look for a static library.
-            if test "X$found_dir" = "X"; then
-              if test -f "$dir/$libname.$acl_libext"; then
-                found_dir="$dir"
-                found_a="$dir/$libname.$acl_libext"
-              fi
-            fi
-            if test "X$found_dir" != "X"; then
-              if test -f "$dir/$libname.la"; then
-                found_la="$dir/$libname.la"
-              fi
-            fi
+            done
           fi
           if test "X$found_dir" = "X"; then
             for x in $LDFLAGS $LTLIB[]NAME; do
@@ -737,7 +1491,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
                   dir=`echo "X$x" | sed -e 's/^X-L//'`
                   dnl First look for a shared library.
                   if test -n "$acl_shlibext"; then
-                    if test -f "$dir/$libname$shrext"; then
+                    if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then
                       found_dir="$dir"
                       found_so="$dir/$libname$shrext"
                     else
@@ -747,14 +1501,14 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
                               | sed -e "s,^$libname$shrext\\\\.,," \
                               | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
                               | sed 1q ) 2>/dev/null`
-                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then
                           found_dir="$dir"
                           found_so="$dir/$libname$shrext.$ver"
                         fi
                       else
                         eval library_names=\"$acl_library_names_spec\"
                         for f in $library_names; do
-                          if test -f "$dir/$f"; then
+                          if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then
                             found_dir="$dir"
                             found_so="$dir/$f"
                             break
@@ -765,7 +1519,7 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
                   fi
                   dnl Then look for a static library.
                   if test "X$found_dir" = "X"; then
-                    if test -f "$dir/$libname.$acl_libext"; then
+                    if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then
                       found_dir="$dir"
                       found_a="$dir/$libname.$acl_libext"
                     fi
@@ -791,7 +1545,8 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
               dnl standard /usr/lib.
               if test "$enable_rpath" = no \
                  || test "X$found_dir" = "X/usr/$acl_libdirstem" \
-                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem2" \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then
                 dnl No hardcoding is needed.
                 LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
               else
@@ -891,6 +1646,13 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
                 fi
                 additional_includedir="$basedir/include"
                 ;;
+              */$acl_libdirstem3 | */$acl_libdirstem3/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'`
+                if test "$name" = '$1'; then
+                  LIB[]NAME[]_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
             esac
             if test "X$additional_includedir" != "X"; then
               dnl Potentially add $additional_includedir to $INCNAME.
@@ -941,19 +1703,21 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
               for dep in $dependency_libs; do
                 case "$dep" in
                   -L*)
-                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
-                    dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+                    dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+                    dnl Potentially add $dependency_libdir to $LIBNAME and $LTLIBNAME.
                     dnl But don't add it
                     dnl   1. if it's the standard /usr/lib,
                     dnl   2. if it's /usr/local/lib and we are using GCC on Linux,
                     dnl   3. if it's already present in $LDFLAGS or the already
                     dnl      constructed $LIBNAME,
                     dnl   4. if it doesn't exist as a directory.
-                    if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
-                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+                    if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \
+                       && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \
+                       && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then
                       haveit=
-                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
-                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+                      if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \
+                         || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \
+                         || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then
                         if test -n "$GCC"; then
                           case $host_os in
                             linux* | gnu* | k*bsd*-gnu) haveit=yes;;
@@ -964,29 +1728,29 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
                         haveit=
                         for x in $LDFLAGS $LIB[]NAME; do
                           AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                          if test "X$x" = "X-L$additional_libdir"; then
+                          if test "X$x" = "X-L$dependency_libdir"; then
                             haveit=yes
                             break
                           fi
                         done
                         if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                            dnl Really add $additional_libdir to $LIBNAME.
-                            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
+                          if test -d "$dependency_libdir"; then
+                            dnl Really add $dependency_libdir to $LIBNAME.
+                            LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$dependency_libdir"
                           fi
                         fi
                         haveit=
                         for x in $LDFLAGS $LTLIB[]NAME; do
                           AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
-                          if test "X$x" = "X-L$additional_libdir"; then
+                          if test "X$x" = "X-L$dependency_libdir"; then
                             haveit=yes
                             break
                           fi
                         done
                         if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                            dnl Really add $additional_libdir to $LTLIBNAME.
-                            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
+                          if test -d "$dependency_libdir"; then
+                            dnl Really add $dependency_libdir to $LTLIBNAME.
+                            LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$dependency_libdir"
                           fi
                         fi
                       fi
@@ -1084,7 +1848,6 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
       LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
     done
   fi
-  popdef([P_A_C_K])
   popdef([PACKLIBS])
   popdef([PACKUP])
   popdef([PACK])
@@ -1135,7 +1898,8 @@ AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
           dir="$next"
           dnl No need to hardcode the standard /usr/lib.
           if test "X$dir" != "X/usr/$acl_libdirstem" \
-             && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+             && test "X$dir" != "X/usr/$acl_libdirstem2" \
+             && test "X$dir" != "X/usr/$acl_libdirstem3"; then
             rpathdirs="$rpathdirs $dir"
           fi
           next=
@@ -1145,7 +1909,8 @@ AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
             -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
                  dnl No need to hardcode the standard /usr/lib.
                  if test "X$dir" != "X/usr/$acl_libdirstem" \
-                    && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+                    && test "X$dir" != "X/usr/$acl_libdirstem2" \
+                    && test "X$dir" != "X/usr/$acl_libdirstem3"; then
                    rpathdirs="$rpathdirs $dir"
                  fi
                  next= ;;
@@ -1190,21 +1955,14 @@ AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
   AC_SUBST([$1])
 ])
 
-# lib-prefix.m4 serial 7 (gettext-0.18)
-dnl Copyright (C) 2001-2005, 2008-2016 Free Software Foundation, Inc.
+# lib-prefix.m4 serial 17
+dnl Copyright (C) 2001-2005, 2008-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
 dnl From Bruno Haible.
 
-dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
-dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
-dnl require excessive bracketing.
-ifdef([AC_HELP_STRING],
-[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
-[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
-
 dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
 dnl to access previously installed libraries. The basic assumption is that
 dnl a user will want packages to use other packages he previously installed
@@ -1224,9 +1982,9 @@ AC_DEFUN([AC_LIB_PREFIX],
     eval additional_includedir=\"$includedir\"
     eval additional_libdir=\"$libdir\"
   ])
-  AC_LIB_ARG_WITH([lib-prefix],
-[  --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
-  --without-lib-prefix    don't search for libraries in includedir and libdir],
+  AC_ARG_WITH([lib-prefix],
+[[  --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+  --without-lib-prefix    don't search for libraries in includedir and libdir]],
 [
     if test "X$withval" = "Xno"; then
       use_additional=no
@@ -1346,76 +2104,179 @@ AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
 ])
 
 dnl AC_LIB_PREPARE_MULTILIB creates
-dnl - a variable acl_libdirstem, containing the basename of the libdir, either
-dnl   "lib" or "lib64" or "lib/64",
-dnl - a variable acl_libdirstem2, as a secondary possible value for
-dnl   acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
-dnl   "lib/amd64".
+dnl - a function acl_is_expected_elfclass, that tests whether standard input
+dn;   has a 32-bit or 64-bit ELF header, depending on the host CPU ABI,
+dnl - 3 variables acl_libdirstem, acl_libdirstem2, acl_libdirstem3, containing
+dnl   the basename of the libdir to try in turn, either "lib" or "lib64" or
+dnl   "lib/64" or "lib32" or "lib/sparcv9" or "lib/amd64" or similar.
 AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
 [
-  dnl There is no formal standard regarding lib and lib64.
-  dnl On glibc systems, the current practice is that on a system supporting
+  dnl There is no formal standard regarding lib, lib32, and lib64.
+  dnl On most glibc systems, the current practice is that on a system supporting
   dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
-  dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
-  dnl the compiler's default mode by looking at the compiler's library search
-  dnl path. If at least one of its elements ends in /lib64 or points to a
-  dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
-  dnl Otherwise we use the default, namely "lib".
+  dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. However, on
+  dnl Arch Linux based distributions, it's the opposite: 32-bit libraries go
+  dnl under $prefix/lib32 and 64-bit libraries go under $prefix/lib.
+  dnl We determine the compiler's default mode by looking at the compiler's
+  dnl library search path. If at least one of its elements ends in /lib64 or
+  dnl points to a directory whose absolute pathname ends in /lib64, we use that
+  dnl for 64-bit ABIs. Similarly for 32-bit ABIs. Otherwise we use the default,
+  dnl namely "lib".
   dnl On Solaris systems, the current practice is that on a system supporting
   dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
   dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
   dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
   AC_REQUIRE([AC_CANONICAL_HOST])
-  acl_libdirstem=lib
-  acl_libdirstem2=
-  case "$host_os" in
-    solaris*)
-      dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
-      dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
-      dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
-      dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
-      dnl symlink is missing, so we set acl_libdirstem2 too.
-      AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
-        [AC_EGREP_CPP([sixtyfour bits], [
-#ifdef _LP64
-sixtyfour bits
-#endif
-           ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
-        ])
-      if test $gl_cv_solaris_64bit = yes; then
-        acl_libdirstem=lib/64
-        case "$host_cpu" in
-          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
-          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
-        esac
-      fi
-      ;;
-    *)
-      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
-      if test -n "$searchpath"; then
-        acl_save_IFS="${IFS= 	}"; IFS=":"
-        for searchdir in $searchpath; do
-          if test -d "$searchdir"; then
-            case "$searchdir" in
-              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
-              */../ | */.. )
-                # Better ignore directories of this form. They are misleading.
-                ;;
-              *) searchdir=`cd "$searchdir" && pwd`
-                 case "$searchdir" in
-                   */lib64 ) acl_libdirstem=lib64 ;;
-                 esac ;;
-            esac
-          fi
-        done
-        IFS="$acl_save_IFS"
-      fi
-      ;;
-  esac
-  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+  AC_REQUIRE([gl_HOST_CPU_C_ABI_32BIT])
+
+  AC_CACHE_CHECK([for ELF binary format], [gl_cv_elf],
+    [AC_EGREP_CPP([Extensible Linking Format],
+       [#ifdef __ELF__
+        Extensible Linking Format
+        #endif
+       ],
+       [gl_cv_elf=yes],
+       [gl_cv_elf=no])
+     ])
+  if test $gl_cv_elf; then
+    # Extract the ELF class of a file (5th byte) in decimal.
+    # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header
+    if od -A x < /dev/null >/dev/null 2>/dev/null; then
+      # Use POSIX od.
+      func_elfclass ()
+      {
+        od -A n -t d1 -j 4 -N 1
+      }
+    else
+      # Use BSD hexdump.
+      func_elfclass ()
+      {
+        dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 "%3d "'
+        echo
+      }
+    fi
+changequote(,)dnl
+    case $HOST_CPU_C_ABI_32BIT in
+      yes)
+        # 32-bit ABI.
+        acl_is_expected_elfclass ()
+        {
+          test "`func_elfclass | sed -e 's/[ 	]//g'`" = 1
+        }
+        ;;
+      no)
+        # 64-bit ABI.
+        acl_is_expected_elfclass ()
+        {
+          test "`func_elfclass | sed -e 's/[ 	]//g'`" = 2
+        }
+        ;;
+      *)
+        # Unknown.
+        acl_is_expected_elfclass ()
+        {
+          :
+        }
+        ;;
+    esac
+changequote([,])dnl
+  else
+    acl_is_expected_elfclass ()
+    {
+      :
+    }
+  fi
+
+  dnl Allow the user to override the result by setting acl_cv_libdirstems.
+  AC_CACHE_CHECK([for the common suffixes of directories in the library search path],
+    [acl_cv_libdirstems],
+    [dnl Try 'lib' first, because that's the default for libdir in GNU, see
+     dnl <https://www.gnu.org/prep/standards/html_node/Directory-Variables.html>.
+     acl_libdirstem=lib
+     acl_libdirstem2=
+     acl_libdirstem3=
+     case "$host_os" in
+       solaris*)
+         dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
+         dnl <https://docs.oracle.com/cd/E19253-01/816-5138/dev-env/index.html>.
+         dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
+         dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
+         dnl symlink is missing, so we set acl_libdirstem2 too.
+         if test $HOST_CPU_C_ABI_32BIT = no; then
+           acl_libdirstem2=lib/64
+           case "$host_cpu" in
+             sparc*)        acl_libdirstem3=lib/sparcv9 ;;
+             i*86 | x86_64) acl_libdirstem3=lib/amd64 ;;
+           esac
+         fi
+         ;;
+       *)
+         dnl If $CC generates code for a 32-bit ABI, the libraries are
+         dnl surely under $prefix/lib or $prefix/lib32, not $prefix/lib64.
+         dnl Similarly, if $CC generates code for a 64-bit ABI, the libraries
+         dnl are surely under $prefix/lib or $prefix/lib64, not $prefix/lib32.
+         dnl Find the compiler's search path. However, non-system compilers
+         dnl sometimes have odd library search paths. But we can't simply invoke
+         dnl '/usr/bin/gcc -print-search-dirs' because that would not take into
+         dnl account the -m32/-m31 or -m64 options from the $CC or $CFLAGS.
+         searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \
+                     | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+         if test $HOST_CPU_C_ABI_32BIT != no; then
+           # 32-bit or unknown ABI.
+           if test -d /usr/lib32; then
+             acl_libdirstem2=lib32
+           fi
+         fi
+         if test $HOST_CPU_C_ABI_32BIT != yes; then
+           # 64-bit or unknown ABI.
+           if test -d /usr/lib64; then
+             acl_libdirstem3=lib64
+           fi
+         fi
+         if test -n "$searchpath"; then
+           acl_save_IFS="${IFS= 	}"; IFS=":"
+           for searchdir in $searchpath; do
+             if test -d "$searchdir"; then
+               case "$searchdir" in
+                 */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;;
+                 */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;;
+                 */../ | */.. )
+                   # Better ignore directories of this form. They are misleading.
+                   ;;
+                 *) searchdir=`cd "$searchdir" && pwd`
+                    case "$searchdir" in
+                      */lib32 ) acl_libdirstem2=lib32 ;;
+                      */lib64 ) acl_libdirstem3=lib64 ;;
+                    esac ;;
+               esac
+             fi
+           done
+           IFS="$acl_save_IFS"
+           if test $HOST_CPU_C_ABI_32BIT = yes; then
+             # 32-bit ABI.
+             acl_libdirstem3=
+           fi
+           if test $HOST_CPU_C_ABI_32BIT = no; then
+             # 64-bit ABI.
+             acl_libdirstem2=
+           fi
+         fi
+         ;;
+     esac
+     test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+     test -n "$acl_libdirstem3" || acl_libdirstem3="$acl_libdirstem"
+     acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3"
+    ])
+  dnl Decompose acl_cv_libdirstems into acl_libdirstem, acl_libdirstem2, and
+  dnl acl_libdirstem3.
+changequote(,)dnl
+  acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'`
+  acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,//' -e 's/,.*//'`
+  acl_libdirstem3=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'`
+changequote([,])dnl
 ])
 
-# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1427,10 +2288,10 @@ sixtyfour bits
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.15'
+[am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.15], [],
+m4_if([$1], [1.16.3], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -1446,14 +2307,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.15])dnl
+[AM_AUTOMAKE_VERSION([1.16.3])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1505,7 +2366,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1536,7 +2397,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1727,13 +2588,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
 AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@@ -1741,49 +2601,43 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  AS_CASE([$CONFIG_FILES],
+          [*\'*], [eval set x "$CONFIG_FILES"],
+          [*], [set x $CONFIG_FILES])
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`AS_DIRNAME("$mf")`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`AS_DIRNAME(["$file"])`
-      AS_MKDIR_P([$dirpart/$fdir])
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`AS_DIRNAME(["$am_mf"])`
+    am_filepart=`AS_BASENAME(["$am_mf"])`
+    AM_RUN_LOG([cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles]) || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE="gmake" (or whatever is
+    necessary).  You can also try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).])
+  fi
+  AS_UNSET([am_dirpart])
+  AS_UNSET([am_filepart])
+  AS_UNSET([am_mf])
+  AS_UNSET([am_rc])
+  rm -f conftest-deps.mk
 }
 ])# _AM_OUTPUT_DEPENDENCY_COMMANDS
 
@@ -1792,18 +2646,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
 # -----------------------------
 # This macro should only be invoked once -- use via AC_REQUIRE.
 #
-# This code is only required when automatic dependency tracking
-# is enabled.  FIXME.  This creates each '.P' file that we will
-# need in order to bootstrap the dependency handling code.
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
 AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 [AC_CONFIG_COMMANDS([depfiles],
      [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
-     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
+     [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1890,8 +2743,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
 AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
 # We need awk for the "check" target (and possibly the TAP driver).  The
 # system "awk" is bad on some platforms.
@@ -1958,7 +2811,7 @@ END
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -2000,7 +2853,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2021,7 +2874,7 @@ if test x"${install_sh+set}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2040,7 +2893,7 @@ fi
 rmdir .tst 2>/dev/null
 AC_SUBST([am__leading_dot])])
 
-# Copyright (C) 1998-2014 Free Software Foundation, Inc.
+# Copyright (C) 1998-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2060,7 +2913,7 @@ fi])
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2068,49 +2921,42 @@ fi])
 
 # AM_MAKE_INCLUDE()
 # -----------------
-# Check to see how make treats includes.
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
 AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
 am__doit:
-	@echo this is the am__doit target
+	@echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
-     ;;
-   esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+  AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+      ['0:this is the am__doit target'],
+      [AS_CASE([$s],
+          [BSD], [am__include='.include' am__quote='"'],
+          [am__include='include' am__quote=''])])
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2131,12 +2977,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([missing])dnl
 if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\	*)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
@@ -2149,7 +2990,7 @@ fi
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2178,7 +3019,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2225,7 +3066,7 @@ AC_LANG_POP([C])])
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2244,7 +3085,7 @@ AC_DEFUN([AM_RUN_LOG],
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2325,7 +3166,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+# Copyright (C) 2009-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2385,7 +3226,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2413,7 +3254,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -2432,7 +3273,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+# Copyright (C) 2004-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/cexport.c b/cexport.c
index aa55fb3..f94b155 100644
--- a/cexport.c
+++ b/cexport.c
@@ -38,6 +38,8 @@
 
 #include "config.h"
 #include <stdio.h>
+#include <err.h>
+#include <sysexits.h>
 #if STDC_HEADERS
 # include <string.h>
 #else
@@ -55,7 +57,7 @@
 
 #define LINELEN BUFSIZ
 
-static int err = 0;                         /* Global error counter */
+static int nerr = 0;                         /* Global error counter */
 static char *cppcmd = CPP;
 static char *extension = ".e";
 
@@ -186,7 +188,7 @@ static void export(i)
 	    if (brace < 0) {
 		fprintf(stderr, "%s:%ld: syntax error (too many '}'s)\n",
 			curname, lineno);
-		err++;
+		nerr++;
 		brace = 0;
 	    }
             break;
@@ -236,14 +238,14 @@ static void export(i)
 		fprintf(stderr,
 			"%s:%ld: syntax error (string didn't end)\n",
 			curname, lineno);
-		err++;
+		nerr++;
 		dquote = 0;
 	    }
 	    if (squote) {
 		fprintf(stderr,
 			"%s:%ld: syntax error (char const didn't end)\n",
 			curname, lineno);
-		err++;
+		nerr++;
 		squote = 0;
 	    }
 	    break;
@@ -301,15 +303,15 @@ static void process(file, cpp)
     eof = 0;
     lineno = 0;
     in = popen(cmd, "r");			/* Pipe file through cpp */
-    if (! in) { perror(cmd); err++; return; }
-    
+    if (! in) { warn("%s", cmd); nerr++; return; }
+
     if (file) {
         strcpy(outname, file);			/* Construct output file */
         s = strrchr(outname, '.');		/* Extension becomes .e */
         if (! s) s = outname + strlen(outname);
         strcpy(s, extension);
         out = fopen(outname, "w");
-        if (! out) { perror(outname); err++; return; }
+        if (! out) { warn("%s", outname); nerr++; return; }
     } else {
         out = stdout;				/* No file name, use stdout */
     }
@@ -343,7 +345,7 @@ static void process(file, cpp)
 		if (brace < 0) {
 		    fprintf(stderr, "%s:%ld: syntax error (too many '}'s)\n",
 			    curname, lineno);
-		    err++;
+		    nerr++;
 		    brace = 0;
 		}
                 break;
@@ -355,7 +357,7 @@ static void process(file, cpp)
 		if (paren < 0) {
 		    fprintf(stderr, "%s:%ld: syntax error (too many ')'s)\n",
 			    curname, lineno);
-		    err++;
+		    nerr++;
 		    paren = 0;
 		}
                 break;
@@ -370,14 +372,14 @@ static void process(file, cpp)
 		    fprintf(stderr,
 			    "%s:%ld: syntax error (string didn't end)\n",
 			    curname, lineno);
-		    err++;
+		    nerr++;
 		    dquote = 0;
 		}
 		if (squote) {
 		    fprintf(stderr,
 			    "%s:%ld: syntax error (char const didn't end)\n",
 			    curname, lineno);
-		    err++;
+		    nerr++;
 		    squote = 0;
 		}
 		break;
@@ -407,17 +409,17 @@ static void process(file, cpp)
     if (comment) {
 	fprintf(stderr, "%s:%ld: syntax error (comment didn't end)\n",
 		curname, lineno);
-	err++;
+	nerr++;
     }
     if (dquote) {
 	fprintf(stderr, "%s:%ld: syntax error (string didn't end)\n",
 		curname, lineno);
-	err++;
+	nerr++;
     }
     if (squote) {
 	fprintf(stderr, "%s:%ld: syntax error (char const didn't end)\n",
 		curname, lineno);
-	err++;
+	nerr++;
     }
     if (file) fclose(out);
     fclose(in);
@@ -429,7 +431,7 @@ static void usage(s)
     fprintf(stderr,
 	    "Usage: %s {-Idir|-Dsym} [-h] [-c cppcmd] [-e ext] {file}\n",
 	    s);
-    err++;
+    nerr++;
 }
 
 int main(argc, argv)
@@ -466,6 +468,6 @@ int main(argc, argv)
     if (nfiles == 0)				/* no arguments, use stdin */
         process(NULL, cpp);
 
-    return err;
+    return nerr;
 }
 
diff --git a/class.e b/class.e
index 5acf953..ae07e44 100644
--- a/class.e
+++ b/class.e
@@ -1,3 +1,5 @@
 extern conststring contains(const conststring s, const conststring word);
-extern _Bool has_class(pairlist attribs, const string word);
-extern _Bool has_class_in_list(const pairlist attribs, const string *c);
+extern _Bool 
+           has_class(pairlist attribs, const string word);
+extern _Bool 
+           has_class_in_list(const pairlist attribs, const string *c);
diff --git a/config.h.in b/config.h.in
index 18e687f..25149a7 100644
--- a/config.h.in
+++ b/config.h.in
@@ -64,6 +64,9 @@
 /* Define to 1 if you have the <libintl.h> header file. */
 #undef HAVE_LIBINTL_H
 
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
 /* Define to 1 if you have the <locale.h> header file. */
 #undef HAVE_LOCALE_H
 
@@ -92,6 +95,9 @@
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #undef HAVE_NETINET_IN_H
 
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#undef HAVE_PTRDIFF_T
+
 /* Define to 1 if your system has a GNU libc compatible `realloc' function,
    and to 0 otherwise. */
 #undef HAVE_REALLOC
@@ -312,6 +318,17 @@
    `char[]'. */
 #undef YYTEXT_POINTER
 
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
 /* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
    <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
    #define below would cause a syntax error. */
diff --git a/configure b/configure
index de9e8eb..5bf8f71 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for html-xml-utils 7.7.
+# Generated by GNU Autoconf 2.69 for html-xml-utils 8.6.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='html-xml-utils'
 PACKAGE_TARNAME='html-xml-utils'
-PACKAGE_VERSION='7.7'
-PACKAGE_STRING='html-xml-utils 7.7'
+PACKAGE_VERSION='8.6'
+PACKAGE_STRING='html-xml-utils 8.6'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -651,7 +651,6 @@ am__nodep
 AMDEPBACKSLASH
 AMDEP_FALSE
 AMDEP_TRUE
-am__quote
 am__include
 DEPDIR
 OBJEXT
@@ -728,7 +727,8 @@ PACKAGE_VERSION
 PACKAGE_TARNAME
 PACKAGE_NAME
 PATH_SEPARATOR
-SHELL'
+SHELL
+am__quote'
 ac_subst_files=''
 ac_user_opts='
 enable_option_checking
@@ -740,6 +740,7 @@ with_libiconv_prefix
 with_libidn2
 with_libidn
 with_libcurl
+enable_largefile
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1302,7 +1303,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures html-xml-utils 7.7 to adapt to many kinds of systems.
+\`configure' configures html-xml-utils 8.6 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1373,7 +1374,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of html-xml-utils 7.7:";;
+     short | recursive ) echo "Configuration of html-xml-utils 8.6:";;
    esac
   cat <<\_ACEOF
 
@@ -1388,6 +1389,7 @@ Optional Features:
   --disable-dependency-tracking
                           speeds up one-time build
   --disable-rpath         do not hardcode runtime library paths
+  --disable-largefile     omit support for large files
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1482,7 +1484,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-html-xml-utils configure 7.7
+html-xml-utils configure 8.6
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2077,7 +2079,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by html-xml-utils $as_me 7.7, which was
+It was created by html-xml-utils $as_me 8.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2425,7 +2427,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-am__api_version='1.15'
+am__api_version='1.16'
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
@@ -2630,12 +2632,7 @@ program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\	*)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
@@ -2940,7 +2937,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='html-xml-utils'
- VERSION='7.7'
+ VERSION='8.6'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2970,8 +2967,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
 # For better backward compatibility.  To be removed once Automake 1.9.x
 # dies out for good.  For more background, see:
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
-# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
 # We need awk for the "check" target (and possibly the TAP driver).  The
@@ -3022,7 +3019,7 @@ END
 Aborting the configuration process, to ensure you take notice of the issue.
 
 You can download and install GNU coreutils to get an 'rm' implementation
-that behaves properly: <http://www.gnu.org/software/coreutils/>.
+that behaves properly: <https://www.gnu.org/software/coreutils/>.
 
 If you want to complete the configuration process using your problematic
 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
@@ -3933,45 +3930,45 @@ DEPDIR="${am__leading_dot}deps"
 
 ac_config_commands="$ac_config_commands depfiles"
 
-
-am_make=${MAKE-make}
-cat > confinc << 'END'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+cat > confinc.mk << 'END'
 am__doit:
-	@echo this is the am__doit target
+	@echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5
+   (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+  case $?:`cat confinc.out 2>/dev/null` in #(
+  '0:this is the am__doit target') :
+    case $s in #(
+  BSD) :
+    am__include='.include' am__quote='"' ;; #(
+  *) :
+    am__include='include' am__quote='' ;;
+esac ;; #(
+  *) :
      ;;
-   esac
-fi
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
+esac
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+$as_echo "${_am_result}" >&6; }
 
 # Check whether --enable-dependency-tracking was given.
 if test "${enable_dependency_tracking+set}" = set; then :
@@ -4543,38 +4540,12 @@ if test "${PATH_SEPARATOR+set}" != set; then
        }
 fi
 
-ac_prog=ld
-if test "$GCC" = yes; then
-  # Check if gcc -print-prog-name=ld gives a path.
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld" >&5
+$as_echo_n "checking for ld... " >&6; }
+elif test "$GCC" = yes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
 $as_echo_n "checking for ld used by $CC... " >&6; }
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
-    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
-  *)
-    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
-  esac
-  case $ac_prog in
-    # Accept absolute paths.
-    [\\/]* | ?:[\\/]*)
-      re_direlt='/[^/][^/]*/\.\./'
-      # Canonicalize the pathname of ld
-      ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'`
-      while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do
-        ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
-      done
-      test -z "$LD" && LD="$ac_prog"
-      ;;
-  "")
-    # If it fails, then pretend we aren't using GCC.
-    ac_prog=ld
-    ;;
-  *)
-    # If it is relative, then search for the first ld in PATH.
-    with_gnu_ld=unknown
-    ;;
-  esac
 elif test "$with_gnu_ld" = yes; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
 $as_echo_n "checking for GNU ld... " >&6; }
@@ -4582,44 +4553,129 @@ else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
 $as_echo_n "checking for non-GNU ld... " >&6; }
 fi
-if ${acl_cv_path_LD+:} false; then :
+if test -n "$LD"; then
+  # Let the user override the test with a path.
+  :
+else
+  if ${acl_cv_path_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -z "$LD"; then
-  acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-  for ac_dir in $PATH; do
-    IFS="$acl_save_ifs"
-    test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      acl_cv_path_LD="$ac_dir/$ac_prog"
-      # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some variants of GNU ld only accept -v.
-      # Break only if it was the GNU/non-GNU ld that we prefer.
-      case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in
-      *GNU* | *'with BFD'*)
-        test "$with_gnu_ld" != no && break
-        ;;
-      *)
-        test "$with_gnu_ld" != yes && break
-        ;;
+
+    acl_cv_path_LD= # Final result of this test
+    ac_prog=ld # Program to search in $PATH
+    if test "$GCC" = yes; then
+      # Check if gcc -print-prog-name=ld gives a path.
+      case $host in
+        *-*-mingw*)
+          # gcc leaves a trailing carriage return which upsets mingw
+          acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+        *)
+          acl_output=`($CC -print-prog-name=ld) 2>&5` ;;
+      esac
+      case $acl_output in
+        # Accept absolute paths.
+        [\\/]* | ?:[\\/]*)
+          re_direlt='/[^/][^/]*/\.\./'
+          # Canonicalize the pathname of ld
+          acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'`
+          while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do
+            acl_output=`echo $acl_output | sed "s%$re_direlt%/%"`
+          done
+          # Got the pathname. No search in PATH is needed.
+          acl_cv_path_LD="$acl_output"
+          ac_prog=
+          ;;
+        "")
+          # If it fails, then pretend we aren't using GCC.
+          ;;
+        *)
+          # If it is relative, then search for the first ld in PATH.
+          with_gnu_ld=unknown
+          ;;
       esac
     fi
-  done
-  IFS="$acl_save_ifs"
+    if test -n "$ac_prog"; then
+      # Search for $ac_prog in $PATH.
+      acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+      for ac_dir in $PATH; do
+        IFS="$acl_save_ifs"
+        test -z "$ac_dir" && ac_dir=.
+        if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+          acl_cv_path_LD="$ac_dir/$ac_prog"
+          # Check to see if the program is GNU ld.  I'd rather use --version,
+          # but apparently some variants of GNU ld only accept -v.
+          # Break only if it was the GNU/non-GNU ld that we prefer.
+          case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in
+            *GNU* | *'with BFD'*)
+              test "$with_gnu_ld" != no && break
+              ;;
+            *)
+              test "$with_gnu_ld" != yes && break
+              ;;
+          esac
+        fi
+      done
+      IFS="$acl_save_ifs"
+    fi
+    case $host in
+      *-*-aix*)
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined __powerpc64__ || defined _ARCH_PPC64
+                int ok;
+               #else
+                error fail
+               #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # The compiler produces 64-bit code. Add option '-b64' so that the
+           # linker groks 64-bit object files.
+           case "$acl_cv_path_LD " in
+             *" -b64 "*) ;;
+             *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;;
+           esac
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+        ;;
+      sparc64-*-netbsd*)
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined __sparcv9 || defined __arch64__
+                int ok;
+               #else
+                error fail
+               #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
 else
-  acl_cv_path_LD="$LD" # Let the user override the test with a path.
+  # The compiler produces 32-bit code. Add option '-m elf32_sparc'
+           # so that the linker groks 32-bit object files.
+           case "$acl_cv_path_LD " in
+             *" -m elf32_sparc "*) ;;
+             *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;;
+           esac
+
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+        ;;
+    esac
+
 fi
 
-LD="$acl_cv_path_LD"
+  LD="$acl_cv_path_LD"
+fi
 if test -n "$LD"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
 $as_echo "$LD" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
+  as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
 fi
-test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
 if ${acl_cv_prog_gnu_ld+:} false; then :
@@ -4674,6 +4730,266 @@ else
 fi
 
 
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking 32-bit host C ABI" >&5
+$as_echo_n "checking 32-bit host C ABI... " >&6; }
+if ${gl_cv_host_cpu_c_abi_32bit+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$gl_cv_host_cpu_c_abi"; then
+       case "$gl_cv_host_cpu_c_abi" in
+         i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc)
+           gl_cv_host_cpu_c_abi_32bit=yes ;;
+         x86_64 | alpha | arm64 | hppa64 | ia64 | mips64 | powerpc64 | powerpc64-elfv2 | riscv*-lp64* | s390x | sparc64 )
+           gl_cv_host_cpu_c_abi_32bit=no ;;
+         *)
+           gl_cv_host_cpu_c_abi_32bit=unknown ;;
+       esac
+     else
+       case "$host_cpu" in
+
+         # CPUs that only support a 32-bit ABI.
+         arc \
+         | bfin \
+         | cris* \
+         | csky \
+         | epiphany \
+         | ft32 \
+         | h8300 \
+         | m68k \
+         | microblaze | microblazeel \
+         | nds32 | nds32le | nds32be \
+         | nios2 | nios2eb | nios2el \
+         | or1k* \
+         | or32 \
+         | sh | sh1234 | sh1234elb \
+         | tic6x \
+         | xtensa* )
+           gl_cv_host_cpu_c_abi_32bit=yes
+           ;;
+
+         # CPUs that only support a 64-bit ABI.
+         alpha | alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] \
+         | mmix )
+           gl_cv_host_cpu_c_abi_32bit=no
+           ;;
+
+         i[34567]86 )
+           gl_cv_host_cpu_c_abi_32bit=yes
+           ;;
+
+         x86_64 )
+           # On x86_64 systems, the C compiler may be generating code in one of
+           # these ABIs:
+           # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
+           # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
+           #   with native Windows (mingw, MSVC).
+           # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
+           # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if (defined __x86_64__ || defined __amd64__ \
+                       || defined _M_X64 || defined _M_AMD64) \
+                      && !(defined __ILP32__ || defined _ILP32)
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=no
+else
+  gl_cv_host_cpu_c_abi_32bit=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         arm* | aarch64 )
+           # Assume arm with EABI.
+           # On arm64 systems, the C compiler may be generating code in one of
+           # these ABIs:
+           # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
+           # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
+           # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined __aarch64__ && !(defined __ILP32__ || defined _ILP32)
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=no
+else
+  gl_cv_host_cpu_c_abi_32bit=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
+           # On hppa, the C compiler may be generating 32-bit code or 64-bit
+           # code. In the latter case, it defines _LP64 and __LP64__.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __LP64__
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=no
+else
+  gl_cv_host_cpu_c_abi_32bit=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         ia64* )
+           # On ia64 on HP-UX, the C compiler may be generating 64-bit code or
+           # 32-bit code. In the latter case, it defines _ILP32.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef _ILP32
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=yes
+else
+  gl_cv_host_cpu_c_abi_32bit=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         mips* )
+           # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
+           # at 32.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=no
+else
+  gl_cv_host_cpu_c_abi_32bit=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         powerpc* )
+           # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
+           # No need to distinguish them here; the caller may distinguish
+           # them based on the OS.
+           # On powerpc64 systems, the C compiler may still be generating
+           # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
+           # be generating 64-bit code.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined __powerpc64__ || defined _ARCH_PPC64
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=no
+else
+  gl_cv_host_cpu_c_abi_32bit=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         rs6000 )
+           gl_cv_host_cpu_c_abi_32bit=yes
+           ;;
+
+         riscv32 | riscv64 )
+           # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
+           # Size of 'long' and 'void *':
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined __LP64__
+                    int ok;
+                  #else
+                    error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=no
+else
+  gl_cv_host_cpu_c_abi_32bit=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         s390* )
+           # On s390x, the C compiler may be generating 64-bit (= s390x) code
+           # or 31-bit (= s390) code.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined __LP64__ || defined __s390x__
+                    int ok;
+                  #else
+                    error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=no
+else
+  gl_cv_host_cpu_c_abi_32bit=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         sparc | sparc64 )
+           # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
+           # C compiler still generates 32-bit code.
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined __sparcv9 || defined __arch64__
+                   int ok;
+                  #else
+                   error fail
+                  #endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_host_cpu_c_abi_32bit=no
+else
+  gl_cv_host_cpu_c_abi_32bit=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           ;;
+
+         *)
+           gl_cv_host_cpu_c_abi_32bit=unknown
+           ;;
+       esac
+     fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_host_cpu_c_abi_32bit" >&5
+$as_echo "$gl_cv_host_cpu_c_abi_32bit" >&6; }
+
+  HOST_CPU_C_ABI_32BIT="$gl_cv_host_cpu_c_abi_32bit"
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4944,67 +5260,152 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
 
 
 
-  acl_libdirstem=lib
-  acl_libdirstem2=
-  case "$host_os" in
-    solaris*)
-                                    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5
-$as_echo_n "checking for 64-bit host... " >&6; }
-if ${gl_cv_solaris_64bit+:} false; then :
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF binary format" >&5
+$as_echo_n "checking for ELF binary format... " >&6; }
+if ${gl_cv_elf+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-
-#ifdef _LP64
-sixtyfour bits
-#endif
+#ifdef __ELF__
+        Extensible Linking Format
+        #endif
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "sixtyfour bits" >/dev/null 2>&1; then :
-  gl_cv_solaris_64bit=yes
+  $EGREP "Extensible Linking Format" >/dev/null 2>&1; then :
+  gl_cv_elf=yes
 else
-  gl_cv_solaris_64bit=no
+  gl_cv_elf=no
 fi
 rm -f conftest*
 
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5
-$as_echo "$gl_cv_solaris_64bit" >&6; }
-      if test $gl_cv_solaris_64bit = yes; then
-        acl_libdirstem=lib/64
-        case "$host_cpu" in
-          sparc*)        acl_libdirstem2=lib/sparcv9 ;;
-          i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
-        esac
-      fi
-      ;;
-    *)
-      searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
-      if test -n "$searchpath"; then
-        acl_save_IFS="${IFS= 	}"; IFS=":"
-        for searchdir in $searchpath; do
-          if test -d "$searchdir"; then
-            case "$searchdir" in
-              */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
-              */../ | */.. )
-                # Better ignore directories of this form. They are misleading.
-                ;;
-              *) searchdir=`cd "$searchdir" && pwd`
-                 case "$searchdir" in
-                   */lib64 ) acl_libdirstem=lib64 ;;
-                 esac ;;
-            esac
-          fi
-        done
-        IFS="$acl_save_IFS"
-      fi
-      ;;
-  esac
-  test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_elf" >&5
+$as_echo "$gl_cv_elf" >&6; }
+  if test $gl_cv_elf; then
+    # Extract the ELF class of a file (5th byte) in decimal.
+    # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header
+    if od -A x < /dev/null >/dev/null 2>/dev/null; then
+      # Use POSIX od.
+      func_elfclass ()
+      {
+        od -A n -t d1 -j 4 -N 1
+      }
+    else
+      # Use BSD hexdump.
+      func_elfclass ()
+      {
+        dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 "%3d "'
+        echo
+      }
+    fi
+    case $HOST_CPU_C_ABI_32BIT in
+      yes)
+        # 32-bit ABI.
+        acl_is_expected_elfclass ()
+        {
+          test "`func_elfclass | sed -e 's/[ 	]//g'`" = 1
+        }
+        ;;
+      no)
+        # 64-bit ABI.
+        acl_is_expected_elfclass ()
+        {
+          test "`func_elfclass | sed -e 's/[ 	]//g'`" = 2
+        }
+        ;;
+      *)
+        # Unknown.
+        acl_is_expected_elfclass ()
+        {
+          :
+        }
+        ;;
+    esac
+  else
+    acl_is_expected_elfclass ()
+    {
+      :
+    }
+  fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the common suffixes of directories in the library search path" >&5
+$as_echo_n "checking for the common suffixes of directories in the library search path... " >&6; }
+if ${acl_cv_libdirstems+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            acl_libdirstem=lib
+     acl_libdirstem2=
+     acl_libdirstem3=
+     case "$host_os" in
+       solaris*)
+                                                      if test $HOST_CPU_C_ABI_32BIT = no; then
+           acl_libdirstem2=lib/64
+           case "$host_cpu" in
+             sparc*)        acl_libdirstem3=lib/sparcv9 ;;
+             i*86 | x86_64) acl_libdirstem3=lib/amd64 ;;
+           esac
+         fi
+         ;;
+       *)
+                                                                                 searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \
+                     | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+         if test $HOST_CPU_C_ABI_32BIT != no; then
+           # 32-bit or unknown ABI.
+           if test -d /usr/lib32; then
+             acl_libdirstem2=lib32
+           fi
+         fi
+         if test $HOST_CPU_C_ABI_32BIT != yes; then
+           # 64-bit or unknown ABI.
+           if test -d /usr/lib64; then
+             acl_libdirstem3=lib64
+           fi
+         fi
+         if test -n "$searchpath"; then
+           acl_save_IFS="${IFS= 	}"; IFS=":"
+           for searchdir in $searchpath; do
+             if test -d "$searchdir"; then
+               case "$searchdir" in
+                 */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;;
+                 */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;;
+                 */../ | */.. )
+                   # Better ignore directories of this form. They are misleading.
+                   ;;
+                 *) searchdir=`cd "$searchdir" && pwd`
+                    case "$searchdir" in
+                      */lib32 ) acl_libdirstem2=lib32 ;;
+                      */lib64 ) acl_libdirstem3=lib64 ;;
+                    esac ;;
+               esac
+             fi
+           done
+           IFS="$acl_save_IFS"
+           if test $HOST_CPU_C_ABI_32BIT = yes; then
+             # 32-bit ABI.
+             acl_libdirstem3=
+           fi
+           if test $HOST_CPU_C_ABI_32BIT = no; then
+             # 64-bit ABI.
+             acl_libdirstem2=
+           fi
+         fi
+         ;;
+     esac
+     test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+     test -n "$acl_libdirstem3" || acl_libdirstem3="$acl_libdirstem"
+     acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3"
 
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_libdirstems" >&5
+$as_echo "$acl_cv_libdirstems" >&6; }
+      acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'`
+  acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,//' -e 's/,.*//'`
+  acl_libdirstem3=`echo "$acl_cv_libdirstems" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'`
 
 
 
@@ -5025,6 +5426,8 @@ $as_echo "$gl_cv_solaris_64bit" >&6; }
 
     eval additional_includedir=\"$includedir\"
     eval additional_libdir=\"$libdir\"
+    eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\"
+    eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\"
 
   exec_prefix="$acl_save_exec_prefix"
   prefix="$acl_save_prefix"
@@ -5045,6 +5448,8 @@ if test "${with_libiconv_prefix+set}" = set; then :
 
           eval additional_includedir=\"$includedir\"
           eval additional_libdir=\"$libdir\"
+          eval additional_libdir2=\"$exec_prefix/$acl_libdirstem2\"
+          eval additional_libdir3=\"$exec_prefix/$acl_libdirstem3\"
 
   exec_prefix="$acl_save_exec_prefix"
   prefix="$acl_save_prefix"
@@ -5052,15 +5457,19 @@ if test "${with_libiconv_prefix+set}" = set; then :
       else
         additional_includedir="$withval/include"
         additional_libdir="$withval/$acl_libdirstem"
-        if test "$acl_libdirstem2" != "$acl_libdirstem" \
-           && ! test -d "$withval/$acl_libdirstem"; then
-          additional_libdir="$withval/$acl_libdirstem2"
-        fi
+        additional_libdir2="$withval/$acl_libdirstem2"
+        additional_libdir3="$withval/$acl_libdirstem3"
       fi
     fi
 
 fi
 
+  if test "X$additional_libdir2" = "X$additional_libdir"; then
+    additional_libdir2=
+  fi
+  if test "X$additional_libdir3" = "X$additional_libdir"; then
+    additional_libdir3=
+  fi
       LIBICONV=
   LTLIBICONV=
   INCICONV=
@@ -5106,45 +5515,51 @@ fi
             shrext=
           fi
           if test $use_additional = yes; then
-            dir="$additional_libdir"
-                                    if test -n "$acl_shlibext"; then
-              if test -f "$dir/$libname$shrext"; then
-                found_dir="$dir"
-                found_so="$dir/$libname$shrext"
-              else
-                if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
-                  ver=`(cd "$dir" && \
-                        for f in "$libname$shrext".*; do echo "$f"; done \
-                        | sed -e "s,^$libname$shrext\\\\.,," \
-                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
-                        | sed 1q ) 2>/dev/null`
-                  if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
-                    found_dir="$dir"
-                    found_so="$dir/$libname$shrext.$ver"
+            for additional_libdir_variable in additional_libdir additional_libdir2 additional_libdir3; do
+              if test "X$found_dir" = "X"; then
+                eval dir=\$$additional_libdir_variable
+                if test -n "$dir"; then
+                                                      if test -n "$acl_shlibext"; then
+                    if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then
+                      found_dir="$dir"
+                      found_so="$dir/$libname$shrext"
+                    else
+                      if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+                        ver=`(cd "$dir" && \
+                              for f in "$libname$shrext".*; do echo "$f"; done \
+                              | sed -e "s,^$libname$shrext\\\\.,," \
+                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+                              | sed 1q ) 2>/dev/null`
+                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then
+                          found_dir="$dir"
+                          found_so="$dir/$libname$shrext.$ver"
+                        fi
+                      else
+                        eval library_names=\"$acl_library_names_spec\"
+                        for f in $library_names; do
+                          if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then
+                            found_dir="$dir"
+                            found_so="$dir/$f"
+                            break
+                          fi
+                        done
+                      fi
+                    fi
                   fi
-                else
-                  eval library_names=\"$acl_library_names_spec\"
-                  for f in $library_names; do
-                    if test -f "$dir/$f"; then
+                                    if test "X$found_dir" = "X"; then
+                    if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then
                       found_dir="$dir"
-                      found_so="$dir/$f"
-                      break
+                      found_a="$dir/$libname.$acl_libext"
                     fi
-                  done
+                  fi
+                  if test "X$found_dir" != "X"; then
+                    if test -f "$dir/$libname.la"; then
+                      found_la="$dir/$libname.la"
+                    fi
+                  fi
                 fi
               fi
-            fi
-                        if test "X$found_dir" = "X"; then
-              if test -f "$dir/$libname.$acl_libext"; then
-                found_dir="$dir"
-                found_a="$dir/$libname.$acl_libext"
-              fi
-            fi
-            if test "X$found_dir" != "X"; then
-              if test -f "$dir/$libname.la"; then
-                found_la="$dir/$libname.la"
-              fi
-            fi
+            done
           fi
           if test "X$found_dir" = "X"; then
             for x in $LDFLAGS $LTLIBICONV; do
@@ -5161,7 +5576,7 @@ fi
                 -L*)
                   dir=`echo "X$x" | sed -e 's/^X-L//'`
                                     if test -n "$acl_shlibext"; then
-                    if test -f "$dir/$libname$shrext"; then
+                    if test -f "$dir/$libname$shrext" && acl_is_expected_elfclass < "$dir/$libname$shrext"; then
                       found_dir="$dir"
                       found_so="$dir/$libname$shrext"
                     else
@@ -5171,14 +5586,14 @@ fi
                               | sed -e "s,^$libname$shrext\\\\.,," \
                               | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
                               | sed 1q ) 2>/dev/null`
-                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+                        if test -n "$ver" && test -f "$dir/$libname$shrext.$ver" && acl_is_expected_elfclass < "$dir/$libname$shrext.$ver"; then
                           found_dir="$dir"
                           found_so="$dir/$libname$shrext.$ver"
                         fi
                       else
                         eval library_names=\"$acl_library_names_spec\"
                         for f in $library_names; do
-                          if test -f "$dir/$f"; then
+                          if test -f "$dir/$f" && acl_is_expected_elfclass < "$dir/$f"; then
                             found_dir="$dir"
                             found_so="$dir/$f"
                             break
@@ -5188,7 +5603,7 @@ fi
                     fi
                   fi
                                     if test "X$found_dir" = "X"; then
-                    if test -f "$dir/$libname.$acl_libext"; then
+                    if test -f "$dir/$libname.$acl_libext" && ${AR-ar} -p "$dir/$libname.$acl_libext" | acl_is_expected_elfclass; then
                       found_dir="$dir"
                       found_a="$dir/$libname.$acl_libext"
                     fi
@@ -5210,7 +5625,8 @@ fi
             if test "X$found_so" != "X"; then
                                                         if test "$enable_rpath" = no \
                  || test "X$found_dir" = "X/usr/$acl_libdirstem" \
-                 || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem2" \
+                 || test "X$found_dir" = "X/usr/$acl_libdirstem3"; then
                                 LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so"
               else
                                                                                 haveit=
@@ -5289,6 +5705,13 @@ fi
                 fi
                 additional_includedir="$basedir/include"
                 ;;
+              */$acl_libdirstem3 | */$acl_libdirstem3/)
+                basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem3/"'*$,,'`
+                if test "$name" = 'iconv'; then
+                  LIBICONV_PREFIX="$basedir"
+                fi
+                additional_includedir="$basedir/include"
+                ;;
             esac
             if test "X$additional_includedir" != "X"; then
                                                                                                                 if test "X$additional_includedir" != "X/usr/include"; then
@@ -5334,12 +5757,14 @@ fi
                             for dep in $dependency_libs; do
                 case "$dep" in
                   -L*)
-                    additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
-                                                                                                                                                                if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
-                       && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+                    dependency_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+                                                                                                                                                                if test "X$dependency_libdir" != "X/usr/$acl_libdirstem" \
+                       && test "X$dependency_libdir" != "X/usr/$acl_libdirstem2" \
+                       && test "X$dependency_libdir" != "X/usr/$acl_libdirstem3"; then
                       haveit=
-                      if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
-                         || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+                      if test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem" \
+                         || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem2" \
+                         || test "X$dependency_libdir" = "X/usr/local/$acl_libdirstem3"; then
                         if test -n "$GCC"; then
                           case $host_os in
                             linux* | gnu* | k*bsd*-gnu) haveit=yes;;
@@ -5358,14 +5783,14 @@ fi
   exec_prefix="$acl_save_exec_prefix"
   prefix="$acl_save_prefix"
 
-                          if test "X$x" = "X-L$additional_libdir"; then
+                          if test "X$x" = "X-L$dependency_libdir"; then
                             haveit=yes
                             break
                           fi
                         done
                         if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                                                        LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir"
+                          if test -d "$dependency_libdir"; then
+                                                        LIBICONV="${LIBICONV}${LIBICONV:+ }-L$dependency_libdir"
                           fi
                         fi
                         haveit=
@@ -5379,14 +5804,14 @@ fi
   exec_prefix="$acl_save_exec_prefix"
   prefix="$acl_save_prefix"
 
-                          if test "X$x" = "X-L$additional_libdir"; then
+                          if test "X$x" = "X-L$dependency_libdir"; then
                             haveit=yes
                             break
                           fi
                         done
                         if test -z "$haveit"; then
-                          if test -d "$additional_libdir"; then
-                                                        LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir"
+                          if test -d "$dependency_libdir"; then
+                                                        LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$dependency_libdir"
                           fi
                         fi
                       fi
@@ -5475,7 +5900,6 @@ fi
 
 
 
-
           am_save_CPPFLAGS="$CPPFLAGS"
 
   for element in $INCICONV; do
@@ -5676,15 +6100,27 @@ int result = 0;
 #endif
   /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
      provided.  */
-  if (/* Try standardized names.  */
-      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
-      /* Try IRIX, OSF/1 names.  */
-      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
-      /* Try AIX names.  */
-      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
-      /* Try HP-UX names.  */
-      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
-    result |= 16;
+  {
+    /* Try standardized names.  */
+    iconv_t cd1 = iconv_open ("UTF-8", "EUC-JP");
+    /* Try IRIX, OSF/1 names.  */
+    iconv_t cd2 = iconv_open ("UTF-8", "eucJP");
+    /* Try AIX names.  */
+    iconv_t cd3 = iconv_open ("UTF-8", "IBM-eucJP");
+    /* Try HP-UX names.  */
+    iconv_t cd4 = iconv_open ("utf8", "eucJP");
+    if (cd1 == (iconv_t)(-1) && cd2 == (iconv_t)(-1)
+        && cd3 == (iconv_t)(-1) && cd4 == (iconv_t)(-1))
+      result |= 16;
+    if (cd1 != (iconv_t)(-1))
+      iconv_close (cd1);
+    if (cd2 != (iconv_t)(-1))
+      iconv_close (cd2);
+    if (cd3 != (iconv_t)(-1))
+      iconv_close (cd3);
+    if (cd4 != (iconv_t)(-1))
+      iconv_close (cd4);
+  }
   return result;
 
   ;
@@ -5774,13 +6210,15 @@ fi
          $am_cv_proto_iconv" >&5
 $as_echo "
          $am_cv_proto_iconv" >&6; }
+  else
+            am_cv_proto_iconv_arg1=""
+  fi
 
 cat >>confdefs.h <<_ACEOF
 #define ICONV_CONST $am_cv_proto_iconv_arg1
 _ACEOF
 
 
-  fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
@@ -6449,118 +6887,6 @@ _ACEOF
 
 
 # Checks for header files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-		   (('a' <= (c) && (c) <= 'i') \
-		     || ('j' <= (c) && (c) <= 'r') \
-		     || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-	|| toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
 if test "x$ac_cv_type_size_t" = xyes; then :
 
@@ -6758,7 +7084,7 @@ _ACEOF
 
 fi
 
-for ac_header in arpa/inet.h errno.h fcntl.h inttypes.h libintl.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/param.h sys/socket.h sys/time.h unistd.h search.h wchar.h
+for ac_header in arpa/inet.h errno.h fcntl.h inttypes.h libintl.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdlib.h stdint.h string.h strings.h sys/param.h sys/socket.h sys/time.h unistd.h search.h wchar.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -6773,6 +7099,206 @@ done
 
 
 # Checks for typedefs, structures, and compiler characteristics.
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+  enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+	 # IRIX 6.2 and later do not support large files by default,
+	 # so use the C compiler's -n32 option if that helps.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+	 if ac_fn_c_try_compile "$LINENO"; then :
+  break
+fi
+rm -f core conftest.err conftest.$ac_objext
+	 CC="$CC -n32"
+	 if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+	 break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  while :; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_cv_sys_file_offset_bits=unknown
+  break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+  if test $ac_cv_sys_file_offset_bits = unknown; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  while :; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+		       && LARGE_OFF_T % 2147483647 == 1)
+		      ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  ac_cv_sys_large_files=unknown
+  break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+  no | unknown) ;;
+  *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+  fi
+
+
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
 if ${ac_cv_header_stdbool_h+:} false; then :
@@ -7078,6 +7604,16 @@ _ACEOF
 ;;
   esac
 
+ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default"
+if test "x$ac_cv_type_ptrdiff_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PTRDIFF_T 1
+_ACEOF
+
+
+fi
+
 
 # Checks for library functions.
 for ac_header in stdlib.h
@@ -7993,7 +8529,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by html-xml-utils $as_me 7.7, which was
+This file was extended by html-xml-utils $as_me 8.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8059,7 +8595,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-html-xml-utils config.status 7.7
+html-xml-utils config.status 8.6
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -8178,7 +8714,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 #
 # INIT-COMMANDS
 #
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"
 
 _ACEOF
 
@@ -8790,29 +9326,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  case $CONFIG_FILES in #(
+  *\'*) :
+    eval set x "$CONFIG_FILES" ;; #(
+  *) :
+    set x $CONFIG_FILES ;; #(
+  *) :
+     ;;
+esac
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`$as_dirname -- "$mf" ||
-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$mf" : 'X\(//\)[^/]' \| \
-	 X"$mf" : 'X\(//\)$' \| \
-	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$mf" |
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`$as_dirname -- "$am_mf" ||
+$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$am_mf" : 'X\(//\)[^/]' \| \
+	 X"$am_mf" : 'X\(//\)$' \| \
+	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$am_mf" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -8830,53 +9372,50 @@ $as_echo X"$mf" |
 	    q
 	  }
 	  s/.*/./; q'`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
-	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`$as_dirname -- "$file" ||
-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$file" : 'X\(//\)[^/]' \| \
-	 X"$file" : 'X\(//\)$' \| \
-	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
+    am_filepart=`$as_basename -- "$am_mf" ||
+$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$am_mf" : 'X\(//\)$' \| \
+	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$am_mf" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
 	  }
-	  /^X\(\/\/\)$/{
+	  /^X\/\(\/\/\)$/{
 	    s//\1/
 	    q
 	  }
-	  /^X\(\/\).*/{
+	  /^X\/\(\/\).*/{
 	    s//\1/
 	    q
 	  }
 	  s/.*/./; q'`
-      as_dir=$dirpart/$fdir; as_fn_mkdir_p
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    { echo "$as_me:$LINENO: cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles" >&5
+   (cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE=\"gmake\" (or whatever is
+    necessary).  You can also try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+  { am_dirpart=; unset am_dirpart;}
+  { am_filepart=; unset am_filepart;}
+  { am_mf=; unset am_mf;}
+  { am_rc=; unset am_rc;}
+  rm -f conftest-deps.mk
 }
  ;;
 
diff --git a/configure.ac b/configure.ac
index 8a3636b..5df7058 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
 #                                               -*- Autoconf -*-
 # Process this file with autoconf to produce a configure script.
 AC_PREREQ([2.69])
-AC_INIT([html-xml-utils],[7.7])
+AC_INIT([html-xml-utils],[8.6])
 dnl print all automake warnings with -Wall
 dnl http://sources.redhat.com/automake/automake.html#Options
 AM_INIT_AUTOMAKE([-Wall])
@@ -29,11 +29,11 @@ LIBIDN_CHECK
 LIBCURL_CHECK_CONFIG(yes, 7.9.7)
 
 # Checks for header files.
-AC_HEADER_STDC
 AC_FUNC_ALLOCA
-AC_CHECK_HEADERS([arpa/inet.h errno.h fcntl.h inttypes.h libintl.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/param.h sys/socket.h sys/time.h unistd.h search.h wchar.h])
+AC_CHECK_HEADERS([arpa/inet.h errno.h fcntl.h inttypes.h libintl.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdlib.h stdint.h string.h strings.h sys/param.h sys/socket.h sys/time.h unistd.h search.h wchar.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
+AC_SYS_LARGEFILE
 AC_CHECK_HEADER_STDBOOL
 AC_C_CONST
 AC_C_INLINE
@@ -45,6 +45,7 @@ AC_TYPE_SSIZE_T
 AC_TYPE_UINT16_T
 AC_TYPE_UINT32_T
 AC_TYPE_UINT8_T
+AC_CHECK_TYPES([ptrdiff_t])
 
 # Checks for library functions.
 AC_FUNC_MALLOC
@@ -66,4 +67,4 @@ AC_OUTPUT
 
 if test "$libidn2" = "no" && test "$libidn" = "no"; then
   AC_MSG_WARN([Neither libidn2 nor libidn found])
-fi   
+fi
diff --git a/debian/changelog b/debian/changelog
index b7cc25b..858c6c3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-html-xml-utils (7.7-2) UNRELEASED; urgency=medium
+html-xml-utils (8.6-1) UNRELEASED; urgency=medium
 
   [ Francisco Vilmar Cardoso Ruviaro ]
   * Using new DH level format. Consequently:
@@ -16,8 +16,10 @@ html-xml-utils (7.7-2) UNRELEASED; urgency=medium
   [ Debian Janitor ]
   * Remove constraints unnecessary since buster:
     + Build-Depends: Drop versioned constraint on libcurl4-gnutls-dev.
+  * New upstream release.
+  * New upstream release.
 
- -- Francisco Vilmar Cardoso Ruviaro <francisco.ruviaro@riseup.net>  Tue, 09 Feb 2021 22:22:26 +0000
+ -- Francisco Vilmar Cardoso Ruviaro <francisco.ruviaro@riseup.net>  Wed, 24 May 2023 05:29:53 -0000
 
 html-xml-utils (7.7-1.1) unstable; urgency=medium
 
diff --git a/dict.c b/dict.c
index 247b9d3..b186fb3 100644
--- a/dict.c
+++ b/dict.c
@@ -5,6 +5,7 @@
  * dict_add(dict, key, value) -- add value for key, overwriting if it exists
  * dict_destroy(dict, key) -- remove value for key
  * dict_delete(dict) -- remove table, free memory
+ * dict_next(dict, prevkey) -- return next key; or the 1st, if prevkey is NULL
  *
  * The dictionary will automatically expand beyond its initial size if
  * it gets full. But enlarging a large dictionary can be slow. The
@@ -12,10 +13,15 @@
  * long as there is memory available), so an initial size of more than
  * twice the total number of keys results in the best performance.
  *
+ * Memory for destroyed entries is freed, but their slots in the
+ * dictionary aren't reused, so the dictionary can also become full
+ * with deleted entries. The slots are reclaimed when the dictionary
+ * is expanded.
+ *
  * Part of HTML-XML-utils, see:
  * http://www.w3.org/Tools/HTML-XML-utils/
  *
- * Copyright © 2008 World Wide Web Consortium
+ * Copyright © 2008-2021 World Wide Web Consortium
  * See http://www.w3.org/Consortium/Legal/copyright-software
  *
  * Author: Bert Bos <bert@w3.org>
@@ -27,7 +33,7 @@
 #include <string.h>
 #include "export.h"
 
-#define eq(s, t) (*(s) == *(t) && strcmp(s, t) == 0)
+#define eq(s, t) (!(s) ? !(t) : (t) && strcmp((s), (t)) == 0)
 
 
 EXPORT typedef struct _Dictionary * Dictionary;
@@ -44,6 +50,7 @@ static unsigned long hash(const unsigned long n, const char *s)
 {
   unsigned long h = 5381;
 
+  assert(s);
   for (; *s; s++) h = ((h << 5) + h) ^ (unsigned)*s;
   h = h % n;
   if (h == 0) h = 1;		/* We don't use index 0 */
@@ -57,6 +64,7 @@ static unsigned long find(Dictionary d, const char *key)
   unsigned long index0, index, seqno;
 
   assert(d);
+  if (!key) return 0;		/* NULL keys aren't stored */
   index0 = hash(d->size, key);
   index = index0;
   while (1) {
@@ -103,8 +111,10 @@ EXPORT void dict_delete(Dictionary d)
 
   assert(d);
   for (i = 0; i < d->entries; i++) {
-    free(d->keys[d->seqno2index[i]]);
-    free(d->values[d->seqno2index[i]]);
+    if (d->keys[d->seqno2index[i]]) {
+      free(d->keys[d->seqno2index[i]]);
+      free(d->values[d->seqno2index[i]]);
+    }
   }
   free(d->keys);
   free(d->values);
@@ -120,10 +130,11 @@ EXPORT void dict_destroy_all(Dictionary d)
   unsigned long i;
 
   assert(d);
-  for (i = 0; i < d->entries; i++) {
-    free(d->keys[d->seqno2index[i]]);
-    free(d->values[d->seqno2index[i]]);
-  }
+  for (i = 0; i < d->entries; i++)
+    if (d->keys[d->seqno2index[i]]) { /* Not an already deleted entry? */
+      free(d->keys[d->seqno2index[i]]);
+      free(d->values[d->seqno2index[i]]);
+    }
   d->entries = 0;
 }
 
@@ -131,18 +142,13 @@ EXPORT void dict_destroy_all(Dictionary d)
 /* dict_destroy -- delete a value from the dictionary */
 EXPORT void dict_destroy(Dictionary d, const char *key)
 {
-  unsigned long index, seqno;
+  unsigned long index;
 
   assert(d);
   if ((index = find(d, key)) > 0) {
     free(d->keys[index]);
     free(d->values[index]);
-    seqno = d->index2seqno[index];
-    assert(seqno < d->entries);
-    assert(d->entries > 0);
-    d->entries--;
-    d->seqno2index[seqno] = d->seqno2index[d->entries];
-    d->index2seqno[d->seqno2index[seqno]] = seqno;
+    d->keys[index] = NULL;	/* NULL means "deleted" */
   }
 }
 
@@ -157,6 +163,8 @@ EXPORT int dict_add(Dictionary d, const char *key, const char *value)
   unsigned long index0, index, seqno, found;
 
   assert(d);
+  assert(key);
+  assert(value);
   index0 = hash(d->size, key);
   index = index0;
   while (1) {
@@ -190,7 +198,7 @@ EXPORT int dict_add(Dictionary d, const char *key, const char *value)
 /* expand -- make the tables in the dictionary larger, return 0 if out of mem */
 static int expand(Dictionary d)
 {
-  unsigned long i;
+  unsigned long i, index;
   Dictionary h;
 
   assert(d);
@@ -199,17 +207,20 @@ static int expand(Dictionary d)
 
   /* Add all old entries to the new dictionary */
   for (i = 0; i < d->entries; i++) {
-    if (!dict_add(h, d->keys[d->seqno2index[i]],d->values[d->seqno2index[i]])) {
+    index = d->seqno2index[i];
+    if (d->keys[index] == NULL) continue; /* Deleted item */
+    if (!dict_add(h, d->keys[index], d->values[index])) {
       dict_delete(h);
       return 0;			/* Failed */
     }
   }
 
   /* Succeeded in making a copy, now delete the old entries */
-  for (i = 0; i < d->entries; i++) {
-    free(d->keys[d->seqno2index[i]]);
-    free(d->values[d->seqno2index[i]]);
-  }
+  for (i = 0; i < d->entries; i++)
+    if (d->keys[d->seqno2index[i]]) { /* Not a deleted item */
+      free(d->keys[d->seqno2index[i]]);
+      free(d->values[d->seqno2index[i]]);
+    }
   free(d->keys);
   free(d->values);
   free(d->seqno2index);
@@ -245,10 +256,11 @@ EXPORT const char *dict_next(Dictionary d, const char *prev_key)
 
   assert(d);
   if (d->entries == 0) return NULL; /* Empty dictionary */
-  if (!prev_key) return d->keys[d->seqno2index[0]]; /* Return first key */
-  index = find(d, prev_key);
-  if (index == 0) return NULL;	/* Error, unknown key */
-  seqno = d->index2seqno[index] + 1;
+  if (!prev_key) seqno = 0;	    /* First key */
+  else if (!(index = find(d, prev_key))) return NULL; /* Unknown key */
+  else seqno = d->index2seqno[index] + 1;
+  /* Skip over deleted items: */
+  while (seqno < d->entries && !d->keys[d->seqno2index[seqno]]) seqno++;
   if (seqno == d->entries) return NULL; /* No more keys */
   return d->keys[d->seqno2index[seqno]];
 }
diff --git a/dtd.c b/dtd.c
index 24bf470..5e75c8b 100644
--- a/dtd.c
+++ b/dtd.c
@@ -1,4 +1,4 @@
-/* C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.1 */
 /* Command-line: gperf -a -c -C -o -t -p -T -k '1,2,$' -N lookup_element dtd.hash  */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -25,7 +25,7 @@
       && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
       && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
 /* The character set is not based on ISO-646.  */
-error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
 #endif
 
 #line 1 "dtd.hash"
@@ -79,7 +79,7 @@ EXPORT const ElementType * lookup_element(/* register const char *str,
 
 /* Different kinds of parent elements: */
 #define PHRASE "abbr", "acronym", "b", "bdi", "bdo", "big", "cite", "code", "dfn", "em", "i", "kbd", "q", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "tt", "u", "var"
-#define BRIDGE "p", "address", "caption", "dt", "h1", "h2", "h3", "h4", "h5", "h6", "legend", "pre"
+#define BRIDGE "body", "p", "address", "caption", "dt", "h1", "h2", "h3", "h4", "h5", "h6", "legend", "pre"
 #define FLOW "article", "aside", "dd", "del", "details", "div", "fieldset", "figcaption", "figure", "footer", "header", "ins", "li", "nav", "section", "main", "object", "td", "th"
 #define INLINE_PARENT BRIDGE, PHRASE, FLOW
 #define BLOCK_PARENT "body", "blockquote", "map", "main"
@@ -99,9 +99,7 @@ inline
 #endif
 #endif
 static unsigned int
-hash (str, len)
-     register const char *str;
-     register unsigned int len;
+hash (register const char *str, register size_t len)
 {
   static const unsigned char asso_values[] =
     {
@@ -132,7 +130,7 @@ hash (str, len)
       228, 228, 228, 228, 228, 228, 228, 228, 228, 228,
       228, 228, 228, 228, 228, 228
     };
-  register int hval = len;
+  register unsigned int hval = len;
 
   switch (hval)
     {
@@ -146,16 +144,8 @@ hash (str, len)
   return hval + asso_values[(unsigned char)str[len - 1]];
 }
 
-#ifdef __GNUC__
-__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
-__attribute__ ((__gnu_inline__))
-#endif
-#endif
 const ElementType *
-lookup_element (str, len)
-     register const char *str;
-     register unsigned int len;
+lookup_element (register const char *str, register size_t len)
 {
   static const ElementType wordlist[] =
     {
@@ -178,14 +168,14 @@ lookup_element (str, len)
       {"textarea",	1, 0, 0, 1, 1, 1, 0, 0, {INLINE_PARENT, "a", "label", NULL}},
       {""},
 #line 61 "dtd.hash"
-      {"%data",	1, 0, 0, 1, 0, 0, 0, 0, {"p", NULL}},
+      {"%data",	1, 0, 0, 1, 0, 0, 0, 0, {INLINE_PARENT, NULL}},
       {""},
 #line 84 "dtd.hash"
       {"dd",		1, 0, 0, 1, 0, 0, 1, 1, {"dl", NULL}},
 #line 85 "dtd.hash"
       {"del",		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, BLOCK_PARENT, "a", "button", "noscript", "form", "label", "option", "textarea", NULL}},
 #line 120 "dtd.hash"
-      {"meta",		0, 1, 0, 1, 0, 0, 1, 0, {INLINE_PARENT, "head", "a", "button", "noscript", "label", NULL}},
+      {"meta",		0, 1, 0, 1, 0, 0, 1, 0, {"head", INLINE_PARENT, "a", "button", "noscript", "label", NULL}},
 #line 92 "dtd.hash"
       {"embed",		0, 1, 0, 1, 0, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}},
 #line 115 "dtd.hash"
@@ -323,7 +313,7 @@ lookup_element (str, len)
       {"fieldset",	1, 0, 0, 1, 1, 0, 1, 1, {BLOCK_PARENT, FLOW, "form", NULL}},
       {""}, {""},
 #line 132 "dtd.hash"
-      {"script",		1, 0, 1, 1, 1, 1, 1, 0, {"body", INLINE_PARENT, "blockquote", "head", "map", "a", "button", "noscript", "form", "label", NULL}},
+      {"script",		1, 0, 1, 1, 1, 1, 1, 0, {"head", "body", INLINE_PARENT, "blockquote", "map", "a", "button", "noscript", "form", "label", NULL}},
 #line 79 "dtd.hash"
       {"caption",	1, 0, 0, 1, 1, 0, 1, 1, {"table", NULL}},
 #line 87 "dtd.hash"
@@ -355,14 +345,14 @@ lookup_element (str, len)
 #line 121 "dtd.hash"
       {"nav",		1, 0, 0, 1, 1, 0, 1, 1, {BLOCK_PARENT, FLOW, "button", "noscript", "form", NULL}},
 #line 76 "dtd.hash"
-      {"body",		0, 0, 0, 0, 0, 0, 1, 1, {"html", NULL}},
+      {"body",		1, 0, 0, 0, 0, 0, 1, 1, {"html", NULL}},
 #line 94 "dtd.hash"
       {"figcaption",	1, 0, 0, 1, 1, 0, 1, 1, {"figure", NULL}},
       {""},
 #line 141 "dtd.hash"
-      {"summary",	1, 0, 0, 1, 1, 0, 0, 0, {"details", NULL}},
+      {"summary",	1, 0, 0, 1, 1, 0, 1, 1, {"details", NULL}},
 #line 157 "dtd.hash"
-      {"wbr",		0, 1, 0, 1, 0, 0, 0, 1, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}},
+      {"wbr",		0, 1, 0, 1, 0, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}},
       {""}, {""}, {""}, {""},
 #line 83 "dtd.hash"
       {"colgroup",	0, 0, 0, 1, 1, 0, 1, 1, {"table", NULL}},
@@ -403,9 +393,9 @@ lookup_element (str, len)
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
     {
-      register int key = hash (str, len);
+      register unsigned int key = hash (str, len);
 
-      if (key <= MAX_HASH_VALUE && key >= 0)
+      if (key <= MAX_HASH_VALUE)
         {
           register const char *s = wordlist[key].name;
 
diff --git a/dtd.hash b/dtd.hash
index 9659e55..221d415 100644
--- a/dtd.hash
+++ b/dtd.hash
@@ -48,7 +48,7 @@ EXPORT const ElementType * lookup_element(/* register const char *str,
 
 /* Different kinds of parent elements: */
 #define PHRASE "abbr", "acronym", "b", "bdi", "bdo", "big", "cite", "code", "dfn", "em", "i", "kbd", "q", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "tt", "u", "var"
-#define BRIDGE "p", "address", "caption", "dt", "h1", "h2", "h3", "h4", "h5", "h6", "legend", "pre"
+#define BRIDGE "body", "p", "address", "caption", "dt", "h1", "h2", "h3", "h4", "h5", "h6", "legend", "pre"
 #define FLOW "article", "aside", "dd", "del", "details", "div", "fieldset", "figcaption", "figure", "footer", "header", "ins", "li", "nav", "section", "main", "object", "td", "th"
 #define INLINE_PARENT BRIDGE, PHRASE, FLOW
 #define BLOCK_PARENT "body", "blockquote", "map", "main"
@@ -58,7 +58,7 @@ ElementType {}
 %%
 # name     mixed empty cdata stag etag pre b a parents
 # ----     ----- ----- ----- ---- ---- --- - - -------
-"%data",	1, 0, 0, 1, 0, 0, 0, 0, {"p", NULL}
+"%data",	1, 0, 0, 1, 0, 0, 0, 0, {INLINE_PARENT, NULL}
 a,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "label", NULL}
 abbr,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 acronym,	1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
@@ -73,7 +73,7 @@ bdi,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label"
 bdo,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 big,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 blockquote,	0, 0, 0, 1, 1, 0, 1, 1, {BLOCK_PARENT, FLOW, "button", "noscript", "form", NULL}
-body,		0, 0, 0, 0, 0, 0, 1, 1, {"html", NULL}
+body,		1, 0, 0, 0, 0, 0, 1, 1, {"html", NULL}
 br,		0, 1, 0, 1, 0, 0, 0, 1, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 button,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "label", NULL}
 caption,	1, 0, 0, 1, 1, 0, 1, 1, {"table", NULL}
@@ -117,7 +117,7 @@ li,		1, 0, 0, 1, 0, 0, 1, 1, {"ul", "ol", NULL}
 link,		0, 1, 0, 1, 0, 0, 1, 0, {"head", NULL}
 main,		1, 0, 0, 1, 1, 0, 1, 1, {"body", "div", "noscript", NULL}
 map,		0, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
-meta,		0, 1, 0, 1, 0, 0, 1, 0, {INLINE_PARENT, "head", "a", "button", "noscript", "label", NULL}
+meta,		0, 1, 0, 1, 0, 0, 1, 0, {"head", INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 nav,		1, 0, 0, 1, 1, 0, 1, 1, {BLOCK_PARENT, FLOW, "button", "noscript", "form", NULL}
 noscript,	1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, BLOCK_PARENT, "a", "button", "noscript", "form", "label", "option", "textarea",  NULL}
 object,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "del", "header", "aside", "section", "main", "article", "nav", "fieldset", "head", "ins", "label", "object", NULL}
@@ -129,7 +129,7 @@ param,		0, 1, 0, 1, 0, 0, 1, 1, {"object", NULL}
 pre,		1, 0, 0, 1, 1, 1, 1, 1, {BLOCK_PARENT, FLOW, "button", "noscript", "form", NULL}
 q,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 samp,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
-script,		1, 0, 1, 1, 1, 1, 1, 0, {"body", INLINE_PARENT, "blockquote", "head", "map", "a", "button", "noscript", "form", "label", NULL}
+script,		1, 0, 1, 1, 1, 1, 1, 0, {"head", "body", INLINE_PARENT, "blockquote", "map", "a", "button", "noscript", "form", "label", NULL}
 section,	1, 0, 0, 1, 1, 0, 1, 1, {BLOCK_PARENT, FLOW, "button", "noscript", "form", NULL}
 select,		0, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "label", NULL}
 small,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
@@ -138,7 +138,7 @@ span,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label
 strong,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 style,		1, 0, 1, 1, 1, 1, 1, 0, {"head", NULL}
 sub,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
-summary,	1, 0, 0, 1, 1, 0, 0, 0, {"details", NULL}
+summary,	1, 0, 0, 1, 1, 0, 1, 1, {"details", NULL}
 sup,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 table,		0, 0, 0, 1, 1, 0, 1, 1, {BLOCK_PARENT, FLOW, "button", "noscript", "form", NULL}
 tbody,		0, 0, 0, 0, 0, 0, 1, 1, {"table", NULL}
@@ -154,5 +154,5 @@ tt,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label",
 ul,		0, 0, 0, 1, 1, 0, 1, 1, {BLOCK_PARENT, FLOW, "button", "noscript", "form", NULL}
 var,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 video,		1, 0, 0, 1, 1, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
-wbr,		0, 1, 0, 1, 0, 0, 0, 1, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
+wbr,		0, 1, 0, 1, 0, 0, 0, 0, {INLINE_PARENT, "a", "button", "noscript", "label", NULL}
 %%
diff --git a/errexit.c b/errexit.c
deleted file mode 100644
index 26957ec..0000000
--- a/errexit.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* errexit.c -- print message and exit
- *
- * Part of HTML-XML-utils, see:
- * http://www.w3.org/Tools/HTML-XML-utils/
- *
- * Copyright © 1994-2000 World Wide Web Consortium
- * See http://www.w3.org/Consortium/Legal/copyright-software
- *
- * Author: Bert Bos <bert@w3.org>
- * Created: 12 May 1998
- **/
-#include "config.h"
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_STRING_H
-#  include <string.h>
-#elif HAVE_STRINGS_H
-#  include <strings.h>
-#endif
-#include "export.h"
-
-/* errexit -- print message and exit */
-EXPORT int errexit(char *format,...)
-{
-  va_list ap;
-
-  va_start(ap, format);
-  vfprintf(stderr, format, ap);
-  va_end(ap);
-  exit(1);
-}
-
-
diff --git a/errexit.e b/errexit.e
deleted file mode 100644
index b864488..0000000
--- a/errexit.e
+++ /dev/null
@@ -1 +0,0 @@
-extern int errexit(char *format,...);
diff --git a/fopencookie.c b/fopencookie.c
index 3860343..1d4c375 100644
--- a/fopencookie.c
+++ b/fopencookie.c
@@ -22,7 +22,8 @@
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
-#include "errexit.e"
+#include <err.h>
+#include <sysexits.h>
 #include "fopencookie.h"
 
 typedef struct {
@@ -86,7 +87,8 @@ FILE *fopencookie(void *cookie, const char *mode,
   if ((mask & 2) && !funcs.write) {errno = EINVAL; return NULL;}
   if ((mask & 4) && !funcs.seek) {errno = EINVAL; return NULL;}
 
-  if (mask == 7) errexit("Bug: fopencookie() can't yet handle mode \"a+\"\n");
+  if (mask == 7)
+    errx(EX_SOFTWARE, "Bug: fopencookie() can't yet handle mode \"a+\"");
 
   /* Open the "file" */
   if (!(s = malloc(sizeof(*s)))) {errno = ENOMEM; return NULL;}
diff --git a/genid.c b/genid.c
index caa5201..523b369 100644
--- a/genid.c
+++ b/genid.c
@@ -18,6 +18,8 @@
 #ifdef HAVE_ERRNO_H
 #  include <errno.h>
 #endif
+#include <err.h>
+#include <sysexits.h>
 #include <ctype.h>
 
 #ifdef HAVE_SEARCH_H
@@ -41,7 +43,6 @@
 #include "heap.e"
 #include "types.e"
 #include "tree.e"
-#include "errexit.e"
 
 
 #define MAXIDLEN 45				/* Max len of a generated ID */
@@ -102,7 +103,7 @@ EXPORT string gen_id(Tree t)
   string s;
   int len = 0;
 
-  if (! (s = malloc(MAXIDLEN + 1))) errexit("Out of memory\n");
+  if (! (s = malloc(MAXIDLEN + 1))) err(EX_OSERR, NULL);
 
   assert(MAXIDLEN > 4);
   gen_id_r(t, s, &len, MAXIDLEN - 4);
diff --git a/html.c b/html.c
old mode 100755
new mode 100644
index 4f4b00f..945ed5e
--- a/html.c
+++ b/html.c
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.2.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison implementation for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    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
@@ -40,11 +41,14 @@
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 /* Identify Bison output.  */
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.2"
+#define YYBISON_VERSION "3.3.2"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -61,8 +65,8 @@
 
 
 
-/* Copy the first part of user declarations.  */
-#line 1 "html.y" /* yacc.c:339  */
+/* First part of user prologue.  */
+#line 1 "html.y" /* yacc.c:337  */
 
 /*
  * Simple XML grammar, with call-back functions.
@@ -164,13 +168,16 @@ static void yyerror(const string s)
 /* call -- if the function exists, call it with the given aguments */
 #define call(fn, args) do {if (fn) (fn)args;} while (0)
 
-#line 168 "html.c" /* yacc.c:339  */
-
+#line 172 "html.c" /* yacc.c:337  */
 # ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
 #  else
-#   define YY_NULLPTR 0
+#   define YY_NULLPTR ((void*)0)
 #  endif
 # endif
 
@@ -225,16 +232,18 @@ extern int yydebug;
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
+
 union YYSTYPE
 {
-#line 103 "html.y" /* yacc.c:355  */
+#line 103 "html.y" /* yacc.c:352  */
 
     string s;
     pairlist p;
 
-#line 237 "html.c" /* yacc.c:355  */
+#line 244 "html.c" /* yacc.c:352  */
 };
+
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
@@ -246,9 +255,7 @@ int yyparse (void);
 
 #endif /* !YY_YY_HTML_H_INCLUDED  */
 
-/* Copy the second part of user declarations.  */
 
-#line 252 "html.c" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -269,13 +276,13 @@ typedef signed char yytype_int8;
 #ifdef YYTYPE_UINT16
 typedef YYTYPE_UINT16 yytype_uint16;
 #else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
 #endif
 
 #ifdef YYTYPE_INT16
 typedef YYTYPE_INT16 yytype_int16;
 #else
-typedef short int yytype_int16;
+typedef short yytype_int16;
 #endif
 
 #ifndef YYSIZE_T
@@ -287,7 +294,7 @@ typedef short int yytype_int16;
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
-#  define YYSIZE_T unsigned int
+#  define YYSIZE_T unsigned
 # endif
 #endif
 
@@ -323,15 +330,6 @@ typedef short int yytype_int16;
 # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
 #endif
 
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
 # define YYUSE(E) ((void) (E))
@@ -339,7 +337,7 @@ typedef short int yytype_int16;
 # define YYUSE(E) /* empty */
 #endif
 
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
     _Pragma ("GCC diagnostic push") \
@@ -501,16 +499,16 @@ union yyalloc
 /* YYNSTATES -- Number of states.  */
 #define YYNSTATES  33
 
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   267
 
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
 #define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+  ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
+   as returned by yylex.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -673,22 +671,22 @@ static const yytype_uint8 yyr2[] =
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
 
 /* Error token number */
 #define YYTERROR        1
@@ -728,37 +726,37 @@ do {                                                                      \
 } while (0)
 
 
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
 
 static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep)
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
+  FILE *yyoutput = yyo;
+  YYUSE (yyoutput);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
 # endif
   YYUSE (yytype);
 }
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
 
 static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep)
 {
-  YYFPRINTF (yyoutput, "%s %s (",
+  YYFPRINTF (yyo, "%s %s (",
              yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
-  YYFPRINTF (yyoutput, ")");
+  yy_symbol_value_print (yyo, yytype, yyvaluep);
+  YYFPRINTF (yyo, ")");
 }
 
 /*------------------------------------------------------------------.
@@ -792,7 +790,7 @@ do {                                                            \
 static void
 yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
 {
-  unsigned long int yylno = yyrline[yyrule];
+  unsigned long yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -803,7 +801,7 @@ yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr,
                        yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                       &yyvsp[(yyi + 1) - (yynrhs)]
                                               );
       YYFPRINTF (stderr, "\n");
     }
@@ -907,7 +905,10 @@ yytnamerr (char *yyres, const char *yystr)
           case '\\':
             if (*++yyp != '\\')
               goto do_not_strip_quotes;
-            /* Fall through.  */
+            else
+              goto append;
+
+          append:
           default:
             if (yyres)
               yyres[yyn] = *yyp;
@@ -925,7 +926,7 @@ yytnamerr (char *yyres, const char *yystr)
   if (! yyres)
     return yystrlen (yystr);
 
-  return yystpcpy (yyres, yystr) - yyres;
+  return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
 }
 # endif
 
@@ -1003,10 +1004,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
                 yyarg[yycount++] = yytname[yyx];
                 {
                   YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+                    yysize = yysize1;
+                  else
                     return 2;
-                  yysize = yysize1;
                 }
               }
         }
@@ -1018,6 +1019,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
       case N:                               \
         yyformat = S;                       \
       break
+    default: /* Avoid compiler warnings. */
       YYCASE_(0, YY_("syntax error"));
       YYCASE_(1, YY_("syntax error, unexpected %s"));
       YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -1029,9 +1031,10 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
 
   {
     YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+      yysize = yysize1;
+    else
       return 2;
-    yysize = yysize1;
   }
 
   if (*yymsg_alloc < yysize)
@@ -1157,23 +1160,31 @@ yyparse (void)
   yychar = YYEMPTY; /* Cause a token to be read.  */
   goto yysetstate;
 
+
 /*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
+| yynewstate -- push a new state, which is found in yystate.  |
 `------------------------------------------------------------*/
- yynewstate:
+yynewstate:
   /* In all cases, when you get here, the value and location stacks
      have just been pushed.  So pushing a state here evens the stacks.  */
   yyssp++;
 
- yysetstate:
-  *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  *yyssp = (yytype_int16) yystate;
 
   if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
     {
       /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
+      YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
 
-#ifdef yyoverflow
+# if defined yyoverflow
       {
         /* Give user a chance to reallocate the stack.  Use copies of
            these so that the &'s don't force the real ones into
@@ -1189,14 +1200,10 @@ yyparse (void)
                     &yyss1, yysize * sizeof (*yyssp),
                     &yyvs1, yysize * sizeof (*yyvsp),
                     &yystacksize);
-
         yyss = yyss1;
         yyvs = yyvs1;
       }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
         goto yyexhaustedlab;
@@ -1212,22 +1219,22 @@ yyparse (void)
           goto yyexhaustedlab;
         YYSTACK_RELOCATE (yyss_alloc, yyss);
         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
         if (yyss1 != yyssa)
           YYSTACK_FREE (yyss1);
       }
 # endif
-#endif /* no yyoverflow */
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
+                  (unsigned long) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
         YYABORT;
     }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
@@ -1236,11 +1243,11 @@ yyparse (void)
 
   goto yybackup;
 
+
 /*-----------.
 | yybackup.  |
 `-----------*/
 yybackup:
-
   /* Do appropriate processing given the current state.  Read a
      lookahead token if we need one and don't already have one.  */
 
@@ -1313,7 +1320,7 @@ yydefault:
 
 
 /*-----------------------------.
-| yyreduce -- Do a reduction.  |
+| yyreduce -- do a reduction.  |
 `-----------------------------*/
 yyreduce:
   /* yyn is the number of a rule to reduce with.  */
@@ -1334,118 +1341,118 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 116 "html.y" /* yacc.c:1646  */
+#line 116 "html.y" /* yacc.c:1652  */
     {data = h.start ? h.start() : NULL;}
-#line 1340 "html.c" /* yacc.c:1646  */
+#line 1347 "html.c" /* yacc.c:1652  */
     break;
 
   case 3:
-#line 117 "html.y" /* yacc.c:1646  */
+#line 117 "html.y" /* yacc.c:1652  */
     {call(h.end, (data));}
-#line 1346 "html.c" /* yacc.c:1646  */
+#line 1353 "html.c" /* yacc.c:1652  */
     break;
 
   case 4:
-#line 120 "html.y" /* yacc.c:1646  */
+#line 120 "html.y" /* yacc.c:1652  */
     {call(h.comment, (data, (yyvsp[0].s)));}
-#line 1352 "html.c" /* yacc.c:1646  */
+#line 1359 "html.c" /* yacc.c:1652  */
     break;
 
   case 5:
-#line 121 "html.y" /* yacc.c:1646  */
+#line 121 "html.y" /* yacc.c:1652  */
     {call(h.text, (data, (yyvsp[0].s)));}
-#line 1358 "html.c" /* yacc.c:1646  */
+#line 1365 "html.c" /* yacc.c:1652  */
     break;
 
   case 9:
-#line 125 "html.y" /* yacc.c:1646  */
+#line 125 "html.y" /* yacc.c:1652  */
     {call(h.pi, (data, (yyvsp[0].s)));}
-#line 1364 "html.c" /* yacc.c:1646  */
+#line 1371 "html.c" /* yacc.c:1652  */
     break;
 
   case 10:
-#line 126 "html.y" /* yacc.c:1646  */
+#line 126 "html.y" /* yacc.c:1652  */
     {call(h.endincl, (data));}
-#line 1370 "html.c" /* yacc.c:1646  */
+#line 1377 "html.c" /* yacc.c:1652  */
     break;
 
   case 13:
-#line 131 "html.y" /* yacc.c:1646  */
+#line 131 "html.y" /* yacc.c:1652  */
     {call(h.starttag, (data, (yyvsp[-2].s), (yyvsp[-1].p)));}
-#line 1376 "html.c" /* yacc.c:1646  */
+#line 1383 "html.c" /* yacc.c:1652  */
     break;
 
   case 14:
-#line 132 "html.y" /* yacc.c:1646  */
+#line 132 "html.y" /* yacc.c:1652  */
     {call(h.emptytag, (data, (yyvsp[-2].s), (yyvsp[-1].p)));}
-#line 1382 "html.c" /* yacc.c:1646  */
+#line 1389 "html.c" /* yacc.c:1652  */
     break;
 
   case 15:
-#line 135 "html.y" /* yacc.c:1646  */
+#line 135 "html.y" /* yacc.c:1652  */
     {(yyval.p) = (yyvsp[-1].p); (yyval.p)->next = (yyvsp[0].p);}
-#line 1388 "html.c" /* yacc.c:1646  */
+#line 1395 "html.c" /* yacc.c:1652  */
     break;
 
   case 16:
-#line 136 "html.y" /* yacc.c:1646  */
+#line 136 "html.y" /* yacc.c:1652  */
     {(yyval.p) = NULL;}
-#line 1394 "html.c" /* yacc.c:1646  */
+#line 1401 "html.c" /* yacc.c:1652  */
     break;
 
   case 17:
-#line 139 "html.y" /* yacc.c:1646  */
+#line 139 "html.y" /* yacc.c:1652  */
     {pairlist h = malloc(sizeof(*h));
 					 assert(h != NULL); h->name = (yyvsp[0].s);
 					 h->value=NULL; (yyval.p) = h;}
-#line 1402 "html.c" /* yacc.c:1646  */
+#line 1409 "html.c" /* yacc.c:1652  */
     break;
 
   case 18:
-#line 142 "html.y" /* yacc.c:1646  */
+#line 142 "html.y" /* yacc.c:1652  */
     {pairlist h = malloc(sizeof(*h));
 					 assert(h != NULL); h->name = (yyvsp[-2].s);
 					 h->value = (yyvsp[0].s); (yyval.p) = h;}
-#line 1410 "html.c" /* yacc.c:1646  */
+#line 1417 "html.c" /* yacc.c:1652  */
     break;
 
   case 19:
-#line 145 "html.y" /* yacc.c:1646  */
+#line 145 "html.y" /* yacc.c:1652  */
     {pairlist h = malloc(sizeof(*h));
 					 assert(h != NULL); h->name = (yyvsp[-2].s);
 					 h->value = (yyvsp[0].s); (yyval.p) = h;}
-#line 1418 "html.c" /* yacc.c:1646  */
+#line 1425 "html.c" /* yacc.c:1652  */
     break;
 
   case 20:
-#line 150 "html.y" /* yacc.c:1646  */
+#line 150 "html.y" /* yacc.c:1652  */
     {call(h.endtag, (data, (yyvsp[-1].s)));}
-#line 1424 "html.c" /* yacc.c:1646  */
+#line 1431 "html.c" /* yacc.c:1652  */
     break;
 
   case 21:
-#line 153 "html.y" /* yacc.c:1646  */
+#line 153 "html.y" /* yacc.c:1652  */
     {call(h.decl, (data, (yyvsp[-4].s), (yyvsp[-2].s), (yyvsp[-1].s)));}
-#line 1430 "html.c" /* yacc.c:1646  */
+#line 1437 "html.c" /* yacc.c:1652  */
     break;
 
   case 22:
-#line 154 "html.y" /* yacc.c:1646  */
+#line 154 "html.y" /* yacc.c:1652  */
     {if (strcasecmp((yyvsp[-2].s), "public") == 0)
 				     	   call(h.decl, (data, (yyvsp[-3].s), (yyvsp[-1].s), NULL));
 					 else /* "system" */
 					   call(h.decl, (data, (yyvsp[-3].s), NULL, (yyvsp[-1].s)));}
-#line 1439 "html.c" /* yacc.c:1646  */
+#line 1446 "html.c" /* yacc.c:1652  */
     break;
 
   case 23:
-#line 158 "html.y" /* yacc.c:1646  */
+#line 158 "html.y" /* yacc.c:1652  */
     {call(h.decl, (data, (yyvsp[-1].s), NULL, NULL));}
-#line 1445 "html.c" /* yacc.c:1646  */
+#line 1452 "html.c" /* yacc.c:1652  */
     break;
 
 
-#line 1449 "html.c" /* yacc.c:1646  */
+#line 1456 "html.c" /* yacc.c:1652  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1470,14 +1477,13 @@ yyreduce:
   /* Now 'shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
 
   goto yynewstate;
 
@@ -1560,12 +1566,10 @@ yyerrlab:
 | yyerrorlab -- error raised explicitly by YYERROR.  |
 `---------------------------------------------------*/
 yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
 
   /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
@@ -1627,6 +1631,7 @@ yyacceptlab:
   yyresult = 0;
   goto yyreturn;
 
+
 /*-----------------------------------.
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
@@ -1634,6 +1639,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
+
 #if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
@@ -1644,6 +1650,10 @@ yyexhaustedlab:
   /* Fall through.  */
 #endif
 
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result.  |
+`-----------------------------------------------------*/
 yyreturn:
   if (yychar != YYEMPTY)
     {
diff --git a/html.e b/html.e
old mode 100755
new mode 100644
diff --git a/html.h b/html.h
index f7519f5..12eaae4 100644
--- a/html.h
+++ b/html.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.2.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    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
@@ -30,6 +31,9 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 #ifndef YY_YY_HTML_H_INCLUDED
 # define YY_YY_HTML_H_INCLUDED
 /* Debug traces.  */
@@ -71,16 +75,18 @@ extern int yydebug;
 
 /* Value type.  */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
+
 union YYSTYPE
 {
-#line 103 "html.y" /* yacc.c:1909  */
+#line 103 "html.y" /* yacc.c:1921  */
 
     string s;
     pairlist p;
 
-#line 83 "html.h" /* yacc.c:1909  */
+#line 87 "html.h" /* yacc.c:1921  */
 };
+
+typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
 #endif
diff --git a/hxaddid.c b/hxaddid.c
index 2d825ea..c0d15c4 100644
--- a/hxaddid.c
+++ b/hxaddid.c
@@ -6,7 +6,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 20 Aug 2000
- * Version: $Id: hxaddid.c,v 1.8 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxaddid.c,v 1.9 2023/01/23 21:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -15,6 +15,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #if STDC_HEADERS
 # include <string.h>
@@ -39,7 +41,6 @@
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 #include "genid.e"
 #include "class.e"
 
@@ -169,8 +170,9 @@ static void expand(Tree t)
 /* usage -- print usage message and exit */
 static void usage(string name)
 {
-  errexit("Usage: %s [-x] [-v] [--] elem|.class|elem.class [html-file]\n",
-	  name);
+  fprintf(stderr,
+    "Usage: %s [-x] [-v] [--] elem|.class|elem.class [html-file]\n", name);
+  exit(EX_USAGE);
 }
 
 
@@ -217,8 +219,8 @@ int main(int argc, char *argv[])
   else if (i == argc - 1) yyin = fopenurl(argv[i], "r", &status);
   else usage(argv[0]);
 
-  if (yyin == NULL) {perror(argv[i]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[i], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[i]);
+  if (status != 200) errx(EX_IOERR, "%s: %s", argv[i], http_strerror(status));
 
   if (yyparse() != 0) exit(3);
 
diff --git a/hxcite.c b/hxcite.c
index f93ba6f..d1bf726 100644
--- a/hxcite.c
+++ b/hxcite.c
@@ -66,7 +66,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 18 March 2000
- * Version: $Id: hxcite.c,v 1.11 2018/02/15 19:02:36 bbos Exp $
+ * Version: $Id: hxcite.c,v 1.12 2023/01/23 21:19:41 bbos Exp $
  **/
 
 #include "config.h"
@@ -77,6 +77,8 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <stdio.h>
+#include <err.h>
+#include <sysexits.h>
 #if STDC_HEADERS
 # include <string.h>
 #else
@@ -100,7 +102,6 @@
 #include "export.h"
 #include "heap.e"
 #include "types.e"
-#include "errexit.e"
 
 
 /* Warning: arbitrary limits! */
@@ -245,12 +246,12 @@ static void store_labels_and_keywords(const string label, const string keys)
   if (!label1) return;				/* Empty label */
   entry.key = newstring(label1);
   entry.data = newstring(label1);
-  if (!hsearch(entry, ENTER)) errexit("%s: %s\n", prog, strerror(errno));
+  if (!hsearch(entry, ENTER)) err(EX_OSERR, NULL);
   if (keys) {
     for (h = strtok_r(keys, WS, &b); h; h = strtok_r(NULL, WS, &b)) {
       entry.key = newstring(h);
       entry.data = newstring(label1);
-      if (!hsearch(entry, ENTER)) errexit("%s: %s\n", prog, strerror(errno));
+      if (!hsearch(entry, ENTER)) err(EX_OSERR, NULL);
     }
   }
 }
@@ -264,10 +265,10 @@ static void parse_db(const string db)
   int e;
   string label = NULL, keywords = NULL;
 
-  if (!(f = fopen(db,"r"))) errexit("%s: %s: %s\n", prog, db, strerror(errno));
+  if (!(f = fopen(db,"r"))) err(EX_IOERR, "%s", db);
 
   /* Initialize the hash table */
-  if (! hcreate(HASHSIZE)) errexit("%s: %s\n", prog, strerror(errno));
+  if (! hcreate(HASHSIZE)) err(EX_OSERR, NULL);
 
   /* Search for %L lines */
   clearerr(f);
@@ -284,17 +285,19 @@ static void parse_db(const string db)
   }
   if (label) store_labels_and_keywords(label, keywords);
 
-  if ((e = ferror(f))) errexit("%s: %s: %s\n", prog, db, strerror(e));
+  if ((e = ferror(f))) errx(EX_IOERR, "%s: %s", db, strerror(e));
 
-  if (fclose(f) != 0) errexit("%s: %s: %s\n", prog, db, strerror(errno));
+  if (fclose(f) != 0) err(EX_IOERR, "%s", db);
 }
 
 
 /* usage -- print usage message and exit */
 static void usage(void)
 {
-  errexit("Usage: %s [-b base] [-p pattern] [-a auxfile] [-c] [-v] bib-file [HTML-file]\n",
+  fprintf(stderr,
+    "Usage: %s [-b base] [-p pattern] [-a auxfile] [-c] [-v] bib-file [HTML-file]\n",
 	  prog);
+  exit(EX_USAGE);
 }
 
 
@@ -339,18 +342,18 @@ int main(int argc, char *argv[])
     }
   }
   if (! (aux = fopen(auxfile, "w")))
-    errexit("%s: %s: %s\n", prog, auxfile, strerror(errno));
+    err(EX_IOERR, "%s", auxfile);
 
   /* Open input file or use stdin */
   f = infile ? fopen(infile, "r") : stdin;
-  if (!f) errexit("%s: %s: %s\n", prog, infile, strerror(errno));
+  if (!f) err(EX_IOERR, "%s", infile);
 
   /* Read input line by line */
   clearerr(f);
   lineno = 1;
   while (fgets(line, sizeof(line), f))
     process_line(line, infile, lineno++, &in_comment);
-  if ((e = ferror(f))) errexit("%s: %s\n", prog, strerror(e));
+  if ((e = ferror(f))) errx(EX_IOERR, "%s", strerror(e));
 
   fclose(aux);
   fclose(f);
diff --git a/hxclean.c b/hxclean.c
index 2826a65..a1ed44a 100644
--- a/hxclean.c
+++ b/hxclean.c
@@ -7,11 +7,13 @@
  *
  * 16 September 1997
  * Bert Bos
- * $Id: hxclean.c,v 1.4 2017/11/24 09:50:25 bbos Exp $
+ * $Id: hxclean.c,v 1.5 2023/01/23 21:19:41 bbos Exp $
  */
 #include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <err.h>
+#include <sysexits.h>
 #include "export.h"
 #include "types.e"
 #include "tree.e"
@@ -101,10 +103,7 @@ int main(int argc, char *argv[])
     yyin = stdin;
   } else if (argc == 2) {
     yyin = fopen(argv[1], "r");
-    if (yyin == NULL) {
-      perror(argv[1]);
-      exit(2);
-    }
+    if (yyin == NULL) err(EX_IOERR, "%s", argv[1]);
   } else {
     fprintf(stderr, "Version %s\n", VERSION);
     fprintf(stderr, "Usage: %s [html-file]\n", argv[0]);
diff --git a/hxcopy.c b/hxcopy.c
index 991860d..d450f32 100644
--- a/hxcopy.c
+++ b/hxcopy.c
@@ -26,7 +26,10 @@
 #include <assert.h>
 #include <unistd.h>
 #include <errno.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
+#include <ctype.h>
 #if HAVE_STRING_H
 #  include <string.h>
 #endif
@@ -41,7 +44,6 @@
 #include "url.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 
 #define same(a, b) ((a) ? ((b) && eq((a), (b))) : !(b))
 
@@ -89,12 +91,19 @@ static string path_from_url_to_url(const conststring a, const conststring b)
 
 
 /* adjust_url -- return a new URL relative to newurl instead of oldurl */
-static conststring adjust_url(const conststring url)
+static conststring adjust_url(const string url)
 {
-  if (!replace_self && (!url || !url[0] || url[0] == '#' || url[0] == '?'))
-    return url;			/* Don't replace references to self */
+  string u = url;
+  int i;
+
+  if (u) while (isspace(*u)) u++;
+  if (u) if (!(u = strdup(u))) err(EX_OSERR, NULL);
+  if (u) for (i = strlen(u) - 1; i >= 0 && isspace(u[i]); i--) u[i] = '\0';
+
+  if (!replace_self && (!u || !u[0] || u[0] == '#' || u[0] == '?'))
+    return u;			/* Don't replace references to self */
   else
-    return URL_s_absolutize(newbase, url);
+    return URL_s_absolutize(newbase, u);
 }
 
 
@@ -259,17 +268,17 @@ int main(int argc, char *argv[])
   if (argc > optind + 2) usage(argv[0]);
   if (argc > optind + 1) out =  fopenurl(argv[optind+1], "w", NULL);
   else if (newurl) out = stdout;
-  else errexit("%s: option -o is required if output is to stdout\n", argv[0]);
-  if (!out) {perror(argv[optind+1]); exit(3);}
+  else errx(EX_USAGE, "option -o is required if output is to stdout");
+  if (!out) err(EX_IOERR, "%s", argv[optind+1]);
   if (argc > optind) yyin = fopenurl(argv[optind], "r", &status);
   else if (oldurl) yyin = stdin;
-  else errexit("%s: option -i is required if input is from stdin\n", argv[0]);
-  if (!yyin) {perror(argv[optind]); exit(2);}
-  if (status != 200) errexit("%s : %s\n", argv[1], http_strerror(status));
+  else errx(EX_USAGE, " option -i is required if input is from stdin");
+  if (!yyin) err(EX_IOERR, "%s", argv[optind]);
+  if (status != 200) errx(EX_IOERR, "%s: %s", argv[1], http_strerror(status));
   if (!oldurl) oldurl = argv[optind];
   if (!newurl) newurl = argv[optind+1];
   newbase = path_from_url_to_url(newurl, oldurl);
-  if (!newbase) errexit("%s: could not parse argument as a URL\n", argv[0]);
+  if (!newbase) errx(EX_USAGE, "%s: could not parse argument as a URL",argv[0]);
   if (yyparse() != 0) exit(4);
   return has_errors ? 1 : 0;
 }
diff --git a/hxcount.c b/hxcount.c
index bb1acc0..b0d3a96 100644
--- a/hxcount.c
+++ b/hxcount.c
@@ -10,7 +10,7 @@
  *
  * Bert Bos
  * Created Nov 1998
- * $Id: hxcount.c,v 1.5 2017/11/24 09:50:25 bbos Exp $
+ * $Id: hxcount.c,v 1.6 2023/01/23 21:19:41 bbos Exp $
  */
 #include "config.h"
 #include <stdio.h>
@@ -31,6 +31,8 @@
 #endif
 #include <stdlib.h>
 #include <assert.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
@@ -38,7 +40,6 @@
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 
 typedef struct _pair {
   char *name;
@@ -153,8 +154,8 @@ int main(int argc, char *argv[])
   else if (argc == 2) yyin = fopenurl(argv[1], "r", &status);
   else usage(argv[0]);
 
-  if (yyin == NULL) {perror(argv[1]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[1], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[1]);
+  if (status != 200) errx(EX_IOERR, "%s: %s", argv[1], http_strerror(status));
 
   /* Parse input */
   if (yyparse() != 0) exit(3);
diff --git a/hxextract.c b/hxextract.c
index fde9ed4..aae7d03 100644
--- a/hxextract.c
+++ b/hxextract.c
@@ -7,7 +7,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 20 Aug 2000
- * Version: $Id: hxextract.c,v 1.7 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxextract.c,v 1.8 2023/01/23 21:19:41 bbos Exp $
  */
 #include "config.h"
 #include <assert.h>
@@ -15,6 +15,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #if STDC_HEADERS
 # include <string.h>
@@ -153,14 +155,14 @@ static void process_configfile(const string configfile)
   char line[MAXLINELEN], chapter[MAXLINELEN];
   FILE *f;
 
-  if (! (f = fopenurl(configfile, "r", NULL))) {perror(configfile); exit(2);}
+  if (! (f = fopenurl(configfile, "r", NULL))) err(EX_IOERR, "%s", configfile);
 
   /* ToDo: accept quoted file names with spaces in their name */
   while (fgets(line, sizeof(line), f)) {
     if (sscanf(line, " @chapter %s", chapter) == 1) {
       if (!base) base = chapter;
       yyin = fopenurl(chapter, "r", NULL);
-      if (yyin == NULL) {perror(chapter); exit(2);}
+      if (yyin == NULL) err(EX_IOERR, "%s", chapter);
       if (yyparse() != 0) exit(3);
       fclose(yyin);
       base = NULL;
@@ -220,7 +222,7 @@ int main(int argc, char *argv[])
     } else if (targetelement || targetclass) {	/* It's a file name or URL */
       if (!base) base = argv[i];
       yyin = fopenurl(argv[i], "r", NULL);
-      if (yyin == NULL) {perror(argv[i]); exit(2);}
+      if (yyin == NULL) err(EX_IOERR, "%s", argv[i]);
       if (yyparse() != 0) exit(3);
       fclose(yyin);
       base = NULL;
diff --git a/hxincl.c b/hxincl.c
index 645c778..9a0ee0e 100644
--- a/hxincl.c
+++ b/hxincl.c
@@ -19,7 +19,7 @@
  *
  * Author: Bert Bos
  * Created: 2 Dec 1998
- * Version: $Id: hxincl.c,v 1.14 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxincl.c,v 1.15 2023/01/23 21:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -42,10 +42,10 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
-#include "errexit.e"
 #include "html.e"
 #include "scan.e"
 #include "dict.e"
@@ -118,10 +118,11 @@ static void add_substitution(const string assignment)
 
   /* To do: handle file names containing '='. Add escapes? */
   if (!substitutions) substitutions = dict_create(10);
-  if (!substitutions) errexit("Out of memory.\n");
-  if (!(s = strchr(assignment, '='))) errexit("No '=' found in option -s\n");
+  if (!substitutions) err(EX_OSERR, NULL);
+  if (!(s = strchr(assignment, '=')))
+    errx(EX_USAGE, "No '=' found in option -s");
   *s = '\0';
-  if (!dict_add(substitutions, assignment, s + 1)) errexit("Out of memory?\n");
+  if (!dict_add(substitutions, assignment, s + 1)) err(EX_OSERR, NULL);
   *s = '=';
 }
 
@@ -242,10 +243,10 @@ void handle_comment(void *clientdata, string commenttext)
     s = URL_s_absolutize(get_yyin_name(), url);
     if (target) printf(" \\\n %s", s); /* To do: escape spaces in s */
     if (!(f = fopenurl(s, "r", &status))) {
-      if (!target || warn_missing) perror(url);
+      if (!target || warn_missing) warn("%s", url);
     } else if (status != 200) {
       if (!target || warn_missing)
-	fprintf(stderr, "%s : %s\n", url, http_strerror(status));
+	warn("%s : %s\n", url, http_strerror(status));
     } else {
       if (!final && !target) printf("<!--%s %s-->", BEGIN, commenttext + i);
       push(&skipping, false);
@@ -387,8 +388,8 @@ int main(int argc, char *argv[])
     usage(argv[0]);
   }
 
-  if (yyin == NULL) {perror(argv[optind]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[optind], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[optind]);
+  if (status != 200) errx(EX_IOERR,"%s: %s",argv[optind],http_strerror(status));
 
   if (target) printf("%s:", target);
   if (yyparse() != 0) exit(3);
diff --git a/hxindex.c b/hxindex.c
index 53a81a0..b62c83f 100644
--- a/hxindex.c
+++ b/hxindex.c
@@ -39,7 +39,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 11 Apr 2000
- * Version: $Id: hxindex.c,v 1.24 2018/02/23 19:05:04 bbos Exp $
+ * Version: $Id: hxindex.c,v 1.25 2023/01/23 21:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -52,6 +52,7 @@
 #include <iconv.h>
 #include <unistd.h>
 #include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #if STDC_HEADERS
 # include <string.h>
@@ -298,16 +299,14 @@ static void parse_subterms(const Indexterm term, const conststring s)
 
     /* Then convert from UTF-8 to wchar_t */
     cd = iconv_open("wchar_t", "UTF-8");
-    if (cd == (iconv_t)(-1)) {perror("hxindex"); exit(1);}
+    if (cd == (iconv_t)(-1)) err(EX_OSERR, NULL);
     len = strlen(h) + 1;
     newarray(term->sortkeys[i], len); /* Large enough */
     p = (string) term->sortkeys[i];
     len2 = len * sizeof(term->sortkeys[i][0]);
-    if (iconv(cd, &h, &len, &p, &len2) == (size_t)(-1)) {
-      perror("hxindex"); exit(1);
-    }
+    if (iconv(cd, &h, &len, &p, &len2) == (size_t)(-1)) err(EX_OSERR, NULL);
     /* *p = L'\0'; */
-    if (iconv_close(cd) == -1) {perror("hxindex"); exit(1);}
+    if (iconv_close(cd) == -1) err(EX_OSERR, NULL);
   }
 }
 
@@ -636,7 +635,7 @@ static void copy_to_index(Tree t, Indexterm *terms, int importance,
       h = newnstring(title + i, n);
       parse_subterms(term, h);
       if (! tsearch(term, (void**)terms, termcmp))
-	errx(1, "Out of memory while parsing term %s\n", h);
+	errx(1, "Out of memory while parsing term %s", h);
       i += n;
       if (title[i]) i++;			/* Skip '|' */
     }
@@ -867,7 +866,7 @@ int main(int argc, char *argv[])
   else if (eq(argv[optind], "-")) yyin = stdin;
   else yyin = fopenurl(argv[optind], "r", &status);
 
-  if (yyin == NULL) {perror(argv[optind]); exit(1);}
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[optind]);
   if (status != 200) errx(1, "%s : %s", argv[optind], http_strerror(status));
 
   if (!base) base = newstring("");
diff --git a/hxmkbib.c b/hxmkbib.c
index f282d64..f5235a9 100644
--- a/hxmkbib.c
+++ b/hxmkbib.c
@@ -67,7 +67,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 19 March 2000
- * Version: $Id: hxmkbib.c,v 1.8 2018/02/15 19:04:22 bbos Exp $
+ * Version: $Id: hxmkbib.c,v 1.9 2023/01/23 21:19:41 bbos Exp $
  **/
 #include "config.h"
 #ifdef HAVE_ERRNO_H
@@ -95,10 +95,11 @@
 #endif
 
 #include <ctype.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "heap.e"
 #include "types.e"
-#include "errexit.e"
 
 
 #define LINESIZE 32768
@@ -261,7 +262,7 @@ static int conditional(const string pattern, const string key,
   if (pattern[i] == '!') on = !get_field(key, pattern[++i]);
   else on = get_field(key, pattern[i]) != NULL;
 
-  if (pattern[i+1] != ':') errexit("%s: missing ':' in pattern\n", prog);
+  if (pattern[i+1] != ':') errx(EX_DATAERR, "missing ':' in pattern");
 
   /* Skip or copy until matching '%}' */
   if (! on) {					/* Skip until matching '}' */
@@ -332,12 +333,12 @@ static void copy(const string pattern, string *keys, const int n)
       else if (pattern[end] == '{') level++;
     }
   }
-  if (level != 0) errexit("%s: unbalanced %{..%} in pattern\n", prog);
+  if (level != 0) errx(EX_DATAERR, "unbalanced %%{..%%} in pattern");
 
   /* End now points just after '}'. Loop over keys */
   for (j = 0; j < n; j++)
     conditional(pattern + start, keys[j], &last);
-    
+
   /* Copy postamble */
   printf("%s", pattern + end);
 }
@@ -373,7 +374,7 @@ static string *read_keys(FILE *f, int *number)
       keys[n++] = newstring(line);
     }
   }
-  if ((e = ferror(f))) errexit("%s: %s\n", prog, strerror(e));
+  if ((e = ferror(f))) errx(EX_IOERR, "%s", strerror(e));
 
   *number = n;
   return keys;
@@ -408,7 +409,7 @@ static void read_entries(FILE *f, const string *keys, const int n)
   for (i = 0; i < n; i++) {
     e.key = newstring(keys[i]);
     e.data = NULL;
-    if (! hsearch(e, ENTER)) errexit("%s: %s\n", prog, strerror(errno));
+    if (! hsearch(e, ENTER)) err(EX_OSERR, NULL);
   }
 
   /* Now read entries from the database */
@@ -432,7 +433,7 @@ static void read_entries(FILE *f, const string *keys, const int n)
       i++;
     }
   }
-  if ((fe = ferror(f))) errexit("%s: %s\n", prog, strerror(fe));
+  if ((fe = ferror(f))) errx(EX_IOERR, "%s", strerror(fe));
 
   /* Check if last entry was already stored */
   if (i != 0)					/* We were still in an entry */
@@ -443,7 +444,7 @@ static void read_entries(FILE *f, const string *keys, const int n)
     e.key = keys[i];
     e1 = hsearch(e, FIND);
     assert(e1);
-    if (! e1->data) errexit("%s: entry for \"%s\" not found\n", prog, keys[i]);
+    if (! e1->data) errx(EX_DATAERR, "entry for \"%s\" not found", keys[i]);
   }
 
 }
@@ -469,8 +470,9 @@ static string read_pattern(FILE *f)
 /* usage -- print usage message and exit */
 static void usage(void)
 {
-  errexit("Version %s\nUsage: %s [-a auxfile] [-s sep] [-n maxauthors] [-r moreauthors] bibfile [inputfile]\n",
+  fprintf(stderr, "Version %s\nUsage: %s [-a auxfile] [-s sep] [-n maxauthors] [-r moreauthors] bibfile [inputfile]\n",
 	  VERSION, prog);
+  exit(EX_USAGE);
 }
 
 
@@ -514,7 +516,7 @@ int main(int argc, char *argv[])
   }
 
   /* Create a hash table */
-  if (! hcreate(HASHSIZE)) errexit("%s: not enough memory for hash table\n", prog);
+  if (! hcreate(HASHSIZE)) err(EX_OSERR, "creating hash table");
 
   /* Read the pattern *before* the auxfile, so that we have a chance
      that the pipeline
@@ -524,24 +526,19 @@ int main(int argc, char *argv[])
 
   /* Read pattern into memory */
   if (! (f = inputfile ? fopen(inputfile, "r") : stdin))
-    errexit("%s: %s: %s\n", prog, inputfile, strerror(errno));
+    err(EX_IOERR, "%s", inputfile);
   pattern = read_pattern(f);
-  if (fclose(f) != 0)
-    errexit("%s: %s: %s\n", prog, inputfile, strerror(errno));
+  if (fclose(f) != 0) err(EX_IOERR, "%s", inputfile);
 
   /* Read keys from aux file */
-  if (! (aux = fopen(auxfile, "r")))
-    errexit("%s: %s: %s\n", prog, auxfile, strerror(errno));
+  if (! (aux = fopen(auxfile, "r"))) err(EX_IOERR, "%s", auxfile);
   keys = read_keys(aux, &n);
-  if (fclose(aux) != 0)
-    errexit("%s: %s: %s\n", prog, auxfile, strerror(errno));
+  if (fclose(aux) != 0) err(EX_IOERR, "%s", auxfile);
 
   /* Read the entries we need from the database */
-  if (! (db = fopen(dbfile, "r")))
-    errexit("%s: %s: %s\n", prog, dbfile, strerror(errno));
+  if (! (db = fopen(dbfile, "r"))) err(EX_IOERR, "%s", dbfile);
   read_entries(db, keys, n);
-  if (fclose(db) != 0)
-    errexit("%s: %s: %s\n", prog, dbfile, strerror(errno));
+  if (fclose(db) != 0) err(EX_IOERR, "%s", dbfile);
 
   /* Copy and expand the pattern */
   copy(pattern, keys, n);
diff --git a/hxmultitoc.c b/hxmultitoc.c
index 20d859d..c35cef9 100644
--- a/hxmultitoc.c
+++ b/hxmultitoc.c
@@ -18,7 +18,7 @@
  *
  * Bert Bos <bert@w3.org>
  * Created Sep 1997
- * $Id: hxmultitoc.c,v 1.6 2017/11/24 09:50:25 bbos Exp $
+ * $Id: hxmultitoc.c,v 1.7 2023/01/23 21:19:41 bbos Exp $
  */
 #include "config.h"
 #include <assert.h>
@@ -26,6 +26,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #if STDC_HEADERS
 # include <string.h>
@@ -203,14 +205,14 @@ static void process_configfile(const string configfile)
   char line[MAXLINELEN], chapter[MAXLINELEN];
   FILE *f;
 
-  if (! (f = fopenurl(configfile, "r", NULL))) {perror(configfile); exit(2);}
+  if (! (f = fopenurl(configfile, "r", NULL))) err(EX_IOERR, "%s", configfile);
 
   /* ToDo: accept quoted file names with spaces in their name */
   while (fgets(line, sizeof(line), f)) {
     if (sscanf(line, " @chapter %s", chapter) == 1) {
       if (!base) base = chapter;
       yyin = fopenurl(chapter, "r", NULL);
-      if (yyin == NULL) {perror(chapter); exit(2);}
+      if (yyin == NULL) err(EX_IOERR, "%s", chapter);
       if (yyparse() != 0) exit(3);
       fclose(yyin);
       base = NULL;
@@ -275,7 +277,7 @@ int main(int argc, char *argv[])
     } else {
       if (!base) base = argv[i];
       yyin = fopenurl(argv[i], "r", NULL);
-      if (yyin == NULL) {perror(argv[1]); exit(2);}
+      if (yyin == NULL) err(EX_IOERR, "%s", argv[1]);
       if (yyparse() != 0) exit(3);
       fclose(yyin);
       base = NULL;
diff --git a/hxname2id.c b/hxname2id.c
index eb7895a..25c7876 100644
--- a/hxname2id.c
+++ b/hxname2id.c
@@ -11,7 +11,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: Dec 2004
- * Version: $Id: hxname2id.c,v 1.7 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxname2id.c,v 1.8 2023/01/23 21:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -20,6 +20,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #if STDC_HEADERS
 # include <string.h>
@@ -50,7 +52,6 @@
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 
 
 static Tree tree;
@@ -204,7 +205,8 @@ static void process(Tree t, bool remove_anchor)
 /* usage -- print usage message and exit */
 static void usage(string name)
 {
-  errexit("Version %s\nUsage: %s [-x] [html-file]\n", VERSION, name);
+  fprintf(stderr, "Version %s\nUsage: %s [-x] [html-file]\n", VERSION, name);
+  exit(EX_USAGE);
 }
 
 
@@ -234,8 +236,8 @@ int main(int argc, char *argv[])
       /* yyin = stdin; */
     } else {
       yyin = fopenurl(argv[i], "r", &status);
-      if (yyin == NULL) {perror(argv[1]); exit(2);}
-      if (status != 200) errexit("%s : %s\n", argv[i], http_strerror(status));
+      if (yyin == NULL) err(EX_IOERR, "%s", argv[1]);
+      if (status != 200) errx(EX_IOERR,"%s: %s",argv[i],http_strerror(status));
     }
   }
   if (yyparse() != 0) exit(3);
diff --git a/hxnormalize.1 b/hxnormalize.1
index 68e1e74..c2e441e 100644
--- a/hxnormalize.1
+++ b/hxnormalize.1
@@ -4,6 +4,7 @@ hxnormalize \- pretty-print an HTML file
 .SH SYNOPSIS
 .B hxnormalize
 .RB "[\| " \-x " \|]"
+.RB "[\| " \-X " \|]"
 .RB "[\| " \-e " \|]"
 .RB "[\| " \-d " \|]"
 .RB "[\| " \-s " \|]"
@@ -19,22 +20,35 @@ hxnormalize \- pretty-print an HTML file
 .LP
 The
 .B hxnormalize
-command pretty-prints an HTML file, and also tries to fix small
-errors. The output is the same HTML, but with a maximum line length
+command pretty-prints an HTML or XML file, and also tries to fix small
+HTML errors. The output is the same file, but with a maximum line length
 and with optional indentation to indicate the nesting level of each
 line.
 .SH OPTIONS
 The following options are supported:
 .TP 10
 .B \-x
-Use XML conventions: empty elements are written with a slash at the
-end: <IMG\ />. Implies
+Applies XML conventions: empty elements are written with a slash at
+the end (e.g., <IMG\ />) and, if the input is HTML, any \(oq<\(cq and
+\(oq&\(cq inside <style> and <script> elements are escaped as
+\(oq&lt;\(cq and \(oq&amp;\(cq. (The input is assumed to be HTML
+unless the
+.B \-X
+option is present.) Implies
 .BR \-e .
 .TP
 .B \-e
-Always insert endtags, even if HTML does not require them (for
+Always inserts endtags, even if HTML does not require them (for
 example: </p> and </li>).
 .TP
+.B \-X
+Makes
+.B hxnormalize
+assume the input is well-formed XML. It does not try to infer omitted
+HTML tags, does not assume elements such as <img> and <br> are empty,
+and does not treat \(oq<\(cq and \(oq&\(cq inside <style> and <script>
+as normal characters.
+.TP
 .B \-d
 Omit the DOCTYPE from the output.
 .TP
@@ -50,7 +64,7 @@ Sets the maximum length of lines.
 will wrap lines so that all lines are as long as possible, but no
 longer than this length. Default is 72. Words that are longer than the
 line length will not be broken, and will extend past this length. A
-\(lqword\(rq is a sequence of characters delimited by white space.) The
+\(oqword\(cq is a sequence of characters delimited by white space.) The
 content of the STYLE, SCRIPT and PRE elements will not be
 line-wrapped.
 .TP
@@ -58,8 +72,9 @@ line-wrapped.
 Omit <span> tags that don't have any attributes.
 .TP
 .B \-L
-Remove redundant "lang" and "xml:lang" attributes. (I.e., those whose
-value is the same as the language inherited from the parent element.)
+Remove redundant \(oqlang\(cq and \(oqxml:lang\(cq attributes. (I.e.,
+those whose value is the same as the language inherited from the
+parent element.)
 .TP
 .BI \-c " commentmagic"
 Comments are normally placed right after the preceding text. That is
@@ -69,7 +84,7 @@ on a separate line.
 is a string and when that string occurs inside a comment,
 .B hxnormalize
 will output an empty line before that comment. E.g. \fB\-c "===="\fR
-can be used to put all comments that contain "====" on a separate
+can be used to put all comments that contain \(oq====\(cq on a separate
 line, preceded by an empty line. By default, no comments are treated
 that way.
 .SH OPERANDS
@@ -102,13 +117,44 @@ The error recovery for incorrect HTML is primitive.
 .B hxnormalize
 will not omit an endtag if the white space after it could possibly be
 significant. E.g., it will not remove the first </p> from
-"<div><p>text</p> <p>text</p></div>".
+\(oq<div><p>text</p> <p>text</p></div>\(cq.
 .LP
 .B hxnormalize
 can currently only retrieve remote files over HTTP. It doesn't handle
 password-protected files, nor files whose content depends on HTTP
-"cookies."
+\(oqcookies.\(cq
+.LP
+When converting from XML to HTML (option
+.B \-X
+without option
+.BR \-x ),
+any pairs of \(OQ<![CDATA[\(CQ and \(oq]]>\(cq are removed and
+character entities &lt; &gt; &quot; &apos; and &amp; are expanded (to
+\(oq<\(cq, \(oq>\(cq, \(oq"\(cq, \(oq'\(cq and \(oq&\(cq,
+respectively), but any other character entities are not expanded. To
+expand other character entities, pipe the input through
+.BR hxunent (1)
+first.
+.LP
+To limit lines to a given number of characters,
+.B hxnormalize
+breaks lines at spaces (or inside tags). Some writing systems do not
+use spaces between words and thus
+.B hxnormalize
+may not be able to break lines, except at already existing line
+breaks.
+.LP
+To make short lines longer,
+.B hxnormalize
+will combine lines and replace a line break by a space, except in
+writing systems that do not put spaces between words, where the line
+break is replaced by nothing.
+.B hxnormalize
+currently only does the latter for Japanese, Chinese, Korean,
+Khmer and Thai. (The text must be correctly marked up with
+\(oqlang\(cq or \(oqxml:lang\(cq.)
 .SH "SEE ALSO"
 .BR asc2xml (1),
 .BR xml2asc (1),
+.BR hxunent (1),
 .BR UTF-8 " (RFC 2279)"
diff --git a/hxnormalize.c b/hxnormalize.c
index 23a2efd..3eb4fe8 100644
--- a/hxnormalize.c
+++ b/hxnormalize.c
@@ -6,7 +6,7 @@
  *
  * Created 9 May 1998
  * Bert Bos <bert@w3.org>
- * $Id: hxnormalize.c,v 1.22 2017/11/24 09:50:25 bbos Exp $
+ * $Id: hxnormalize.c,v 1.27 2023/01/23 21:19:41 bbos Exp $
  */
 #include "config.h"
 #include <stdio.h>
@@ -21,6 +21,8 @@
 #  include <strings.h>
 #endif
 #include <assert.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
@@ -30,7 +32,7 @@
 #include "textwrap.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
+#include "langinfo.e"
 
 static Tree tree;
 static bool do_xml = false;
@@ -40,6 +42,7 @@ static bool do_doctype = true;
 static bool clean_span = false;
 static string long_comment = NULL;
 static bool do_lang = false;
+static bool input_is_xml = false;
 
 
 /* handle_error -- called when a parse error occurred */
@@ -68,10 +71,16 @@ void handle_comment(void *clientdata, string commenttext)
   tree = append_comment(tree, commenttext);
 }
 
+/* handle_html_text -- called after a text chunk is parsed */
+void handle_html_text(void *clientdata, string text)
+{
+  tree = append_text(tree, text);
+}
+
 /* handle_text -- called after a text chunk is parsed */
 void handle_text(void *clientdata, string text)
 {
-  tree = append_text(tree, text);
+  tree = tree_append_text(tree, text);
 }
 
 /* handle_decl -- called after a declaration is parsed */
@@ -87,46 +96,47 @@ void handle_pi(void *clientdata, string pi_text)
   tree = append_procins(tree, pi_text);
 }
 
+/* handle_html_starttag -- called after a start tag is parsed */
+void handle_html_starttag(void *clientdata, string name, pairlist attribs)
+{
+  tree = html_push(tree, name, attribs);
+  free(name);
+}
+
 /* handle_starttag -- called after a start tag is parsed */
 void handle_starttag(void *clientdata, string name, pairlist attribs)
 {
-  tree = html_push(tree, name, attribs);
+  tree = tree_push(tree, name, attribs);
+  free(name);
 }
 
-/* handle_emptytag -- called after an empty tag is parsed */
-void handle_emptytag(void *clientdata, string name, pairlist attribs)
+/* handle_html_emptytag -- called after an empty tag is parsed */
+void handle_html_emptytag(void *clientdata, string name, pairlist attribs)
 {
   tree = html_push(tree, name, attribs);
+  free(name);
 }
 
-/* handle_endtag -- called after an endtag is parsed (name may be "") */
-void handle_endtag(void *clientdata, string name)
+/* handle_emptytag -- called after an empty tag is parsed */
+void handle_emptytag(void *clientdata, string name, pairlist attribs)
 {
-  tree = html_pop(tree, name);
+  tree = tree_push(tree, name, attribs);
+  tree = tree_pop(tree, name);
   free(name);
 }
 
-/* insert -- insert an attribute into a sorted list of attributes */
-static pairlist insert(pairlist x, pairlist list)
+/* handle_html_endtag -- called after an endtag is parsed (name may be "") */
+void handle_html_endtag(void *clientdata, string name)
 {
-  if (! list) {					/* Empty list */
-    x->next = NULL;
-    return x;
-  } else if (strcmp(x->name, list->name) <= 0) { /* Insert at head */
-    x->next = list;
-    return x;
-  } else {					/* Insert not at head */
-    list->next = insert(x, list->next);
-    return list;
-  }
+  tree = html_pop(tree, name);
+  free(name);
 }
 
-/* sort_list -- sort a linked list of attributes, return reordered list */
-static pairlist sort_list(pairlist list)
+/* handle_endtag -- called after an endtag is parsed (name may be "") */
+void handle_endtag(void *clientdata, string name)
 {
-  /* Insertion sort should be fast enough... */
-  if (! list) return NULL;
-  else return insert(list, sort_list(list->next));
+  tree = tree_pop(tree, name);
+  free(name);
 }
 
 /* next_ambiguous -- check if omitting end changes the meaning */
@@ -162,57 +172,58 @@ static bool needs_quotes(const string s)
 static void pp(Tree n, bool preformatted, bool allow_text,
 	       conststring lang)
 {
-  bool pre, mixed;
+  bool pre, mixed, with_space;
   conststring lang2;
   string s;
   pairlist h;
   size_t i, j;
   Tree l;
 
+  with_space = with_spaces(lang);	/* Language with spaces between words? */
+
   switch (n->tp) {
     case Text:
       if (!allow_text) {
 	assert(only_space(n->text));
       } else {
 	s = n->text;
-	i = strlen(s);
-	outn(s, i, preformatted);
+	out(s, preformatted, with_space);
       }
       break;
     case Comment:
       if (long_comment && strstr(n->text, long_comment) && !preformatted) {
 	/* Found a comment that should have an empty line before it */
 	outbreak();
-	outln(NULL, true);
+	outln(NULL, true, with_space);
       }
-      out("<!--", true); out(n->text, true);
-      if (allow_text || preformatted) out("-->", true);
-      else outln("-->", preformatted);
+      out("<!--", true, true); out(n->text, true, with_space);
+      if (allow_text || preformatted) out("-->", true, true);
+      else outln("-->", preformatted, true);
       break;
     case Declaration:
       if (do_doctype) {
-	out("<!DOCTYPE ", false);
-	out(n->name, false);
+	out("<!DOCTYPE ", false, true);
+	out(n->name, false, true);
 	if (n->text) {
-	  out(" PUBLIC \"", false);
-	  out(n->text, false);
-	  out("\"", false);
+	  out(" PUBLIC \"", false, true);
+	  out(n->text, false, true);
+	  out("\"", false, true);
 	}
 	if (n->url) {
-	  if (!n->text) out(" SYSTEM", false);
-	  out(" \"", false);
-	  out(n->url, false);
-	  out("\"", false);
+	  if (!n->text) out(" SYSTEM", false, true);
+	  out(" \"", false, true);
+	  out(n->url, false, true);
+	  out("\"", false, true);
 	} else if (n->text && do_xml) {	/* XML cannot omit the system literal */
-	  out(" \"\"", false);
+	  out(" \"\"", false, true);
 	}
-	outln(">", false);
+	outln(">", false, true);
       }
       break;
     case Procins:
-      out("<?", false); out(n->text, true);
-      if (allow_text || preformatted) out(">", false);
-      else outln(">", false);
+      out("<?", false, true); out(n->text, true, true);
+      if (allow_text || preformatted) out(">", false, true);
+      else outln(">", false, true);
       break;
     case Element:
       if (clean_span && eq(n->name, "span") && ! n->attribs) {
@@ -221,100 +232,114 @@ static void pp(Tree n, bool preformatted, bool allow_text,
 	  pp(l, preformatted, true, lang);
 	break;
       }
-      /* Determine language, remove redundant language attribute */
-      if (do_lang) {
-	if ((lang2 = pairlist_get(n->attribs, "lang")) ||
-	    (lang2 = pairlist_get(n->attribs, "xml:lang"))) {
-	  if (lang && eq(lang, lang2)) {
-	    pairlist_unset(&n->attribs, "lang");
-	    pairlist_unset(&n->attribs, "xml:lang");
-	  }
-	  lang = lang2;
-	}
+      /* Check for language attribute. */
+      lang2 = pairlist_get(n->attribs, "lang");
+      if (!lang2) lang2 = pairlist_get(n->attribs, "xml:lang");
+
+      /* Remove redundant language attribute */
+      if (do_lang && lang && lang2 && eq(lang, lang2)) {
+	pairlist_unset(&n->attribs, "lang");
+	pairlist_unset(&n->attribs, "xml:lang");
       }
-      if (!preformatted && break_before(n->name)) outln(NULL, false);
-      out("<", preformatted); out(n->name, preformatted);
+
+      /* Update inherited language. */
+      if (lang2) lang = lang2;
+
+      if (!preformatted && break_before(n->name)) outln(NULL, false, true);
+      out("<", preformatted, true); out(n->name, preformatted, true);
       if (break_before(n->name)) inc_indent();
-      n->attribs = sort_list(n->attribs);
+      n->attribs = pairlist_sort(n->attribs);
       for (h = n->attribs; h != NULL; h = h->next) {
-	out(" ", false); out(h->name, false);
+	out(" ", false, true); out(h->name, false, true);
 	if (do_xml) {
-	  out("=\"", false);
-	  out(h->value ? h->value : h->name, true);
-	  outc('"', false);
+	  out("=\"", false, true);
+	  out(h->value ? h->value : h->name, true, true);
+	  outc('"', false, true);
 	} else if (h->value == NULL) {
 	  /* The h->name *is* the value (and the attribute name is implicit) */
 	} else if (!needs_quotes(h->value)) {
-	  out("=", false); /* Omit the quotes */
-	  out(h->value, true);
+	  out("=", false, true); /* Omit the quotes */
+	  out(h->value, true, true);
 	} else {
-	  out("=\"", false);
-	  out(h->value, true);
-	  outc('"', false);
+	  out("=\"", false, true);
+	  out(h->value, true, true);
+	  outc('"', false, true);
 	}
       }
       if (is_empty(n->name)) {
 	assert(n->children == NULL);
 	outbreakpoint();
-	out(do_xml ? " />" : ">", true);
+	out(do_xml ? " />" : ">", true, true);
 	if (break_before(n->name)) dec_indent();
-	if (!preformatted && break_after(n->name)) outln(NULL, false);
+	if (!preformatted && break_after(n->name)) outln(NULL, false, true);
 
-      } else if (do_xml && is_cdata_elt(n->name)) {
-	/* Insert <![CDATA[...]]>, but only if input was HTML, not XML */
+      } else if (do_xml && !input_is_xml && is_cdata_elt(n->name)) {
+	/* Escape '<' and '&', but only if input was HTML, not XML */
 	if (!n->children) {
-	  out(" />", true);
+	  out(" />", true, true);
 	  if (break_before(n->name)) dec_indent();
 	} else {
-	  out(">", preformatted);
-	  /* TODO: Strictly speaking, if the input is HTML (not XML),
-	     then the string "<![CDATA[" in <style> or <script> is to
-	     be taken as literal text. In practice, the string
-	     "<![CDATA[" is nearly always preceeded by "<!--" or "//"
-	     and so this simplistic check will usually work... */
-	  assert(n->children->tp == Text);
-	  if (!hasprefix(n->children->text, "<![CDATA[")) out("<![CDATA[",true);
+	  outbreakpoint();
+	  out(">", preformatted, true);
 	  for (l = n->children; l; l = l->sister) {
-	    assert(n->children->tp == Text);
-	    out(l->text, true);
+	    assert(l->tp == Text);
+	    for (s = l->text; *s; s++)
+	      if (*s == '<') out("&lt;", true, true);
+	      else if (*s == '&') out("&amp;", true, true);
+	      else outc(*s, true, with_space);
 	  }
-	  if (!hasprefix(n->children->text, "<![CDATA[")) out("]]>", true);
 	  if (break_before(n->name)) dec_indent();
-	  out("</", preformatted);
-	  out(n->name, preformatted);
+	  out("</", true, true);
+	  out(n->name, true, true);
 	  outbreakpoint();
-	  out(">", preformatted);
+	  out(">", preformatted, true);
 	}
 	if (!preformatted && break_after(n->name)) outbreak();
 
-      } else if (!do_xml && is_cdata_elt(n->name) && n->children &&
-		 n->children->tp == Text && !n->children->sister &&
-		 hasprefix(n->children->text, "<![CDATA[")) {
-	/* Remove <![CDATA[...]]>, but only if input was XML, not HTML */
-	assert(hasaffix(n->children->text, "]]>"));
-	out(">", preformatted);
-	s = n->children->text + 9; /* Skip "<![CDATA[" */
-	i = strlen(s) - 3;	   /* Omit "]]>" */
-	for (j = 0; j < i; j++) outc(s[j], true);
+      } else if (!do_xml && input_is_xml && is_cdata_elt(n->name) &&
+		 n->children) {
+	/* Remove "<![CDATA[" and "]]>", or unescape &lt; and &amp;,
+	   but only if input was XML, not HTML */
+	outbreakpoint();
+	out(">", preformatted, true);
+	for (l = n->children; l != NULL; l = l->sister) {
+	  if (l->tp != Text) {
+	    errx(EX_DATAERR,
+	      "Cannot convert <%s> to HTML because it has children", n->name);
+	  } else if (hasprefix(l->text, "<![CDATA[")) {
+	    assert(hasaffix(l->text, "]]>"));
+	    s = l->text + 9;	/* Skip "<![CDATA[" */
+	    i = strlen(s) - 3;	/* Omit "]]>" */
+	    for (j = 0; j < i; j++) outc(s[j], true, with_space);
+	  } else {		/* Unescape &lt; and &amp; */
+	    for (s = l->text; *s; s++)
+	      if (hasprefix(s, "&amp;")) {outc('&', true, true); s += 4;}
+	      else if (hasprefix(s, "&lt;")) {outc('<', true, true); s += 3;}
+	      else if (hasprefix(s, "&gt;")) {outc('>', true, true); s += 3;}
+	      else if (hasprefix(s, "&quot;")) {outc('"', true, true); s += 5;}
+	      else if (hasprefix(s, "&apos;")) {outc('\'', true, true); s += 5;}
+	      else outc(*s, true, with_space);
+	  }
+	}
 	if (break_before(n->name)) dec_indent();
-	out("</", preformatted);
-	out(n->name, preformatted);
+	out("</", preformatted, true);
+	out(n->name, preformatted, true);
 	outbreakpoint();
-	out(">", preformatted);
+	out(">", preformatted, true);
 	if (!preformatted && break_after(n->name)) outbreak();
 
       } else {
 	outbreakpoint();
-	out(">", preformatted);
+	out(">", preformatted, true);
 	pre = preformatted || is_pre(n->name);
 	mixed = is_mixed(n->name);
 	for (l = n->children; l != NULL; l = l->sister)
 	  pp(l, pre, mixed, lang);
 	if (break_before(n->name)) dec_indent();
 	if (do_xml || do_endtag || need_etag(n->name) || next_ambiguous(n)) {
-	  out("</", pre); out(n->name, pre);
+	  out("</", pre, true); out(n->name, pre, true);
 	  outbreakpoint();
-	  out(">", preformatted);
+	  out(">", preformatted, true);
 	}
 	if (!preformatted && break_after(n->name)) outbreak();
       }
@@ -347,22 +372,11 @@ int main(int argc, char *argv[])
 {
   int c, status = 200;
 
-  /* Bind the parser callback routines to our handlers */
-  set_error_handler(handle_error);
-  set_start_handler(start);
-  set_end_handler(end);
-  set_comment_handler(handle_comment);
-  set_text_handler(handle_text);
-  set_decl_handler(handle_decl);
-  set_pi_handler(handle_pi);
-  set_starttag_handler(handle_starttag);
-  set_emptytag_handler(handle_emptytag);
-  set_endtag_handler(handle_endtag);
-
-  while ((c = getopt(argc, argv, "edxi:l:sc:L")) != -1)
+  while ((c = getopt(argc, argv, "edxXi:l:sc:L")) != -1)
     switch (c) {
     case 'e': do_endtag = true; break;
     case 'x': do_xml = true; break;
+    case 'X': input_is_xml = true; break;
     case 'd': do_doctype = false; break;
     case 'i': set_indent(atoi(optarg)); break;
     case 'l': set_linelen(atoi(optarg)); break;
@@ -374,8 +388,34 @@ int main(int argc, char *argv[])
   if (optind == argc) yyin = stdin;
   else if (optind == argc - 1) yyin = fopenurl(argv[optind], "r", &status);
   else usage(argv[0]);
-  if (yyin == NULL) {perror(argv[optind]); exit(2);}
-  if (status != 200) errexit("%s : %s\n", argv[optind], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[optind]);
+  if (status != 200) errx(EX_IOERR,"%s: %s",argv[optind],http_strerror(status));
+
+  /* Bind the parser callback routines to our handlers */
+  if (input_is_xml) {
+    set_error_handler(handle_error);
+    set_start_handler(start);
+    set_end_handler(end);
+    set_comment_handler(handle_comment);
+    set_text_handler(handle_text);
+    set_decl_handler(handle_decl);
+    set_pi_handler(handle_pi);
+    set_starttag_handler(handle_starttag);
+    set_emptytag_handler(handle_emptytag);
+    set_endtag_handler(handle_endtag);
+  } else {			/* Input is HTML */
+    set_error_handler(handle_error);
+    set_start_handler(start);
+    set_end_handler(end);
+    set_comment_handler(handle_comment);
+    set_text_handler(handle_html_text);
+    set_decl_handler(handle_decl);
+    set_pi_handler(handle_pi);
+    set_starttag_handler(handle_html_starttag);
+    set_emptytag_handler(handle_html_emptytag);
+    set_endtag_handler(handle_html_endtag);
+  }
+
   if (yyparse() != 0) {exit(3);}
   tree = get_root(tree);
   prettyprint(tree);
diff --git a/hxnsxml.c b/hxnsxml.c
index 17343aa..31999c2 100644
--- a/hxnsxml.c
+++ b/hxnsxml.c
@@ -30,6 +30,8 @@
 #endif
 #include <stdlib.h>
 #include <assert.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
@@ -37,7 +39,6 @@
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 
 #define XML "{http://www.w3.org/XML/1998/namespace}"
 
@@ -207,8 +208,8 @@ int main(int argc, char *argv[])
   else if (argc == 2) yyin = fopenurl(argv[1], "r", &status);
   else yyin = stdin;
 
-  if (!yyin) {perror(argv[1]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[1], http_strerror(status));
+  if (!yyin) err(EX_IOERR, "%s", argv[1]);
+  if (status != 200) errx(EX_IOERR, "%s: %s\n", argv[1], http_strerror(status));
 
   if (yyparse() != 0) exit(3);
 
diff --git a/hxnum.c b/hxnum.c
index f21f5d8..c6bc852 100644
--- a/hxnum.c
+++ b/hxnum.c
@@ -8,7 +8,7 @@
  *
  * Bert Bos
  * Created Sep 1997
- * $Id: hxnum.c,v 1.11 2017/11/24 09:50:25 bbos Exp $
+ * $Id: hxnum.c,v 1.13 2023/01/23 21:19:41 bbos Exp $
  */
 #include "config.h"
 #include <stdio.h>
@@ -28,6 +28,8 @@
 # endif
 #endif
 #include <stdlib.h>
+#include <err.h>
+#include <sysexits.h>
 #include <assert.h>
 #include "export.h"
 #include "types.e"
@@ -36,7 +38,6 @@
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 
 #define SECNO "secno"				/* class attribute */
 #define NO_NUM "no-num"				/* class-attribute */
@@ -46,8 +47,8 @@ static int h[] = {-1, 0, 0, 0, 0, 0, 0};	/* Counters for each level */
 static int low = 1;				/* First counter to use */
 static int high = 6;				/* Last counter to use */
 static string format[7] = {			/* Format for each counter */
-  NULL, "%d.", "%d.%d.", "%d.%d.%d.", "%d.%d.%d.%d.",
-  "%d.%d.%d.%d.%d.", "%d.%d.%d.%d.%d.%d."};
+  NULL, "%d. ", "%d.%d. ", "%d.%d.%d. ", "%d.%d.%d.%d. ",
+  "%d.%d.%d.%d.%d. ", "%d.%d.%d.%d.%d.%d. "};
 static int skipping = 0;			/* >0 to suppress output */
 
 
@@ -179,7 +180,7 @@ void handle_starttag(void *clientdata, string name, pairlist attribs)
 	putchar(*s);
       }
     }
-    printf(" </span>");
+    printf("</span>");
   }
 }
 
@@ -224,12 +225,12 @@ static void help(void)
   printf("  -l low     lowest header level to number (1-6) [default 1]\n");
   printf("  -h high    highest header level to number (1-6) [default 6]\n");
   printf("  -n start   number of first heading [default: 1]\n");
-  printf("  -1 format  format for level 1 [default \"%%d.\"]\n");
-  printf("  -2 format  format for level 2 [default \"%%d.%%d.\"]\n");
-  printf("  -3 format  format for level 3 [default \"%%d.%%d.%%d.\"]\n");
-  printf("  -4 format  format for level 4 [default \"%%d.%%d.%%d.%%d.\"]\n");
-  printf("  -5 format  format for level 5 [default \"%%d.%%d.%%d.%%d.%%d.\"]\n");
-  printf("  -6 format  format for level 6 [default \"%%d.%%d.%%d.%%d.%%d.%%d.\"]\n");
+  printf("  -1 format  format for level 1 [default \"%%d. \"]\n");
+  printf("  -2 format  format for level 2 [default \"%%d.%%d. \"]\n");
+  printf("  -3 format  format for level 3 [default \"%%d.%%d.%%d. \"]\n");
+  printf("  -4 format  format for level 4 [default \"%%d.%%d.%%d.%%d. \"]\n");
+  printf("  -5 format  format for level 5 [default \"%%d.%%d.%%d.%%d.%%d. \"]\n");
+  printf("  -6 format  format for level 6 [default \"%%d.%%d.%%d.%%d.%%d.%%d. \"]\n");
   printf("  -?         this help\n");
   printf("The format strings may contain:\n");
   printf("  %%d  replaced by decimal number\n");
@@ -272,9 +273,8 @@ int main(int argc, char *argv[])
 
 #ifdef HAVE_GETOPT_OPTRESET
   optreset = 1;
-#else
-  optind = 1;
 #endif
+  optind = 1;
 
   /* If -l and/or -h have been set, the default formats are different */
   if (low != 1 || high != 6) {
@@ -304,8 +304,8 @@ int main(int argc, char *argv[])
   else if (optind == argc - 1) yyin = fopenurl(argv[optind], "r", &status);
   else usage(argv[0]);
 
-  if (yyin == NULL) {perror(argv[optind]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[optind], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[optind]);
+  if (status != 200) errx(EX_IOERR,"%s: %s",argv[optind],http_strerror(status));
 
   if (yyparse() != 0) {
     exit(3);
diff --git a/hxpipe.1 b/hxpipe.1
index 693b5cd..f92af4f 100644
--- a/hxpipe.1
+++ b/hxpipe.1
@@ -1,4 +1,4 @@
-.TH "HXPIPE" "1" "10 Jul 2011" "7.x" "HTML-XML-utils"
+.TH "HXPIPE" "1" "10 Feb 2022" "8.x" "HTML-XML-utils"
 
 .de d \" begin display
 .sp
@@ -20,6 +20,7 @@ hxpipe \- convert XML file to a format easier to parse with Perl or AWK
 .SH SYNOPSIS
 .B hxpipe
 .RB "[\| " \-l " \|]"
+.RB "[\| " \-H " \|]"
 .RB "[\| " \-\- " \|]"
 .RI "[\| " file-or-URL " \|]"
 .SH DESCRIPTION
@@ -102,7 +103,7 @@ End tags are output as
 I.e., as a line starting with ")" followed by the element type.
 .TP
 <empty att1="val1" att2="val2"/>
-Empty elements (in XML) are output as
+Empty elements are output as
 .d
 Aatt1 CDATA val1
 Aatt2 CDATA val2
@@ -138,18 +139,32 @@ where "12" is replaced with the line number in the source where the
 next output came from.
 .LP
 .B hxpipe
-does not normalize the input and does not add mising tags. It is thus
-possible that there are unequal numbers of "(" and ")" lines. If it is
-important that every start tag is matched by an end tag, pipe the
-input through
-.B hxnormalize -x
-first.
+normalizes the input only in the sense that it outputs attributes in a
+fixed order (alphabetical, but not locale-dependent). It does not read
+a DTD and thus cannot remove redundant white space and cannot add
+implied attributes. It does not expand character entities. (But you
+can pipe the input through
+.B hxunent
+beforehand.) It also does not add implied tags. (But see the
+.B \-H
+option.)
 .SH OPTIONS
 The following options are supported:
 .TP 10
 .B \-l
 Add "L" lines to the output to indicate the line numbers in the
-source.
+source. Currently does not work together with the
+.B \-H
+ option.
+.TP
+.B \-H
+Apply special rules for HTML. Normally,
+.B hxpipe
+assumes well-formed XML. With this option,
+.B hxpipe
+will assume the input is HTML and will add implied tags, recognize
+empty elements and treat the contents of <script> and <style> elements
+as literal text.
 .SH OPERANDS
 The following operand is supported:
 .TP 10
@@ -176,10 +191,17 @@ E.g.,
 .SH BUGS
 .LP
 The error recovery for incorrect HTML is primitive.
-.B hxnormalize
+.LP
+.B hxpipe
 can currently only retrieve remote files over HTTP. It doesn't handle
 password-protected files, nor files whose content depends on HTTP
 "cookies."
+.LP
+Option
+.B \-l
+ought to work also with HTML input (option
+.BR \-H ).
 .SH "SEE ALSO"
 .BR hxunpipe (1),
+.BR hxunent (1),
 .BR onsgmls (1).
diff --git a/hxpipe.c b/hxpipe.c
index 3b5c3e5..7b1000f 100644
--- a/hxpipe.c
+++ b/hxpipe.c
@@ -1,5 +1,5 @@
 /*
- * pipe - output HTML/XML in canonical ("sgmls" form
+ * pipe - output HTML/XML in canonical ("sgmls") form
  *
  * Parse HTML/XML and output in approximate "nsgmls" format. Some of
  * the differences are that comments are also printed (see * below),
@@ -72,7 +72,7 @@
  *
  * Author: Bert Bos
  * Created: 2 Dec 1998
- * Version: $Id: hxpipe.c,v 1.9 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxpipe.c,v 1.13 2023/01/23 21:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -91,20 +91,25 @@
 #endif
 #include <stdlib.h>
 #include <assert.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
+#include "heap.e"
 #include "types.e"
+#include "tree.e"
 #include "html.e"
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 
 #define XMLID "{http://www.w3.org/XML/1998/namespace}id"
 
 static bool has_error = false;
 static bool in_text = false;
 static bool linenumbering = false;
+static bool input_is_html = false;
+static Tree tree;
 
 
 /* escape -- print a string with certain characters escaped */
@@ -124,6 +129,93 @@ static void escape(const string t)
 }
 
 
+/* print_attrs -- print attributes */
+void print_attrs(const pairlist attribs)
+{
+  pairlist p;
+
+  for (p = pairlist_sort(attribs); p; p = p->next) {
+    putchar('A');
+    printf("%s", p->name);
+    if (eq(p->name, "xmlid") || eq(p->name, "xml:id") ||
+	eq(p->name, XMLID)) printf(" TOKEN ");
+    else printf(" CDATA ");
+    if (p->value) escape(p->value); else printf("%s", p->name);
+    putchar('\n');
+  }
+}
+
+
+/* output -- output children of an HTML element (or root) in canonical form */
+static void output(Tree t)
+{
+  Tree n, h;
+
+  assert(t->tp == Root || t->tp == Element);
+  for (n = t->children; n != NULL; n = n->sister)
+    switch (n->tp) {
+    case Text:
+      putchar('-');
+      escape(n->text);
+      putchar('\n');
+      break;
+    case Comment:
+      putchar('*');
+      escape(n->text);
+      putchar('\n');
+      break;
+    case Declaration:
+      printf("!%s \"%s\" %s\n", n->name, n->text ? n->text : "",
+	n->url ? n->url : "");
+      break;
+    case Procins:
+      putchar('?');
+      escape(n->text);
+      putchar('\n');
+      break;
+    case Element:
+      print_attrs(n->attribs);
+      if (is_empty(n->name)) {
+	assert(n->children == NULL);
+	putchar('|');
+	printf("%s", n->name);
+	putchar('\n');
+      } else {
+	putchar('(');
+	printf("%s", n->name);
+	putchar('\n');
+	output(n);
+	putchar(')');
+	printf("%s", n->name);
+	putchar('\n');
+      }
+      break;
+    default:
+      assert(!"Cannot happen");
+    }
+}
+
+
+/* combine_text_nodes -- merge all adjacent text nodes into one */
+static void combine_text_nodes(Tree t)
+{
+  Tree n, h;
+
+  assert(t->tp == Root || t->tp == Element);
+  for (n = t->children; n != NULL; n = n->sister)
+    if (n->tp == Element)
+      combine_text_nodes(n);
+    else if (n->tp == Text)
+      while (n->sister && n->sister->tp == Text) {
+	h = n->sister;
+	strapp(&n->text, h->text, NULL);
+	n->sister = h->sister;
+	dispose(h->text);
+	dispose(h);
+      }
+}
+
+
 /* --------------- implements interface api.h -------------------------- */
 
 /* handle_error -- called when a parse error occurred */
@@ -133,19 +225,40 @@ void handle_error(void *clientdata, const string s, int lineno)
   has_error = true;
 }
 
-/* start -- called before the first event is reported */
+/* html_start -- called before the first event is reported (HTML mode) */
+void* html_start(void)
+{
+  tree = create();
+  return NULL;
+}
+
+/* start -- called before the first event is reported (XML mode) */
 void* start(void)
 {
   return NULL;
 }
-  
-/* end -- called after the last event is reported */
+
+/* html_end -- called after the last event is reported (HTML mode) */
+void html_end(void *clientdata)
+{
+  tree = get_root(tree);
+  combine_text_nodes(tree);
+  output(tree);
+}
+
+/* end -- called after the last event is reported (XML mode) */
 void end(void *clientdata)
 {
   if (in_text) {putchar('\n'); in_text = false;}
 }
 
-/* handle_comment -- called after a comment is parsed */
+/* handle_html_comment -- called after a comment is parsed (HTML mode) */
+void handle_html_comment(void *clientdata, string commenttext)
+{
+  tree = append_comment(tree, commenttext);
+}
+
+/* handle_comment -- called after a comment is parsed (XML mode) */
 void handle_comment(void *clientdata, string commenttext)
 {
   if (in_text) {putchar('\n'); in_text = false;}
@@ -155,7 +268,13 @@ void handle_comment(void *clientdata, string commenttext)
   putchar('\n');
 }
 
-/* handle_text -- called after a text chunk is parsed */
+/* handle_html_text -- called after a text chunk is parsed (HTML mode) */
+void handle_html_text(void *clientdata, string text)
+{
+  tree = append_text(tree, text);
+}
+
+/* handle_text -- called after a text chunk is parsed (XML mode) */
 void handle_text(void *clientdata, string text)
 {
   /* There may be several consecutive calls to this routine. The
@@ -170,7 +289,14 @@ void handle_text(void *clientdata, string text)
   escape(text);
 }
 
-/* handle_decl -- called after a declaration is parsed */
+/* handle_html_decl -- called after a declaration is parsed (HTML mode) */
+void handle_html_decl(void *clientdata, string gi,
+		 string fpi, string url)
+{
+  tree = append_declaration(tree, gi, fpi, url);
+}
+
+/* handle_decl -- called after a declaration is parsed (XML mode) */
 void handle_decl(void *clientdata, string gi, string fpi,
 		 string url)
 {
@@ -179,6 +305,12 @@ void handle_decl(void *clientdata, string gi, string fpi,
   printf("!%s \"%s\" %s\n", gi, fpi ? fpi : "", url ? url : "");
 }
 
+/* handle_html_pi -- called after a PI is parsed (HTML mode) */
+void handle_html_pi(void *clientdata, string pi_text)
+{
+  tree = append_procins(tree, pi_text);
+}
+
 /* handle_pi -- called after a PI is parsed */
 void handle_pi(void *clientdata, string pi_text)
 {
@@ -189,23 +321,14 @@ void handle_pi(void *clientdata, string pi_text)
   putchar('\n');
 }
 
-/* print_attrs -- print attributes */
-void print_attrs(const pairlist attribs)
+/* handle_html_starttag -- called after a start tag is parsed (HTML mode) */
+void handle_html_starttag(void *clientdata, string name, pairlist attribs)
 {
-  pairlist p;
-
-  for (p = attribs; p; p = p->next) {
-    putchar('A');
-    printf("%s", p->name);
-    if (eq(p->name, "xmlid") || eq(p->name, "xml:id") ||
-	eq(p->name, XMLID)) printf(" TOKEN ");
-    else printf(" CDATA ");
-    if (p->value) escape(p->value); else printf("%s", p->name);
-    putchar('\n');
-  }
+  tree = html_push(tree, name, attribs);
+  free(name);
 }
 
-/* handle_starttag -- called after a start tag is parsed */
+/* handle_starttag -- called after a start tag is parsed (XML mode) */
 void handle_starttag(void *clientdata, string name, pairlist attribs)
 {
   if (in_text) {putchar('\n'); in_text = false;}
@@ -216,7 +339,14 @@ void handle_starttag(void *clientdata, string name, pairlist attribs)
   putchar('\n');
 }
 
-/* handle_emptytag -- called after an empty tag is parsed */
+/* handle_html_emptytag -- called after an empty tag is parsed (HTML mode) */
+void handle_html_emptytag(void *clientdata, string name, pairlist attribs)
+{
+  tree = html_push(tree, name, attribs);
+  free(name);
+}
+
+/* handle_emptytag -- called after an empty tag is parsed (XML mode) */
 void handle_emptytag(void *clientdata, string name, pairlist attribs)
 {
   if (in_text) {putchar('\n'); in_text = false;}
@@ -227,6 +357,13 @@ void handle_emptytag(void *clientdata, string name, pairlist attribs)
   putchar('\n');
 }
 
+/* handle_html_endtag -- called after an endtag is parsed (name may be "") */
+void handle_html_endtag(void *clientdata, string name)
+{
+  tree = html_pop(tree, name);
+  free(name);
+}
+
 /* handle_endtag -- called after an endtag is parsed (name may be "") */
 void handle_endtag(void *clientdata, string name)
 {
@@ -250,21 +387,10 @@ int main(int argc, char *argv[])
 {
   int c, status = 200;
 
-  /* Bind the parser callback routines to our handlers */
-  set_error_handler(handle_error);
-  set_start_handler(start);
-  set_end_handler(end);
-  set_comment_handler(handle_comment);
-  set_text_handler(handle_text);
-  set_decl_handler(handle_decl);
-  set_pi_handler(handle_pi);
-  set_starttag_handler(handle_starttag);
-  set_emptytag_handler(handle_emptytag);
-  set_endtag_handler(handle_endtag);
-
   /* Parse command line arguments */
-  while ((c = getopt(argc, argv, "lv")) != -1)
+  while ((c = getopt(argc, argv, "Hlv")) != -1)
     switch (c) {
+    case 'H': input_is_html = true; break;
     case 'l': linenumbering = true; break;
     case 'v': printf("Version: %s %s\n", PACKAGE, VERSION); return 0;
     case '?': usage(argv[0]); break;
@@ -276,8 +402,33 @@ int main(int argc, char *argv[])
   else if (optind == argc - 1) yyin = fopenurl(argv[optind], "r", &status);
   else usage(argv[0]);
 
-  if (yyin == NULL) {perror(argv[optind]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[optind], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[optind]);
+  if (status != 200) errx(EX_IOERR,"%s: %s",argv[optind],http_strerror(status));
+
+  /* Bind the parser callback routines to our handlers */
+  if (!input_is_html) {		/* Input is XML */
+    set_error_handler(handle_error);
+    set_start_handler(start);
+    set_end_handler(end);
+    set_comment_handler(handle_comment);
+    set_text_handler(handle_text);
+    set_decl_handler(handle_decl);
+    set_pi_handler(handle_pi);
+    set_starttag_handler(handle_starttag);
+    set_emptytag_handler(handle_emptytag);
+    set_endtag_handler(handle_endtag);
+  } else {			/* Input is HTML */
+    set_error_handler(handle_error);
+    set_start_handler(html_start);
+    set_end_handler(html_end);
+    set_comment_handler(handle_html_comment);
+    set_text_handler(handle_html_text);
+    set_decl_handler(handle_html_decl);
+    set_pi_handler(handle_html_pi);
+    set_starttag_handler(handle_html_starttag);
+    set_emptytag_handler(handle_html_emptytag);
+    set_endtag_handler(handle_html_endtag);
+  }
 
   if (yyparse() != 0) exit(3);
 
diff --git a/hxprintlinks.c b/hxprintlinks.c
index 0f8f697..ca89088 100644
--- a/hxprintlinks.c
+++ b/hxprintlinks.c
@@ -10,7 +10,10 @@
 #include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
+#include <ctype.h>
 #ifdef HAVE_STRING_H
 #  include <string.h>
 #elif HAVE_STRINGS_H
@@ -22,7 +25,6 @@
 #include "types.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 #include "heap.e"
 #include "html.e"
 #include "scan.e"
@@ -37,6 +39,19 @@ static bool has_error = false;		/* Parsing errors occurred */
 static conststring base = NULL;		/* Make URLs relative to this base */
 
 
+/* trim -- remove leading and trailing spaces */
+static string trim(const conststring s)
+{
+  string t;
+  int i;
+
+  t = strdup(s);
+  while (isspace(*t)) t++;
+  for (i = strlen(t) - 1; i >= 0 && isspace(t[i]); i--) t[i] = '\0';
+  return t;
+}
+
+
 /* pairlist_push -- insert a name/value pair at the start of a list */
 static void pairlist_push(pairlist *p, const conststring name, const conststring val)
 {
@@ -90,7 +105,7 @@ void* start(void)
   return NULL;
 }
 
-  
+
 /* end -- called after the last event is reported */
 void end(void *clientdata)
 {
@@ -160,7 +175,7 @@ void handle_starttag(void *clientdata, string name, pairlist attribs)
   /* Store any URLs from attributes */
   for (i = 0; i < sizeof(attname)/sizeof(*attname); i++)
     if ((url = pairlist_get(attribs, attname[i])))
-      pairlist_push(&list, url, attname[i]);
+      pairlist_push(&list, trim(url), attname[i]);
 
   printf("<%s", name);
   print_attrs(attribs);
@@ -222,8 +237,8 @@ int main(int argc, char *argv[])
   else if (optind > argc - 1 || eq(argv[optind], "-")) yyin = stdin;
   else yyin = fopenurl(argv[optind], "r", &status);
 
-  if (!yyin) {perror(argv[optind]); exit(2);}
-  if (status != 200) errexit("%s : %s\n", argv[optind], http_strerror(status));
+  if (!yyin) err(EX_IOERR, "%s", argv[optind]);
+  if (status != 200) errx(EX_IOERR,"%s: %s",argv[optind],http_strerror(status));
 
   /* Bind the parser callback routines to our handlers */
   set_error_handler(handle_error);
diff --git a/hxprune.c b/hxprune.c
index e2c7cda..db6a639 100644
--- a/hxprune.c
+++ b/hxprune.c
@@ -6,7 +6,7 @@
  *
  * Bert Bos <bert@w3.org>
  * Created Feb 2000
- * $Id: hxprune.c,v 1.8 2017/11/24 09:50:25 bbos Exp $
+ * $Id: hxprune.c,v 1.10 2023/01/23 21:25:05 bbos Exp $
  *
  **/
 /* #include <mcheck.h> */
@@ -16,6 +16,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #if STDC_HEADERS
 # include <string.h>
@@ -36,7 +38,6 @@
 #include "dict.e"
 #include "openurl.e"
 #include "class.e"
-#include "errexit.e"
 
 #define EXCLUDE_CLASS "exclude"			/* Default value for class */
 
@@ -192,8 +193,8 @@ int main(int argc, char *argv[])
       xml = true;
     } else {
       yyin = fopenurl(argv[i], "r", &status);
-      if (yyin == NULL) {perror(argv[1]); exit(2);}
-      if (status != 200) errexit("%s : %s\n", argv[i], http_strerror(status));
+      if (yyin == NULL) err(EX_IOERR, "%s", argv[1]);
+      if (status != 200) errx(EX_IOERR,"%s: %s",argv[i],http_strerror(status));
     }
   }
 
diff --git a/hxref.c b/hxref.c
index a6af26f..bcbd9cb 100644
--- a/hxref.c
+++ b/hxref.c
@@ -22,7 +22,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 4 August 2000
- * Version: $Id: hxref.c,v 1.14 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxref.c,v 1.15 2023/01/23 21:19:41 bbos Exp $
  **/
 
 #include "config.h"
@@ -30,6 +30,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 
 #ifdef HAVE_ERRNO_H
@@ -60,7 +62,6 @@
 #include "dict.e"
 #include "openurl.e"
 #include "genid.e"
-#include "errexit.e"
 
 
 /* Warning: arbitrary limit! */
@@ -160,7 +161,7 @@ static void load_definitions(FILE *f)
 
   while (fgets(buf, sizeof(buf), f)) {		/* Format is PHRASE\tURL\n */
     h = strchr(buf, '\t');
-    if (! h) errexit("%s: index file not in correct format\n", progname);
+    if (! h) errx(EX_DATAERR, "index file not in correct format\n");
     chomp(h);
     entry.key = newnstring(buf, h - buf);
     entry.data = newstring(h + 1);
@@ -466,7 +467,7 @@ int main(int argc, char *argv[])
 	if (!argv[i][2] && i + 1 == argc) usage(); /* Missing argument */
 	if (db) usage();			/* Index was already set */
 	db = fopen(argv[i][2] ? argv[i] + 2 : argv[++i], "a+");
-	if (! db) errexit("%s: %s\n", argv[i], strerror(errno));
+	if (! db) err(EX_IOERR, "%s", argv[i]);
 	break;
       case 'l':
 	if (use_language) usage(); 		/* Option was already set */
@@ -490,31 +491,29 @@ int main(int argc, char *argv[])
     if (yyin) usage();				/* Input was already set */
     if (eq(argv[i], "-")) yyin = stdin;
     else yyin = fopenurl(argv[i], "r", &status);
-    if (! yyin) errexit("%s: %s\n", argv[i], strerror(errno));
-    if (status != 200) errexit("%s : %s\n", argv[i], http_strerror(status));
+    if (! yyin) err(EX_IOERR, "%s", argv[i]);
+    if (status != 200) errx(EX_IOERR, "%s: %s", argv[i], http_strerror(status));
   }
   if (++i < argc) {
     if (outfile) usage();			/* Output was already set */
     if (eq(argv[i], "-")) outfile = stdout;
     else outfile = fopen(argv[i], "w");
-    if (! outfile) perror(argv[i]);
+    if (! outfile) err(EX_IOERR, "%s", argv[i]);
   }
   if (++i < argc) usage();			/* Too many args */
 
   if (! yyin) yyin = stdin;
   if (! outfile) outfile = stdout;
 
-  if (! hcreate(HASHSIZE))
-    errexit("%s: cannot create hash table (out of memory?)\n", argv[0]);
+  if (! hcreate(HASHSIZE)) err(EX_OSERR, "cannot create hash table");
 
   if (db) {
-    if (fseek(db, 0L, SEEK_SET) == -1)
-      errexit("%s: %s\n", progname, strerror(errno));
+    if (fseek(db, 0L, SEEK_SET) == -1) err(EX_OSERR, NULL);
     load_definitions(db);
   }
 
   if (yyparse() != 0) exit(3);
-  
+
   tree = get_root(tree);
   collect_terms(tree, db);
   find_instances(tree, NULL);
diff --git a/hxremove.c b/hxremove.c
index 64a5545..3f83e7b 100644
--- a/hxremove.c
+++ b/hxremove.c
@@ -20,6 +20,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <ctype.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #ifdef HAVE_STRING_H
 # include <string.h>
@@ -30,7 +32,6 @@
 #include "tree.e"
 #include "selector.e"
 #include "heap.e"
-#include "errexit.e"
 #include "html.e"
 #include "scan.e"
 #include "selmatch.e"
@@ -189,7 +190,8 @@ static void handle_endtag(void *clientdata, const string name)
 /* usage -- print usage message and exit */
 static void usage(const conststring progname)
 {
-  errexit("Usage: %s [-v] [-l language] [-i] selector\n", progname);
+  fprintf(stderr, "Usage: %s [-v] [-l language] [-i] selector\n", progname);
+  exit(EX_USAGE);
 }
 
 
@@ -226,7 +228,7 @@ int main(int argc, char *argv[])
   for (s = newstring(argv[optind++]); optind < argc; optind++)
     strapp(&s, " ", argv[optind], NULL);
   selector = parse_selector(s, &s);
-  if (*s) errexit("Syntax error at \"%c\"\n", *s);
+  if (*s) errx(EX_DATAERR, "Syntax error at \"%c\"", *s);
 
   /* Parse the input, build a tree, filter the tree */
   yyin = stdin;
diff --git a/hxselect.1 b/hxselect.1
index f003690..0bcb0c5 100644
--- a/hxselect.1
+++ b/hxselect.1
@@ -71,7 +71,7 @@ have an xml:lang attribute (default: none). Example:
 .TP
 .BI \-s " separator"
 A string to print after each match (default: empty). Accepts
-C-like escapes. Example: 
+C-like escapes. Example:
 .B \-s \(aq\\\\n\\\\n\(aq
 to print an empty line after each match.
 .SH OPERANDS
@@ -81,6 +81,11 @@ The following operand is supported:
 One or more comma-separated selectors. Most selectors from CSS level 3
 are supported, with the exception of selectors that require
 interaction (e.g., ':active') or layout (e.g., ':first-line).
+.SH BUGS
+Case-insensitive selectors (option
+.BR \-i )
+currently only works for ASCII characters ("a" matches "A"), not for
+other characters ("ä" does not match "Ä").
 .SH "SEE ALSO"
 .BR asc2xml (1),
 .BR xml2asc (1),
diff --git a/hxselect.c b/hxselect.c
index d664ca7..54e9bfb 100644
--- a/hxselect.c
+++ b/hxselect.c
@@ -42,7 +42,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 5 Jul 2001
- * Version: $Id: hxselect.c,v 1.10 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxselect.c,v 1.13 2023/02/09 17:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -51,6 +51,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <ctype.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #if STDC_HEADERS
 # include <string.h>
@@ -67,7 +69,6 @@
 #include "tree.e"
 #include "selector.e"
 #include "heap.e"
-#include "errexit.e"
 #include "html.e"
 #include "scan.e"
 #include "selmatch.e"
@@ -102,9 +103,9 @@ static void printsep(const string separator)
       c = *s - '0';
       if ('0' <= *(++s) && *s <= '7') {
 	c = 8 * c + *s - '0';
-	if ('0' <= *(++s) && *s <= '7') c = 8 * c + *s - '0';
+	if ('0' <= *(++s) && *s <= '7') c = 8 * c + *(s++) - '0';
       }
-      putchar(c); s++;
+      putchar(c);
     } else
       switch (*s) {
       case '\0': putchar('\\'); break;
@@ -156,19 +157,22 @@ static void print_tree(Tree t)
 static void match_pseudoelts(Tree t)
 {
   pairlist p;
-
-  assert(selector->pseudoelts);
-
-  /* ::attr() is the only pseudo-element we can handle so far */
-  if (selector->pseudoelts->type == AttrNode) {
-    assert(selector->combinator == Child && selector->context);
-    p = t->attribs;
-    while (p && !same(p->name, selector->pseudoelts->s)) p = p->next;
-    if (p && matches_sel(t, selector->context)) {
-      if (!content_only) printf("%s=\"", p->name);
-      printf("%s", p->value);
-      if (!content_only) printf("\"");
-      printsep(separator);
+  Selector s;
+
+  for (s = selector; s; s = s->next) {
+    if (!s->pseudoelts) continue;
+
+    /* ::attr() is the only pseudo-element we can handle so far */
+    if (s->pseudoelts->type == AttrNode) {
+      assert(s->combinator == Child && s->context);
+      p = t->attribs;
+      while (p && !same(p->name, s->pseudoelts->s)) p = p->next;
+      if (p && matches_sel(t, s->context)) {
+	if (!content_only) printf("%s=\"", p->name);
+	printf("%s", p->value);
+	if (!content_only) printf("\"");
+	printsep(separator);
+      }
     }
   }
 }
@@ -181,8 +185,8 @@ static void walk_tree(Tree t)
 
   switch (t->tp) {
   case Element:
-    if (selector->pseudoelts) match_pseudoelts(t);
-    else if (matches_sel(t, selector)) print_tree(t);
+    if (matches_sel(t, selector)) print_tree(t);
+    match_pseudoelts(t);
     walk_tree(t->children);
     break;
   case Text: break;
@@ -290,8 +294,10 @@ static void handle_endtag(void *clientdata, const string name)
 /* usage -- print usage message and exit */
 static void usage(const conststring progname)
 {
-  errexit("Usage: %s [-v] [-i] [-c] [-l language] [-s separator] selector\n",
+  fprintf(stderr,
+    "Usage: %s [-v] [-i] [-c] [-l language] [-s separator] selector\n",
 	  progname);
+  exit(EX_USAGE);
 }
 
 
@@ -330,7 +336,7 @@ int main(int argc, char *argv[])
   for (s = newstring(argv[optind++]); optind < argc; optind++)
     strapp(&s, " ", argv[optind], NULL);
   selector = parse_selector(s, &s);
-  if (*s) errexit("Syntax error at \"%c\"\n", *s);
+  if (*s) errx(EX_DATAERR, "Syntax error at \"%c\"\n", *s);
 
   /* Walk the tree */
   yyin = stdin;
diff --git a/hxtabletrans.c b/hxtabletrans.c
index c45590c..13134d2 100644
--- a/hxtabletrans.c
+++ b/hxtabletrans.c
@@ -16,6 +16,8 @@
  *
  * TODO: Turn thead, tfoot and tbody into colgroup?
  *
+ * TODO: Reinsert CAPTION.
+ *
  * Copyright © 2012 World Wide Web Consortium
  * See http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
  *
@@ -208,7 +210,8 @@ static int find_all_rows(Tree t, Tree **rows)
 	(*rows)[nrows-1] = g->children;
       }
     } else {
-      assert(eq(h->name, "colgroup") || eq(h->name, "col"));
+      assert(eq(h->name, "colgroup") || eq(h->name, "col") ||
+	     eq(h->name, "caption"));
     }
   }
   return nrows;
diff --git a/hxtoc.1 b/hxtoc.1
index 0fa2cf2..950e771 100644
--- a/hxtoc.1
+++ b/hxtoc.1
@@ -35,11 +35,11 @@ and
 .B \-h
 (unless the option
 .B \-d
-is in effect, see below) and also inserts A elements with NAME
-attributes, so old browsers will recognize the H1 to H6 headers as
-target anchors as well (unless the option
+is in effect, see below). Unless the option
 .B \-t
-is in effect). The output is written to stdout.
+is given, it also inserts A elements with NAME attributes, because old
+browsers do not recognize ID attributes as target anchors. The output
+is written to stdout.
 .LP
 If there is a comment of the form
 .d
@@ -78,7 +78,7 @@ content. Default is 1 (i.e., H1).
 .TP
 .BI \-h " high"
 Sets the highest numbered header to appear in the table of
-content. Default is 6 (i.e., H6).
+content. Default is unlimited.
 .TP
 .B \-t
 Normally,
@@ -89,20 +89,20 @@ still find the target. With this option, the A elements will not be
 generated.
 .TP
 .BI \-c " class"
-The generated UL elements in the table of contents will have a CLASS attribute with the value
+The generated UL elements in the table of contents will have a CLASS
+attribute with the value
 .I class.
 The default is "toc".
 .TP
 .B \-d
 Tries to use sectioning elements as targets in the table of contents
 instead of H1 to H6. A sectioning elements is a DIV, SECTION, ARTICLE,
-ASIDE or NAV element whose first child is a heading element (H1 to H6)
-or an HGROUP. The sectioning element will be given an ID if it doesn't
-have one yet. With this option, the level of any H1 to H6 that is the
-first child of a sectioning element (or of an HGROUP that is itself
-the first child of a sectioning element) is not determined by its
+ASIDE or NAV element that contains at least one heading element (H1 to
+H6) or HGROUP. The sectioning element will be given an ID if it
+doesn't have one yet. With this option, the level of any H1 to H6 that
+is the first heading of a sectioning element is not determined by its
 name, but by the nesting depth of the sectioning elements. (Any H1 to
-H6 that are not the first child of a sectioning element still have
+H6 that are not the first heading of a sectioning element still have
 their level implied by their name.)
 .TP
 .B \-f
diff --git a/hxtoc.c b/hxtoc.c
index 88138e1..cef8dd8 100644
--- a/hxtoc.c
+++ b/hxtoc.c
@@ -23,7 +23,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created Sep 1997
- * Version: $Id: hxtoc.c,v 1.12 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxtoc.c,v 1.14 2023/01/23 21:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -32,8 +32,11 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include <getopt.h>
+#include <limits.h>
 #if STDC_HEADERS
 # include <string.h>
 #else
@@ -63,7 +66,6 @@
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 #include "genid.e"
 #include "class.e"
 
@@ -83,7 +85,7 @@
 #define INDENT " "				/* Amount to indent ToC per level */
 
 static Tree tree;
-static int toc_low = 1, toc_high = 6;		/* Which headers to include */
+static int toc_low = 1, toc_high = INT_MAX;	/* Which headers to include */
 static bool xml = false;			/* Use <empty /> convention */
 static bool bctarget = true;			/* Generate <a name=> after IDs */
 static string toc_class = "toc";		/* <ul class="..."> */
@@ -103,7 +105,7 @@ static void* start(void)
   tree = create();
   return NULL;
 }
-  
+
 /* end -- called after the last event is reported */
 static void end(void *clientdata)
 {
@@ -189,35 +191,38 @@ static int heading_level(Tree t)
   return 0;
 }
 
-/* div_parent -- if t is the first child of a section elt, return that elt */
+/* div_parent -- if t is the first heading in a section elt, return that elt */
 static Tree div_parent(Tree t)
 {
   Tree h, result = NULL;
 
   assert(t->tp == Element);
   assert(t->parent);
+  assert(eq(t->name, "hgroup") || heading_level(t) > 0);
   if (t->parent->tp != Element) return NULL;
   if (has_class(t->parent->attribs, NO_TOC)) return NULL;
   if (is_div(t->parent)) result = t->parent;
-  else if (!eq(t->parent->name, "header")) return NULL;
+  else if (!eq(t->parent->name, "hgroup")) return NULL;
   else if (!(result = div_parent(t->parent))) return NULL;
-  for (h = t->parent->children; h != t; h = h->sister) {
-    if (h->tp == Element) return NULL;
-    if (h->tp == Text && !only_space(h->text)) return NULL;
-  }
-  return result;
+
+  /* Check if t is the first heading in its parent. */
+  for (h = t->parent->children; h != t; h = h->sister)
+    if (h->tp == Element && (eq(h->name, "hgroup") || heading_level(h) > 0))
+      return NULL;		/* No, it's not */
+  return result;		/* Yes, it is */
 }
 
-/* first_child_is_heading -- true if first child is a Hn or HEADER */
-static bool first_child_is_heading(Tree t)
+/* has_heading -- true if the element has at least one Hn or HGROUP as child */
+static bool has_heading(Tree t)
 {
   Tree h;
 
   assert(t->tp == Element);
   for (h = t->children; h; h = h->sister) {
+#if 0
     switch (h->tp) {
     case Element:
-      return eq(h->name, "header") || heading_level(h) > 0;
+      return eq(h->name, "hgroup") || heading_level(h) > 0;
     case Text:
       if (!only_space(h->text))
 	return false;
@@ -225,6 +230,10 @@ static bool first_child_is_heading(Tree t)
     default:
       break;
     }
+#else
+    if (h->tp == Element &&
+	(eq(h->name, "hgroup") || heading_level(h) > 0)) return true;
+#endif
   }
   return false;
 }
@@ -246,8 +255,8 @@ static void toc(Tree t, int *curlevel, bool *item_is_open, int div_depth)
     case Declaration: break;
     case Procins: break;
     case Element:
-      if (use_div && is_div(t) && first_child_is_heading(t)) {
-	/* It's a section element with a heading as first child */
+      if (use_div && is_div(t) && has_heading(t)) {
+	/* It's a section element with a heading */
 	div_depth++;
 	level = 0;
       } else {
@@ -358,7 +367,7 @@ static void expand(Tree t, bool *write, bool exp, bool keep_anchors,
 	if (*write) printf("<?%s>", h->text);
 	break;
       case Element:
-	if (use_div && is_div(h) && first_child_is_heading(h)) {
+	if (use_div && is_div(h) && has_heading(h)) {
 	  /* It's a section element with a heading as first child */
 	  div_depth++;
 	  level = div_depth;
@@ -434,8 +443,9 @@ static void expand(Tree t, bool *write, bool exp, bool keep_anchors,
 /* usage -- print usage message and exit */
 static void usage(string name)
 {
-  errexit("Version %s\nUsage: %s [-l low] [-h high] [-x] [-t] [-d] [-c class] [html-file]\n",
+  fprintf(stderr, "Version %s\nUsage: %s [-l low] [-h high] [-x] [-t] [-d] [-c class] [html-file]\n",
 	  VERSION, name);
+  exit(EX_USAGE);
 }
 
 
@@ -457,16 +467,15 @@ int main(int argc, char *argv[])
     }
   }
   if (toc_low < 1) toc_low = 1;
-  if (toc_high > 6) toc_high = 6;
 
   if (argc > optind + 1) {
     usage(argv[0]);
   } else if (optind >= argc || eq(argv[optind], "-")) {
     yyin = stdin;
   } else if (!(yyin = fopenurl(argv[optind], "r", &status))) {
-    perror(argv[optind]); exit(2);
+    err(EX_IOERR, "%s", argv[optind]);
   } else if (status != 200) {
-    errexit("%s : %s\n", argv[optind], http_strerror(status));
+    errx(EX_IOERR, "%s: %s", argv[optind], http_strerror(status));
   }
 
   /* Bind the parser callback routines to our handlers */
diff --git a/hxuncdata.c b/hxuncdata.c
index 699f04f..1c1f27c 100644
--- a/hxuncdata.c
+++ b/hxuncdata.c
@@ -14,12 +14,14 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 20 Feb 2002
- * Version: $Id: hxuncdata.c,v 1.2 2009/01/08 14:35:09 bbos Exp $
+ * Version: $Id: hxuncdata.c,v 1.3 2023/01/23 21:19:41 bbos Exp $
  */
 
 #include <stdio.h>
 #include <assert.h>
 #include <string.h>
+#include <err.h>
+#include <sysexits.h>
 
 
 /* process -- process one file */
@@ -136,9 +138,9 @@ int main(int argc, char *argv[])
     printf("Usage: %s [XML-FILE]...\n", argv[0]);
   else
     for (i = 1; i < argc; i++) {
-      if (!(f = fopen(argv[i], "r"))) {perror(argv[i]); err++; continue;}
+      if (!(f = fopen(argv[i], "r"))) {warn("%s", argv[i]); err++; continue;}
       process(f);
-      if (fclose(f) != 0) {perror(argv[i]); err++; continue;}
+      if (fclose(f) != 0) {warn("%s", argv[i]); err++; continue;}
     }
   return err;
 }
diff --git a/hxunentmain.c b/hxunentmain.c
index 88e99ec..c095e29 100644
--- a/hxunentmain.c
+++ b/hxunentmain.c
@@ -9,6 +9,8 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <err.h>
+#include <sysexits.h>
 #include "export.h"
 #include "unent.e"
 
@@ -143,7 +145,7 @@ int main(int argc, char *argv[])
   if (optind == argc) infile = stdin;
   else if (optind == argc - 1) infile = fopen(argv[optind], "r");
   else usage(argv[0]);
-  if (infile == NULL) {perror(argv[optind]); exit(1);}
+  if (infile == NULL) err(EX_IOERR, "%s", argv[optind]);
 
   expand(infile);
 
diff --git a/hxunpipe.c b/hxunpipe.c
index 11ea5ff..30fefbe 100644
--- a/hxunpipe.c
+++ b/hxunpipe.c
@@ -6,12 +6,14 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 23 May 1999
- * Version: $Id: hxunpipe.c,v 1.11 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxunpipe.c,v 1.12 2023/01/23 21:19:41 bbos Exp $
  */
 #include "config.h"
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #ifdef HAVE_UNISTD_H
 #  include <unistd.h>
@@ -25,7 +27,6 @@
 #include "export.h"
 #include "types.e"
 #include "heap.e"
-#include "errexit.e"
 #include "dict.e"
 #include "openurl.e"
 
@@ -84,14 +85,14 @@ static void put_attr(void)
 
   for (j = 0; j < nrattrs; j++) {
     for (i = 0; attrs[j][i] && attrs[j][i] != ' '; i++);
-    if (attrs[j][i] != ' ') errexit("Incorrect A (attribute) line\n");
+    if (attrs[j][i] != ' ') errx(EX_DATAERR, "Incorrect A (attribute) line");
     if (! eq(attrs[j] + i + 1, "IMPLIED")) {
       putchar(' ');
       for (i = 0; attrs[j][i] && attrs[j][i] != ' '; i++) putchar(attrs[j][i]);
-      if (attrs[j][i] != ' ') errexit("Incorrect A (attribute) line\n");
+      if (attrs[j][i] != ' ') errx(EX_DATAERR, "Incorrect A (attribute) line");
       putchar('=');
       for (i++; attrs[j][i] && attrs[j][i] != ' '; i++) ; /* skip type */
-      if (attrs[j][i] != ' ') errexit("Incorrect A (attribute) line\n");
+      if (attrs[j][i] != ' ') errx(EX_DATAERR, "Incorrect A (attribute) line");
       putchar('"');
       for (i++; attrs[j][i]; i++) {
 	if (attrs[j][i] != '\\') putchar(attrs[j][i]);
@@ -132,12 +133,12 @@ static void put_decl(FILE *in)
   while (c == ' ') c = getc(in);
   if (c == '"') {
     if ((c = getc(in)) == EOF || c == '\n')
-      errexit("Incorrect DOCTYPE declaration\n");
+      errx(EX_DATAERR, "Incorrect DOCTYPE declaration");
     if (c != '"') {
       hasfpi = true;
       printf(" PUBLIC \"%c", c);
       while ((c = getc(in)) != EOF && c != '\n' && c != '"') putchar(c);
-      if (c != '"') errexit("Incorrect DOCTYPE declaration\n");
+      if (c != '"') errx(EX_DATAERR, "Incorrect DOCTYPE declaration");
       putchar('"');
     }
     c = getc(in);
@@ -176,8 +177,8 @@ int main(int argc, char *argv[])
   else if (optind == argc - 1) in = fopenurl(argv[optind], "r", &status);
   else usage(argv[0]);
 
-  if (in == NULL) { perror(argv[optind]); exit(2); }
-  if (status != 200) errexit("%s : %s\n", argv[optind], http_strerror(status));
+  if (in == NULL) err(EX_IOERR, "%s", argv[optind]);
+  if (status != 200) errx(EX_IOERR,"%s: %s",argv[optind],http_strerror(status));
 
   while ((c = getc(in)) != EOF) {
     switch (c) {
@@ -198,7 +199,7 @@ int main(int argc, char *argv[])
     case 'C': break;
     }
   }
-  if (! feof(in)) { perror(argv[0]); exit(1); }
+  if (! feof(in)) err(EX_IOERR, "%s", argv[0]);
   fclose(in);
   return 0;
 }
diff --git a/hxunxmlns.c b/hxunxmlns.c
index 2c9e3e5..2cc871e 100644
--- a/hxunxmlns.c
+++ b/hxunxmlns.c
@@ -11,7 +11,7 @@
  *
  * Author: Bert Bos
  * Created: 8 November 2005
- * Version: $Id: hxunxmlns.c,v 1.7 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxunxmlns.c,v 1.8 2023/01/23 21:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -30,6 +30,8 @@
 #endif
 #include <stdlib.h>
 #include <assert.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
@@ -37,7 +39,6 @@
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 
 
 #define XMLNS "{http://www.w3.org/XML/1998/namespace}"
@@ -215,8 +216,8 @@ int main(int argc, char *argv[])
   else if (i == argc - 1) yyin = fopenurl(argv[i], "r", &status);
   else usage(argv[0]);
 
-  if (yyin == NULL) {perror(argv[i]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[i], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[i]);
+  if (status != 200) errx(EX_IOERR, "%s: %s", argv[i], http_strerror(status));
 
   if (yyparse() != 0) exit(3);
 
diff --git a/hxwls.c b/hxwls.c
index bfa7d4b..a1f1cee 100644
--- a/hxwls.c
+++ b/hxwls.c
@@ -6,7 +6,7 @@
  *
  * Bert Bos <bert@w3.org>
  * Created 31 July 1999
- * $Id: hxwls.c,v 1.12 2017/12/07 02:05:23 bbos Exp $
+ * $Id: hxwls.c,v 1.14 2023/01/23 21:10:47 bbos Exp $
  */
 #include "config.h"
 #include <assert.h>
@@ -16,6 +16,8 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #if STDC_HEADERS
 # include <string.h>
@@ -36,7 +38,6 @@
 #include "dict.e"
 #include "openurl.e"
 #include "url.e"
-#include "errexit.e"
 #include "unent.e"
 
 static bool has_error = false;
@@ -95,6 +96,7 @@ static void output(const conststring type, const conststring rel,
   if (url) {					/* If we found a URL */
 
     /* Replace entities. */
+    while (isspace(*url)) url++;		/* Trim leading spaces */
     h = newnstring(url, 2 * strlen(url));	/* Reserve sufficient space */
     for (p = url, q = h; *p; p++) {
       if (*p != '&') {
@@ -111,6 +113,7 @@ static void output(const conststring type, const conststring rel,
       }
     }
     *q = '\0';
+    while (--q > h && isspace(*q)) *q = '\0';	/* Trim trailing spaces */
     url = h;
 
     /* Make URL absolute */
@@ -172,7 +175,7 @@ void* start(void)
   }
   return NULL;
 }
-  
+
 /* end -- called after the last event is reported */
 void end(void *clientdata)
 {
@@ -228,13 +231,14 @@ void handle_starttag(void *clientdata, string name, pairlist attribs)
     output("a", pairlist_get(attribs, "rel"), pairlist_get(attribs, "href"));
   } else if (strcasecmp(name, "img") == 0) {
     output("img", NULL, pairlist_get(attribs, "src"));
-    output("longdesc", NULL, pairlist_get(attribs, "longdesc"));
+    output("img", "longdesc", pairlist_get(attribs, "longdesc"));
+    output("img", "srcset", pairlist_get(attribs, "srcset"));
   } else if (strcasecmp(name, "input") == 0) {
-    output("input", NULL, pairlist_get(attribs, "src"));
+    output("input", "src", pairlist_get(attribs, "src"));
   } else if (strcasecmp(name, "object") == 0) {
     output("object", NULL,  pairlist_get(attribs, "data"));
-    output("object", NULL,  pairlist_get(attribs, "classid"));
-    output("object", NULL,  pairlist_get(attribs, "codebase"));
+    output("object", "classid",  pairlist_get(attribs, "classid"));
+    output("object", "codebase",  pairlist_get(attribs, "codebase"));
   } else if (strcasecmp(name, "area") == 0) {
     output("area", pairlist_get(attribs, "rel"), pairlist_get(attribs, "href"));
   } else if (strcasecmp(name, "ins") == 0) {
@@ -262,8 +266,8 @@ void handle_starttag(void *clientdata, string name, pairlist attribs)
   } else if (strcasecmp(name, "audio") == 0) {
     output("audio", NULL, pairlist_get(attribs, "src"));
   } else if (strcasecmp(name, "source") == 0) {
-    output("source", NULL, pairlist_get(attribs, "srcset"));
-    output("source", NULL, pairlist_get(attribs, "src"));
+    output("source", "srcset", pairlist_get(attribs, "srcset"));
+    output("source", "src", pairlist_get(attribs, "src"));
   }
 
   /* Free memory */
@@ -337,8 +341,8 @@ int main(int argc, char *argv[])
     usage(argv[0]);
   }
 
-  if (yyin == NULL) {perror(argv[optind]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[optind], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[optind]);
+  if (status != 200) errx(EX_IOERR,"%s: %s",argv[optind],http_strerror(status));
 
   if (yyparse() != 0) exit(3);
 
diff --git a/hxxmlns.c b/hxxmlns.c
index cc9ef33..5c7166e 100644
--- a/hxxmlns.c
+++ b/hxxmlns.c
@@ -11,7 +11,7 @@
  *
  * Author: Bert Bos
  * Created: 22 Mar 2000
- * Version: $Id: hxxmlns.c,v 1.8 2017/11/24 09:50:25 bbos Exp $
+ * Version: $Id: hxxmlns.c,v 1.9 2023/01/23 21:19:41 bbos Exp $
  *
  **/
 #include "config.h"
@@ -30,6 +30,8 @@
 #endif
 #include <stdlib.h>
 #include <assert.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
@@ -38,7 +40,6 @@
 #include "scan.e"
 #include "dict.e"
 #include "openurl.e"
-#include "errexit.e"
 
 extern int yylineno;				/* From scan.l */
 
@@ -282,8 +283,8 @@ int main(int argc, char *argv[])
   else if (i == argc - 1) yyin = fopenurl(argv[i], "r", &status);
   else usage(argv[0]);
 
-  if (yyin == NULL) {perror(argv[i]); exit(1);}
-  if (status != 200) errexit("%s : %s\n", argv[i], http_strerror(status));
+  if (yyin == NULL) err(EX_IOERR, "%s", argv[i]);
+  if (status != 200) errx(EX_IOERR, "%s: %s", argv[i], http_strerror(status));
 
   if (yyparse() != 0) exit(3);
 
diff --git a/langinfo.c b/langinfo.c
new file mode 100644
index 0000000..2262378
--- /dev/null
+++ b/langinfo.c
@@ -0,0 +1,38 @@
+/*
+ * Information about natural languages, in particular if the language
+ * has spaces between words.
+ *
+ * Copyright © 1994-2012 World Wide Web Consortium
+ * See http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+ *
+ * Created 9 May 1998
+ * Bert Bos <bert@w3.org>
+ * $Id: langinfo.c,v 1.2 2019/10/05 23:25:46 bbos Exp $
+ */
+#include "config.h"
+#ifdef HAVE_STRING_H
+#  include <string.h>
+#elif HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+#include <assert.h>
+#include <stdbool.h>
+#include "export.h"
+#include "types.e"
+
+
+/* with_spaces -- return true if the language has spaces between words */
+EXPORT bool with_spaces(const conststring lang)
+{
+  if (!lang) return true;	/* Default is with spaces */
+  if (eq(lang, "ja") || hasprefix(lang, "ja-")) return false; /* Japanese */
+  if (eq(lang, "zh") || hasprefix(lang, "zh-")) return false; /* Chinese */
+  if (eq(lang, "ko") || hasprefix(lang, "ko-")) return false; /* Korean */
+  if (eq(lang, "km") || hasprefix(lang, "km-")) return false; /* Khmer */
+  if (eq(lang, "th") || hasprefix(lang, "th-")) return false; /* Thai */
+#if 0
+  if (eq(lang, "lo") || hasprefix(lang, "lo-")) return false; /* Lao */
+  if (eq(lang, "my") || hasprefix(lang, "my-")) return false; /* Myanmar */
+#endif
+  return true;			/* Other languages are with spaces */
+}
diff --git a/langinfo.e b/langinfo.e
new file mode 100644
index 0000000..19e939f
--- /dev/null
+++ b/langinfo.e
@@ -0,0 +1,2 @@
+extern _Bool 
+           with_spaces(const conststring lang);
diff --git a/m4/libcurl.m4 b/m4/libcurl.m4
index d7d5a52..1e0c66f 100644
--- a/m4/libcurl.m4
+++ b/m4/libcurl.m4
@@ -61,7 +61,7 @@ AC_DEFUN([LIBCURL_CHECK_CONFIG],
   AH_TEMPLATE([LIBCURL_PROTOCOL_SMTP],[Defined if libcurl supports SMTP])
 
   AC_ARG_WITH(libcurl,
-     AC_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]),
+     AS_HELP_STRING([--with-libcurl=PREFIX],[look for the curl library in PREFIX/lib and headers in PREFIX/include]),
      [_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])])
 
   if test "$_libcurl_with" != "no" ; then
diff --git a/m4/libidn.m4 b/m4/libidn.m4
index f077156..3f81f79 100644
--- a/m4/libidn.m4
+++ b/m4/libidn.m4
@@ -3,8 +3,7 @@
 # Define --with-libidn and test macro HAVE_LIBIDN
 AC_DEFUN([LIBIDN_CHECK],
 [
-AC_ARG_WITH(libidn, AC_HELP_STRING([--with-libidn=[PREFIX]],
-                                [Look for libidn in PREFIX/lib and PREFIX/include]),
+AC_ARG_WITH(libidn, AS_HELP_STRING([--with-libidn=[PREFIX]],[Look for libidn in PREFIX/lib and PREFIX/include]),
   libidn=$withval, libidn=yes)
 if test "$libidn" != "no"; then
   if test "$libidn" != "yes"; then
diff --git a/m4/libidn2.m4 b/m4/libidn2.m4
index b57731f..f5a2a13 100644
--- a/m4/libidn2.m4
+++ b/m4/libidn2.m4
@@ -3,8 +3,7 @@
 # Define --with-libidn2 and test macro HAVE_LIBIDN2
 AC_DEFUN([LIBIDN2_CHECK],
 [
-AC_ARG_WITH(libidn2, AC_HELP_STRING([--with-libidn2=[PREFIX]],
-                                [Look for libidn2 in PREFIX/lib and PREFIX/include]),
+AC_ARG_WITH(libidn2, AS_HELP_STRING([--with-libidn2=[PREFIX]],[Look for libidn2 in PREFIX/lib and PREFIX/include]),
   libidn2=$withval, libidn2=yes)
 if test "$libidn2" != "no"; then
   if test "$libidn2" != "yes"; then
diff --git a/m4/optreset.m4 b/m4/optreset.m4
index 89d5371..bde4d00 100644
--- a/m4/optreset.m4
+++ b/m4/optreset.m4
@@ -4,14 +4,10 @@
 AC_DEFUN([CHECK_GETOPT_OPTRESET],
 [AC_CACHE_CHECK([whether getopt has optreset support],
 		ac_cv_have_getopt_optreset, [
-	AC_TRY_LINK(
-		[
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <getopt.h>
-		],
-		[ extern int optreset; optreset = 0; ],
-		[ ac_cv_have_getopt_optreset="yes" ],
-		[ ac_cv_have_getopt_optreset="no" ]
-	)
+		]], [[ extern int optreset; optreset = 0; ]])],[ ac_cv_have_getopt_optreset="yes" ],[ ac_cv_have_getopt_optreset="no" 
+	])
 ])
 if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then
 	AC_DEFINE(HAVE_GETOPT_OPTRESET, 1,
diff --git a/openurl.c b/openurl.c
index 07cd91c..1b81ced 100644
--- a/openurl.c
+++ b/openurl.c
@@ -69,6 +69,8 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <assert.h>
+#include <err.h>
+#include <sysexits.h>
 #include "export.h"
 #if HAVE_LIBCURL && !HAVE_FOPENCOOKIE
 # include "fopencookie.h"	/* Use our own fopencookie() */
@@ -76,7 +78,6 @@
 #include "dict.e"
 #include "heap.e"
 #include "types.e"
-#include "errexit.e"
 
 #define MAXREDIRECTS 10		/* Maximum # of 30x redirects to follow */
 
@@ -238,7 +239,7 @@ static CURLcode wait_for_data(URL_FILE *file, size_t want)
     while (rc == CURLM_CALL_MULTI_PERFORM);
 
     if (rc == CURLM_OUT_OF_MEMORY) return CURLE_OUT_OF_MEMORY;
-    if (rc != CURLM_OK) errexit("Error waiting for data (%d)\n", rc);
+    if (rc != CURLM_OK) errx(EX_IOERR, "Error waiting for data (%d)", rc);
 
     /* Stop if the connection is closed, after checking why */
     if (!file->still_running) {
@@ -266,11 +267,11 @@ static CURLcode wait_for_data(URL_FILE *file, size_t want)
     maxfd = -1;
     rc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
     if (rc == CURLM_OUT_OF_MEMORY) return CURLE_OUT_OF_MEMORY;
-    if (rc != CURLM_OK) errexit("Error waiting for data (%d)\n", rc);
+    if (rc != CURLM_OK) errx(EX_IOERR, "Error waiting for data (%d)", rc);
 
     /* Call select() to wait for either some data or a timeout */
     if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout) < 0)
-      errexit("select error: %s\n", strerror(errno));
+      err(EX_IOERR, "in select()");
   }
 
   return CURLE_OK;
diff --git a/scan.c b/scan.c
index 6d29cc0..cf7f8e5 100644
--- a/scan.c
+++ b/scan.c
@@ -8,7 +8,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 1
+#define YY_FLEX_SUBMINOR_VERSION 4
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -83,10 +83,16 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#ifndef SIZE_MAX
+#define SIZE_MAX               (~(size_t)0)
+#endif
+
 #endif /* ! C99 */
 
 #endif /* ! FLEXINT_H */
 
+/* begin standard C++ headers. */
+
 /* TODO: this is always defined, so inline it */
 #define yyconst const
 
@@ -99,32 +105,26 @@ typedef unsigned int flex_uint32_t;
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+/* Promotes a possibly negative, possibly signed char to an
+ *   integer in range [0..255] for use as an array index.
  */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
 
 /* Enter a start condition.  This macro really ought to take a parameter,
  * but we do it the disgusting crufty way forced on us by the ()-less
  * definition of BEGIN.
  */
 #define BEGIN (yy_start) = 1 + 2 *
-
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
 #define YY_START (((yy_start) - 1) / 2)
 #define YYSTATE YY_START
-
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
 /* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin  )
-
+#define YY_NEW_FILE yyrestart( yyin  )
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
@@ -161,7 +161,7 @@ extern FILE *yyin, *yyout;
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
-
+    
     #define YY_LESS_LINENO(n)
     #define YY_LINENO_REWIND_TO(ptr)
     
@@ -178,7 +178,6 @@ extern FILE *yyin, *yyout;
 		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
-
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -260,7 +259,6 @@ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
 #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
                           ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
                           : NULL)
-
 /* Same as previous macro, but useful when we know that the buffer stack is not
  * NULL or when we need an lvalue. For internal use only.
  */
@@ -281,65 +279,59 @@ static int yy_start = 0;	/* start state number */
  */
 static int yy_did_buffer_switch_on_eof;
 
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
-
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+void yyrestart ( FILE *input_file  );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size  );
+void yy_delete_buffer ( YY_BUFFER_STATE b  );
+void yy_flush_buffer ( YY_BUFFER_STATE b  );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer  );
+void yypop_buffer_state ( void );
 
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+static void yyensure_buffer_stack ( void );
+static void yy_load_buffer_state ( void );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file  );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
 
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size  );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str  );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len  );
 
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
+void *yyalloc ( yy_size_t  );
+void *yyrealloc ( void *, yy_size_t  );
+void yyfree ( void *  );
 
 #define yy_new_buffer yy_create_buffer
-
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
         yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
-
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
         yyensure_buffer_stack (); \
 		YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
-
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
 /* Begin user sect3 */
 
 #define yywrap() (/*CONSTCOND*/1)
 #define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
+typedef flex_uint8_t YY_CHAR;
 
 FILE *yyin = NULL, *yyout = NULL;
 
 typedef int yy_state_type;
 
 extern int yylineno;
-
 int yylineno = 1;
 
 extern char *yytext;
@@ -348,20 +340,20 @@ extern char *yytext;
 #endif
 #define yytext_ptr yytext
 
-static yyconst flex_int16_t yy_nxt[][39] =
+static const flex_int16_t yy_nxt[][31] =
     {
     {
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0
+        0
     },
 
     {
        13,   14,   14,   15,   16,   14,   14,   14,   14,   14,
        14,   14,   17,   14,   14,   14,   14,   14,   14,   14,
        14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-       14,   14,   14,   14,   14,   14,   14,   14,   18
+       18
     },
 
     {
@@ -369,21 +361,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
        14,   14,   17,   14,   14,   14,   14,   14,   14,   14,
 
        14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-       14,   14,   14,   14,   14,   14,   14,   14,   18
+       18
     },
 
     {
        13,   19,   20,   21,   22,   19,   19,   19,   23,   23,
        24,   23,   25,   26,   27,   19,   23,   23,   23,   23,
-       23,   23,   23,   23,   19,   19,   23,   23,   23,   23,
-       23,   23,   23,   23,   28,   19,   23,   23,   23
+       23,   23,   23,   23,   19,   19,   28,   19,   23,   23,
+       23
     },
 
     {
        13,   19,   20,   21,   22,   19,   19,   19,   23,   23,
        24,   23,   25,   26,   27,   19,   23,   23,   23,   23,
-       23,   23,   23,   23,   19,   19,   23,   23,   23,   23,
-       23,   23,   23,   23,   28,   19,   23,   23,   23
+       23,   23,   23,   23,   19,   19,   28,   19,   23,   23,
+       23
 
     },
 
@@ -391,36 +383,36 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,   29,   30,   31,   32,   29,   33,   34,   29,   29,
        29,   29,   19,   29,   19,   29,   29,   29,   29,   29,
        29,   29,   29,   29,   29,   29,   29,   29,   29,   29,
-       29,   29,   29,   29,   29,   29,   29,   29,   29
+       29
     },
 
     {
        13,   29,   30,   31,   32,   29,   33,   34,   29,   29,
        29,   29,   19,   29,   19,   29,   29,   29,   29,   29,
        29,   29,   29,   29,   29,   29,   29,   29,   29,   29,
-       29,   29,   29,   29,   29,   29,   29,   29,   29
+       29
     },
 
     {
        13,   19,   35,   36,   37,   19,   38,   39,   40,   40,
        19,   40,   19,   19,   41,   19,   40,   40,   40,   40,
 
-       40,   40,   40,   40,   19,   19,   40,   40,   40,   40,
-       40,   40,   40,   40,   42,   19,   40,   40,   40
+       40,   40,   40,   40,   19,   19,   42,   19,   40,   40,
+       40
     },
 
     {
        13,   19,   35,   36,   37,   19,   38,   39,   40,   40,
        19,   40,   19,   19,   41,   19,   40,   40,   40,   40,
-       40,   40,   40,   40,   19,   19,   40,   40,   40,   40,
-       40,   40,   40,   40,   42,   19,   40,   40,   40
+       40,   40,   40,   40,   19,   19,   42,   19,   40,   40,
+       40
     },
 
     {
        13,   14,   14,   15,   16,   14,   14,   14,   14,   14,
        14,   14,   17,   14,   14,   14,   14,   14,   14,   14,
        14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-       14,   14,   14,   14,   14,   14,   14,   14,   14
+       14
 
     },
 
@@ -428,14 +420,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,   14,   14,   15,   16,   14,   14,   14,   14,   14,
        14,   14,   17,   14,   14,   14,   14,   14,   14,   14,
        14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
-       14,   14,   14,   14,   14,   14,   14,   14,   14
+       14
     },
 
     {
        13,   43,   43,   44,   43,   43,   43,   43,   43,   43,
        43,   43,   45,   43,   43,   43,   43,   43,   43,   43,
        43,   43,   43,   43,   43,   43,   43,   43,   43,   43,
-       43,   43,   43,   43,   43,   43,   43,   43,   43
+       43
     },
 
     {
@@ -443,21 +435,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
        43,   43,   45,   43,   43,   43,   43,   43,   43,   43,
 
        43,   43,   43,   43,   43,   43,   43,   43,   43,   43,
-       43,   43,   43,   43,   43,   43,   43,   43,   43
+       43
     },
 
     {
       -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,
       -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,
       -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,
-      -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13,  -13
+      -13
     },
 
     {
        13,   46,   46,  -14,  -14,   46,   46,   46,   46,   46,
        46,   46,  -14,   46,   46,   46,   46,   46,   46,   46,
        46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46
+       46
 
     },
 
@@ -465,36 +457,36 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
       -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
       -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,
-      -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15,  -15
+      -15
     },
 
     {
        13,  -16,  -16,   47,  -16,  -16,  -16,  -16,  -16,  -16,
       -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
       -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,
-      -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16,  -16
+      -16
     },
 
     {
        13,  -17,  -17,  -17,  -17,   48,  -17,  -17,   49,   49,
        50,   49,  -17,  -17,  -17,   51,   49,   49,   49,   49,
 
-       49,   49,   49,   49,  -17,  -17,   49,   49,   49,   49,
-       49,   49,   49,   49,   52,  -17,   49,   49,   49
+       49,   49,   49,   49,  -17,  -17,   52,  -17,   49,   49,
+       49
     },
 
     {
        13,   46,   46,  -18,  -18,   46,   46,   46,   46,   46,
        46,   46,  -18,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   53,   46,   46
+       46,   46,   46,   46,   46,   46,   46,   46,   53,   46,
+       46
     },
 
     {
        13,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
       -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
       -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,
-      -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19,  -19
+      -19
 
     },
 
@@ -502,14 +494,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -20,   54,  -20,  -20,  -20,  -20,  -20,  -20,  -20,
       -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,
       -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,
-      -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20
+      -20
     },
 
     {
        13,  -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,
       -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,
       -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,
-      -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21,  -21
+      -21
     },
 
     {
@@ -517,21 +509,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,
 
       -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,
-      -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22,  -22
+      -22
     },
 
     {
        13,  -23,  -23,  -23,  -23,  -23,  -23,  -23,   56,   56,
       -23,   56,  -23,  -23,  -23,  -23,   56,   56,   56,   56,
-       56,   56,   56,   56,  -23,  -23,   56,   56,   56,   56,
-       56,   56,   56,   56,  -23,  -23,   56,   56,   56
+       56,   56,   56,   56,  -23,  -23,  -23,  -23,   56,   56,
+       56
     },
 
     {
        13,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
       -24,  -24,  -24,  -24,   57,  -24,  -24,  -24,  -24,  -24,
       -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,
-      -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24,  -24
+      -24
 
     },
 
@@ -539,14 +531,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
       -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
       -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,
-      -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25,  -25
+      -25
     },
 
     {
        13,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
       -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,
-      -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26,  -26
+      -26
     },
 
     {
@@ -554,21 +546,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
 
       -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,
-      -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27,  -27
+      -27
     },
 
     {
        13,   58,  -28,  -28,  -28,   58,   58,   58,   58,   58,
        58,   58,   58,   58,   58,   58,   58,   58,   58,   58,
-       58,   58,   58,   58,   58,   58,   58,   58,   58,   58,
-       58,   58,   58,   58,   58,   59,   58,   58,   58
+       58,   58,   58,   58,   58,   58,   58,   59,   58,   58,
+       58
     },
 
     {
        13,   60,  -29,  -29,  -29,   60,  -29,  -29,   60,   60,
        60,   60,  -29,   60,  -29,   60,   60,   60,   60,   60,
        60,   60,   60,   60,   60,   60,   60,   60,   60,   60,
-       60,   60,   60,   60,   60,   60,   60,   60,   60
+       60
 
     },
 
@@ -576,14 +568,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -30,   61,  -30,  -30,  -30,  -30,  -30,  -30,  -30,
       -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,
       -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,
-      -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30,  -30
+      -30
     },
 
     {
        13,  -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,
       -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,
       -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,
-      -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31,  -31
+      -31
     },
 
     {
@@ -591,21 +583,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,
 
       -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,
-      -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32,  -32
+      -32
     },
 
     {
        13,   63,   63,   63,   63,   63,   64,   63,   63,   63,
        63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
        63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
-       63,   63,   63,   63,   63,   63,   63,   63,   63
+       63
     },
 
     {
        13,   65,   65,   65,   65,   65,   65,   66,   65,   65,
        65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
        65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65
+       65
 
     },
 
@@ -613,14 +605,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -35,   67,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
       -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
       -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,
-      -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35,  -35
+      -35
     },
 
     {
        13,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
       -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
       -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,
-      -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36,  -36
+      -36
     },
 
     {
@@ -628,58 +620,58 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
 
       -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,
-      -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37,  -37
+      -37
     },
 
     {
        13,   69,   69,   69,   69,   69,   70,   69,   69,   69,
        69,   69,   69,   69,   69,   69,   69,   69,   69,   69,
        69,   69,   69,   69,   69,   69,   69,   69,   69,   69,
-       69,   69,   69,   69,   69,   69,   69,   69,   69
+       69
     },
 
     {
        13,   71,   71,   71,   71,   71,   71,   72,   71,   71,
        71,   71,   71,   71,   71,   71,   71,   71,   71,   71,
        71,   71,   71,   71,   71,   71,   71,   71,   71,   71,
-       71,   71,   71,   71,   71,   71,   71,   71,   71
+       71
 
     },
 
     {
        13,  -40,  -40,  -40,  -40,  -40,  -40,  -40,   73,   73,
       -40,   73,  -40,  -40,  -40,  -40,   73,   73,   73,   73,
-       73,   73,   73,   73,  -40,  -40,   73,   73,   73,   73,
-       73,   73,   73,   73,  -40,  -40,   73,   73,   73
+       73,   73,   73,   73,  -40,  -40,  -40,  -40,   73,   73,
+       73
     },
 
     {
        13,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
       -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
       -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,
-      -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41,  -41
+      -41
     },
 
     {
        13,   74,  -42,  -42,  -42,   74,   74,   74,   74,   74,
        74,   74,   74,   74,   74,   74,   74,   74,   74,   74,
 
-       74,   74,   74,   74,   74,   74,   74,   74,   74,   74,
-       74,   74,   74,   74,   74,   75,   74,   74,   74
+       74,   74,   74,   74,   74,   74,   74,   75,   74,   74,
+       74
     },
 
     {
        13,   76,   76,   76,   76,   76,   76,   76,   76,   76,
        76,   76,   77,   76,   76,   76,   76,   76,   76,   76,
        76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
-       76,   76,   76,   76,   76,   76,   76,   76,   76
+       76
     },
 
     {
        13,   76,   76,   76,   76,   76,   76,   76,   76,   76,
        76,   76,   77,   76,   76,   76,   76,   76,   76,   76,
        76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
-       76,   76,   76,   76,   76,   76,   76,   76,   76
+       76
 
     },
 
@@ -687,14 +679,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,   76,   76,   76,   76,   76,   76,   76,   76,   76,
        78,   76,   76,   76,   76,   76,   76,   76,   76,   76,
        76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
-       76,   76,   76,   76,   76,   76,   76,   76,   76
+       76
     },
 
     {
        13,   46,   46,  -46,  -46,   46,   46,   46,   46,   46,
        46,   46,  -46,   46,   46,   46,   46,   46,   46,   46,
        46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46
+       46
     },
 
     {
@@ -702,58 +694,58 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,
 
       -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,
-      -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47,  -47
+      -47
     },
 
     {
        13,  -48,  -48,  -48,  -48,  -48,  -48,  -48,   79,  -48,
       -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,   80,  -48,
-      -48,  -48,  -48,  -48,   81,  -48,  -48,  -48,   80,  -48,
-      -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48,  -48
+      -48,  -48,  -48,  -48,   81,  -48,  -48,  -48,  -48,  -48,
+      -48
     },
 
     {
        13,  -49,  -49,  -49,  -49,  -49,  -49,  -49,   49,   49,
       -49,   49,  -49,  -49,  -49,  -49,   49,   49,   49,   49,
-       49,   49,   49,   49,  -49,  -49,   49,   49,   49,   49,
-       49,   49,   49,   49,  -49,  -49,   49,   49,   49
+       49,   49,   49,   49,  -49,  -49,  -49,  -49,   49,   49,
+       49
 
     },
 
     {
        13,  -50,  -50,  -50,  -50,  -50,  -50,  -50,   82,   82,
       -50,   82,  -50,  -50,  -50,  -50,   82,   82,   82,   82,
-       82,   82,   82,   82,  -50,  -50,   82,   82,   82,   82,
-       82,   82,   82,   82,   83,  -50,   82,   82,   82
+       82,   82,   82,   82,  -50,  -50,   83,  -50,   82,   82,
+       82
     },
 
     {
        13,   84,   84,   84,   84,   84,   84,   84,   84,   84,
        84,   84,   84,   84,   85,   84,   84,   84,   84,   84,
        84,   84,   84,   84,   84,   84,   84,   84,   84,   84,
-       84,   84,   84,   84,   84,   84,   84,   84,   84
+       84
     },
 
     {
        13,   86,  -52,  -52,  -52,   86,   86,   86,   86,   86,
        86,   86,   86,   86,   86,   86,   86,   86,   86,   86,
 
-       86,   86,   86,   86,   86,   86,   86,   86,   86,   86,
-       86,   86,   86,   86,   86,   87,   86,   86,   86
+       86,   86,   86,   86,   86,   86,   86,   87,   86,   86,
+       86
     },
 
     {
        13,   46,   46,  -53,  -53,   46,   46,   46,   46,   46,
        46,   46,  -53,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   88,   46
+       46,   46,   46,   46,   46,   46,   46,   46,   46,   88,
+       46
     },
 
     {
        13,  -54,   54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,
       -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,
       -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,
-      -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54,  -54
+      -54
 
     },
 
@@ -761,14 +753,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,
       -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,
       -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,
-      -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55,  -55
+      -55
     },
 
     {
        13,  -56,  -56,  -56,  -56,  -56,  -56,  -56,   56,   56,
       -56,   56,  -56,  -56,  -56,  -56,   56,   56,   56,   56,
-       56,   56,   56,   56,  -56,  -56,   56,   56,   56,   56,
-       56,   56,   56,   56,  -56,  -56,   56,   56,   56
+       56,   56,   56,   56,  -56,  -56,  -56,  -56,   56,   56,
+       56
     },
 
     {
@@ -776,21 +768,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
 
       -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,
-      -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57,  -57
+      -57
     },
 
     {
        13,   58,  -58,  -58,  -58,   58,   58,   58,   58,   58,
        58,   58,   58,   58,   58,   58,   58,   58,   58,   58,
-       58,   58,   58,   58,   58,   58,   58,   58,   58,   58,
-       58,   58,   58,   58,   58,   59,   58,   58,   58
+       58,   58,   58,   58,   58,   58,   58,   59,   58,   58,
+       58
     },
 
     {
        13,  -59,  -59,  -59,  -59,  -59,  -59,  -59,   56,   56,
       -59,   56,  -59,  -59,  -59,  -59,   56,   56,   56,   56,
-       56,   56,   56,   56,  -59,  -59,   56,   56,   56,   56,
-       56,   56,   56,   56,  -59,  -59,   56,   56,   56
+       56,   56,   56,   56,  -59,  -59,  -59,  -59,   56,   56,
+       56
 
     },
 
@@ -798,14 +790,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,   60,  -60,  -60,  -60,   60,  -60,  -60,   60,   60,
        60,   60,  -60,   60,  -60,   60,   60,   60,   60,   60,
        60,   60,   60,   60,   60,   60,   60,   60,   60,   60,
-       60,   60,   60,   60,   60,   60,   60,   60,   60
+       60
     },
 
     {
        13,  -61,   61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,
       -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,
       -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,
-      -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61,  -61
+      -61
     },
 
     {
@@ -813,21 +805,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
 
       -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,
-      -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62,  -62
+      -62
     },
 
     {
        13,   63,   63,   63,   63,   63,   64,   63,   63,   63,
        63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
        63,   63,   63,   63,   63,   63,   63,   63,   63,   63,
-       63,   63,   63,   63,   63,   63,   63,   63,   63
+       63
     },
 
     {
        13,  -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,
       -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,
       -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,
-      -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64,  -64
+      -64
 
     },
 
@@ -835,14 +827,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,   65,   65,   65,   65,   65,   65,   66,   65,   65,
        65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
        65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
-       65,   65,   65,   65,   65,   65,   65,   65,   65
+       65
     },
 
     {
        13,  -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,
       -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,
       -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,
-      -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66,  -66
+      -66
     },
 
     {
@@ -850,21 +842,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,
 
       -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,
-      -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67,  -67
+      -67
     },
 
     {
        13,  -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,
       -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,
       -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,
-      -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68,  -68
+      -68
     },
 
     {
        13,   69,   69,   69,   69,   69,   70,   69,   69,   69,
        69,   69,   69,   69,   69,   69,   69,   69,   69,   69,
        69,   69,   69,   69,   69,   69,   69,   69,   69,   69,
-       69,   69,   69,   69,   69,   69,   69,   69,   69
+       69
 
     },
 
@@ -872,14 +864,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,
       -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,
       -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,
-      -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70,  -70
+      -70
     },
 
     {
        13,   71,   71,   71,   71,   71,   71,   72,   71,   71,
        71,   71,   71,   71,   71,   71,   71,   71,   71,   71,
        71,   71,   71,   71,   71,   71,   71,   71,   71,   71,
-       71,   71,   71,   71,   71,   71,   71,   71,   71
+       71
     },
 
     {
@@ -887,36 +879,36 @@ static yyconst flex_int16_t yy_nxt[][39] =
       -72,  -72,  -72,  -72,  -72,  -72,  -72,  -72,  -72,  -72,
 
       -72,  -72,  -72,  -72,  -72,  -72,  -72,  -72,  -72,  -72,
-      -72,  -72,  -72,  -72,  -72,  -72,  -72,  -72,  -72
+      -72
     },
 
     {
        13,  -73,  -73,  -73,  -73,  -73,  -73,  -73,   73,   73,
       -73,   73,  -73,  -73,  -73,  -73,   73,   73,   73,   73,
-       73,   73,   73,   73,  -73,  -73,   73,   73,   73,   73,
-       73,   73,   73,   73,  -73,  -73,   73,   73,   73
+       73,   73,   73,   73,  -73,  -73,  -73,  -73,   73,   73,
+       73
     },
 
     {
        13,   74,  -74,  -74,  -74,   74,   74,   74,   74,   74,
        74,   74,   74,   74,   74,   74,   74,   74,   74,   74,
-       74,   74,   74,   74,   74,   74,   74,   74,   74,   74,
-       74,   74,   74,   74,   74,   75,   74,   74,   74
+       74,   74,   74,   74,   74,   74,   74,   75,   74,   74,
+       74
 
     },
 
     {
        13,  -75,  -75,  -75,  -75,  -75,  -75,  -75,   73,   73,
       -75,   73,  -75,  -75,  -75,  -75,   73,   73,   73,   73,
-       73,   73,   73,   73,  -75,  -75,   73,   73,   73,   73,
-       73,   73,   73,   73,  -75,  -75,   73,   73,   73
+       73,   73,   73,   73,  -75,  -75,  -75,  -75,   73,   73,
+       73
     },
 
     {
        13,   76,   76,   76,   76,   76,   76,   76,   76,   76,
        76,   76,   77,   76,   76,   76,   76,   76,   76,   76,
        76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
-       76,   76,   76,   76,   76,   76,   76,   76,   76
+       76
     },
 
     {
@@ -924,21 +916,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
        89,   76,   76,   76,   76,   76,   76,   76,   76,   76,
 
        76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
-       76,   76,   76,   76,   76,   76,   76,   76,   76
+       76
     },
 
     {
        13,   76,   76,   76,   76,   76,   76,   76,   90,   90,
-       76,   91,   76,   76,   76,   76,   91,   91,   91,   91,
-       91,   91,   91,   91,   76,   76,   90,   90,   90,   90,
-       90,   90,   90,   90,   92,   76,   91,   91,   91
+       76,   91,   76,   76,   76,   76,   90,   90,   90,   90,
+       90,   90,   90,   90,   76,   76,   92,   76,   91,   91,
+       91
     },
 
     {
        13,  -79,  -79,  -79,  -79,  -79,  -79,  -79,   93,  -79,
       -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,
       -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,
-      -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79,  -79
+      -79
 
     },
 
@@ -946,36 +938,36 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -80,  -80,  -80,  -80,  -80,  -80,  -80,  -80,  -80,
       -80,  -80,  -80,  -80,  -80,  -80,  -80,  -80,  -80,  -80,
        94,  -80,  -80,  -80,  -80,  -80,  -80,  -80,  -80,  -80,
-       94,  -80,  -80,  -80,  -80,  -80,  -80,  -80,  -80
+      -80
     },
 
     {
        13,  -81,  -81,  -81,  -81,  -81,  -81,  -81,  -81,  -81,
       -81,  -81,  -81,  -81,  -81,  -81,  -81,   95,  -81,  -81,
-      -81,  -81,  -81,  -81,  -81,  -81,  -81,   95,  -81,  -81,
-      -81,  -81,  -81,  -81,  -81,  -81,  -81,  -81,  -81
+      -81,  -81,  -81,  -81,  -81,  -81,  -81,  -81,  -81,  -81,
+      -81
     },
 
     {
        13,  -82,  -82,  -82,  -82,  -82,  -82,  -82,   82,   82,
       -82,   82,  -82,  -82,  -82,  -82,   82,   82,   82,   82,
 
-       82,   82,   82,   82,  -82,  -82,   82,   82,   82,   82,
-       82,   82,   82,   82,  -82,  -82,   82,   82,   82
+       82,   82,   82,   82,  -82,  -82,  -82,  -82,   82,   82,
+       82
     },
 
     {
        13,   96,  -83,  -83,  -83,   96,   96,   96,   96,   96,
        96,   96,   96,   96,   96,   96,   96,   96,   96,   96,
-       96,   96,   96,   96,   96,   96,   96,   96,   96,   96,
-       96,   96,   96,   96,   96,   97,   96,   96,   96
+       96,   96,   96,   96,   96,   96,   96,   97,   96,   96,
+       96
     },
 
     {
        13,   84,   84,   84,   84,   84,   84,   84,   84,   84,
        84,   84,   84,   84,   85,   84,   84,   84,   84,   84,
        84,   84,   84,   84,   84,   84,   84,   84,   84,   84,
-       84,   84,   84,   84,   84,   84,   84,   84,   84
+       84
 
     },
 
@@ -983,110 +975,110 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,
       -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,
       -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,
-      -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85,  -85
+      -85
     },
 
     {
        13,   86,  -86,  -86,  -86,   86,   86,   86,   86,   86,
        86,   86,   86,   86,   86,   86,   86,   86,   86,   86,
-       86,   86,   86,   86,   86,   86,   86,   86,   86,   86,
-       86,   86,   86,   86,   86,   87,   86,   86,   86
+       86,   86,   86,   86,   86,   86,   86,   87,   86,   86,
+       86
     },
 
     {
        13,  -87,  -87,  -87,  -87,  -87,  -87,  -87,   49,   49,
       -87,   49,  -87,  -87,  -87,  -87,   49,   49,   49,   49,
 
-       49,   49,   49,   49,  -87,  -87,   49,   49,   49,   49,
-       49,   49,   49,   49,  -87,  -87,   49,   49,   49
+       49,   49,   49,   49,  -87,  -87,  -87,  -87,   49,   49,
+       49
     },
 
     {
        13,   46,   46,  -88,  -88,   46,   46,   46,   46,   46,
        46,   46,  -88,   46,   46,   46,   46,   46,   46,   46,
        46,   46,   46,   46,   46,   46,   46,   46,   46,   46,
-       46,   46,   46,   46,   46,   46,   46,   46,   46
+       46
     },
 
     {
        13,   76,   76,   76,   76,   76,   76,   76,  -89,  -89,
-       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
        76,   76,   76,   76,   76,   76,  -89,  -89,  -89,  -89,
-      -89,  -89,  -89,  -89,  -89,   76,   76,   76,   76
+      -89,  -89,  -89,  -89,   76,   76,  -89,   76,   76,   76,
+       76
 
     },
 
     {
        13,  -90,  -90,  -90,  -90,  -90,  -90,  -90,   90,   90,
       -90,   90,  -90,  -90,  -90,  -90,   90,   90,   90,   90,
-       90,   90,   90,   90,  -90,  -90,   90,   90,   90,   90,
-       90,   90,   90,   90,  -90,  -90,   90,   90,   90
+       90,   90,   90,   90,  -90,  -90,  -90,  -90,   90,   90,
+       90
     },
 
     {
        13,   76,   76,   76,   76,   76,   76,   76,   91,   91,
        76,   91,   77,   76,   76,   76,   91,   91,   91,   91,
-       91,   91,   91,   91,   76,   76,   91,   91,   91,   91,
-       91,   91,   91,   91,   76,   76,   91,   91,   91
+       91,   91,   91,   91,   76,   76,   76,   76,   91,   91,
+       91
     },
 
     {
        13,   98,  -92,  -92,  -92,   98,   98,   98,   98,   98,
        98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
 
-       98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
-       98,   98,   98,   98,   98,   99,   98,   98,   98
+       98,   98,   98,   98,   98,   98,   98,   99,   98,   98,
+       98
     },
 
     {
        13,  100,  100,  100,  100,  100,  100,  100,  101,  100,
       100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
       100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
-      100,  100,  100,  100,  100,  100,  100,  100,  100
+      100
     },
 
     {
        13,  -94,  -94,  -94,  -94,  -94,  -94,  -94,  -94,  -94,
       -94,  -94,  -94,  -94,  -94,  -94,  -94,  102,  -94,  -94,
-      -94,  -94,  -94,  -94,  -94,  -94,  -94,  102,  -94,  -94,
-      -94,  -94,  -94,  -94,  -94,  -94,  -94,  -94,  -94
+      -94,  -94,  -94,  -94,  -94,  -94,  -94,  -94,  -94,  -94,
+      -94
 
     },
 
     {
        13,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,
       -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  103,  -95,
-      -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  103,  -95,
-      -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95
+      -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,  -95,
+      -95
     },
 
     {
        13,   96,  -96,  -96,  -96,   96,   96,   96,   96,   96,
        96,   96,   96,   96,   96,   96,   96,   96,   96,   96,
-       96,   96,   96,   96,   96,   96,   96,   96,   96,   96,
-       96,   96,   96,   96,   96,   97,   96,   96,   96
+       96,   96,   96,   96,   96,   96,   96,   97,   96,   96,
+       96
     },
 
     {
        13,  -97,  -97,  -97,  -97,  -97,  -97,  -97,   82,   82,
       -97,   82,  -97,  -97,  -97,  -97,   82,   82,   82,   82,
 
-       82,   82,   82,   82,  -97,  -97,   82,   82,   82,   82,
-       82,   82,   82,   82,  -97,  -97,   82,   82,   82
+       82,   82,   82,   82,  -97,  -97,  -97,  -97,   82,   82,
+       82
     },
 
     {
        13,   98,  -98,  -98,  -98,   98,   98,   98,   98,   98,
        98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
-       98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
-       98,   98,   98,   98,   98,   99,   98,   98,   98
+       98,   98,   98,   98,   98,   98,   98,   99,   98,   98,
+       98
     },
 
     {
        13,  -99,  -99,  -99,  -99,  -99,  -99,  -99,   90,   90,
       -99,   90,  -99,  -99,  -99,  -99,   90,   90,   90,   90,
-       90,   90,   90,   90,  -99,  -99,   90,   90,   90,   90,
-       90,   90,   90,   90,  -99,  -99,   90,   90,   90
+       90,   90,   90,   90,  -99,  -99,  -99,  -99,   90,   90,
+       90
 
     },
 
@@ -1094,14 +1086,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  100,  100,  100,  100,  100,  100,  100,  101,  100,
       100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
       100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
-      100,  100,  100,  100,  100,  100,  100,  100,  100
+      100
     },
 
     {
        13,  100,  100,  100,  100,  100,  100,  100,  104,  100,
       100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
       100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
-      100,  100,  100,  100,  100,  100,  100,  100,  100
+      100
     },
 
     {
@@ -1109,21 +1101,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
      -102, -102, -102, -102, -102, -102, -102, -102, -102, -102,
 
      -102, -102,  105, -102, -102, -102, -102, -102, -102, -102,
-     -102, -102,  105, -102, -102, -102, -102, -102, -102
+     -102
     },
 
     {
        13, -103, -103, -103, -103, -103, -103, -103, -103, -103,
      -103, -103, -103, -103, -103, -103,  106, -103, -103, -103,
-     -103, -103, -103, -103, -103, -103,  106, -103, -103, -103,
-     -103, -103, -103, -103, -103, -103, -103, -103, -103
+     -103, -103, -103, -103, -103, -103, -103, -103, -103, -103,
+     -103
     },
 
     {
        13,  100,  100,  100,  100,  100,  100,  100,  100,  100,
       100,  100,  100,  100,  107,  100,  100,  100,  100,  100,
       100,  100,  100,  100,  100,  100,  100,  100,  100,  100,
-      100,  100,  100,  100,  100,  100,  100,  100,  100
+      100
 
     },
 
@@ -1131,14 +1123,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13, -105, -105, -105, -105, -105, -105, -105, -105, -105,
      -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
      -105, -105, -105,  108, -105, -105, -105, -105, -105, -105,
-     -105, -105, -105,  108, -105, -105, -105, -105, -105
+     -105
     },
 
     {
        13, -106, -106, -106, -106, -106, -106, -106, -106, -106,
      -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
      -106, -106,  109, -106, -106, -106, -106, -106, -106, -106,
-     -106, -106,  109, -106, -106, -106, -106, -106, -106
+     -106
     },
 
     {
@@ -1146,36 +1138,36 @@ static yyconst flex_int16_t yy_nxt[][39] =
      -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
 
      -107, -107, -107, -107, -107, -107, -107, -107, -107, -107,
-     -107, -107, -107, -107, -107, -107, -107, -107, -107
+     -107
     },
 
     {
        13, -108, -108, -108, -108, -108, -108, -108, -108, -108,
      -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
      -108,  110, -108, -108, -108, -108, -108, -108, -108, -108,
-     -108,  110, -108, -108, -108, -108, -108, -108, -108
+     -108
     },
 
     {
        13, -109, -109, -109, -109, -109, -109, -109, -109, -109,
      -109, -109, -109, -109, -109, -109,  111, -109, -109, -109,
-     -109, -109, -109, -109, -109, -109,  111, -109, -109, -109,
-     -109, -109, -109, -109, -109, -109, -109, -109, -109
+     -109, -109, -109, -109, -109, -109, -109, -109, -109, -109,
+     -109
 
     },
 
     {
        13, -110, -110, -110, -110, -110, -110, -110, -110, -110,
      -110, -110, -110, -110, -110, -110, -110, -110, -110,  112,
-     -110, -110, -110, -110, -110, -110, -110, -110, -110,  112,
-     -110, -110, -110, -110, -110, -110, -110, -110, -110
+     -110, -110, -110, -110, -110, -110, -110, -110, -110, -110,
+     -110
     },
 
     {
        13, -111, -111, -111, -111, -111, -111, -111, -111, -111,
      -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
      -111, -111, -111, -111,  113, -111, -111, -111, -111, -111,
-     -111, -111, -111, -111, -111, -111, -111, -111, -111
+     -111
     },
 
     {
@@ -1183,21 +1175,21 @@ static yyconst flex_int16_t yy_nxt[][39] =
      -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
 
      -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
-     -112, -112, -112, -112, -112, -112, -112, -112, -112
+     -112
     },
 
     {
        13,  115,  115,  115,  115,  115,  115,  115,  115,  115,
       115,  115,  115,  115,  115,  115,  115,  115,  115,  115,
       115,  115,  115,  115,  115,  116,  115,  115,  115,  115,
-      115,  115,  115,  115,  115,  115,  115,  115,  115
+      115
     },
 
     {
        13, -114, -114, -114, -114, -114, -114, -114, -114, -114,
      -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
      -114, -114, -114, -114, -114, -114, -114, -114, -114, -114,
-     -114, -114, -114, -114, -114, -114, -114, -114, -114
+     -114
 
     },
 
@@ -1205,14 +1197,14 @@ static yyconst flex_int16_t yy_nxt[][39] =
        13,  115,  115,  115,  115,  115,  115,  115,  115,  115,
       115,  115,  115,  115,  115,  115,  115,  115,  115,  115,
       115,  115,  115,  115,  115,  116,  115,  115,  115,  115,
-      115,  115,  115,  115,  115,  115,  115,  115,  115
+      115
     },
 
     {
        13,  115,  115,  115,  115,  115,  115,  115,  115,  115,
       115,  115,  115,  115,  115,  115,  115,  115,  115,  115,
       115,  115,  115,  115,  115,  117,  115,  115,  115,  115,
-      115,  115,  115,  115,  115,  115,  115,  115,  115
+      115
     },
 
     {
@@ -1220,22 +1212,22 @@ static yyconst flex_int16_t yy_nxt[][39] =
       115,  115,  115,  115,  118,  115,  115,  115,  115,  115,
 
       115,  115,  115,  115,  115,  115,  115,  115,  115,  115,
-      115,  115,  115,  115,  115,  115,  115,  115,  115
+      115
     },
 
     {
        13, -118, -118, -118, -118, -118, -118, -118, -118, -118,
      -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
      -118, -118, -118, -118, -118, -118, -118, -118, -118, -118,
-     -118, -118, -118, -118, -118, -118, -118, -118, -118
+     -118
     },
 
     } ;
 
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yynoreturn yy_fatal_error (yyconst char* msg  );
+static yy_state_type yy_get_previous_state ( void );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state  );
+static int yy_get_next_buffer ( void );
+static void yynoreturn yy_fatal_error ( const char* msg  );
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
@@ -1246,7 +1238,6 @@ static void yynoreturn yy_fatal_error (yyconst char* msg  );
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
-
 #define YY_NUM_RULES 32
 #define YY_END_OF_BUFFER 33
 /* This struct is not used in this scanner,
@@ -1256,7 +1247,7 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[119] =
+static const flex_int16_t yy_accept[119] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
        29,   29,   33,    4,    6,    6,   10,    4,   31,   13,
@@ -1273,7 +1264,7 @@ static yyconst flex_int16_t yy_accept[119] =
         0,    0,    0,    8,    0,    0,    0,    5
     } ;
 
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    2,    4,    1,    1,    1,    1,    1,    1,    1,
@@ -1281,26 +1272,26 @@ static yyconst YY_CHAR yy_ec[256] =
         1,    2,    5,    6,    1,    1,    1,    1,    7,    1,
         1,    1,    1,    1,    8,    9,   10,   11,   11,   11,
        11,   11,   11,   11,   11,   11,   11,    9,    1,   12,
-       13,   14,   15,    1,   16,   11,   17,   18,   19,   11,
-       11,   11,   11,   11,   11,   11,   11,   11,   20,   21,
-       11,   11,   11,   22,   11,   11,   11,   11,   23,   11,
-       24,    1,   25,    1,    9,    1,   26,    9,   27,   28,
-
-       29,    9,    9,    9,    9,    9,    9,    9,    9,    9,
-       30,   31,    9,    9,    9,   32,    9,    9,    9,    9,
-       33,    9,   34,    1,   35,    1,    1,   11,   11,   11,
+       13,   14,   15,    1,   16,    9,   17,   18,   19,    9,
+        9,    9,    9,    9,    9,    9,    9,    9,   20,   21,
+        9,    9,    9,   22,    9,    9,    9,    9,   23,    9,
+       24,    1,   25,    1,    9,    1,   16,    9,   17,   18,
+
+       19,    9,    9,    9,    9,    9,    9,    9,    9,    9,
+       20,   21,    9,    9,    9,   22,    9,    9,    9,    9,
+       23,    9,   26,    1,   27,    1,    1,   11,   11,   11,
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
-       11,   11,   11,   11,   11,   11,   36,   11,   11,   11,
-       37,   11,   11,   11,   11,   11,   11,   11,   11,   11,
+       11,   11,   11,   11,   11,   11,   28,   11,   11,   11,
+       29,   11,   11,   11,   11,   11,   11,   11,   11,   11,
 
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
-       11,   11,   11,   11,   11,   11,   11,   11,   38,   11,
+       11,   11,   11,   11,   11,   11,   11,   11,   30,   11,
        11,   11,   11,   11,   11,   11,   11,   11,   11,   11,
        11,   11,   11,   11,   11
     } ;
@@ -1342,13 +1333,14 @@ char *yytext;
 #endif
 #include <stdlib.h>
 #include <ctype.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
 #include "heap.e"
 #include "html.h"
 #include "html.e"
-#include "errexit.e"
 
 
 EXPORT extern FILE *yyin;
@@ -1392,7 +1384,7 @@ EXPORT void include_file(FILE *f, const conststring name)
   h->next = stack;
   stack = h;
   yyin_name = newstring(name);
-  yy_switch_to_buffer(yy_create_buffer(f,YY_BUF_SIZE));
+  yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
 }
 
 /* pop_file -- back to previous input file */
@@ -1427,7 +1419,7 @@ static string esc(string s)
   }
   /* Copy and expand */
   u = malloc(i + 1);
-  if (!u) errexit("Out of memory\n");
+  if (!u) err(EX_OSERR, NULL);
   for (i = 0, j = 1; s[j] != s[0]; i++, j++) {
     if (s[j] == '"')  {strcpy(u + i, "&#34;"); i += 4;}
     else if (s[j] == '<')  {strcpy(u + i, "&#60;"); i += 4;}
@@ -1447,7 +1439,7 @@ static string esc(string s)
 static string strndup(const string s, size_t n)
 {
   string t = malloc(n + 1);
-  if (!t) errexit("Out of memory\n");
+  if (!t) err(EX_OSERR, NULL);
   strncpy(t, s, n);
   t[n] = '\0';
   return t;
@@ -1479,9 +1471,10 @@ static void lns(const string t)
   }
 }
 
+#line 1475 "scan.c"
 /* thing is rather too permissive, but it will accept <img src=/path>... */
 
-#line 1485 "scan.c"
+#line 1478 "scan.c"
 
 #define INITIAL 0
 #define MARKUP 1
@@ -1502,36 +1495,36 @@ static void lns(const string t)
 #define YY_EXTRA_TYPE void *
 #endif
 
-static int yy_init_globals (void );
+static int yy_init_globals ( void );
 
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
-int yylex_destroy (void );
+int yylex_destroy ( void );
 
-int yyget_debug (void );
+int yyget_debug ( void );
 
-void yyset_debug (int debug_flag  );
+void yyset_debug ( int debug_flag  );
 
-YY_EXTRA_TYPE yyget_extra (void );
+YY_EXTRA_TYPE yyget_extra ( void );
 
-void yyset_extra (YY_EXTRA_TYPE user_defined  );
+void yyset_extra ( YY_EXTRA_TYPE user_defined  );
 
-FILE *yyget_in (void );
+FILE *yyget_in ( void );
 
-void yyset_in  (FILE * _in_str  );
+void yyset_in  ( FILE * _in_str  );
 
-FILE *yyget_out (void );
+FILE *yyget_out ( void );
 
-void yyset_out  (FILE * _out_str  );
+void yyset_out  ( FILE * _out_str  );
 
-			int yyget_leng (void );
+			int yyget_leng ( void );
 
-char *yyget_text (void );
+char *yyget_text ( void );
 
-int yyget_lineno (void );
+int yyget_lineno ( void );
 
-void yyset_lineno (int _line_number  );
+void yyset_lineno ( int _line_number  );
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -1539,9 +1532,9 @@ void yyset_lineno (int _line_number  );
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int yywrap (void );
+extern "C" int yywrap ( void );
 #else
-extern int yywrap (void );
+extern int yywrap ( void );
 #endif
 #endif
 
@@ -1550,19 +1543,18 @@ extern int yywrap (void );
 #endif
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
+static void yy_flex_strncpy ( char *, const char *, int );
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
+static int yy_flex_strlen ( const char * );
 #endif
 
 #ifndef YY_NO_INPUT
-
 #ifdef __cplusplus
-static int yyinput (void );
+static int yyinput ( void );
 #else
-static int input (void );
+static int input ( void );
 #endif
 
 #endif
@@ -1593,7 +1585,7 @@ static int input (void );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		size_t n; \
+		int n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -1606,7 +1598,7 @@ static int input (void );
 	else \
 		{ \
 		errno=0; \
-		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+		while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
 			{ \
 			if( errno != EINTR) \
 				{ \
@@ -1695,18 +1687,18 @@ YY_DECL
 		if ( ! YY_CURRENT_BUFFER ) {
 			yyensure_buffer_stack ();
 			YY_CURRENT_BUFFER_LVALUE =
-				yy_create_buffer(yyin,YY_BUF_SIZE );
+				yy_create_buffer( yyin, YY_BUF_SIZE );
 		}
 
-		yy_load_buffer_state( );
+		yy_load_buffer_state(  );
 		}
 
 	{
-#line 177 "scan.l"
+#line 178 "scan.l"
 
 
 
-#line 1710 "scan.c"
+#line 1702 "scan.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1753,159 +1745,159 @@ do_action:	/* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 180 "scan.l"
+#line 181 "scan.l"
 {BEGIN(INIT); /* Byte Order Mark is ignored */}
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 182 "scan.l"
+#line 183 "scan.l"
 {BEGIN(MARKUP); yylval.s=strdup(yytext+1); return START;}
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 183 "scan.l"
+#line 184 "scan.l"
 {BEGIN(MARKUP); yylval.s=strdup(yytext+2); return END;}
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 184 "scan.l"
+#line 185 "scan.l"
 {yylval.s=strdup(yytext); return TEXT;}
 	YY_BREAK
 case 5:
 /* rule 5 can match eol */
 YY_RULE_SETUP
-#line 185 "scan.l"
+#line 186 "scan.l"
 {yylval.s=strdup(yytext); lns(yytext); return TEXT;}
 	YY_BREAK
 case 6:
 /* rule 6 can match eol */
 YY_RULE_SETUP
-#line 186 "scan.l"
+#line 187 "scan.l"
 {yylval.s=strdup(yytext); lineno++; return TEXT;}
 	YY_BREAK
 case 7:
 /* rule 7 can match eol */
 YY_RULE_SETUP
-#line 187 "scan.l"
+#line 188 "scan.l"
 {yylval.s=strndup(yytext+4,yyleng-7); lns(yytext); return COMMENT;}
 	YY_BREAK
 case 8:
 /* rule 8 can match eol */
 YY_RULE_SETUP
-#line 188 "scan.l"
+#line 189 "scan.l"
 {BEGIN(DECL); lns(yytext+9); return DOCTYPE;}
 	YY_BREAK
 case 9:
 /* rule 9 can match eol */
 YY_RULE_SETUP
-#line 189 "scan.l"
+#line 190 "scan.l"
 {yylval.s=strndup(yytext+2,yyleng-3); lns(yytext); return PROCINS;}
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 190 "scan.l"
+#line 191 "scan.l"
 {yylval.s=strdup("&lt;"); return TEXT;}
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 192 "scan.l"
+#line 193 "scan.l"
 {yylval.s = strdup(yytext); return NAME;}
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 193 "scan.l"
+#line 194 "scan.l"
 {BEGIN(VALUE); return '=';}
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 194 "scan.l"
+#line 195 "scan.l"
 {; /* skip */}
 	YY_BREAK
 case 14:
 /* rule 14 can match eol */
 YY_RULE_SETUP
-#line 195 "scan.l"
+#line 196 "scan.l"
 {lineno++; /* skip */}
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 196 "scan.l"
+#line 197 "scan.l"
 {BEGIN(INIT); return '>';}
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 197 "scan.l"
+#line 198 "scan.l"
 {BEGIN(INIT); return EMPTYEND;}
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 198 "scan.l"
+#line 199 "scan.l"
 {BEGIN(INIT); yyless(0); return '>'; /* Implicit ">" */} 
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 200 "scan.l"
+#line 201 "scan.l"
 {; /* skip */}
 	YY_BREAK
 case 19:
 /* rule 19 can match eol */
 YY_RULE_SETUP
-#line 201 "scan.l"
+#line 202 "scan.l"
 {lineno++; /* skip */}
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 202 "scan.l"
+#line 203 "scan.l"
 {BEGIN(MARKUP); yylval.s=strdup(yytext); return NAME;}
 	YY_BREAK
 case 21:
 /* rule 21 can match eol */
-#line 204 "scan.l"
+#line 205 "scan.l"
 case 22:
 /* rule 22 can match eol */
 YY_RULE_SETUP
-#line 204 "scan.l"
+#line 205 "scan.l"
 {BEGIN(MARKUP); yylval.s=esc(yytext); lns(yytext); return STRING;}
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 206 "scan.l"
+#line 207 "scan.l"
 {yylval.s = strdup(yytext); return NAME;}
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 207 "scan.l"
+#line 208 "scan.l"
 {; /* skip */}
 	YY_BREAK
 case 25:
 /* rule 25 can match eol */
 YY_RULE_SETUP
-#line 208 "scan.l"
+#line 209 "scan.l"
 {lineno++; /* skip */}
 	YY_BREAK
 case 26:
 /* rule 26 can match eol */
-#line 210 "scan.l"
+#line 211 "scan.l"
 case 27:
 /* rule 27 can match eol */
 YY_RULE_SETUP
-#line 210 "scan.l"
+#line 211 "scan.l"
 {lns(yytext); yylval.s = esc(yytext); return STRING;}
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 211 "scan.l"
+#line 212 "scan.l"
 {BEGIN(INIT); return '>';}
 	YY_BREAK
 case 29:
 /* rule 29 can match eol */
 YY_RULE_SETUP
-#line 213 "scan.l"
+#line 214 "scan.l"
 {lns(yytext); yylval.s = strdup(yytext); return TEXT;}
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 214 "scan.l"
+#line 215 "scan.l"
 {lns(yytext);
 			 if (strcasecmp(yytext+2, cur_cdata_element) == 0) {
 			   BEGIN(MARKUP);
@@ -1919,7 +1911,7 @@ YY_RULE_SETUP
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 225 "scan.l"
+#line 226 "scan.l"
 {return *yytext; /* illegal char, in fact */}
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
@@ -1928,15 +1920,15 @@ case YY_STATE_EOF(VALUE):
 case YY_STATE_EOF(DECL):
 case YY_STATE_EOF(INIT):
 case YY_STATE_EOF(CDATA):
-#line 227 "scan.l"
+#line 228 "scan.l"
 {if (pop_file()) return ENDINCL; else yyterminate();}
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 229 "scan.l"
+#line 230 "scan.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
 	YY_BREAK
-#line 1940 "scan.c"
+#line 1932 "scan.c"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -2012,7 +2004,7 @@ YY_FATAL_ERROR( "flex scanner jammed" );
 				{
 				(yy_did_buffer_switch_on_eof) = 0;
 
-				if ( yywrap( ) )
+				if ( yywrap(  ) )
 					{
 					/* Note: because we've taken care in
 					 * yy_get_next_buffer() to have set up
@@ -2144,7 +2136,8 @@ static int yy_get_next_buffer (void)
 
 				b->yy_ch_buf = (char *)
 					/* Include room in for 2 EOB chars. */
-					yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+					yyrealloc( (void *) b->yy_ch_buf,
+							 (yy_size_t) (b->yy_buf_size + 2)  );
 				}
 			else
 				/* Can't grow it, we don't own it. */
@@ -2176,7 +2169,7 @@ static int yy_get_next_buffer (void)
 		if ( number_to_move == YY_MORE_ADJ )
 			{
 			ret_val = EOB_ACT_END_OF_FILE;
-			yyrestart(yyin  );
+			yyrestart( yyin  );
 			}
 
 		else
@@ -2193,9 +2186,12 @@ static int yy_get_next_buffer (void)
 	if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+			(void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size  );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+		/* "- 2" to take care of EOB's */
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
 	}
 
 	(yy_n_chars) += number_to_move;
@@ -2282,7 +2278,7 @@ static int yy_get_next_buffer (void)
 
 		else
 			{ /* need more input */
-			int offset = (yy_c_buf_p) - (yytext_ptr);
+			int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
 			++(yy_c_buf_p);
 
 			switch ( yy_get_next_buffer(  ) )
@@ -2299,13 +2295,13 @@ static int yy_get_next_buffer (void)
 					 */
 
 					/* Reset buffer status. */
-					yyrestart(yyin );
+					yyrestart( yyin );
 
 					/*FALLTHROUGH*/
 
 				case EOB_ACT_END_OF_FILE:
 					{
-					if ( yywrap( ) )
+					if ( yywrap(  ) )
 						return 0;
 
 					if ( ! (yy_did_buffer_switch_on_eof) )
@@ -2343,11 +2339,11 @@ static int yy_get_next_buffer (void)
 	if ( ! YY_CURRENT_BUFFER ){
         yyensure_buffer_stack ();
 		YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE );
+            yy_create_buffer( yyin, YY_BUF_SIZE );
 	}
 
-	yy_init_buffer(YY_CURRENT_BUFFER,input_file );
-	yy_load_buffer_state( );
+	yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+	yy_load_buffer_state(  );
 }
 
 /** Switch to a different input buffer.
@@ -2375,7 +2371,7 @@ static int yy_get_next_buffer (void)
 		}
 
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
-	yy_load_buffer_state( );
+	yy_load_buffer_state(  );
 
 	/* We don't actually know whether we did this switch during
 	 * EOF (yywrap()) processing, but the only time this flag
@@ -2403,22 +2399,22 @@ static void yy_load_buffer_state  (void)
 {
 	YY_BUFFER_STATE b;
     
-	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+	b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
-	b->yy_buf_size = (yy_size_t)size;
+	b->yy_buf_size = size;
 
 	/* yy_ch_buf has to be 2 characters longer than the size given because
 	 * we need to put in 2 end-of-buffer characters.
 	 */
-	b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+	b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2)  );
 	if ( ! b->yy_ch_buf )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
 	b->yy_is_our_buffer = 1;
 
-	yy_init_buffer(b,file );
+	yy_init_buffer( b, file );
 
 	return b;
 }
@@ -2437,9 +2433,9 @@ static void yy_load_buffer_state  (void)
 		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
 
 	if ( b->yy_is_our_buffer )
-		yyfree((void *) b->yy_ch_buf  );
+		yyfree( (void *) b->yy_ch_buf  );
 
-	yyfree((void *) b  );
+	yyfree( (void *) b  );
 }
 
 /* Initializes or reinitializes a buffer.
@@ -2451,7 +2447,7 @@ static void yy_load_buffer_state  (void)
 {
 	int oerrno = errno;
     
-	yy_flush_buffer(b );
+	yy_flush_buffer( b );
 
 	b->yy_input_file = file;
 	b->yy_fill_buffer = 1;
@@ -2494,7 +2490,7 @@ static void yy_load_buffer_state  (void)
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
 	if ( b == YY_CURRENT_BUFFER )
-		yy_load_buffer_state( );
+		yy_load_buffer_state(  );
 }
 
 /** Pushes the new state onto the stack. The new state becomes
@@ -2525,7 +2521,7 @@ void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
 	YY_CURRENT_BUFFER_LVALUE = new_buffer;
 
 	/* copied from yy_switch_to_buffer. */
-	yy_load_buffer_state( );
+	yy_load_buffer_state(  );
 	(yy_did_buffer_switch_on_eof) = 1;
 }
 
@@ -2544,7 +2540,7 @@ void yypop_buffer_state (void)
 		--(yy_buffer_stack_top);
 
 	if (YY_CURRENT_BUFFER) {
-		yy_load_buffer_state( );
+		yy_load_buffer_state(  );
 		(yy_did_buffer_switch_on_eof) = 1;
 	}
 }
@@ -2554,7 +2550,7 @@ void yypop_buffer_state (void)
  */
 static void yyensure_buffer_stack (void)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     
 	if (!(yy_buffer_stack)) {
 
@@ -2611,11 +2607,11 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 		/* They forgot to leave room for the EOB's. */
 		return NULL;
 
-	b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+	b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
 
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_size = (int) (size - 2);	/* "- 2" to take care of EOB's */
 	b->yy_buf_pos = b->yy_ch_buf = base;
 	b->yy_is_our_buffer = 0;
 	b->yy_input_file = NULL;
@@ -2625,7 +2621,7 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
 	b->yy_fill_buffer = 0;
 	b->yy_buffer_status = YY_BUFFER_NEW;
 
-	yy_switch_to_buffer(b  );
+	yy_switch_to_buffer( b  );
 
 	return b;
 }
@@ -2638,10 +2634,10 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
  * @note If you want to scan bytes that may contain NUL values, then use
  *       yy_scan_bytes() instead.
  */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+YY_BUFFER_STATE yy_scan_string (const char * yystr )
 {
     
-	return yy_scan_bytes(yystr,(int) strlen(yystr) );
+	return yy_scan_bytes( yystr, (int) strlen(yystr) );
 }
 
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
@@ -2651,7 +2647,7 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
  * 
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+YY_BUFFER_STATE yy_scan_bytes  (const char * yybytes, int  _yybytes_len )
 {
 	YY_BUFFER_STATE b;
 	char *buf;
@@ -2660,7 +2656,7 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = (yy_size_t) (_yybytes_len + 2);
-	buf = (char *) yyalloc(n  );
+	buf = (char *) yyalloc( n  );
 	if ( ! buf )
 		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 
@@ -2669,7 +2665,7 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
 
 	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
 
-	b = yy_scan_buffer(buf,n );
+	b = yy_scan_buffer( buf, n );
 	if ( ! b )
 		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
 
@@ -2685,9 +2681,9 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yynoreturn yy_fatal_error (yyconst char* msg )
+static void yynoreturn yy_fatal_error (const char* msg )
 {
-			(void) fprintf( stderr, "%s\n", msg );
+			fprintf( stderr, "%s\n", msg );
 	exit( YY_EXIT_FAILURE );
 }
 
@@ -2822,7 +2818,7 @@ int yylex_destroy  (void)
     
     /* Pop the buffer stack, destroying each element. */
 	while(YY_CURRENT_BUFFER){
-		yy_delete_buffer(YY_CURRENT_BUFFER  );
+		yy_delete_buffer( YY_CURRENT_BUFFER  );
 		YY_CURRENT_BUFFER_LVALUE = NULL;
 		yypop_buffer_state();
 	}
@@ -2843,7 +2839,7 @@ int yylex_destroy  (void)
  */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+static void yy_flex_strncpy (char* s1, const char * s2, int n )
 {
 		
 	int i;
@@ -2853,7 +2849,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
+static int yy_flex_strlen (const char * s )
 {
 	int n;
 	for ( n = 0; s[n]; ++n )
@@ -2888,8 +2884,7 @@ void yyfree (void * ptr )
 
 #define YYTABLES_NAME "yytables"
 
-#line 229 "scan.l"
-
+#line 230 "scan.l"
 
 
 /* set_cdata_element -- set parsing rule for an element with CDATA content */
diff --git a/scan.e b/scan.e
old mode 100755
new mode 100644
diff --git a/scan.l b/scan.l
index 63e2e78..b4ddda6 100644
--- a/scan.l
+++ b/scan.l
@@ -22,13 +22,14 @@
 #endif
 #include <stdlib.h>
 #include <ctype.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
 #include "heap.e"
 #include "html.h"
 #include "html.e"
-#include "errexit.e"
 
 
 EXPORT extern FILE *yyin;
@@ -107,7 +108,7 @@ static string esc(string s)
   }
   /* Copy and expand */
   u = malloc(i + 1);
-  if (!u) errexit("Out of memory\n");
+  if (!u) err(EX_OSERR, NULL);
   for (i = 0, j = 1; s[j] != s[0]; i++, j++) {
     if (s[j] == '"')  {strcpy(u + i, "&#34;"); i += 4;}
     else if (s[j] == '<')  {strcpy(u + i, "&#60;"); i += 4;}
@@ -127,7 +128,7 @@ static string esc(string s)
 static string strndup(const string s, size_t n)
 {
   string t = malloc(n + 1);
-  if (!t) errexit("Out of memory\n");
+  if (!t) err(EX_OSERR, NULL);
   strncpy(t, s, n);
   t[n] = '\0';
   return t;
@@ -210,7 +211,7 @@ cdata		<!\[[Cc][Dd][Aa][Tt][Aa]\[([^]]|\][^]]|\]\][^>])*\]\]>
 <DECL>\'[^']*\'		{lns(yytext); yylval.s = esc(yytext); return STRING;}
 <DECL>">"		{BEGIN(INIT); return '>';}
 
-<CDATA>([^<]|\<[^/]|\<\/[^{a-z:._-])* {lns(yytext); yylval.s = strdup(yytext); return TEXT;}
+<CDATA>([^<]|\<[^/]|\<\/[^{a-zA-Z:._-])* {lns(yytext); yylval.s = strdup(yytext); return TEXT;}
 <CDATA>"</"{name}	{lns(yytext);
 			 if (strcasecmp(yytext+2, cur_cdata_element) == 0) {
 			   BEGIN(MARKUP);
diff --git a/selector.c b/selector.c
index 25a5f7c..ad4a4d8 100644
--- a/selector.c
+++ b/selector.c
@@ -1,9 +1,6 @@
 /*
  * Type definitions and a parser for CSS selectors.
  *
- * Only parses selectors that allow incremental rendering
- * of a document.
- *
  * The Selector type is a linked list of simple selectors, with the
  * subject at the head, and its context linked from the "context"
  * field. The "combinator" field is the relation between this simple
@@ -13,7 +10,7 @@
  *
  * Author: Bert Bos <bert@w3.org>
  * Created: 8 July 2001
- * Version: $Id: selector.c,v 1.14 2017/11/24 17:33:50 bbos Exp $
+ * Version: $Id: selector.c,v 1.19 2023/01/23 21:19:41 bbos Exp $
  **/
 
 #include "config.h"
@@ -21,6 +18,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #ifdef HAVE_STRING_H
 #  include <string.h>
@@ -30,21 +29,20 @@
 #include "export.h"
 #include "heap.e"
 #include "types.e"
-#include "errexit.e"
 
 EXPORT typedef enum {				/* Pseudo-classes & -elements */
   AttrNode,					/* ::attr() */
   RootSel, NthChild, NthOfType, FirstChild, FirstOfType, Lang,
   NthLastChild, NthLastOfType, LastChild, LastOfType, OnlyChild,
   OnlyOfType, Empty,
-  Not,
+  Not, Is,
 } PseudoType;
 
 EXPORT typedef struct _PseudoCond {
   PseudoType type;
   int a, b;					/* :nth-child(an+b) */
-  string s;					/* :lang(s) */
-  struct _SimpleSelector *sel;			/* :not(sel) */
+  string s;					/* :lang(s), attr(s) */
+  struct _SimpleSelector *sel;			/* :not(sel), :is(sel,...) */
   struct _PseudoCond *next;
 } PseudoCond;
 
@@ -80,7 +78,7 @@ typedef enum {
   PSEUDO_ELT, IN_PSEUDO, LANG, IN_PSEUDO_, PSEUDO__O, PSEUDO__E, AFTER_N,
   AFTER_NUM, END_PSEUDO, AFTER_PLUS, AFTER_MINUS, PSEUDO__OD, PSEUDO__ODD,
   PSEUDO__EV, PSEUDO__EVE, PSEUDO__EVEN, LANG_, PSEUDO_ELT_ATTR,
-  PSEUDO_ELT_ATTR_, IN_PSEUDO_PLUS, IN_PSEUDO_MINUS, NOT,
+  PSEUDO_ELT_ATTR_, IN_PSEUDO_PLUS, IN_PSEUDO_MINUS, NOT, IS
 } State;
 
 
@@ -137,10 +135,10 @@ static bool isnmchar(unsigned int c)
 static void parse_comment(string *s)
 {
   assert(s && *s && **s == '/');
-  if (*(++*s) != '*') errexit("Unexpected \"/\"\n");
+  if (*(++*s) != '*') errx(EX_DATAERR, "Unexpected \"/\"");
   for ((*s)++; **s; (*s)++)
     if (**s == '*' && *(*s+1) == '/') {(*s) += 2; return;}
-  errexit("Comment is missing the closing \"*/\"\n");
+  errx(EX_DATAERR, "Comment is missing the closing \"*/\"");
 }
 
 /* parse_escape -- parse a backslash-escaped character, append UTF-8 to value */
@@ -194,7 +192,7 @@ static void parse_escape(string *s, string *value)
 static string parse_ident(string *s)
 {
   string ident = NULL;
-  
+
   assert(*s && isnmchar(**s));	/* Not isnmstart(), it may be a HASH (#...) */
   if (**s == '\\') parse_escape(s, &ident);
   else strappc(&ident, *(*s)++);
@@ -212,10 +210,11 @@ static int parse_int(string *s)
 
   assert(s && *s && (**s == '-' || **s == '+' || isdigit(**s)));
   if (**s == '+') (*s)++; else if (**s == '-') {neg = true; (*s)++;}
-  if (!isdigit(**s))errexit("Expected a number after +/- but found \"%c\"\n",**s);
+  if (!isdigit(**s))
+    errx(EX_DATAERR, "Expected a number after +/- but found \"%c\"", **s);
   while (isdigit(**s)) {
     n = 10 * n + (**s - '0');
-    if (n < 0) errexit("Cannot handle a number this big\n");
+    if (n < 0) errx(EX_DATAERR, "Cannot handle a number this big");
     (*s)++;
   }
   return neg ? -n : n;
@@ -229,7 +228,7 @@ EXPORT Selector parse_selector(const string selector, string *rest)
   string s = selector;
   AttribCond *attsel;
   PseudoCond *pseudosel;
-  Selector sel = NULL, h;
+  Selector sel = NULL;
   int n = 0;			/* Avoid warning about uninitialized */
 
   push_sel(&sel, Descendant);
@@ -247,7 +246,7 @@ EXPORT Selector parse_selector(const string selector, string *rest)
       else if (*s == '+') {s++; push_sel(&sel, Adjacent); state = INIT;}
       else if (*s == '>') {s++; push_sel(&sel, Child); state = INIT;}
       else if (*s == '~') {s++; push_sel(&sel, Sibling); state = INIT;}
-      else if (*s == ',') {h = parse_selector(s+1, &s); h->next = sel; sel = h;}
+      else if (*s == ',') {sel->next = parse_selector(s+1, &s);}
       else if (*s == ')') {*rest = s; return sel;}
       else {push_sel(&sel, Descendant); state = INIT;}
       break;
@@ -258,7 +257,7 @@ EXPORT Selector parse_selector(const string selector, string *rest)
       else if (*s == '[') {s++; state = ATTR;}
       else if (*s == ':') {s++; state = PSEUDO;}
       else if (isnmstart(*s)) {sel->name = parse_ident(&s); state = AFTER_TYPE;}
-      else errexit("Unexpected \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Unexpected \"%c\"", *s);
       break;
     case AFTER_TYPE:				/* After a type sel */
       if (*s == '/') parse_comment(&s);
@@ -266,7 +265,7 @@ EXPORT Selector parse_selector(const string selector, string *rest)
       else if (*s == '#') {s++; state = ID;}
       else if (*s == '[') {s++; state = ATTR;}
       else if (*s == ':') {s++; state = PSEUDO;}
-      else if (isnmstart(*s)) errexit("Unexpected \"%c\"\n", *s);
+      else if (isnmstart(*s)) errx(EX_DATAERR, "Unexpected \"%c\"", *s);
       else state = AFTER_SIMPLE;
       break;
     case CLASS:					/* Just seen a '.' */
@@ -274,20 +273,20 @@ EXPORT Selector parse_selector(const string selector, string *rest)
       else if (isnmstart(*s)) {new(attsel); attsel->op = HasClass;
 	attsel->value = parse_ident(&s); attsel->next = sel->attribs;
 	sel->attribs = attsel; state = AFTER_TYPE;}
-      else errexit("Unexpected \"%c\" after \".\"\n", *s);
+      else errx(EX_DATAERR, "Unexpected \"%c\" after \".\"", *s);
       break;
     case ID:					/* Just seen a '#' */
       if (isnmchar(*s)) {new(attsel); attsel->op = HasID;
 	attsel->value = parse_ident(&s); attsel->next = sel->attribs;
 	sel->attribs = attsel; state = AFTER_TYPE;}
-      else errexit("Unexpected \"%c\" after \"#\"\n", *s);
+      else errx(EX_DATAERR, "Unexpected \"%c\" after \"#\"", *s);
       break;
     case ATTR:					/* Just seen '[' */
       if (isspace(*s)) s++;
       else if (*s == '/') parse_comment(&s);
       else if (isnmstart(*s)) {new(attsel); attsel->name = parse_ident(&s);
 	attsel->next = sel->attribs; sel->attribs = attsel; state = AFTER_ATTR;}
-      else errexit("Unexpected \"%c\" after \"[\"\n", *s);
+      else errx(EX_DATAERR, "Unexpected \"%c\" after \"[\"", *s);
       break;
     case AFTER_ATTR:				/* Just seen a '[' + ident */
       if (isspace(*s)) s++;
@@ -301,7 +300,7 @@ EXPORT Selector parse_selector(const string selector, string *rest)
       else {sel->attribs->op = Equals; state = EQ;}
       break;
     case EQ:					/* Expect '=' */
-      if (*s != '=') errexit("Expected '=' instead of \"%c\"\n", *s);
+      if (*s != '=') errx(EX_DATAERR, "Expected '=' instead of \"%c\"", *s);
       else {s++; sel->attribs->value = NULL; state = START_VALUE;}
       break;
     case START_VALUE:				/* After '=' */
@@ -311,15 +310,23 @@ EXPORT Selector parse_selector(const string selector, string *rest)
       else if (*s == '\'') {s++; state = SSTRING;}
       else if (isnmstart(*s)) {sel->attribs->value = parse_ident(&s);
 	state = AFTER_VALUE;}
-      else errexit("Expected string or name after \"=\" but found \"%c\"\n",*s);
+      else errx(EX_DATAERR, "Expected string or name after \"=\" but found \"%c\"",*s);
       break;
     case DSTRING:				/* Inside "..." */
-      if (*s == '"') {s++; state = AFTER_VALUE;}
+      if (*s == '"') {
+        s++;
+        if (!sel->attribs->value) sel->attribs->value = newstring("");
+        state = AFTER_VALUE;
+      }
       else if (*s == '\\') parse_escape(&s, &sel->attribs->value);
       else {strappc(&sel->attribs->value, *s); s++;}
       break;
     case SSTRING:				/* Inside "..." */
-      if (*s == '\'') {s++; state = AFTER_VALUE;}
+      if (*s == '\'') {
+        s++;
+        if (!sel->attribs->value) sel->attribs->value = newstring("");
+        state = AFTER_VALUE;
+      }
       else if (*s == '\\') parse_escape(&s, &sel->attribs->value);
       else {strappc(&sel->attribs->value, *s); s++;}
       break;
@@ -327,15 +334,15 @@ EXPORT Selector parse_selector(const string selector, string *rest)
       if (isspace(*s)) s++;
       else if (*s == '/') parse_comment(&s);
       else if (*s == ']') {s++; state = AFTER_TYPE;}
-      else errexit("Expected ']' instead of \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expected ']' instead of \"%c\"", *s);
       break;
     case PSEUDO:				/* After ':' */
       if (*s == '/') parse_comment(&s);
       else if (*s == ':') {s++; state = PSEUDO_ELT;}
       else if (!isnmstart(*s))
-	errexit("Expected a pseudo-class after \":\" but found \"%c\"\n", *s);
+	errx(EX_DATAERR, "Expected a pseudo-class after \":\" but found \"%c\"", *s);
       else {new(pseudosel); pseudosel->next = sel->pseudos;
-	sel->pseudos = pseudosel; name = parse_ident(&s); 
+	sel->pseudos = pseudosel; name = parse_ident(&s);
 	if (strcasecmp(name, "root") == 0) {
 	  pseudosel->type = RootSel; state = AFTER_TYPE;}
 	else if (strcasecmp(name, "nth-child") == 0) {
@@ -364,12 +371,15 @@ EXPORT Selector parse_selector(const string selector, string *rest)
 	  pseudosel->type = Lang; state = LANG;}
 	else if (strcasecmp(name, "not") == 0) {
 	  pseudosel->type = Not; state = NOT;}
-	else errexit("Unknown pseudo-class \"%s\"\n", name);
+	else if (strcasecmp(name, "is") == 0
+	  || strcasecmp(name, "where") == 0) {
+	  pseudosel->type = Is; state = IS;}
+	else errx(EX_DATAERR, "Unknown pseudo-class \"%s\"", name);
       }
       break;
     case IN_PSEUDO:				/* After ':...', expect '(' */
       if (*s == '(') {s++; state = IN_PSEUDO_;}
-      else errexit("Expecting a \"(\" but found \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expecting a \"(\" but found \"%c\"", *s);
       break;
     case IN_PSEUDO_:				/* Expecting an+b */
       if (isspace(*s)) s++;
@@ -380,17 +390,17 @@ EXPORT Selector parse_selector(const string selector, string *rest)
       else if (*s == '+') {s++; state = IN_PSEUDO_PLUS;}
       else if (*s == '-') {s++; state = IN_PSEUDO_MINUS;}
       else if (isdigit(*s)) {n = parse_int(&s); state = AFTER_NUM;}
-      else errexit("Expected a number, but found \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expected a number, but found \"%c\"", *s);
       break;
     case IN_PSEUDO_PLUS:			/* After ':pseudo(+' */
       if (*s == 'n') {sel->pseudos->a = 1; s++; state = AFTER_N;}
       else if (isdigit(*s)) {n = parse_int(&s); state = AFTER_NUM;}
-      else errexit("Expected a number after \"+\" but found \"%c\"\n", *s);
+      else errx(EX_DATAERR,"Expected a number after \"+\" but found \"%c\"",*s);
       break;
     case IN_PSEUDO_MINUS:			/* After ':pseudo(-' */
       if (*s == 'n') {sel->pseudos->a = -1; s++; state = AFTER_N;}
       else if (isdigit(*s)) {n = -parse_int(&s); state = AFTER_NUM;}
-      else errexit("Expected a number after \"-\" but found \"%c\"\n", *s);
+      else errx(EX_DATAERR,"Expected a number after \"-\" but found \"%c\"",*s);
       break;
     case AFTER_NUM:				/* After ':pseudo(' + number */
       if (*s == 'n' || *s == 'N') {sel->pseudos->a = n;	s++; state = AFTER_N;}
@@ -405,85 +415,90 @@ EXPORT Selector parse_selector(const string selector, string *rest)
     case AFTER_PLUS:				/* After an+ */
       if (isspace(*s)) s++;
       else if (isdigit(*s)) {sel->pseudos->b = parse_int(&s); state=END_PSEUDO;}
-      else errexit("Expected a number after the \"+\", but found \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expected a number after the \"+\", but found \"%c\"", *s);
       break;
     case AFTER_MINUS:				/* After an- */
       if (isspace(*s)) s++;
       else if (isdigit(*s)) {sel->pseudos->b= -parse_int(&s); state=END_PSEUDO;}
-      else errexit("Expected a number after the \"-\", but found \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expected a number after the \"-\", but found \"%c\"", *s);
       break;
     case END_PSEUDO:				/* Expecting ')' */
       if (isspace(*s)) s++;
       else if (*s == '/') parse_comment(&s);
       else if (*s == ')') {s++; state = AFTER_TYPE;}
-      else errexit("Expected \")\" but found \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expected \")\" but found \"%c\"", *s);
       break;
     case PSEUDO__O:				/* After :nth...(o */
       if (*s == 'd' || *s == 'D') {s++; state = PSEUDO__OD;}
-      else errexit("Illegal character \"%c\" in \":nth-...(\"\n", *s);
+      else errx(EX_DATAERR, "Illegal character \"%c\" in \":nth-...(\"", *s);
       break;
     case PSEUDO__OD:				/* After :nth...(od */
       if (*s == 'd' || *s == 'D') {s++; state = PSEUDO__ODD;}
-      else errexit("Illegal character \"%c\" in \":nth-...(\"\n", *s);
+      else errx(EX_DATAERR, "Illegal character \"%c\" in \":nth-...(\"", *s);
       break;
     case PSEUDO__ODD:				/* After :nth-...(odd */
       if (!isnmchar(*s)) {state = END_PSEUDO;
         sel->pseudos->a = 2; sel->pseudos->b = 1;}
-      else errexit("Illegal character \"%c\" in \":nth-...(\"\n", *s);
+      else errx(EX_DATAERR, "Illegal character \"%c\" in \":nth-...(\"", *s);
       break;
     case PSEUDO__E:				/* After :nth-...(e */
       if (*s == 'v' || *s == 'V') {s++; state = PSEUDO__EV;}
-      else errexit("Illegal character \"%c\" in \":nth-...(\"\n", *s);
+      else errx(EX_DATAERR, "Illegal character \"%c\" in \":nth-...(\"", *s);
       break;
     case PSEUDO__EV:				/* After :nth-...(ev */
       if (*s == 'e' || *s == 'E') {s++; state = PSEUDO__EVE;}
-      else errexit("Illegal character \"%c\" in \":nth-...(\"\n", *s);
+      else errx(EX_DATAERR, "Illegal character \"%c\" in \":nth-...(\"", *s);
       break;
     case PSEUDO__EVE:				/* After :nth-...(eve */
       if (*s == 'n' || *s == 'N') {s++; state = PSEUDO__EVEN;}
-      else errexit("Illegal character \"%c\" in \":nth-...(\"\n", *s);
+      else errx(EX_DATAERR, "Illegal character \"%c\" in \":nth-...(\"", *s);
       break;
     case PSEUDO__EVEN:				/* Afte :nth-...(even */
       if (!isnmchar(*s)) {state = END_PSEUDO;
         sel->pseudos->a = 2; sel->pseudos->b = 0;}
-      else errexit("Illegal character \"%c\" in \":nth-...(\"\n", *s);
+      else errx(EX_DATAERR, "Illegal character \"%c\" in \":nth-...(\"", *s);
       break;
     case LANG:					/* After ':lang' */
       if (*s == '(') {s++; state = LANG_;}
-      else errexit("Expecting \"(\" after \":lang\" but found \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expecting \"(\" after \":lang\" but found \"%c\"", *s);
       break;
     case LANG_:					/* After ':lang(' */
       if (isspace(*s)) s++;
       else if (*s == '/') parse_comment(&s);
       else if (isnmstart(*s)) {sel->pseudos->s = parse_ident(&s);
 	state = END_PSEUDO;}
-      else errexit("Incorrect \":lang(\" at \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Incorrect \":lang(\" at \"%c\"", *s);
       break;
     case NOT:					/* After ':not' */
       if (*s == '(') {sel->pseudos->sel = parse_selector(s + 1, &s);
 	state = END_PSEUDO;}
-      else errexit("Expecting \"(\" after \":not\" but found \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expecting \"(\" after \":not\" but found \"%c\"", *s);
+      break;
+    case IS:					/* After ':is' */
+      if (*s == '(') {sel->pseudos->sel = parse_selector(s + 1, &s);
+	state = END_PSEUDO;}
+      else errx(EX_DATAERR, "Expecting \"(\" after \":is\" but found \"%c\"", *s);
       break;
     case PSEUDO_ELT:				/* After '::' */
       if (*s == '/') parse_comment(&s);
       else if (!isnmstart(*s))
-	errexit("Expected a pseudo-element after \"::\" but found \"%c\"\n",*s);
+	errx(EX_DATAERR, "Expected a pseudo-element after \"::\" but found \"%c\"",*s);
       else {push_sel(&sel, Child); new(pseudosel);
 	pseudosel->next = sel->pseudoelts; sel->pseudoelts = pseudosel;
 	name = parse_ident(&s);
 	if (strcasecmp(name, "attr") == 0) {
 	  sel->pseudoelts->type = AttrNode; state = PSEUDO_ELT_ATTR;}
-	else errexit("Unknown pseudo-element \"%s\"\n", name);
+	else errx(EX_DATAERR, "Unknown pseudo-element \"%s\"", name);
       }
       break;
     case PSEUDO_ELT_ATTR:			/* After '::attr' */
       if (*s == '(') {s++; state = PSEUDO_ELT_ATTR_;}
-      else errexit("Expected \"(\" after \"::attr\" but found \"%c\"\n", *s);
+      else errx(EX_DATAERR, "Expected \"(\" after \"::attr\" but found \"%c\"", *s);
       break;
     case PSEUDO_ELT_ATTR_:			/* After '::attr(' */
       if (isspace(*s)) s++;
       else if (*s == '/') parse_comment(&s);
-      else if (!isnmstart(*s)) errexit("Expected a name after \"::attr(\"\n");
+      else if (!isnmstart(*s)) errx(EX_DATAERR, "Expected a name after \"::attr(\"");
       else {sel->pseudoelts->s = parse_ident(&s); state = END_PSEUDO;}
       break;
     default:
@@ -491,7 +506,7 @@ EXPORT Selector parse_selector(const string selector, string *rest)
     }
   }
   if (state != AFTER_TYPE && state != AFTER_SIMPLE)
-    errexit("Incomplete selector (state %d)\n", state);
+    errx(EX_DATAERR, "Incomplete selector (state %d)", state);
 
   *rest = s;
   return sel;
@@ -520,20 +535,17 @@ static int utf8toint(conststring s, conststring *t)
 static void esc(FILE *f, conststring s)
 {
   assert(s);
-  assert(*s);
-
-  if (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z') ||
-      *s == '_' || *s & 0x80)
-    putc(*(s++), f);
-  else
-    fprintf(f, "\\%X ", utf8toint(s, &s));
 
-  while (*s) {
-    if (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z') ||
-	('0' <= *s && *s <= '9') || *s == '-' || *s == '_' || *s & 0x80)
-      putc(*(s++), f);
-    else
-      fprintf(f, "\\%X ", utf8toint(s, &s));
+  if (!*s)	     /* Can only happen with a string, not an ident */
+    fprintf(f, "\"\"");
+  else {
+    while (*s) {
+      if (('a' <= *s && *s <= 'z') || ('A' <= *s && *s <= 'Z') ||
+	  ('0' <= *s && *s <= '9') || *s == '-' || *s == '_' || *s & 0x80)
+	putc(*(s++), f);
+      else
+	fprintf(f, "\\%X ", utf8toint(s, &s));
+    }
   }
 }
 
@@ -579,6 +591,7 @@ EXPORT void dump_simple_selector(FILE *f, const SimpleSelector *s)
     case OnlyOfType: fprintf(f, ":only-of-type"); break;
     case Empty: fprintf(f, ":empty"); break;
     case Not: fprintf(f,":not("); dump_selector(f,p->sel); fprintf(f,")");break;
+    case Is: fprintf(f,":is("); dump_selector(f,p->sel); fprintf(f,")");break;
     default: assert(!"Cannot happen");
     }
   }
@@ -594,10 +607,7 @@ EXPORT void dump_simple_selector(FILE *f, const SimpleSelector *s)
 EXPORT void dump_selector(FILE *f, const Selector s)
 {
   assert(s);
-  if (s->next) {
-    dump_selector(f, s->next);
-    fprintf(f, ", ");
-  }
+
   if (s->context) {
     dump_selector(f, s->context);
     switch (s->combinator) {
@@ -609,4 +619,9 @@ EXPORT void dump_selector(FILE *f, const Selector s)
     }
   }
   dump_simple_selector(f, s);
+
+  if (s->next) {
+    fprintf(f, ", ");
+    dump_selector(f, s->next);
+  }
  }
diff --git a/selector.e b/selector.e
index 6a6f771..81fab3e 100644
--- a/selector.e
+++ b/selector.e
@@ -3,7 +3,7 @@ typedef enum {
   RootSel, NthChild, NthOfType, FirstChild, FirstOfType, Lang,
   NthLastChild, NthLastOfType, LastChild, LastOfType, OnlyChild,
   OnlyOfType, Empty,
-  Not,
+  Not, Is,
 } PseudoType;
 typedef struct _PseudoCond {
   PseudoType type;
diff --git a/selmatch.c b/selmatch.c
index 517494d..34ca08f 100644
--- a/selmatch.c
+++ b/selmatch.c
@@ -10,6 +10,7 @@
  * Author: Bert Bos <bert@w3.org>
  * Created: 11 Aug 2017
  */
+#define _GNU_SOURCE		/* Include strcasestr() in string.h */
 #include "config.h"
 #include <assert.h>
 #include <stdio.h>
@@ -27,7 +28,6 @@
 #include "selector.e"
 #include "export.h"
 #include "heap.e"
-#include "errexit.e"
 
 
 static conststring language = "";		/* Initial language */
@@ -142,7 +142,9 @@ static bool ends_with(const string line, const string suffix)
 /* contains -- check if line contains s */
 static bool contains(const string line, const string s)
 {
-  return strstr(line, s) != NULL;
+  return case_insensitive
+    ? strcasestr(line, s) != NULL
+    : strstr(line, s) != NULL;
 }
 
 
@@ -246,7 +248,6 @@ static bool simple_match(const Tree n, const SimpleSelector *s)
     case Empty:
       for (c = n->children; c; c = c->sister)
 	if (c->tp == Element || c->tp == Text) return false;
-      return true;
       break;
     case Lang:
       if (!lang_match(get_language(n), q->s)) return false;
@@ -254,6 +255,9 @@ static bool simple_match(const Tree n, const SimpleSelector *s)
     case Not:
       if (matches_sel(n, q->sel)) return false;
       break;
+    case Is:
+      if (!matches_sel(n, q->sel)) return false;
+      break;
     default:
       assert(!"Cannot happen");
     }
@@ -262,33 +266,40 @@ static bool simple_match(const Tree n, const SimpleSelector *s)
 }
 
 
-/* matches_sel -- check if an element t matches the selector s */
-EXPORT bool matches_sel(const Tree t, const Selector s)
+/* matches_sel -- check if an element t matches the selector */
+EXPORT bool matches_sel(const Tree t, const Selector selector)
 {
   Tree g, h;
+  Selector s;
 
-  assert(s);
+  assert(selector);
   if (!t || t->tp == Root) return false;
   assert(t->tp == Element);
-  if (!simple_match(t, s)) return s->next && matches_sel(t, s->next);
-  if (!s->context) return true;
-  switch (s->combinator) {
-  case Descendant:
-    for (h = t->parent; h->tp != Root && !matches_sel(h, s->context);
-	 h = h->parent);
-    return h->tp != Root;
-  case Child:
-    return matches_sel(t->parent, s->context);
-  case Adjacent:
-    for (g = NULL, h = t->parent->children; h != t; h = h->sister)
-      if (h->tp == Element) g = h;
-    return g && matches_sel(g, s->context);
-  case Sibling:
-    for (h = t->parent->children; h != t; h = h->sister)
-      if (matches_sel(h, s->context)) return true;
-    return false;
-  default:
-    assert(!"Cannot happen");
-    return false;
+  for (s = selector; s; s = s->next) { /* Try all alternative selectors */
+    if (!simple_match(t, s)) continue;
+    if (!s->context) return true;
+    switch (s->combinator) {
+    case Descendant:
+      for (h = t->parent; h->tp != Root && !matches_sel(h, s->context);
+	   h = h->parent);
+      if (h->tp != Root) return true;
+      break;
+    case Child:
+      if (matches_sel(t->parent, s->context)) return true;
+      break;
+    case Adjacent:
+      for (g = NULL, h = t->parent->children; h != t; h = h->sister)
+	if (h->tp == Element) g = h;
+      if (g && matches_sel(g, s->context)) return true;
+      break;
+    case Sibling:
+      for (h = t->parent->children; h != t; h = h->sister)
+	if (h->tp == Element && matches_sel(h, s->context)) return true;
+      break;
+    default:
+      assert(!"Cannot happen");
+      return false;
+    }
   }
+  return false;
 }
diff --git a/selmatch.e b/selmatch.e
index ff96552..1e893ab 100644
--- a/selmatch.e
+++ b/selmatch.e
@@ -3,4 +3,4 @@ extern void set_case_insensitive(void);
 extern _Bool 
            same(const string a, const string b);
 extern _Bool 
-           matches_sel(const Tree t, const Selector s);
+           matches_sel(const Tree t, const Selector selector);
diff --git a/tests/clean1.sh b/tests/clean1.sh
index 19a6ac3..9c93a40 100755
--- a/tests/clean1.sh
+++ b/tests/clean1.sh
@@ -6,10 +6,10 @@ TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
 
 echo '<!- this is not a comment -->' >$TMP3
 
-echo '<html><body><p>&lt;!- this is not a comment -->' >$TMP2
-echo '</p></body></html>' >>$TMP2
+echo '<html><body>&lt;!- this is not a comment -->' >$TMP2
+echo '</body></html>' >>$TMP2
 
 ./hxclean $TMP3 >$TMP1
 echo >>$TMP1		       # Add a newline at the end
 
-cmp -s $TMP1 $TMP2
+diff -u $TMP2 $TMP1
diff --git a/tests/index.sh b/tests/index.sh
index 1521851..c27386a 100755
--- a/tests/index.sh
+++ b/tests/index.sh
@@ -23,10 +23,15 @@ EOF
 (./hxnum $TMP1 | LC_ALL=C ./hxindex -t -n; echo) >$TMP2
 
 cat >$TMP3 <<EOF
-<html><body><h1><span class="secno">1. </span>Heading 0</h1><h1 class="no-num">Heading 1</h1><p><dfn id="a-term">A-term</dfn>
-</p><h2><span class="secno">1.1. </span>Heading 2</h2><p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
-</p><h3><span class="secno">1.1.1. </span>Heading 3</h3><p><dfn id="z-term">Z-term</dfn>
-</p><h1><span class="secno">2. </span>Index</h1><!--begin-index-->
+<html><body><h1><span class="secno">1. </span>Heading 0</h1>
+<h1 class="no-num">Heading 1</h1>
+<p><dfn id="a-term">A-term</dfn>
+</p><h2><span class="secno">1.1. </span>Heading 2</h2>
+<p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
+</p><h3><span class="secno">1.1.1. </span>Heading 3</h3>
+<p><dfn id="z-term">Z-term</dfn>
+</p><h1><span class="secno">2. </span>Index</h1>
+<!--begin-index-->
 <ul class="indexlist">
 <li>&lt;M-term&gt;, <a href="#ltm-termgt" title="section 1.1."><strong>1.1.</strong></a>
 <li>A-term, <a href="#a-term" title="section ??"><strong>??</strong></a>
@@ -34,4 +39,4 @@ cat >$TMP3 <<EOF
 </ul><!--end-index--></body></html>
 EOF
 
-cmp -s $TMP2 $TMP3
+diff -u $TMP3 $TMP2
diff --git a/tests/index10.sh b/tests/index10.sh
index 78f22a4..62b43eb 100755
--- a/tests/index10.sh
+++ b/tests/index10.sh
@@ -32,7 +32,8 @@ cat >$TMP6 <<EOF
 <li>term1, <a href="foo1#term1"><strong>#</strong></a>, <a href="foo2#term1"><strong>#</strong></a>
 <li>term2, <a href="foo1#term2"><strong>#</strong></a>
 <li>term3, <a href="foo2#term3"><strong>#</strong></a>
-</ul><!--end-index--></body></html>
+</ul><!--end-index-->
+</body></html>
 EOF
 
 # Check.
diff --git a/tests/index2.sh b/tests/index2.sh
index 529ee45..3700e4f 100755
--- a/tests/index2.sh
+++ b/tests/index2.sh
@@ -23,10 +23,15 @@ EOF
 (./hxnum $TMP1 | LC_ALL=C ./hxindex -t -n -f; echo) >$TMP2
 
 cat >$TMP3 <<EOF
-<html><body><h1><span class="secno">1. </span>Heading 0</h1><h1 class="no-num">Heading 1</h1><p><dfn id="a-term">A-term</dfn>
-</p><h2><span class="secno">1.1. </span>Heading 2</h2><p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
-</p><h3><span class="secno">1.1.1. </span>Heading 3</h3><p><dfn id="z-term">Z-term</dfn>
-</p><h1><span class="secno">2. </span>Index</h1><ul class="indexlist">
+<html><body><h1><span class="secno">1. </span>Heading 0</h1>
+<h1 class="no-num">Heading 1</h1>
+<p><dfn id="a-term">A-term</dfn>
+</p><h2><span class="secno">1.1. </span>Heading 2</h2>
+<p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
+</p><h3><span class="secno">1.1.1. </span>Heading 3</h3>
+<p><dfn id="z-term">Z-term</dfn>
+</p><h1><span class="secno">2. </span>Index</h1>
+<ul class="indexlist">
 <li>term
   <ul>
   <li>A, <a href="#a-term" title="section ??"><strong>??</strong></a>
@@ -36,4 +41,4 @@ cat >$TMP3 <<EOF
 </ul></body></html>
 EOF
 
-cmp -s $TMP2 $TMP3
+diff -u $TMP3 $TMP2
diff --git a/tests/index3.sh b/tests/index3.sh
index d6a75a9..f39d310 100755
--- a/tests/index3.sh
+++ b/tests/index3.sh
@@ -27,14 +27,19 @@ EOF
 (./hxnum $TMP1 | LC_ALL=C ./hxindex -t -n -f; echo) >$TMP2
 
 cat >$TMP3 <<EOF
-<html><body><h1><span class="secno">1. </span>Heading 0</h1><h1 class="no-num">Heading 1</h1><p><dfn id="a-term">A-term</dfn>
+<html><body><h1><span class="secno">1. </span>Heading 0</h1>
+<h1 class="no-num">Heading 1</h1>
+<p><dfn id="a-term">A-term</dfn>
 </p><p><span id="z-term" class="index">Z-term</span>
-</p><h2><span class="secno">1.1. </span>Heading 2</h2><p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
+</p><h2><span class="secno">1.1. </span>Heading 2</h2>
+<p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
 </p><p><span id="a-term0" class="index">A-term</span>
-</p><h3><span class="secno">1.1.1. </span>Heading 3</h3><p><dfn id="z-term0">Z-term</dfn>
+</p><h3><span class="secno">1.1.1. </span>Heading 3</h3>
+<p><dfn id="z-term0">Z-term</dfn>
 </p><p><span id="m-term" class="index">M-term</span>
 </p><p><span id="termm." class="index">term!!M.</span>
-</p><h1><span class="secno">2. </span>Index</h1><ul class="indexlist">
+</p><h1><span class="secno">2. </span>Index</h1>
+<ul class="indexlist">
 <li>term
   <ul>
   <li>A, <a href="#a-term" title="section ??"><strong>??</strong></a>, <a href="#a-term0" title="section 1.1.">1.1.</a>
@@ -44,4 +49,4 @@ cat >$TMP3 <<EOF
 </ul></body></html>
 EOF
 
-cmp -s $TMP2 $TMP3
+diff -u $TMP3 $TMP2
diff --git a/tests/index4.sh b/tests/index4.sh
index 3162966..938eadc 100755
--- a/tests/index4.sh
+++ b/tests/index4.sh
@@ -26,13 +26,18 @@ EOF
 (./hxnum $TMP1 | LC_ALL=C ./hxindex -t -n -f -r; echo) >$TMP2
 
 cat >$TMP3 <<EOF
-<html><body><h1><span class="secno">1. </span>Heading 0</h1><h1 class="no-num">Heading 1</h1><p><dfn id="a-term">A-term</dfn>
+<html><body><h1><span class="secno">1. </span>Heading 0</h1>
+<h1 class="no-num">Heading 1</h1>
+<p><dfn id="a-term">A-term</dfn>
 </p><p><span id="z-term" class="index">Z-term</span>
-</p><h2><span class="secno">1.1. </span>Heading 2</h2><p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
+</p><h2><span class="secno">1.1. </span>Heading 2</h2>
+<p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
 </p><p><span id="a-term0" class="index">A-term</span>
-</p><h3><span class="secno">1.1.1. </span>Heading 3</h3><p><dfn id="z-term0">Z-term</dfn>
+</p><h3><span class="secno">1.1.1. </span>Heading 3</h3>
+<p><dfn id="z-term0">Z-term</dfn>
 </p><p><span id="m-term" class="index">M-term</span>
-</p><h1><span class="secno">2. </span>Index</h1><ul class="indexlist">
+</p><h1><span class="secno">2. </span>Index</h1>
+<ul class="indexlist">
 <li>term
   <ul>
   <li>A, <a href="#a-term" title="section ??"><strong>??</strong></a>, <a href="#a-term0" title="section 1.1.">1.1.</a>
@@ -44,4 +49,4 @@ cat >$TMP3 <<EOF
 </ul></body></html>
 EOF
 
-cmp -s $TMP2 $TMP3
+diff -u $TMP3 $TMP2
diff --git a/tests/index9.sh b/tests/index9.sh
index 7810991..87630dd 100755
--- a/tests/index9.sh
+++ b/tests/index9.sh
@@ -26,10 +26,15 @@ EOF
 
 cat >$TMP3 <<EOF
 <html><head><title>Document title</title></head><body><p><dfn id="term">0-term</dfn>
-</p><h1><span class="secno">1. </span>Heading 0</h1><h1 class="no-num">Heading 1</h1><p><dfn id="a-term">A-term</dfn>
-</p><h2><span class="secno">1.1. </span>Heading 2</h2><p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
-</p><h3><span class="secno">1.1.1. </span>Heading 3</h3><p><dfn id="z-term">Z-term</dfn>
-</p><h1><span class="secno">2. </span>Index</h1><!--begin-index-->
+</p><h1><span class="secno">1. </span>Heading 0</h1>
+<h1 class="no-num">Heading 1</h1>
+<p><dfn id="a-term">A-term</dfn>
+</p><h2><span class="secno">1.1. </span>Heading 2</h2>
+<p><dfn id="ltm-termgt"><em>&lt;M-term&gt;</em></dfn>
+</p><h3><span class="secno">1.1.1. </span>Heading 3</h3>
+<p><dfn id="z-term">Z-term</dfn>
+</p><h1><span class="secno">2. </span>Index</h1>
+<!--begin-index-->
 <ul class="indexlist">
 <li>0-term, <a href="#term"><strong>Document title</strong></a>
 <li>&lt;M-term&gt;, <a href="#ltm-termgt"><strong><span class="secno">1.1. </span>Heading 2</strong></a>
@@ -38,4 +43,4 @@ cat >$TMP3 <<EOF
 </ul><!--end-index--></body></html>
 EOF
 
-diff -u $TMP2 $TMP3
+diff -u $TMP3 $TMP2
diff --git a/tests/normalize13.sh b/tests/normalize13.sh
new file mode 100755
index 0000000..0097da4
--- /dev/null
+++ b/tests/normalize13.sh
@@ -0,0 +1,35 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<!DOCTYPE html>
+
+	<html>
+	<head>
+	<style>
+	<![CDATA[123]]>
+	&lt;foo>
+	&amp;foo;&quot;&apos;&gt;
+	</style>
+	</head>
+	<body>
+	</body>
+EOF
+cat >$TMP2 <<-EOF
+	<!DOCTYPE html>
+
+	<html>
+	<head>
+	<style>
+	123
+	<foo>
+	&foo;"'>
+	</style>
+
+	<body>
+EOF
+./hxnormalize -X -i 0 -L $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/normalize14.sh b/tests/normalize14.sh
new file mode 100755
index 0000000..30a55dc
--- /dev/null
+++ b/tests/normalize14.sh
@@ -0,0 +1,29 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<EOF
+<!DOCTYPE html>
+<html lang=ja-JP>
+
+<p>PやH2内の各行をその
+  マージンの間に中央寄せして描画します。
+  すると、このようになります:
+
+<p lang=en>Here there
+  are spaces.
+EOF
+cat >$TMP2 <<-EOF
+<!DOCTYPE html>
+
+<html lang=ja-JP>
+  <body>
+    <p>PやH2内の各行をそのマージンの間に中央寄せして描画します。すると、このようになります:
+
+    <p lang=en>Here there are spaces.
+EOF
+./hxnormalize -i 2 $TMP1 >$TMP3
+
+diff -u $TMP2 $TMP3
diff --git a/tests/normalize2.sh b/tests/normalize2.sh
index 4a7e02b..82de8f3 100755
--- a/tests/normalize2.sh
+++ b/tests/normalize2.sh
@@ -29,4 +29,4 @@ cat >$TMP2 <<-EOF
 	</dl>
 EOF
 ./hxnormalize -i 0 -L $TMP1 >$TMP3
-cmp -s $TMP2 $TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/normalize4.sh b/tests/normalize4.sh
index c7bb993..2949841 100755
--- a/tests/normalize4.sh
+++ b/tests/normalize4.sh
@@ -24,7 +24,7 @@ cat >$TMP2 <<-EOF
 	<!DOCTYPE html>
 
 	<html>
-	  <body>
+	  <head>
 	    <script>//<![CDATA[
 	Not a delimiter: <
 	Not a delimiter: </
@@ -38,4 +38,4 @@ cat >$TMP2 <<-EOF
 	    <p><![CDATA[<p></p>]]>
 EOF
 ./hxnormalize -i 2 $TMP1 >$TMP3
-cmp -s $TMP2 $TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/normalize5.sh b/tests/normalize5.sh
index 9e49ab1..08385f9 100755
--- a/tests/normalize5.sh
+++ b/tests/normalize5.sh
@@ -17,10 +17,10 @@ cat >$TMP2 <<-EOF
 
 	<html lang="en">
 	<head>
-	<style><![CDATA[
-	/* no <elements> or <![CDATA[ mark-up here */
-	]]></style></head>
+	<style>
+	/* no &lt;elements> or &lt;![CDATA[ mark-up here */
+	</style></head>
 	</html>
 EOF
-./hxnormalize -i 0 -x $TMP1 | ./hxnormalize -i 0 -x >$TMP3
-cmp -s $TMP2 $TMP3
+./hxnormalize -i 0 -x $TMP1 | ./hxnormalize -i 0 -X -x >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/normalize6.sh b/tests/normalize6.sh
index 75257a7..b7560d9 100755
--- a/tests/normalize6.sh
+++ b/tests/normalize6.sh
@@ -28,5 +28,5 @@ cat >$TMP2 <<-EOF
 	<body>
 	<p>...
 EOF
-./hxnormalize -x $TMP1 | ./hxnormalize -i 0 >$TMP3
-cmp -s $TMP2 $TMP3
+./hxnormalize -x $TMP1 | ./hxnormalize -i 0 -X >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/num1.sh b/tests/num1.sh
new file mode 100755
index 0000000..23c4545
--- /dev/null
+++ b/tests/num1.sh
@@ -0,0 +1,22 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang=en>
+	<body>
+	<h2>Heading</h2>
+EOF
+cat >$TMP2 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang="en">
+	<body>
+	<h2><span class="secno">A) </span>Heading</h2>
+EOF
+./hxnum -2 '%n%A) ' $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/num2.sh b/tests/num2.sh
new file mode 100755
index 0000000..7c42c63
--- /dev/null
+++ b/tests/num2.sh
@@ -0,0 +1,22 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang=en>
+	<body>
+	<h2>Heading</h2>
+EOF
+cat >$TMP2 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang="en">
+	<body>
+	<h2><span class="secno">a) </span>Heading</h2>
+EOF
+./hxnum -l 2 -2 '%a) ' $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/num3.sh b/tests/num3.sh
new file mode 100755
index 0000000..43f786f
--- /dev/null
+++ b/tests/num3.sh
@@ -0,0 +1,22 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang=en>
+	<body>
+	<h2>Heading</h2>
+EOF
+cat >$TMP2 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang="en">
+	<body>
+	<h2>Heading</h2>
+EOF
+./hxnum -l 3 -2 '%a) ' $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/num4.sh b/tests/num4.sh
new file mode 100755
index 0000000..45bea09
--- /dev/null
+++ b/tests/num4.sh
@@ -0,0 +1,22 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang=en>
+	<body>
+	<h2>Heading</h2>
+EOF
+cat >$TMP2 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang="en">
+	<body>
+	<h2><span class="secno">1. </span>Heading</h2>
+EOF
+./hxnum -l 2 $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/num5.sh b/tests/num5.sh
new file mode 100755
index 0000000..88faa11
--- /dev/null
+++ b/tests/num5.sh
@@ -0,0 +1,28 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang=en>
+	<body>
+	<h1>Heading</h1>
+	<h2>Heading</h2>
+	<h1>Heading</h1>
+	<h2>Heading</h2>
+EOF
+cat >$TMP2 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang="en">
+	<body>
+	<h1><span class="secno">1. </span>Heading</h1>
+	<h2><span class="secno">1. </span>Heading</h2>
+	<h1><span class="secno">2. </span>Heading</h1>
+	<h2><span class="secno">1. </span>Heading</h2>
+EOF
+./hxnum -2 '%n%d. ' $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/num6.sh b/tests/num6.sh
new file mode 100755
index 0000000..3d88922
--- /dev/null
+++ b/tests/num6.sh
@@ -0,0 +1,28 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang=en>
+	<body>
+	<h1>Heading</h1>
+	<h2>Heading</h2>
+	<h1>Heading</h1>
+	<h2>Heading</h2>
+EOF
+cat >$TMP2 <<-EOF
+	<!DOCTYPE html>
+
+	<html lang="en">
+	<body>
+	<h1>Heading</h1>
+	<h2><span class="secno">1. </span>Heading</h2>
+	<h1>Heading</h1>
+	<h2><span class="secno">2. </span>Heading</h2>
+EOF
+./hxnum -l 2 -2 '%d. ' $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/pipe2.sh b/tests/pipe2.sh
index 47b0095..9b24325 100755
--- a/tests/pipe2.sh
+++ b/tests/pipe2.sh
@@ -4,7 +4,7 @@ TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
 TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
 
 ./hxpipe >$TMP1 <<-EOF
-	<abc foo1=bar1 foo2="bar2 bar2">
+	<abc xxx="bar2 bar2" aaa=bar1>
 	text1
 	<def/>
 	<_foo>text2</_foo>
@@ -12,8 +12,8 @@ TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
 	</abc>
 EOF
 cat >$TMP2 <<-EOF
-Afoo1 CDATA bar1
-Afoo2 CDATA bar2 bar2
+Aaaa CDATA bar1
+Axxx CDATA bar2 bar2
 (abc
 -\ntext1\n
 |def
diff --git a/tests/pipe5.sh b/tests/pipe5.sh
new file mode 100755
index 0000000..6f59aef
--- /dev/null
+++ b/tests/pipe5.sh
@@ -0,0 +1,21 @@
+:
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+./hxpipe -H >$TMP1 <<-EOF
+	<style>
+	p {content: "<p>"}
+	</style>
+EOF
+cat >$TMP2 <<-EOF
+	(html
+	(head
+	(style
+	-\np {content: "<p>"}\n
+	)style
+	)head
+	)html
+EOF
+
+diff -u  $TMP2 $TMP1
diff --git a/tests/pipe6.sh b/tests/pipe6.sh
new file mode 100755
index 0000000..586235f
--- /dev/null
+++ b/tests/pipe6.sh
@@ -0,0 +1,34 @@
+:
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+./hxpipe -H >$TMP1 <<-EOF
+	<p data-foo2="bar2 bar2" data-foo1=bar1>
+	text1
+	<img>
+	<p>text2</p>
+	<p>text3
+EOF
+cat >$TMP2 <<-EOF
+(html
+(body
+Adata-foo1 CDATA bar1
+Adata-foo2 CDATA bar2 bar2
+(p
+-\ntext1\n
+|img
+-\n
+)p
+(p
+-text2
+)p
+-\n
+(p
+-text3\n
+)p
+)body
+)html
+EOF
+
+diff -u $TMP2 $TMP1
diff --git a/tests/pipe7.sh b/tests/pipe7.sh
new file mode 100755
index 0000000..46107b9
--- /dev/null
+++ b/tests/pipe7.sh
@@ -0,0 +1,13 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	test 1
+	test 2
+EOF
+./hxpipe -H file:$TMP1 >$TMP2
+./hxunpipe $TMP2 | ./hxpipe -H >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/printlinks5.sh b/tests/printlinks5.sh
new file mode 100755
index 0000000..583f166
--- /dev/null
+++ b/tests/printlinks5.sh
@@ -0,0 +1,25 @@
+:
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+./hxprintlinks -b "http://example/base/" >$TMP1 <<EOF
+<head profile="  http://www.microformats.org/wiki/hcard-profile  ">
+<link rel=alternate href=" a.atom  ">
+<p><img src="	../b.png " alt="">
+</html>
+EOF
+
+cat >$TMP2 <<EOF
+<head profile="  http://www.microformats.org/wiki/hcard-profile  ">
+<link rel="alternate" href=" a.atom  ">
+<p><img src="	../b.png " alt="">
+<ol class="urllist">
+<li><a class="profile" href="http://www.microformats.org/wiki/hcard-profile">http://www.microformats.org/wiki/hcard-profile</a></li>
+<li><a class="href" href="http://example/base/a.atom">http://example/base/a.atom</a></li>
+<li><a class="src" href="http://example/b.png">http://example/b.png</a></li>
+</ol>
+</html>
+EOF
+
+cmp -s $TMP1 $TMP2
diff --git a/tests/ref1.sh b/tests/ref1.sh
index 09b7416..072fa20 100755
--- a/tests/ref1.sh
+++ b/tests/ref1.sh
@@ -15,10 +15,10 @@ cat >$TMP1 <<-EOF
 (./hxref $TMP1; echo) >$TMP2
 
 cat >$TMP3 <<-EOF
-	<html><body><p><a href="#term-1">term 1</a>
+	<html><body><a href="#term-1">term 1</a>
 	text...
 	<dfn id="term-1">term 1</dfn>
-	</p></body></html>
+	</body></html>
 	EOF
 
-cmp -s $TMP2 $TMP3
+diff -u $TMP3 $TMP2
diff --git a/tests/ref2.sh b/tests/ref2.sh
index 6ed196c..bc2a99c 100755
--- a/tests/ref2.sh
+++ b/tests/ref2.sh
@@ -15,10 +15,10 @@ cat >$TMP1 <<-EOF
 (./hxref $TMP1; echo) >$TMP2
 
 cat >$TMP3 <<-EOF
-	<html><body><p><a href="#other" title="other">term 1</a>
+	<html><body><a href="#other" title="other">term 1</a>
 	text...
 	<dfn id="other">other</dfn>
-	</p></body></html>
+	</body></html>
 	EOF
 
-cmp -s $TMP2 $TMP3
+diff -u $TMP3 $TMP2
diff --git a/tests/ref3.sh b/tests/ref3.sh
index e5c1904..1dc5d95 100755
--- a/tests/ref3.sh
+++ b/tests/ref3.sh
@@ -15,10 +15,10 @@ cat >$TMP1 <<-EOF
 (./hxref $TMP1; echo) >$TMP2
 
 cat >$TMP3 <<-EOF
-	<html><body><p><a href="#term">other</a>
+	<html><body><a href="#term">other</a>
 	text...
 	<dfn id="term" title="other">term</dfn>
-	</p></body></html>
+	</body></html>
 	EOF
 
-cmp -s $TMP2 $TMP3
+diff -u $TMP3 $TMP2
diff --git a/tests/select11.sh b/tests/select11.sh
index d274988..aaeb07d 100755
--- a/tests/select11.sh
+++ b/tests/select11.sh
@@ -11,6 +11,7 @@ TMP2=`mktemp /tmp/addidXXXXXXXX` || exit 1
 	<li>Two</li>
 	<li>Three</li>
 	<li>Select this</li>
+	<!-- A comment -->
 	<li>And this</li>
 	</ul>
 	<address>But not this.</address>
diff --git a/tests/select12.sh b/tests/select12.sh
index 7ea3918..4675ea7 100755
--- a/tests/select12.sh
+++ b/tests/select12.sh
@@ -6,6 +6,8 @@ TMP2=`mktemp /tmp/addidXXXXXXXX` || exit 1
 
 ./hxselect -s '\n' 'div + ul > li:nth-child(-n+2)' >$TMP1 <<-EOF
 	<div><p>Not this.</p></div>
+	Some text
+	<!-- A comment -->
 	<ul>
 	<li>This</li>
 	<li>And this</li>
diff --git a/tests/select13.sh b/tests/select13.sh
index d2f4e9c..bef96e1 100755
--- a/tests/select13.sh
+++ b/tests/select13.sh
@@ -6,6 +6,8 @@ TMP2=`mktemp /tmp/addidXXXXXXXX` || exit 1
 
 ./hxselect -s '\n' 'div + ul > li:nth-last-child(2n+1)' >$TMP1 <<-EOF
 	<div><p>Not this.</p></div>
+	Some text
+	<!-- A comment -->
 	<ul>
 	<li>This</li>
 	<li>Two</li>
diff --git a/tests/select14.sh b/tests/select14.sh
index 7738032..19b518e 100755
--- a/tests/select14.sh
+++ b/tests/select14.sh
@@ -4,7 +4,7 @@ trap 'rm $TMP1 $TMP2' 0
 TMP1=`mktemp /tmp/addidXXXXXXXX` || exit 1
 TMP2=`mktemp /tmp/addidXXXXXXXX` || exit 1
 
-./hxselect -s '\n' ':empty' >$TMP1 <<-EOF
+./hxselect -s '\n' ':lang(en):empty' >$TMP1 <<-EOF
 	<div><p>Not this.</p></div>
 	<ul>
 	<li>One</li>
@@ -14,13 +14,13 @@ TMP2=`mktemp /tmp/addidXXXXXXXX` || exit 1
 	<li>Five</li>
 	</ul>
 	<address>But not this.</address>
-	<div title="This one."/>
-	<div title="And this one."></div>
+	<div lang="en" title="This one."/>
+	<div lang="fr"><!-- not this one --></div>
+	<div lang="en"title="And this one."></div>
 EOF
 cat >$TMP2 <<-EOF
-	<div title="This one."></div>
-	<div title="And this one."></div>
+	<div lang="en" title="This one."></div>
+	<div lang="en" title="And this one."></div>
 EOF
 
 diff -u $TMP1 $TMP2
-# cmp -s $TMP1 $TMP2
diff --git a/tests/select19.sh b/tests/select19.sh
index 2f95d36..f5870ab 100755
--- a/tests/select19.sh
+++ b/tests/select19.sh
@@ -10,6 +10,8 @@ TMP2=`mktemp /tmp/select18-XXXXXX` || exit 1
 	</div>
 	<p>
 	<a>Second</a>
+	Some text
+	<!-- A comment -->
 	<a>Third</a>
 	<a>Fourth</a>
 	</p>
diff --git a/tests/select21.sh b/tests/select21.sh
index 1ebf5fd..31f2cf0 100755
--- a/tests/select21.sh
+++ b/tests/select21.sh
@@ -7,6 +7,8 @@ TMP2=`mktemp /tmp/select18-XXXXXX` || exit 1
 ./hxselect -s '\n' 'div div' >$TMP1 <<-EOF
 	<div id=d1>
 	 <div id=d2 />
+	 Some text
+	 <!-- A comment -->
 	 <div id=d3 />
 	 <div id=d4 />
 	</div>
diff --git a/tests/select25.sh b/tests/select25.sh
new file mode 100755
index 0000000..918baf8
--- /dev/null
+++ b/tests/select25.sh
@@ -0,0 +1,19 @@
+:
+
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmpXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmpXXXXXX` || exit 1
+
+./hxselect -s '\n' 'abc[alt=""]' >$TMP1 <<-EOF
+<doc>
+  <nested>
+    <abc alt="a1">def</abc>
+    <abc alt="">ghi</abc>
+  </nested>
+</doc>
+EOF
+cat >$TMP2 <<EOF
+<abc alt="">ghi</abc>
+EOF
+
+diff -u $TMP1 $TMP2
diff --git a/tests/select26.sh b/tests/select26.sh
new file mode 100755
index 0000000..d071eb7
--- /dev/null
+++ b/tests/select26.sh
@@ -0,0 +1,22 @@
+:
+
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmpXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmpXXXXXX` || exit 1
+
+./hxselect -s '\n' ':is(abc, def)' >$TMP1 <<-EOF
+<doc>
+  <nested>
+    <abc alt="a1">abc</abc>
+    <def alt="">def</def>
+    <abc alt="a2">abc</abc>
+  </nested>
+</doc>
+EOF
+cat >$TMP2 <<EOF
+<abc alt="a1">abc</abc>
+<def alt="">def</def>
+<abc alt="a2">abc</abc>
+EOF
+
+diff -u $TMP1 $TMP2
diff --git a/tests/select27.sh b/tests/select27.sh
new file mode 100755
index 0000000..6b81db5
--- /dev/null
+++ b/tests/select27.sh
@@ -0,0 +1,27 @@
+:
+
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmpXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmpXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmpXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+<doc>
+  <nest1>
+    <abc alt="a1">abc</abc>
+  </nest1>
+  <nest2>
+    <def alt="">def</def>
+    <abc alt="a2">abc</abc>
+  </nest2>
+</doc>
+EOF
+
+./hxselect -s '\n' 'doc nest1 abc, doc nest2 abc, doc nest3 abc' <$TMP1 >$TMP2
+./hxselect -s '\n' ':is(doc) :is(nest1, nest2, nest3) abc' <$TMP1 >$TMP3
+
+cat $TMP2
+echo '======'
+cat $TMP3
+
+diff -u $TMP2 $TMP3
diff --git a/tests/select28.sh b/tests/select28.sh
new file mode 100755
index 0000000..9b3a8b1
--- /dev/null
+++ b/tests/select28.sh
@@ -0,0 +1,19 @@
+:
+
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/addidXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/addidXXXXXXXX` || exit 1
+
+./hxselect -c 'p' >$TMP1 <<-EOF
+	<div>
+	<p>Select this.</p>
+	<address>But not this.</address>
+	</div>
+	<p>Select this, too.<!-- And omit the comment --></p>
+EOF
+cat >$TMP2 <<-EOF
+	Select this.Select this, too.
+EOF
+
+echo >>$TMP1			# Add newline
+diff -u $TMP1 $TMP2
diff --git a/tests/select29.sh b/tests/select29.sh
new file mode 100755
index 0000000..3b5a8bf
--- /dev/null
+++ b/tests/select29.sh
@@ -0,0 +1,24 @@
+:
+
+trap 'rm -f $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmpXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmpXXXXXX` || exit 1
+
+./hxselect -i -s '\n' 'nest2 abc, nest1 abc, nest3 abc' >$TMP1 <<-EOF
+<doc>
+  <nest1>
+    <abc alt="a1">abc</abc>
+  </nest1>
+  <nest2>
+    <def alt="">def</def>
+    <abc alt="a2">abc</abc>
+  </nest2>
+</doc>
+EOF
+
+cat >$TMP2 <<-EOF
+<abc alt="a1">abc</abc>
+<abc alt="a2">abc</abc>
+EOF
+
+diff -u $TMP2 $TMP1
diff --git a/tests/select30.sh b/tests/select30.sh
new file mode 100755
index 0000000..930de8a
--- /dev/null
+++ b/tests/select30.sh
@@ -0,0 +1,24 @@
+:
+
+trap 'rm -f $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmpXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmpXXXXXX` || exit 1
+
+./hxselect -i -s '\n' 'ABC[ALT*=A]' >$TMP1 <<-EOF
+<doc>
+  <nest1>
+    <abc alt="a1">abc</abc>
+  </nest1>
+  <nest2>
+    <def alt="">def</def>
+    <abc alt="a2">abc</abc>
+  </nest2>
+</doc>
+EOF
+
+cat >$TMP2 <<-EOF
+<abc alt="a1">abc</abc>
+<abc alt="a2">abc</abc>
+EOF
+
+diff -u $TMP2 $TMP1
diff --git a/tests/select31.sh b/tests/select31.sh
new file mode 100755
index 0000000..59a712b
--- /dev/null
+++ b/tests/select31.sh
@@ -0,0 +1,25 @@
+:
+
+trap 'rm -f $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmpXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmpXXXXXX` || exit 1
+
+./hxselect -i -s '\n' 'NEST1 ~ Nest2 abc' >$TMP1 <<-EOF
+<doc>
+  <nest1>
+    <abc alt="a1">abc</abc>
+  </nest1>
+  Some text
+  <!-- A comment -->
+  <nest2>
+    <def alt="">def</def>
+    <abc alt="a2">abc</abc>
+  </nest2>
+</doc>
+EOF
+
+cat >$TMP2 <<-EOF
+<abc alt="a2">abc</abc>
+EOF
+
+diff -u $TMP2 $TMP1
diff --git a/tests/select32.sh b/tests/select32.sh
new file mode 100755
index 0000000..6c646be
--- /dev/null
+++ b/tests/select32.sh
@@ -0,0 +1,32 @@
+:
+
+trap 'rm -f $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmpXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmpXXXXXX` || exit 1
+
+./hxselect -s '\n' 'div ~ div div ~ div abc' >$TMP1 <<-EOF
+<doc>
+  <div>
+    <div>
+      <abc>no</abc>
+    </div>
+  </div>
+  <div>
+    <div>
+      <div>
+        <abc>no</abc>
+      </div>
+      <!-- comment -->
+      <div>
+        <abc>yes</abc>
+      </div>
+    </div>
+  </div>
+</doc>
+EOF
+
+cat >$TMP2 <<-EOF
+<abc>yes</abc>
+EOF
+
+diff -u $TMP2 $TMP1
diff --git a/tests/select33.sh b/tests/select33.sh
new file mode 100755
index 0000000..3291fd3
--- /dev/null
+++ b/tests/select33.sh
@@ -0,0 +1,20 @@
+:
+
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/addidXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/addidXXXXXXXX` || exit 1
+
+./hxselect -s '\n' 'q, p::attr(title), p, span::attr(value)' >$TMP1 <<-EOF
+  <div>
+    <p title="Select this.">And this.</p>
+    <span value="And this.">Not this.</span>
+  </div>
+EOF
+
+cat >$TMP2 <<-EOF
+<p title="Select this.">And this.</p>
+title="Select this."
+value="And this."
+EOF
+
+diff -u $TMP2 $TMP1
diff --git a/tests/select34.sh b/tests/select34.sh
new file mode 100755
index 0000000..584501a
--- /dev/null
+++ b/tests/select34.sh
@@ -0,0 +1,54 @@
+:
+
+# Check octal escapes.
+
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/addidXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/addidXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/addidXXXXXXXX` || exit 1
+
+cat >$TMP1 <<EOF
+<div>
+<p>Select this.</p>
+<address>But not this.</address>
+</div>
+<p>Select this, too.</p>
+EOF
+
+# Check that \11 and \011 do the same as \t
+
+./hxselect -s '\t\t' -c p <$TMP1 >$TMP2
+
+./hxselect -s '\11\11' -c p <$TMP1 >$TMP3
+printf '%b' '\\11 same as \\t: \c'
+if cmp $TMP2 $TMP3; then echo OK; else echo fail; exit 1; fi
+
+./hxselect -s '\011\011' -c p <$TMP1 >$TMP3
+printf '%b' '\\011 same as \\t: \c'
+if cmp $TMP2 $TMP3; then echo OK; else echo fail; exit 1; fi
+
+# Check that \15 and \015 do the same as \r
+
+./hxselect -s '\r\r' -c p <$TMP1 >$TMP2
+
+./hxselect -s '\15\15' -c p <$TMP1 >$TMP3
+printf '%b' '\\15 same as \\r: \c'
+if cmp $TMP2 $TMP3; then echo OK; else echo fail; exit 1; fi
+
+./hxselect -s '\015\015' -c p <$TMP1 >$TMP3
+printf '%b' '\\015 same as \\r: \c'
+if cmp $TMP2 $TMP3; then echo OK; else echo fail; exit 1; fi
+
+# Test \0
+
+cat >$TMP2 <<EOF
+Select this.
+
+Select this, too.
+
+EOF
+
+# Use tr to replace the \0 by \n
+./hxselect -s '\0\0' -c p <$TMP1  | tr '\0' '\n' >$TMP3
+printf '%b' '\\0: \c'
+if cmp $TMP2 $TMP3; then echo OK; else echo fail; exit 1; fi
diff --git a/tests/toc1.sh b/tests/toc1.sh
index da77478..34618f6 100755
--- a/tests/toc1.sh
+++ b/tests/toc1.sh
@@ -17,7 +17,8 @@ EOF
 echo >>$TMP1			# Add newline
 
 cat >$TMP2 <<-EOF
-<html><head><title>Test</title></head><body><h1 id="document-heading">Document heading</h1><!--begin-toc-->
+<html><head><title>Test</title></head><body><h1 id="document-heading">Document heading</h1>
+<!--begin-toc-->
 <ul class="toc">
 <li><a href="#document-heading">Document heading</a>
  <ul class="toc">
@@ -26,12 +27,14 @@ cat >$TMP2 <<-EOF
   <li><a href="#third-level-heading-">Third-level heading</a>
   </ul>
  </ul></ul>
-<!--end-toc--><section id="second-level-heading-third-level-heading">
+<!--end-toc-->
+<section id="second-level-heading-third-level-heading">
 <h1>Second-level heading</h1>
 <section id="third-level-heading-">
 <h6>Third-level heading</h6>
 </section>
-</section></body></html>
+</section>
+</body></html>
 EOF
 
-cmp -s $TMP1 $TMP2
+diff -u $TMP2 $TMP1
diff --git a/tests/toc2.sh b/tests/toc2.sh
index d4c98ea..bbc926e 100755
--- a/tests/toc2.sh
+++ b/tests/toc2.sh
@@ -13,7 +13,8 @@ EOF
 echo >>$TMP1			# Add newline
 
 cat >$TMP2 <<-EOF
-<html><head><title>Test</title></head><body><h1 id="document-heading">Document heading</h1><!--begin-toc-->
+<html><head><title>Test</title></head><body><h1 id="document-heading">Document heading</h1>
+<!--begin-toc-->
 <ul class="toc">
 <li><a href="#document-heading">Document heading</a>
  <ul class="toc">
@@ -22,7 +23,10 @@ cat >$TMP2 <<-EOF
   <li><a href="#third-level-heading">Third-level heading</a>
   </ul>
  </ul></ul>
-<!--end-toc--><h2 id="second-level-heading">Second-level heading</h2><h3 id="third-level-heading">Third-level heading</h3></body></html>
+<!--end-toc-->
+<h2 id="second-level-heading">Second-level heading</h2>
+<h3 id="third-level-heading">Third-level heading</h3>
+</body></html>
 EOF
 
-cmp -s $TMP1 $TMP2
+diff -u $TMP2 $TMP1
diff --git a/tests/toc3.sh b/tests/toc3.sh
index 9e1a904..d94349b 100755
--- a/tests/toc3.sh
+++ b/tests/toc3.sh
@@ -14,7 +14,8 @@ EOF
 echo >>$TMP1			# Add newline
 
 cat >$TMP2 <<-EOF
-<html><head><title>Test</title></head><body><h1 id="document-heading">Document <b>heading</b></h1><!--begin-toc-->
+<html><head><title>Test</title></head><body><h1 id="document-heading">Document <b>heading</b></h1>
+<!--begin-toc-->
 <ul class="toc">
 <li><a href="#document-heading">Document heading</a>
  <ul class="toc">
@@ -24,7 +25,11 @@ cat >$TMP2 <<-EOF
   <li><a href="#another-third-level-heading">Another <span dir="ltr">Third-level</span> heading</a>
   </ul>
  </ul></ul>
-<!--end-toc--><h2 id="second-level-">Second-level <img src="" alt="heading"></h2><h3 id="third-level-heading">Third-level <bdo dir="ltr">heading</bdo></h3><h3 id="another-third-level-heading">Another <abbr title="none" dir="ltr">Third-level</abbr> heading</h3></body></html>
+<!--end-toc-->
+<h2 id="second-level-">Second-level <img src="" alt="heading"></h2>
+<h3 id="third-level-heading">Third-level <bdo dir="ltr">heading</bdo></h3>
+<h3 id="another-third-level-heading">Another <abbr title="none" dir="ltr">Third-level</abbr> heading</h3>
+</body></html>
 EOF
 
-cmp -s $TMP1 $TMP2
+diff -u $TMP2 $TMP1
diff --git a/tests/toc4.sh b/tests/toc4.sh
index 5e08124..03d29b4 100755
--- a/tests/toc4.sh
+++ b/tests/toc4.sh
@@ -1,5 +1,5 @@
 :
-# Test if hxtoc treatc some HTML5 elements correctly
+# Test if hxtoc treats some HTML5 elements correctly
 
 trap 'rm $TMP1 $TMP2 $TMP3' 0
 TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
@@ -23,10 +23,12 @@ cat >$TMP1 <<EOF
 EOF
 
 cat >$TMP2 <<EOF
-<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>Title</title></head><body><p>
+<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>Title</title></head><body>
+<p>
 <video controls><source src="gillette_media/powwow_highway.mp4" type="video/mp4">Video</video>
 <em>Powwow Highway: Gillette scene</em>
-</p></body></html>
+</p>
+</body></html>
 EOF
 
 ./hxtoc $TMP1 >$TMP3
diff --git a/tests/toc5.sh b/tests/toc5.sh
new file mode 100755
index 0000000..f5a474e
--- /dev/null
+++ b/tests/toc5.sh
@@ -0,0 +1,45 @@
+:
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+./hxtoc -d -t >$TMP1 <<-EOF
+	<title>Test</title>
+	<h1>Document heading</h1>
+	<!--toc-->
+	<section id=sec1>
+	<p>Multiple headings in this section.
+	<h1>Second-level heading</h1>
+	<h3>Third-level heading</h3>
+	<section id=sec2>
+	<hgroup><h6>Another third-level heading</h6></hgroup>
+	</section>
+	</section>
+EOF
+echo >>$TMP1			# Add newline
+
+cat >$TMP2 <<-EOF
+<html><head><title>Test</title></head><body><h1 id="document-heading">Document heading</h1>
+<!--begin-toc-->
+<ul class="toc">
+<li><a href="#document-heading">Document heading</a>
+ <ul class="toc">
+ <li><a href="#sec1">Second-level heading</a>
+  <ul class="toc">
+  <li><a href="#third-level-heading">Third-level heading</a>
+  <li><a href="#sec2">Another third-level heading</a>
+  </ul>
+ </ul></ul>
+<!--end-toc-->
+<section id="sec1">
+<p>Multiple headings in this section.
+</p><h1>Second-level heading</h1>
+<h3 id="third-level-heading">Third-level heading</h3>
+<section id="sec2">
+<hgroup><h6>Another third-level heading</h6></hgroup>
+</section>
+</section>
+</body></html>
+EOF
+
+diff -u $TMP2 $TMP1
diff --git a/tests/toc6.sh b/tests/toc6.sh
new file mode 100755
index 0000000..a6bcdb5
--- /dev/null
+++ b/tests/toc6.sh
@@ -0,0 +1,91 @@
+:
+trap 'rm $TMP1 $TMP2' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+./hxtoc -d -t -h 8 >$TMP1 <<-EOF
+	<title>Test</title>
+	<h1>Document heading</h1>
+	<!--toc-->
+	<section id=sec2>
+	<h1>Second-level heading</h1>
+	<section id=sec3>
+	<h1>Third-level heading</h1>
+	<section id=sec4>
+	<h1>Fourth-level heading</h1>
+	<section id=sec5>
+	<h1>Fifth-level heading</h1>
+	<section id=sec6>
+	<h1>Sixth-level heading</h1>
+	<section id=sec7>
+	<h1>Seventh-level heading</h1>
+	<section id=sec8>
+	<h1>Eight-level heading</h1>
+	<section id=sec9>
+	<h1>Ninth-level heading</h1>
+	</section>
+	</section>
+	</section>
+	</section>
+	</section>
+	</section>
+	</section>
+	</section>
+EOF
+echo >>$TMP1			# Add newline
+
+cat >$TMP2 <<-EOF
+<html><head><title>Test</title></head><body><h1 id="document-heading">Document heading</h1>
+<!--begin-toc-->
+<ul class="toc">
+<li><a href="#document-heading">Document heading</a>
+ <ul class="toc">
+ <li><a href="#sec2">Second-level heading</a>
+  <ul class="toc">
+  <li><a href="#sec3">Third-level heading</a>
+   <ul class="toc">
+   <li><a href="#sec4">Fourth-level heading</a>
+    <ul class="toc">
+    <li><a href="#sec5">Fifth-level heading</a>
+     <ul class="toc">
+     <li><a href="#sec6">Sixth-level heading</a>
+      <ul class="toc">
+      <li><a href="#sec7">Seventh-level heading</a>
+       <ul class="toc">
+       <li><a href="#sec8">Eight-level heading</a>
+       </ul>
+      </ul>
+     </ul>
+    </ul>
+   </ul>
+  </ul>
+ </ul></ul>
+<!--end-toc-->
+<section id="sec2">
+<h1>Second-level heading</h1>
+<section id="sec3">
+<h1>Third-level heading</h1>
+<section id="sec4">
+<h1>Fourth-level heading</h1>
+<section id="sec5">
+<h1>Fifth-level heading</h1>
+<section id="sec6">
+<h1>Sixth-level heading</h1>
+<section id="sec7">
+<h1>Seventh-level heading</h1>
+<section id="sec8">
+<h1>Eight-level heading</h1>
+<section id="sec9">
+<h1>Ninth-level heading</h1>
+</section>
+</section>
+</section>
+</section>
+</section>
+</section>
+</section>
+</section>
+</body></html>
+EOF
+
+diff -u $TMP2 $TMP1
diff --git a/tests/wls6.sh b/tests/wls6.sh
new file mode 100755
index 0000000..b1382d8
--- /dev/null
+++ b/tests/wls6.sh
@@ -0,0 +1,23 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<link rel=stylesheet href="http://example.org/style.css">
+	<a href="foo.html">.</a>
+	<img src="bar/foo.png">
+	<img src="../bar/foo.png">
+	<img src="../bar/foo.png" srcset="../bar/foo.svg">
+EOF
+cat >$TMP2 <<-EOF
+	link	stylesheet	http://example.org/style.css
+	a		http://example.org/othersub/foo.html
+	img		http://example.org/othersub/bar/foo.png
+	img		http://example.org/bar/foo.png
+	img		http://example.org/bar/foo.png
+	img	srcset	http://example.org/bar/foo.svg
+EOF
+./hxwls -b http://example.org/othersub/base -l $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/tests/wls7.sh b/tests/wls7.sh
new file mode 100755
index 0000000..60f6913
--- /dev/null
+++ b/tests/wls7.sh
@@ -0,0 +1,28 @@
+:
+trap 'rm $TMP1 $TMP2 $TMP3' 0
+TMP1=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP2=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+TMP3=`mktemp /tmp/tmp.XXXXXXXXXX` || exit 1
+
+cat >$TMP1 <<-EOF
+	<link rel=stylesheet href="
+	http://example.org/style.css">
+	<a href=" foo.html ">.</a>
+	<img src="bar/foo.png	">
+	<img src="../bar/foo.png    ">
+	<picture>
+	  <source type="image/svg+xml" srcset="
+	  foo.svg">
+	  <img src="foo.png" alt="">
+	</picture>
+EOF
+cat >$TMP2 <<-EOF
+	http://example.org/style.css
+	../othersub/foo.html
+	../othersub/bar/foo.png
+	../bar/foo.png
+	../othersub/foo.svg
+	../othersub/foo.png
+EOF
+./hxwls -b ../othersub/base $TMP1 >$TMP3
+diff -u $TMP2 $TMP3
diff --git a/textwrap.c b/textwrap.c
index c58f70d..a84dd5d 100644
--- a/textwrap.c
+++ b/textwrap.c
@@ -8,7 +8,7 @@
  *
  * Bert Bos
  * Created 10 May 1998
- * $Id: textwrap.c,v 1.32 2017/11/24 10:14:49 bbos Exp $
+ * $Id: textwrap.c,v 1.35 2023/01/23 21:19:42 bbos Exp $
  */
 #include "config.h"
 #include <stdio.h>
@@ -26,7 +26,6 @@
 #include <stdbool.h>
 #include "export.h"
 #include "types.e"
-#include "errexit.e"
 #include "heap.e"
 
 /* To do: XML 1.1 allows &#1;, so the following isn't safe anymore */
@@ -63,7 +62,7 @@ EXPORT void flush()
       else if ((buf[j] & 0xC0) != 0x80) k++; /* Start of a UTF-8 sequence */
     if (i < 0) break;				/* No breakpoint */
     assert(i >= 0);				/* Found a breakpoint at i */
-    assert(buf[i] == ' ' || buf[i]==BREAKOP);
+    assert(buf[i] == ' ' || buf[i] == BREAKOP);
     /* Print up to breakpoint (removing non-break-space markers) */
     for (j = 0; j < i; j++)
       if (buf[j] != BREAKOP) {
@@ -98,17 +97,24 @@ EXPORT void flush()
 }
 
 /* outc -- add one character to output buffer */
-EXPORT void outc(char c, bool preformatted)
+EXPORT void outc(char c, bool preformatted, bool with_space)
 {
-  if (c == '\n' && !preformatted) c = ' ';	/* Newline is just a space */
-  if (c == '\r' && !preformatted) c = ' ';	/* CR is just a space */
-  if (c == '\t' && !preformatted) c = ' ';	/* Tab is just a space */
-  if (c == '\f' && !preformatted) c = ' ';	/* Formfeed is just a space */
-  if (c == ' ' && preformatted) c = NBSP;	/* Non-break-space marker */
-  if (c == ' ' && prev == ' ') return;		/* Don't add another space */
+  if (c == '\n' || c == '\r' || c == '\f') {
+    if (preformatted) ;		  /* Keep unchanged */
+    else if (with_space) c = ' '; /* Treated as space */
+    else c = BREAKOP;		  /* Treated as a break opportunity */
+  } else if (c == '\t') {
+    if (preformatted) ;		  /* Keep unchanged */
+    else c = ' ';		  /* Tab is just a space */
+  }
+  if (c == ' ') {
+    if (preformatted) c = NBSP;	  /* Non-break-space marker */
+    else if (prev == ' ') return; /* Don't add another space */
+    else if (prev == BREAKOP) return; /* Don't add a space after \n or similar */
+  }
   if ((c == ' ' || c == BREAKOP) && linelen + bufchars >= maxlinelen) flush();
   if (c == '\n' || c == '\r' || c == '\f') flush(); /* Empty the buf */
-  if (c == ' ' && linelen + len == 0) return;	/* No ins at BOL */
+  if (c == ' ' && linelen + len == 0) return;	/* No insert at BOL */
   while (level * indent >= buflen) {buflen += 1024; renewarray(buf, buflen);}
   if (linelen + len == 0 && !preformatted)
     while (len < level * indent) {buf[len++] = NBSP; bufchars++;}
@@ -120,22 +126,22 @@ EXPORT void outc(char c, bool preformatted)
 }
 
 /* out -- add text to current output line, print line if getting too long */
-EXPORT void out(string s, bool preformatted)
+EXPORT void out(string s, bool preformatted, bool with_space)
 {
-  if (s) for (; *s; s++) outc(*s, preformatted);
+  if (s) for (; *s; s++) outc(*s, preformatted, with_space);
 }
 
 /* outn -- add n chars to current output, print line if getting too long */
-EXPORT void outn(string s, size_t n, bool preformatted)
+EXPORT void outn(string s, size_t n, bool preformatted, bool with_space)
 {
   size_t i;
-  for (i = 0; i < n; i++) outc(s[i], preformatted);
+  for (i = 0; i < n; i++) outc(s[i], preformatted, with_space);
 }
 
 /* outln -- add string to output buffer, followed by '\n' */
-EXPORT void outln(char *s, bool preformatted)
+EXPORT void outln(char *s, bool preformatted, bool with_space)
 {
-  out(s, preformatted);
+  out(s, preformatted, with_space);
   flush();
   assert(len == 0);
   assert(bufchars == 0);
@@ -158,7 +164,7 @@ EXPORT void outbreak(void)
 /* outbreakpoint -- mark a possible line break point */
 EXPORT void outbreakpoint(void)
 {
-  outc(BREAKOP, false);
+  outc(BREAKOP, false, true);
 }
 
 
diff --git a/textwrap.e b/textwrap.e
old mode 100755
new mode 100644
index 5654c62..35ab003
--- a/textwrap.e
+++ b/textwrap.e
@@ -3,16 +3,24 @@ extern void set_linelen(int n);
 extern void flush();
 extern void outc(char c, 
                         _Bool 
-                             preformatted);
+                             preformatted, 
+                                           _Bool 
+                                                with_space);
 extern void out(string s, 
                          _Bool 
-                              preformatted);
+                              preformatted, 
+                                            _Bool 
+                                                 with_space);
 extern void outn(string s, size_t n, 
                                     _Bool 
-                                         preformatted);
+                                         preformatted, 
+                                                       _Bool 
+                                                            with_space);
 extern void outln(char *s, 
                           _Bool 
-                               preformatted);
+                               preformatted, 
+                                             _Bool 
+                                                  with_space);
 extern void outbreak(void);
 extern void outbreakpoint(void);
 extern void inc_indent(void);
diff --git a/tree.c b/tree.c
index 6e70977..3d9f548 100644
--- a/tree.c
+++ b/tree.c
@@ -21,12 +21,13 @@
 #endif
 #include <ctype.h>
 #include <stdio.h>
+#include <err.h>
+#include <sysexits.h>
 #include <stdbool.h>
 #include "export.h"
 #include "heap.e"
 #include "types.e"
 #include "dtd.e"
-#include "errexit.e"
 #include "scan.e"
 
 EXPORT typedef enum {
@@ -425,11 +426,13 @@ EXPORT Tree html_push(Tree t, string elem, pairlist attr)
 EXPORT Tree tree_pop(Tree t, string elem)
 {
   assert(t != NULL);
-  if (t->tp == Root) errexit("End tag </%s> without matching start tag\n", elem);
+  if (t->tp == Root)
+    errx(EX_DATAERR, "End tag </%s> without matching start tag", elem);
   assert(t->tp == Element);
   if (*elem == '\0') return pop(t); /* Empty end tag </> */
   if (eq(t->name, elem)) return pop(t);
-  errexit("End tag </%s> doesn't match start tag <%s>\n", elem, t->name);
+  errx(EX_DATAERR, "End tag </%s> doesn't match start tag <%s>",
+    elem, t->name);
   return NULL;			/* Keep lint happy */
 }
 
diff --git a/tree.e b/tree.e
old mode 100755
new mode 100644
diff --git a/types.c b/types.c
index 44f5d89..f22d88a 100644
--- a/types.c
+++ b/types.c
@@ -123,6 +123,31 @@ EXPORT bool pairlist_unset(pairlist *p, const conststring name)
   return true;
 }
 
+
+/* insert -- insert an attribute into a sorted list of attributes */
+static pairlist insert(pairlist x, pairlist list)
+{
+  if (! list) {					/* Empty list */
+    x->next = NULL;
+    return x;
+  } else if (strcmp(x->name, list->name) <= 0) { /* Insert at head */
+    x->next = list;
+    return x;
+  } else {					/* Insert not at head */
+    list->next = insert(x, list->next);
+    return list;
+  }
+}
+
+/* pairlist_sort -- sort a linked list of pairs, return reordered list */
+EXPORT pairlist pairlist_sort(pairlist list)
+{
+  /* Insertion sort should be fast enough... */
+  if (! list) return NULL;
+  else return insert(list, pairlist_sort(list->next));
+}
+
+
 /* strapp -- append to a string, re-allocating memory; last arg must be 0 */
 EXPORT string strapp(string *s,...)
 {
diff --git a/types.e b/types.e
old mode 100755
new mode 100644
index 5f58f29..a3c30d9
--- a/types.e
+++ b/types.e
@@ -24,12 +24,17 @@ extern pairlist pairlist_copy(const pairlist p);
 extern conststring pairlist_get(pairlist p, const conststring name);
 extern void pairlist_set(pairlist *p, const conststring name,
     const conststring val);
-extern _Bool pairlist_unset(pairlist *p, const conststring name);
+extern _Bool 
+           pairlist_unset(pairlist *p, const conststring name);
+extern pairlist pairlist_sort(pairlist list);
 extern string strapp(string *s,...);
 extern void chomp(string s);
 extern int min(int a, int b);
 extern int max(int a, int b);
 extern string down(const string s);
-extern _Bool hasprefix(conststring s, conststring prefix);
-extern _Bool hasaffix(conststring s, conststring affix);
-extern _Bool only_space(conststring s);
+extern _Bool 
+           hasprefix(conststring s, conststring prefix);
+extern _Bool 
+           hasaffix(conststring s, conststring affix);
+extern _Bool 
+           only_space(conststring s);
diff --git a/unent.c b/unent.c
old mode 100755
new mode 100644
index 822a7cf..a177baa
--- a/unent.c
+++ b/unent.c
@@ -1,5 +1,5 @@
 /* ANSI-C code produced by gperf version 3.1 */
-/* Command-line: gperf -a -c -C -o -t -p -k '1,2,$' -D -N lookup_entity unent.hash  */
+/* Command-line: gperf -a -c -C -o -t -p -k 1-6 -N lookup_entity unent.hash  */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
       && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
@@ -70,9 +70,9 @@ struct _Entity;
 #define TOTAL_KEYWORDS 253
 #define MIN_WORD_LENGTH 2
 #define MAX_WORD_LENGTH 8
-#define MIN_HASH_VALUE 10
-#define MAX_HASH_VALUE 533
-/* maximum key range = 524, duplicates = 2 */
+#define MIN_HASH_VALUE 2
+#define MAX_HASH_VALUE 705
+/* maximum key range = 704, duplicates = 0 */
 
 #ifdef __GNUC__
 __inline
@@ -86,34 +86,57 @@ hash (register const char *str, register size_t len)
 {
   static const unsigned short asso_values[] =
     {
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534,  40,
-       70,  20,  50, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 193,   5, 215,   0, 219,
-      534, 185,   5, 215, 190,  45,   5,   0,  30, 199,
-       35, 534,  15,  15,  10, 110,   0, 534,  10,  40,
-        0, 534, 534, 534, 534, 534, 534,  10, 210,   5,
-      155,   0, 200,  10,  15, 100, 175, 155,  20, 150,
-      145,  45,  65, 200,  35, 105,  55,  75, 140, 115,
-        0, 250,  80, 534, 100, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
-      534, 534, 534, 534, 534, 534, 534, 534
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706,  50,
+       45,  85,   0, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 115,   5, 135,   5,  85,
+        0,   0,   0, 145, 706,  20,  65,   0,  15,  75,
+        0, 706,   0,  45,   0, 120, 706, 706,   5,  65,
+       20, 706, 706, 706, 706, 706, 706,   0,  25,  20,
+        0,   5, 135, 240, 220,  15,  94,   5, 120, 175,
+       50,  60,  85, 167,  15,  55,  10,  10,   0,  15,
+       10,  55,  15,   0, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706, 706, 706, 706,
+      706, 706, 706, 706, 706, 706, 706
     };
-  return len + asso_values[(unsigned char)str[1]+2] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
+  register unsigned int hval = len;
+
+  switch (hval)
+    {
+      default:
+        hval += asso_values[(unsigned char)str[5]];
+      /*FALLTHROUGH*/
+      case 5:
+        hval += asso_values[(unsigned char)str[4]];
+      /*FALLTHROUGH*/
+      case 4:
+        hval += asso_values[(unsigned char)str[3]];
+      /*FALLTHROUGH*/
+      case 3:
+        hval += asso_values[(unsigned char)str[2]];
+      /*FALLTHROUGH*/
+      case 2:
+        hval += asso_values[(unsigned char)str[1]+1];
+      /*FALLTHROUGH*/
+      case 1:
+        hval += asso_values[(unsigned char)str[0]];
+        break;
+    }
+  return hval;
 }
 
 const struct _Entity *
@@ -121,583 +144,661 @@ lookup_entity (register const char *str, register size_t len)
 {
   static const struct _Entity wordlist[] =
     {
-#line 114 "unent.hash"
-      {"ecirc", 234},
-#line 113 "unent.hash"
-      {"eacute", 233},
+      {""}, {""},
+#line 148 "unent.hash"
+      {"Mu", 924},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""},
+#line 149 "unent.hash"
+      {"Nu", 925},
+#line 167 "unent.hash"
+      {"eta", 951},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 159 "unent.hash"
+      {"Psi", 936},
+      {""},
 #line 60 "unent.hash"
       {"acute", 180},
+      {""}, {""},
+#line 157 "unent.hash"
+      {"Phi", 934},
+      {""},
+#line 144 "unent.hash"
+      {"Theta", 920},
+      {""}, {""},
+#line 155 "unent.hash"
+      {"Tau", 932},
+#line 209 "unent.hash"
+      {"dArr", 8659},
+      {""}, {""}, {""}, {""}, {""},
+#line 168 "unent.hash"
+      {"theta", 952},
+      {""}, {""},
+#line 180 "unent.hash"
+      {"tau", 964},
+#line 207 "unent.hash"
+      {"uArr", 8657},
+#line 237 "unent.hash"
+      {"equiv", 8801},
+      {""},
+#line 173 "unent.hash"
+      {"nu", 957},
+#line 183 "unent.hash"
+      {"chi", 967},
+#line 208 "unent.hash"
+      {"rArr", 8658},
 #line 106 "unent.hash"
       {"acirc", 226},
+#line 232 "unent.hash"
+      {"there4", 8756},
+      {""}, {""},
+#line 203 "unent.hash"
+      {"darr", 8595},
+#line 114 "unent.hash"
+      {"ecirc", 234},
+      {""}, {""},
+#line 227 "unent.hash"
+      {"and", 8743},
+      {""},
+#line 131 "unent.hash"
+      {"ucirc", 251},
+      {""}, {""}, {""},
+#line 201 "unent.hash"
+      {"uarr", 8593},
+#line 118 "unent.hash"
+      {"icirc", 238},
+      {""}, {""}, {""},
+#line 202 "unent.hash"
+      {"rarr", 8594},
+#line 198 "unent.hash"
+      {"trade", 8482},
 #line 105 "unent.hash"
       {"aacute", 225},
-#line 239 "unent.hash"
-      {"ge", 8805},
-#line 142 "unent.hash"
-      {"Zeta", 918},
-#line 140 "unent.hash"
-      {"Delta", 916},
-#line 147 "unent.hash"
-      {"Lambda", 923},
-#line 138 "unent.hash"
-      {"Beta", 914},
-#line 163 "unent.hash"
-      {"gamma", 947},
-#line 111 "unent.hash"
-      {"ccedil", 231},
-#line 238 "unent.hash"
-      {"le", 8804},
-#line 110 "unent.hash"
-      {"aelig", 230},
-#line 253 "unent.hash"
-      {"lang", 9001},
-#line 64 "unent.hash"
-      {"cedil", 184},
-#line 171 "unent.hash"
-      {"lambda", 955},
-#line 249 "unent.hash"
-      {"lceil", 8968},
-#line 288 "unent.hash"
-      {"Dagger", 8225},
+      {""},
+#line 153 "unent.hash"
+      {"Rho", 929},
+      {""},
 #line 223 "unent.hash"
       {"radic", 8730},
-#line 101 "unent.hash"
-      {"Yacute", 221},
-#line 254 "unent.hash"
-      {"rang", 9002},
-#line 124 "unent.hash"
-      {"ocirc", 244},
-#line 123 "unent.hash"
-      {"oacute", 243},
-#line 54 "unent.hash"
-      {"reg", 174},
-#line 204 "unent.hash"
-      {"harr", 8596},
-#line 250 "unent.hash"
-      {"rceil", 8969},
-#line 200 "unent.hash"
-      {"larr", 8592},
-#line 146 "unent.hash"
-      {"Kappa", 922},
-#line 197 "unent.hash"
-      {"real", 8476},
-#line 266 "unent.hash"
-      {"oelig", 339},
-#line 42 "unent.hash"
-      {"cent", 162},
-#line 51 "unent.hash"
-      {"laquo", 171},
-#line 251 "unent.hash"
-      {"lfloor", 8970},
-#line 229 "unent.hash"
-      {"cap", 8745},
-#line 202 "unent.hash"
-      {"rarr", 8594},
-#line 109 "unent.hash"
-      {"aring", 229},
-#line 62 "unent.hash"
-      {"para", 182},
-#line 131 "unent.hash"
-      {"ucirc", 251},
+#line 113 "unent.hash"
+      {"eacute", 233},
+      {""},
+#line 240 "unent.hash"
+      {"sub", 8834},
+#line 292 "unent.hash"
+      {"euro", 8364},
+      {""},
 #line 130 "unent.hash"
       {"uacute", 250},
-#line 226 "unent.hash"
-      {"ang", 8736},
-#line 67 "unent.hash"
-      {"raquo", 187},
-#line 252 "unent.hash"
-      {"rfloor", 8971},
-#line 155 "unent.hash"
-      {"Tau", 932},
-#line 192 "unent.hash"
-      {"Prime", 8243},
-#line 190 "unent.hash"
-      {"hellip", 8230},
-#line 205 "unent.hash"
-      {"crarr", 8629},
-#line 289 "unent.hash"
-      {"permil", 8240},
-#line 166 "unent.hash"
-      {"zeta", 950},
-#line 185 "unent.hash"
-      {"omega", 969},
-#line 112 "unent.hash"
-      {"egrave", 232},
-#line 118 "unent.hash"
-      {"icirc", 238},
+      {""},
+#line 231 "unent.hash"
+      {"int", 8747},
+#line 243 "unent.hash"
+      {"sube", 8838},
+      {""},
 #line 117 "unent.hash"
       {"iacute", 237},
-#line 273 "unent.hash"
-      {"emsp", 8195},
-#line 198 "unent.hash"
-      {"trade", 8482},
-#line 104 "unent.hash"
-      {"agrave", 224},
-#line 201 "unent.hash"
-      {"uarr", 8593},
-#line 99 "unent.hash"
-      {"Ucirc", 219},
-#line 98 "unent.hash"
-      {"Uacute", 218},
+      {""},
+#line 177 "unent.hash"
+      {"rho", 961},
+#line 216 "unent.hash"
+      {"isin", 8712},
+      {""},
+#line 152 "unent.hash"
+      {"Pi", 928},
+      {""},
+#line 143 "unent.hash"
+      {"Eta", 919},
+#line 242 "unent.hash"
+      {"nsub", 8836},
+      {""},
+#line 150 "unent.hash"
+      {"Xi", 926},
+      {""},
+#line 186 "unent.hash"
+      {"thetasym", 977},
+      {""}, {""},
+#line 174 "unent.hash"
+      {"xi", 958},
+      {""},
+#line 230 "unent.hash"
+      {"cup", 8746},
+      {""},
+#line 205 "unent.hash"
+      {"crarr", 8629},
+#line 44 "unent.hash"
+      {"curren", 164},
+      {""},
+#line 184 "unent.hash"
+      {"psi", 968},
+#line 169 "unent.hash"
+      {"iota", 953},
+#line 124 "unent.hash"
+      {"ocirc", 244},
+#line 71 "unent.hash"
+      {"iquest", 191},
+#line 228 "unent.hash"
+      {"or", 8744},
+#line 182 "unent.hash"
+      {"phi", 966},
+      {""},
+#line 127 "unent.hash"
+      {"divide", 247},
+      {""},
+#line 276 "unent.hash"
+      {"zwj", 8205},
+      {""}, {""}, {""},
+#line 46 "unent.hash"
+      {"brvbar", 166},
+      {""},
+#line 53 "unent.hash"
+      {"shy", 173},
+#line 62 "unent.hash"
+      {"para", 182},
+#line 92 "unent.hash"
+      {"Ocirc", 212},
+#line 133 "unent.hash"
+      {"yacute", 253},
+#line 263 "unent.hash"
+      {"lt", 60},
+#line 229 "unent.hash"
+      {"cap", 8745},
+#line 248 "unent.hash"
+      {"sdot", 8901},
+      {""},
+#line 123 "unent.hash"
+      {"oacute", 243},
+      {""},
 #line 261 "unent.hash"
       {"amp", 38},
-#line 191 "unent.hash"
-      {"prime", 8242},
 #line 212 "unent.hash"
       {"part", 8706},
-#line 187 "unent.hash"
-      {"upsih", 978},
-#line 272 "unent.hash"
-      {"ensp", 8194},
-#line 41 "unent.hash"
-      {"iexcl", 161},
-#line 258 "unent.hash"
-      {"hearts", 9829},
-#line 228 "unent.hash"
-      {"or", 8744},
-#line 180 "unent.hash"
-      {"tau", 964},
-#line 115 "unent.hash"
-      {"euml", 235},
+#line 82 "unent.hash"
+      {"Ecirc", 202},
+#line 101 "unent.hash"
+      {"Yacute", 221},
+      {""},
+#line 241 "unent.hash"
+      {"sup", 8835},
+      {""},
 #line 213 "unent.hash"
       {"exist", 8707},
-#line 128 "unent.hash"
-      {"oslash", 248},
-#line 48 "unent.hash"
-      {"uml", 168},
-#line 247 "unent.hash"
-      {"perp", 8869},
-#line 281 "unent.hash"
-      {"lsquo", 8216},
-#line 290 "unent.hash"
-      {"lsaquo", 8249},
-#line 108 "unent.hash"
-      {"auml", 228},
-#line 196 "unent.hash"
-      {"image", 8465},
-#line 122 "unent.hash"
-      {"ograve", 242},
-#line 167 "unent.hash"
-      {"eta", 951},
-#line 262 "unent.hash"
-      {"apos", 39},
-#line 235 "unent.hash"
-      {"asymp", 8776},
+#line 218 "unent.hash"
+      {"ni", 8715},
+      {""},
+#line 52 "unent.hash"
+      {"not", 172},
+#line 244 "unent.hash"
+      {"supe", 8839},
+      {""},
+#line 91 "unent.hash"
+      {"Oacute", 211},
+      {""},
+#line 270 "unent.hash"
+      {"circ", 710},
+#line 138 "unent.hash"
+      {"Beta", 914},
+#line 134 "unent.hash"
+      {"thorn", 254},
 #line 107 "unent.hash"
       {"atilde", 227},
+      {""}, {""},
+#line 206 "unent.hash"
+      {"lArr", 8656},
+#line 250 "unent.hash"
+      {"rceil", 8969},
+#line 81 "unent.hash"
+      {"Eacute", 201},
+      {""}, {""},
+#line 166 "unent.hash"
+      {"zeta", 950},
+      {""},
+#line 111 "unent.hash"
+      {"ccedil", 231},
+      {""},
+#line 158 "unent.hash"
+      {"Chi", 935},
+#line 142 "unent.hash"
+      {"Zeta", 918},
+#line 74 "unent.hash"
+      {"Acirc", 194},
+#line 89 "unent.hash"
+      {"Ntilde", 209},
+      {""},
+#line 275 "unent.hash"
+      {"zwnj", 8204},
+#line 162 "unent.hash"
+      {"beta", 946},
+#line 99 "unent.hash"
+      {"Ucirc", 219},
+#line 267 "unent.hash"
+      {"Scaron", 352},
+#line 172 "unent.hash"
+      {"mu", 956},
+      {""},
+#line 200 "unent.hash"
+      {"larr", 8592},
+      {""},
+#line 176 "unent.hash"
+      {"pi", 960},
+#line 188 "unent.hash"
+      {"piv", 982},
+#line 48 "unent.hash"
+      {"uml", 168},
+      {""}, {""},
+#line 268 "unent.hash"
+      {"scaron", 353},
 #line 236 "unent.hash"
       {"ne", 8800},
+      {""},
+#line 58 "unent.hash"
+      {"sup2", 178},
+      {""},
+#line 73 "unent.hash"
+      {"Aacute", 193},
+      {""}, {""},
+#line 65 "unent.hash"
+      {"sup1", 185},
+      {""},
+#line 98 "unent.hash"
+      {"Uacute", 218},
+      {""}, {""},
+#line 273 "unent.hash"
+      {"emsp", 8195},
+#line 86 "unent.hash"
+      {"Icirc", 206},
+      {""}, {""}, {""},
+#line 219 "unent.hash"
+      {"prod", 8719},
+#line 170 "unent.hash"
+      {"kappa", 954},
+#line 121 "unent.hash"
+      {"ntilde", 241},
+      {""},
+#line 88 "unent.hash"
+      {"ETH", 208},
+#line 272 "unent.hash"
+      {"ensp", 8194},
+#line 214 "unent.hash"
+      {"empty", 8709},
+      {""}, {""}, {""},
+#line 40 "unent.hash"
+      {"nbsp", 160},
+#line 217 "unent.hash"
+      {"notin", 8713},
+#line 125 "unent.hash"
+      {"otilde", 245},
+      {""}, {""},
+#line 42 "unent.hash"
+      {"cent", 162},
+#line 146 "unent.hash"
+      {"Kappa", 922},
+#line 85 "unent.hash"
+      {"Iacute", 205},
+      {""},
+#line 255 "unent.hash"
+      {"loz", 9674},
+#line 47 "unent.hash"
+      {"sect", 167},
+#line 215 "unent.hash"
+      {"nabla", 8711},
+      {""},
+#line 175 "unent.hash"
+      {"omicron", 959},
+      {""},
+#line 59 "unent.hash"
+      {"sup3", 179},
+      {""},
+#line 93 "unent.hash"
+      {"Otilde", 213},
+      {""},
+#line 220 "unent.hash"
+      {"sum", 8721},
+#line 271 "unent.hash"
+      {"tilde", 732},
+#line 43 "unent.hash"
+      {"pound", 163},
+#line 274 "unent.hash"
+      {"thinsp", 8201},
+      {""},
 #line 120 "unent.hash"
       {"eth", 240},
+#line 55 "unent.hash"
+      {"macr", 175},
+#line 102 "unent.hash"
+      {"THORN", 222},
+#line 260 "unent.hash"
+      {"quot", 34},
+#line 151 "unent.hash"
+      {"Omicron", 927},
+#line 45 "unent.hash"
+      {"yen", 165},
+#line 145 "unent.hash"
+      {"Iota", 921},
+      {""},
+#line 104 "unent.hash"
+      {"agrave", 224},
+      {""}, {""},
+#line 49 "unent.hash"
+      {"copy", 169},
+      {""},
+#line 112 "unent.hash"
+      {"egrave", 232},
+#line 264 "unent.hash"
+      {"gt", 62},
+      {""},
+#line 50 "unent.hash"
+      {"ordf", 170},
+#line 192 "unent.hash"
+      {"Prime", 8243},
+#line 129 "unent.hash"
+      {"ugrave", 249},
+#line 238 "unent.hash"
+      {"le", 8804},
+      {""},
+#line 210 "unent.hash"
+      {"hArr", 8660},
+      {""},
+#line 116 "unent.hash"
+      {"igrave", 236},
+#line 285 "unent.hash"
+      {"rdquo", 8221},
+      {""}, {""},
+#line 249 "unent.hash"
+      {"lceil", 8968},
+#line 68 "unent.hash"
+      {"frac14", 188},
 #line 282 "unent.hash"
       {"rsquo", 8217},
 #line 291 "unent.hash"
       {"rsaquo", 8250},
-#line 292 "unent.hash"
-      {"euro", 8364},
-#line 215 "unent.hash"
-      {"nabla", 8711},
-#line 267 "unent.hash"
-      {"Scaron", 352},
-#line 270 "unent.hash"
-      {"circ", 710},
-#line 161 "unent.hash"
-      {"alpha", 945},
-#line 47 "unent.hash"
-      {"sect", 167},
-#line 170 "unent.hash"
-      {"kappa", 954},
-#line 89 "unent.hash"
-      {"Ntilde", 209},
-#line 56 "unent.hash"
-      {"deg", 176},
-#line 269 "unent.hash"
-      {"Yuml", 376},
+#line 189 "unent.hash"
+      {"bull", 8226},
 #line 164 "unent.hash"
       {"delta", 948},
-#line 129 "unent.hash"
-      {"ugrave", 249},
-#line 126 "unent.hash"
-      {"ouml", 246},
-#line 154 "unent.hash"
-      {"Sigma", 931},
-#line 165 "unent.hash"
-      {"epsilon", 949},
-#line 230 "unent.hash"
-      {"cup", 8746},
-#line 224 "unent.hash"
-      {"prop", 8733},
-#line 245 "unent.hash"
-      {"oplus", 8853},
-#line 125 "unent.hash"
-      {"otilde", 245},
-#line 148 "unent.hash"
-      {"Mu", 924},
-#line 55 "unent.hash"
-      {"macr", 175},
-#line 193 "unent.hash"
-      {"oline", 8254},
+#line 75 "unent.hash"
+      {"Atilde", 195},
+#line 286 "unent.hash"
+      {"bdquo", 8222},
+      {""},
+#line 197 "unent.hash"
+      {"real", 8476},
+#line 140 "unent.hash"
+      {"Delta", 916},
 #line 195 "unent.hash"
       {"weierp", 8472},
-#line 203 "unent.hash"
-      {"darr", 8595},
-#line 144 "unent.hash"
-      {"Theta", 920},
-#line 287 "unent.hash"
-      {"dagger", 8224},
-#line 74 "unent.hash"
-      {"Acirc", 194},
-#line 73 "unent.hash"
-      {"Aacute", 193},
-#line 139 "unent.hash"
-      {"Gamma", 915},
-#line 116 "unent.hash"
-      {"igrave", 236},
-#line 264 "unent.hash"
-      {"gt", 62},
-#line 92 "unent.hash"
-      {"Ocirc", 212},
-#line 91 "unent.hash"
-      {"Oacute", 211},
-#line 159 "unent.hash"
-      {"Psi", 936},
-#line 132 "unent.hash"
-      {"uuml", 252},
-#line 271 "unent.hash"
-      {"tilde", 732},
-#line 97 "unent.hash"
-      {"Ugrave", 217},
-#line 263 "unent.hash"
-      {"lt", 60},
-#line 234 "unent.hash"
-      {"cong", 8773},
-#line 103 "unent.hash"
-      {"szlig", 223},
-#line 149 "unent.hash"
-      {"Nu", 925},
-#line 231 "unent.hash"
-      {"int", 8747},
-#line 243 "unent.hash"
-      {"sube", 8838},
-#line 244 "unent.hash"
-      {"supe", 8839},
-#line 86 "unent.hash"
-      {"Icirc", 206},
-#line 85 "unent.hash"
-      {"Iacute", 205},
-#line 88 "unent.hash"
-      {"ETH", 208},
-#line 277 "unent.hash"
-      {"lrm", 8206},
-#line 82 "unent.hash"
-      {"Ecirc", 202},
-#line 81 "unent.hash"
-      {"Eacute", 201},
-#line 227 "unent.hash"
-      {"and", 8743},
-#line 162 "unent.hash"
-      {"beta", 946},
-#line 102 "unent.hash"
-      {"THORN", 222},
-#line 153 "unent.hash"
-      {"Rho", 929},
-#line 119 "unent.hash"
-      {"iuml", 239},
+      {""}, {""},
+#line 204 "unent.hash"
+      {"harr", 8596},
+#line 225 "unent.hash"
+      {"infin", 8734},
 #line 79 "unent.hash"
       {"Ccedil", 199},
-#line 175 "unent.hash"
-      {"omicron", 959},
-#line 184 "unent.hash"
-      {"psi", 968},
-#line 59 "unent.hash"
-      {"sup3", 179},
-#line 168 "unent.hash"
-      {"theta", 952},
-#line 100 "unent.hash"
-      {"Uuml", 220},
-#line 237 "unent.hash"
-      {"equiv", 8801},
+#line 67 "unent.hash"
+      {"raquo", 187},
+      {""}, {""}, {""},
+#line 262 "unent.hash"
+      {"apos", 39},
+      {""},
 #line 256 "unent.hash"
       {"spades", 9824},
-#line 66 "unent.hash"
-      {"ordm", 186},
-#line 268 "unent.hash"
-      {"scaron", 353},
-#line 174 "unent.hash"
-      {"xi", 958},
-#line 177 "unent.hash"
-      {"rho", 961},
-#line 160 "unent.hash"
-      {"Omega", 937},
+#line 224 "unent.hash"
+      {"prop", 8733},
 #line 257 "unent.hash"
       {"clubs", 9827},
-#line 133 "unent.hash"
-      {"yacute", 253},
-#line 181 "unent.hash"
-      {"upsilon", 965},
-#line 77 "unent.hash"
-      {"Aring", 197},
-#line 65 "unent.hash"
-      {"sup1", 185},
-#line 71 "unent.hash"
-      {"iquest", 191},
-#line 150 "unent.hash"
-      {"Xi", 926},
-#line 210 "unent.hash"
-      {"hArr", 8660},
-#line 284 "unent.hash"
-      {"ldquo", 8220},
-#line 44 "unent.hash"
-      {"curren", 164},
-#line 206 "unent.hash"
-      {"lArr", 8656},
-#line 179 "unent.hash"
-      {"sigma", 963},
-#line 219 "unent.hash"
-      {"prod", 8719},
-#line 194 "unent.hash"
-      {"frasl", 8260},
 #line 222 "unent.hash"
       {"lowast", 8727},
-#line 183 "unent.hash"
-      {"chi", 967},
-#line 285 "unent.hash"
-      {"rdquo", 8221},
-#line 232 "unent.hash"
-      {"there4", 8756},
-#line 241 "unent.hash"
-      {"sup", 8835},
-#line 208 "unent.hash"
-      {"rArr", 8658},
-#line 121 "unent.hash"
-      {"ntilde", 241},
-#line 152 "unent.hash"
-      {"Pi", 928},
-#line 58 "unent.hash"
-      {"sup2", 178},
-#line 96 "unent.hash"
-      {"Oslash", 216},
-#line 246 "unent.hash"
-      {"otimes", 8855},
-#line 156 "unent.hash"
-      {"Upsilon", 933},
-#line 72 "unent.hash"
-      {"Agrave", 192},
-#line 214 "unent.hash"
-      {"empty", 8709},
-#line 274 "unent.hash"
-      {"thinsp", 8201},
-#line 255 "unent.hash"
-      {"loz", 9674},
-#line 50 "unent.hash"
-      {"ordf", 170},
-#line 90 "unent.hash"
-      {"Ograve", 210},
-#line 46 "unent.hash"
-      {"brvbar", 166},
+      {""}, {""},
+#line 66 "unent.hash"
+      {"ordm", 186},
+#line 64 "unent.hash"
+      {"cedil", 184},
+#line 147 "unent.hash"
+      {"Lambda", 923},
+      {""}, {""},
+#line 108 "unent.hash"
+      {"auml", 228},
+      {""},
+#line 70 "unent.hash"
+      {"frac34", 190},
+      {""},
+#line 226 "unent.hash"
+      {"ang", 8736},
+#line 115 "unent.hash"
+      {"euml", 235},
+#line 41 "unent.hash"
+      {"iexcl", 161},
+#line 122 "unent.hash"
+      {"ograve", 242},
+      {""}, {""},
+#line 132 "unent.hash"
+      {"uuml", 252},
+#line 193 "unent.hash"
+      {"oline", 8254},
+#line 69 "unent.hash"
+      {"frac12", 189},
+      {""}, {""},
+#line 119 "unent.hash"
+      {"iuml", 239},
+#line 196 "unent.hash"
+      {"image", 8465},
+      {""},
 #line 283 "unent.hash"
       {"sbquo", 8218},
-#line 68 "unent.hash"
-      {"frac14", 188},
-#line 70 "unent.hash"
-      {"frac34", 190},
-#line 199 "unent.hash"
-      {"alefsym", 8501},
-#line 157 "unent.hash"
-      {"Phi", 934},
-#line 169 "unent.hash"
-      {"iota", 953},
-#line 225 "unent.hash"
-      {"infin", 8734},
-#line 127 "unent.hash"
-      {"divide", 247},
-#line 95 "unent.hash"
-      {"times", 215},
-#line 84 "unent.hash"
-      {"Igrave", 204},
-#line 176 "unent.hash"
-      {"pi", 960},
-#line 216 "unent.hash"
-      {"isin", 8712},
+      {""}, {""}, {""},
+#line 90 "unent.hash"
+      {"Ograve", 210},
+      {""}, {""},
+#line 247 "unent.hash"
+      {"perp", 8869},
+      {""},
+#line 246 "unent.hash"
+      {"otimes", 8855},
+#line 233 "unent.hash"
+      {"sim", 8764},
+      {""},
+#line 259 "unent.hash"
+      {"diams", 9830},
+#line 235 "unent.hash"
+      {"asymp", 8776},
 #line 80 "unent.hash"
       {"Egrave", 200},
-#line 207 "unent.hash"
-      {"uArr", 8657},
-#line 69 "unent.hash"
-      {"frac12", 189},
-#line 76 "unent.hash"
-      {"Auml", 196},
+      {""}, {""},
+#line 254 "unent.hash"
+      {"rang", 9002},
+#line 279 "unent.hash"
+      {"ndash", 8211},
+      {""}, {""}, {""}, {""},
+#line 191 "unent.hash"
+      {"prime", 8242},
+      {""}, {""}, {""},
+#line 95 "unent.hash"
+      {"times", 215},
+#line 63 "unent.hash"
+      {"middot", 183},
+      {""}, {""}, {""}, {""}, {""},
+#line 171 "unent.hash"
+      {"lambda", 955},
+      {""},
+#line 277 "unent.hash"
+      {"lrm", 8206},
+#line 135 "unent.hash"
+      {"yuml", 255},
+      {""}, {""}, {""}, {""},
+#line 126 "unent.hash"
+      {"ouml", 246},
+#line 185 "unent.hash"
+      {"omega", 969},
+#line 72 "unent.hash"
+      {"Agrave", 192},
+      {""}, {""},
+#line 269 "unent.hash"
+      {"Yuml", 376},
+#line 109 "unent.hash"
+      {"aring", 229},
+#line 97 "unent.hash"
+      {"Ugrave", 217},
+#line 284 "unent.hash"
+      {"ldquo", 8220},
 #line 278 "unent.hash"
       {"rlm", 8207},
-#line 173 "unent.hash"
-      {"nu", 957},
-#line 94 "unent.hash"
-      {"Ouml", 214},
-#line 75 "unent.hash"
-      {"Atilde", 195},
-#line 172 "unent.hash"
-      {"mu", 956},
-#line 182 "unent.hash"
-      {"phi", 966},
-#line 93 "unent.hash"
-      {"Otilde", 213},
-#line 189 "unent.hash"
-      {"bull", 8226},
-#line 137 "unent.hash"
-      {"Alpha", 913},
-#line 87 "unent.hash"
-      {"Iuml", 207},
 #line 61 "unent.hash"
       {"micro", 181},
+#line 194 "unent.hash"
+      {"frasl", 8260},
+      {""},
+#line 281 "unent.hash"
+      {"lsquo", 8216},
+#line 290 "unent.hash"
+      {"lsaquo", 8249},
+#line 94 "unent.hash"
+      {"Ouml", 214},
+#line 160 "unent.hash"
+      {"Omega", 937},
+      {""},
+#line 239 "unent.hash"
+      {"ge", 8805},
+#line 56 "unent.hash"
+      {"deg", 176},
+      {""},
+#line 139 "unent.hash"
+      {"Gamma", 915},
+      {""}, {""}, {""},
 #line 83 "unent.hash"
       {"Euml", 203},
-#line 57 "unent.hash"
-      {"plusmn", 177},
-#line 188 "unent.hash"
-      {"piv", 982},
-#line 248 "unent.hash"
-      {"sdot", 8901},
-#line 279 "unent.hash"
-      {"ndash", 8211},
-#line 63 "unent.hash"
-      {"middot", 183},
-#line 40 "unent.hash"
-      {"nbsp", 160},
+      {""}, {""},
+#line 51 "unent.hash"
+      {"laquo", 171},
+      {""},
+#line 221 "unent.hash"
+      {"minus", 8722},
+      {""},
+#line 84 "unent.hash"
+      {"Igrave", 204},
+      {""},
+#line 54 "unent.hash"
+      {"reg", 174},
+#line 136 "unent.hash"
+      {"fnof", 402},
+      {""}, {""}, {""}, {""},
+#line 234 "unent.hash"
+      {"cong", 8773},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""},
+#line 76 "unent.hash"
+      {"Auml", 196},
+      {""}, {""},
+#line 245 "unent.hash"
+      {"oplus", 8853},
+      {""},
+#line 100 "unent.hash"
+      {"Uuml", 220},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 165 "unent.hash"
+      {"epsilon", 949},
+      {""}, {""},
+#line 199 "unent.hash"
+      {"alefsym", 8501},
+      {""},
+#line 181 "unent.hash"
+      {"upsilon", 965},
+#line 103 "unent.hash"
+      {"szlig", 223},
+      {""}, {""}, {""},
+#line 253 "unent.hash"
+      {"lang", 9001},
+      {""},
+#line 258 "unent.hash"
+      {"hearts", 9829},
+      {""}, {""},
+#line 87 "unent.hash"
+      {"Iuml", 207},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""},
+#line 265 "unent.hash"
+      {"OElig", 338},
+      {""}, {""}, {""}, {""},
 #line 280 "unent.hash"
       {"mdash", 8212},
-#line 143 "unent.hash"
-      {"Eta", 919},
-#line 220 "unent.hash"
-      {"sum", 8721},
-#line 260 "unent.hash"
-      {"quot", 34},
-#line 134 "unent.hash"
-      {"thorn", 254},
-#line 186 "unent.hash"
-      {"thetasym", 977},
-#line 135 "unent.hash"
-      {"yuml", 255},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""},
+#line 128 "unent.hash"
+      {"oslash", 248},
+#line 187 "unent.hash"
+      {"upsih", 978},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 77 "unent.hash"
+      {"Aring", 197},
+#line 211 "unent.hash"
+      {"forall", 8704},
+      {""}, {""}, {""},
+#line 161 "unent.hash"
+      {"alpha", 945},
+#line 96 "unent.hash"
+      {"Oslash", 216},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
 #line 78 "unent.hash"
       {"AElig", 198},
-#line 151 "unent.hash"
-      {"Omicron", 927},
-#line 265 "unent.hash"
-      {"OElig", 338},
-#line 218 "unent.hash"
-      {"ni", 8715},
-#line 52 "unent.hash"
-      {"not", 172},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""},
 #line 141 "unent.hash"
       {"Epsilon", 917},
-#line 45 "unent.hash"
-      {"yen", 165},
-#line 209 "unent.hash"
-      {"dArr", 8659},
-#line 233 "unent.hash"
-      {"sim", 8764},
-#line 221 "unent.hash"
-      {"minus", 8722},
-#line 259 "unent.hash"
-      {"diams", 9830},
-#line 43 "unent.hash"
-      {"pound", 163},
-#line 211 "unent.hash"
-      {"forall", 8704},
-#line 145 "unent.hash"
-      {"Iota", 921},
-#line 240 "unent.hash"
-      {"sub", 8834},
-#line 242 "unent.hash"
-      {"nsub", 8836},
-#line 49 "unent.hash"
-      {"copy", 169},
-#line 286 "unent.hash"
-      {"bdquo", 8222},
+      {""}, {""}, {""}, {""}, {""},
+#line 110 "unent.hash"
+      {"aelig", 230},
+#line 252 "unent.hash"
+      {"rfloor", 8971},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""},
+#line 287 "unent.hash"
+      {"dagger", 8224},
+      {""}, {""}, {""}, {""},
+#line 288 "unent.hash"
+      {"Dagger", 8225},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 156 "unent.hash"
+      {"Upsilon", 933},
+      {""}, {""}, {""}, {""}, {""}, {""},
+#line 289 "unent.hash"
+      {"permil", 8240},
+      {""}, {""}, {""}, {""},
+#line 57 "unent.hash"
+      {"plusmn", 177},
+      {""}, {""},
+#line 154 "unent.hash"
+      {"Sigma", 931},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 179 "unent.hash"
+      {"sigma", 963},
+      {""}, {""}, {""}, {""}, {""},
+#line 266 "unent.hash"
+      {"oelig", 339},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""},
+#line 137 "unent.hash"
+      {"Alpha", 913},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""},
+#line 163 "unent.hash"
+      {"gamma", 947},
+#line 251 "unent.hash"
+      {"lfloor", 8970},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+      {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 190 "unent.hash"
+      {"hellip", 8230},
+      {""}, {""}, {""},
 #line 178 "unent.hash"
-      {"sigmaf", 962},
-#line 136 "unent.hash"
-      {"fnof", 402},
-#line 158 "unent.hash"
-      {"Chi", 935},
-#line 217 "unent.hash"
-      {"notin", 8713},
-#line 276 "unent.hash"
-      {"zwj", 8205},
-#line 275 "unent.hash"
-      {"zwnj", 8204},
-#line 53 "unent.hash"
-      {"shy", 173}
-    };
-
-  static const short lookup[] =
-    {
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,    0,    1,   -1,   -1,   -1,    2,
-        -1,   -1,   -1,   -1,    3,    4,    5,   -1,
-         6,    7,    8,   -1,   -1,    9,   10,   11,
-        12,   -1,   -1,   13,   -1,   -1,   -1,   14,
-        15,   16,   -1,   -1,   -1,   17,   18,   -1,
-        -1,   -1,   19,   20,   -1,   -1,   21,   22,
-        23,   -1,   24,   25,   26,   -1,   -1,   -1,
-        27,   28,   -1,   -1,   -1,   29,   30,   -1,
-        -1,   -1,   31,   32,   33,   -1,   34,   35,
-        36,   -1,   -1,   -1,   37,   38,   39,   -1,
-        40,   -1,   41,   42,   -1,   43,   -1,   44,
-        45,   -1,   -1,   -1,   46,   47,   -1,   -1,
-        48,   49,   50,   -1,   -1,   -1,   51,   52,
-        -1,   -1,   53,   54,   55,   -1,   -1,   56,
-        57,   58,   -1,   59,   -1,   60,   -1,   -1,
-        -1,   61,   62,   -1,   -1,   -1,   63,   64,
-        65,   66,   67,   68,   69,   70,   -1,   71,
-        72,   73,   74,   -1,   -1,   75,   76,   77,
-        -1,   78,   79,   80,   81,   82,   83,   -1,
-        84,   85,   -1,   -1,   86,   87,   88,   -1,
-        -1,   89,   90,   -1,   -1,   -1,   91,   92,
-        93,   -1,   94,   95,   96,   97,   -1,   -1,
-        98,   99,   -1,  100,  101,  102,  103,  104,
-       105,   -1,  106,  107,  108,   -1,   -1,  109,
-       110,  111,   -1,  112,  113,  114,  115,  116,
-        -1,  117,  118,   -1,   -1,  119,  120,  121,
-       122,  123,   -1,  124,  125,   -1,  126,  127,
-      -485,  130,  131,  132,  133,  134,  135, -125,
-        -2,  136,  137,  138,   -1,   -1,  139,  140,
-        -1,  141,  142,  143,  144,  145,   -1,   -1,
-        -1,  146,  147,  148,   -1,   -1,  149,   -1,
-       150,  151,  152,  153,  154,  155,  156,  157,
-       158,   -1,  159,  160,   -1,  161,  162,  163,
-        -1,   -1,  164,  165,   -1,   -1,   -1,  166,
-       167,  168,   -1,  169,   -1,  170,  171,   -1,
-       172,  173,   -1,  174,  175,   -1,  176,  177,
-       178,  179,   -1,  180,  181,  182,   -1,  183,
-       184,  185,  186,   -1,   -1,   -1,  187, -571,
-       190,  191,  192,  193,  194,  -65,   -2,   -1,
-       195,  196,  197,   -1,  198,  199,   -1,   -1,
-        -1,  200,   -1,  201,  202,  203,   -1,   -1,
-        -1,  204,  205,  206,   -1,   -1,  207,  208,
-        -1,  209,   -1,   -1,   -1,  210,   -1,   -1,
-        -1,  211,  212,  213,   -1,   -1,  214,   -1,
-        -1,  215,   -1,  216,  217,  218,  219,   -1,
-        -1,  220,  221,   -1,  222,  223,  224,   -1,
-        -1,   -1,   -1,   -1,  225,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  226,  227,   -1,   -1,
-        -1,  228,   -1,   -1,  229,   -1,   -1,  230,
-        -1,   -1,  231,  232,   -1,   -1,  233,   -1,
-       234,  235,   -1,   -1,   -1,  236,   -1,  237,
-        -1,   -1,   -1,   -1,  238,   -1,   -1,   -1,
-        -1,  239,  240,   -1,   -1,  241,   -1,   -1,
-        -1,  242,  243,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,  244,  245,   -1,   -1,   -1,
-        -1,   -1,  246,   -1,   -1,  247,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  248,   -1,  249,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,  250,  251,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        -1,   -1,   -1,   -1,   -1,  252
+      {"sigmaf", 962}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
@@ -706,30 +807,10 @@ lookup_entity (register const char *str, register size_t len)
 
       if (key <= MAX_HASH_VALUE)
         {
-          register int index = lookup[key];
-
-          if (index >= 0)
-            {
-              register const char *s = wordlist[index].name;
-
-              if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
-                return &wordlist[index];
-            }
-          else if (index < -TOTAL_KEYWORDS)
-            {
-              register int offset = - 1 - TOTAL_KEYWORDS - index;
-              register const struct _Entity *wordptr = &wordlist[TOTAL_KEYWORDS + lookup[offset]];
-              register const struct _Entity *wordendptr = wordptr + -lookup[offset + 1];
-
-              while (wordptr < wordendptr)
-                {
-                  register const char *s = wordptr->name;
+          register const char *s = wordlist[key].name;
 
-                  if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
-                    return wordptr;
-                  wordptr++;
-                }
-            }
+          if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+            return &wordlist[key];
         }
     }
   return 0;
diff --git a/unent.e b/unent.e
old mode 100755
new mode 100644

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/debug/.build-id/04/cde00f4b2546fd4ffac643c460f2e9186f8462.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/16/2bd19685bd89279609d96be93d2a1ac20e1e4c.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/2b/0d6dbace11540876bdf865fb9199a287057d7a.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/32/ed34064b1667acf396584bb55e80befa3787ed.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/39/0056b8aff71157b92b6c4441f9fa193e8f8b24.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/4d/f5edc230b92b3191057e46d47bc1d2ce345d1e.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/5b/79572b06e8169de12f18a0bd8555b30f0137ed.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/60/3cd7ca7660954e2965440878239a1169906f92.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/61/d0a4f87000c76fd0e1860e2c89c1ed9a7d66f1.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/6b/dff191a645bca894156757cc5f721dd328e8b1.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/73/13c8c54ac1dc4be5196065f3046e2afb91afa8.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/79/cf31010e4717ba70b9bdb9ae0005e617259a6b.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/7a/376cb6e9abdf079b255c9e604578dbe8aa134f.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/7b/845ddedce84c1cbcd2969de22c546c21e88783.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/7d/c4ddf383fd18bae3e565be2ab2feff6398e580.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/80/4b6f4df845a09f7046a532df87178d69510a04.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/89/a7735124be31e4a4bc7c2436a4143b609dcbb1.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/93/ac28bd845dc5f7fb2d824980c4dc5beab04591.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/9c/d15b5d61f8d8da1d72fe2e39424cf0a7915b92.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/b2/f8699e62de976047f7e37b590223224ef9de6d.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/b3/6b5cb70ddc9a12074001492c8946ed0b56d5d0.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/b9/368c2c879a73cbe34236528a3b69acee542e51.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/c4/c31a3302e6043928698c454b12838af094531d.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/c5/f09b2c3930b0b41663f203b81d40546485b361.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/d6/5c21c38a8171b85f9e557ec24ec5358e02dee6.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/da/3797cfddc9fb6a36f109b825458735fc9d327a.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/dd/a98831a55040a72a1b2078999bb886b5571b74.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/e5/c58df72092f04a9f0b0c6e3154ebbb668fe5c8.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/ee/3f73df88b499097284dd6c13fed977bbb940a1.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/f1/1b5018ecc5eb6948a76b8e490ff8f73c8962a3.debug

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/debug/.build-id/03/15fa69007c322e2a798fda55a2a53bd294b724.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/04/123f457115fc954a31db99cc8ebff2c7792d82.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/0c/867ffb840a4ce7e639cdb64a252676ed4f74d7.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/17/220eb9fc28f708b04e7c7d9d1d3a871a506f31.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/1c/5b2fc40776d94d6aac5d8f33d302fc57723dca.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/2b/e90ec2592c9d9d4b37c0039fc9bfda6fd97b1e.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/2d/24deabf871ad5551bda91d8ea662b603ac626a.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/35/4563ed7be59fd893821ac3ac0063f0e244ec56.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/41/baff937d1633e737c6771bfa0ff6863a691e6b.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/49/df1bf846d180985906712e628cc0117618ccd9.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/4f/a2e49e6963fabc397ba30282c248ec628b359d.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/5d/b1fb442882f07ff3cf4d5539a1e4abbb3e0cda.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/64/0141b383c61b4b2f63bae392c7fe070384537d.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/73/77212dfb87dadd8ba00b239ce186b4f27bcd55.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/8b/84df6a19a330ac0c0d3460498059d162f60bec.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/95/7c4774e822902eddd74655d70946d40d514769.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/a3/631cae27d721ae676d3ef2bf936ddb67fa5ea8.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/a5/c70cc91cfc41dfb8de491129206494d950de22.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/ac/43e6cf855f48ac72608496fc9e990a9f5c3227.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/ae/412a5aaef00013dde3170e86fbd5b3ba631a02.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/b6/15e4e7cab8c913bc2bbffc526286acfd192e55.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/b6/dc6741b286f2eeb029cb946464bb3ee5d153b0.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/be/59305a519655cb16397a2f95e62b3bdf6dcc67.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/c7/6c98cdf551dc767f233732d0afeea5845e7f8e.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/cd/382d93602f12f146be72a87b312b7398107c07.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/ce/0f89b9323b60cec8ace261d64e64950e24eebf.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/ce/834b16232e27a4de14517b4cff34b19a819e46.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/d4/223234436c42753cb24751e902edea893962f9.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/e4/ddce25d4b5e83de5542f0b6fe858567926d863.debug
-rw-r--r--  root/root   /usr/lib/debug/.build-id/e8/5395806ac5f7ca6f8af199589803187f6c60fe.debug

No differences were encountered between the control files of package html-xml-utils

Control files of package html-xml-utils-dbgsym: lines which differ (wdiff format)

  • Build-Ids: 0315fa69007c322e2a798fda55a2a53bd294b724 04123f457115fc954a31db99cc8ebff2c7792d82 0c867ffb840a4ce7e639cdb64a252676ed4f74d7 17220eb9fc28f708b04e7c7d9d1d3a871a506f31 1c5b2fc40776d94d6aac5d8f33d302fc57723dca 2be90ec2592c9d9d4b37c0039fc9bfda6fd97b1e 2d24deabf871ad5551bda91d8ea662b603ac626a 354563ed7be59fd893821ac3ac0063f0e244ec56 41baff937d1633e737c6771bfa0ff6863a691e6b 49df1bf846d180985906712e628cc0117618ccd9 4fa2e49e6963fabc397ba30282c248ec628b359d 5db1fb442882f07ff3cf4d5539a1e4abbb3e0cda 640141b383c61b4b2f63bae392c7fe070384537d 7377212dfb87dadd8ba00b239ce186b4f27bcd55 8b84df6a19a330ac0c0d3460498059d162f60bec 957c4774e822902eddd74655d70946d40d514769 a3631cae27d721ae676d3ef2bf936ddb67fa5ea8 a5c70cc91cfc41dfb8de491129206494d950de22 ac43e6cf855f48ac72608496fc9e990a9f5c3227 ae412a5aaef00013dde3170e86fbd5b3ba631a02 b615e4e7cab8c913bc2bbffc526286acfd192e55 b6dc6741b286f2eeb029cb946464bb3ee5d153b0 be59305a519655cb16397a2f95e62b3bdf6dcc67 c76c98cdf551dc767f233732d0afeea5845e7f8e cd382d93602f12f146be72a87b312b7398107c07 ce0f89b9323b60cec8ace261d64e64950e24eebf ce834b16232e27a4de14517b4cff34b19a819e46 d4223234436c42753cb24751e902edea893962f9 e4ddce25d4b5e83de5542f0b6fe858567926d863 e85395806ac5f7ca6f8af199589803187f6c60fe 04cde00f4b2546fd4ffac643c460f2e9186f8462 162bd19685bd89279609d96be93d2a1ac20e1e4c 2b0d6dbace11540876bdf865fb9199a287057d7a 32ed34064b1667acf396584bb55e80befa3787ed 390056b8aff71157b92b6c4441f9fa193e8f8b24 4df5edc230b92b3191057e46d47bc1d2ce345d1e 5b79572b06e8169de12f18a0bd8555b30f0137ed 603cd7ca7660954e2965440878239a1169906f92 61d0a4f87000c76fd0e1860e2c89c1ed9a7d66f1 6bdff191a645bca894156757cc5f721dd328e8b1 7313c8c54ac1dc4be5196065f3046e2afb91afa8 79cf31010e4717ba70b9bdb9ae0005e617259a6b 7a376cb6e9abdf079b255c9e604578dbe8aa134f 7b845ddedce84c1cbcd2969de22c546c21e88783 7dc4ddf383fd18bae3e565be2ab2feff6398e580 804b6f4df845a09f7046a532df87178d69510a04 89a7735124be31e4a4bc7c2436a4143b609dcbb1 93ac28bd845dc5f7fb2d824980c4dc5beab04591 9cd15b5d61f8d8da1d72fe2e39424cf0a7915b92 b2f8699e62de976047f7e37b590223224ef9de6d b36b5cb70ddc9a12074001492c8946ed0b56d5d0 b9368c2c879a73cbe34236528a3b69acee542e51 c4c31a3302e6043928698c454b12838af094531d c5f09b2c3930b0b41663f203b81d40546485b361 d65c21c38a8171b85f9e557ec24ec5358e02dee6 da3797cfddc9fb6a36f109b825458735fc9d327a dda98831a55040a72a1b2078999bb886b5571b74 e5c58df72092f04a9f0b0c6e3154ebbb668fe5c8 ee3f73df88b499097284dd6c13fed977bbb940a1 f11b5018ecc5eb6948a76b8e490ff8f73c8962a3

More details

Full run details