# Copyright (C) 2007-2009 Internet Systems Consortium, Inc. ("ISC") # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # $Id$ # Generic GNUmakefile for use with xml2rfc. # Default targets all:: text # Where to find citations, etcetera. # # We use XML_LIBRARY for the search path for compatability with xml2rfc. # Since we expand all file inclusions before xml2rfc ever sees them, # this isn't really necessary, we could use, eg, RFC2629TOOLS_PATH. # # Since xmllint and xsltproc can take URLs as pathname components # (using space rather than colon as a separator), what I'd really # -like- to do here is allow that, but all the fun GNU make vpath # stuff would break, with good reason, so for now we're stuck with # local files. # # It would not be hard, however, to write a script that did all the # XSLT preprocessing using URLs pointing to, eg, a Subversion # repository, it just wouldn't work like a Makefile. ifndef RFC2629TOOLS_BASE RFC2629TOOLS_BASE := ${HOME}/rfc2629tools endif ifndef XML_LIBRARY XML_LIBRARY := ${RFC2629TOOLS_BASE} XML_LIBRARY += ${RFC2629TOOLS_BASE}/xml XML_LIBRARY += ${RFC2629TOOLS_BASE}/xml/rfc XML_LIBRARY += ${RFC2629TOOLS_BASE}/xml/draft XML_LIBRARY += ${RFC2629TOOLS_BASE}/xml/rfc2629xslt endif __EMPTY := __SPACE := ${__EMPTY} ${__EMPTY} __PATH = $(subst ${__SPACE},:,$(strip $(1))) export XML_LIBRARY := $(call __PATH, . ${XML_LIBRARY}) vpath %.xml ${XML_LIBRARY} vpath %.xsl ${XML_LIBRARY} vpath %.xslt ${XML_LIBRARY} XSLTPROC := xsltproc --path ${XML_LIBRARY} XMLLINT := xmllint --path ${XML_LIBRARY} # Whether to keep xml:base attributes from XInclude processing. ifndef KEEP_XINCLUDE_ATTRIBUTES KEEP_XINCLUDE_ATTRIBUTES = 1 endif # Rules to expand file inclusions for every XML file in this directory # with a docName attribute. We support both xml2rfc # and XInclude inclusion. # # NB: we freeze the XML as docName.xml, so the source file can't have # that name. Since the docName attribute includes the draft version # number, which you probably don't want in the name of the source file # anyway, this is unlikely to be a serious restriction, except perhaps # for the RFC Editor (and the RFC Editor knows where to find me...). define RULES ifneq ($(1),$(2).xml) TARGETS += $(2) SOURCES += $(1) $(2).xml : $(1) $(3) ; ${XSLTPROC} --xinclude --param keep_xinclude_attributes ${KEEP_XINCLUDE_ATTRIBUTES} -o $(2).xml expand-rfc2629-pi-rfc-include.xsl $(1) else SKIPPED += $(1) endif endef # Generate the above rules for every XML file with a docName attribute. GENERATE = $(if $(2),$(eval $(call RULES,$(1),$(firstword $(2)),$(sort $(filter-out $(firstword $(2)),$(2)))))) EXTRACT = $(shell 2>/dev/null ${XSLTPROC} --novalid GNUmakefile-helper.xsl $(1)) $(foreach F,$(wildcard *.xml),$(call GENERATE,${F},$(strip $(call EXTRACT,${F})))) # Locate the DTD if we can DTD := $(wildcard ${RFC2629TOOLS_BASE}/xml/rfc2629xslt/rfc2629.dtd) ifeq (${DTD},) DTD := else DTD := --dtd=${DTD} endif # Rules to run xml2rfc on the frozen XML %.txt : %.xml xml2rfc ${DTD} $< $@ %.html : %.xml xml2html ${DTD} $< $@ %.nr : %.xml xml2nroff ${DTD} $< $@ # Force cleanup after xml2rfc errors .DELETE_ON_ERROR: # 2-up Postscript, for proofreading PS_UNDERLAY := -uDRAFT %.ps : %.txt a2ps -2 ${PS_UNDERLAY} -o $@ $< # Targets TEXT := $(addsuffix .txt, ${TARGETS}) NROFF := $(addsuffix .nr, ${TARGETS}) HTML := $(addsuffix .html, ${TARGETS}) PS := $(addsuffix .ps, ${TARGETS}) XML := $(addsuffix .xml, ${TARGETS}) text: ${TEXT} nroff: ${NROFF} html: ${HTML} ps: ${PS} xml: ${XML} clean:: rm -f ${TEXT} ${NROFF} ${HTML} ${PS} ${XML} ifeq (,${TARGETS}) OOPS := $(filter-out $(addsuffix .xml,${TARGETS}),${SKIPPED}) all:: ifneq (,${OOPS}) @echo 'Skipped files: ${OOPS}' @echo '' endif @echo "I couldn't find anything to build. Either I had trouble parsing your files," @echo 'or you forgot the docName attribute on the element (oops).' @echo 'Running "make lint" to check for parse errors.' @echo '' all:: lint endif # Julian's reference checker define CHECK_REFERENCES check-references:: @echo Checking references in $(1) ; \ ${XSLTPROC} --novalid --xinclude expand-rfc2629-pi-rfc-include.xsl $(1) 2>/dev/null | \ ${XSLTPROC} --novalid check-references.xslt - endef $(foreach S,${SOURCES},$(eval $(call CHECK_REFERENCES,${S}))) # Julian's dependency plotter define GEN_REFERENCE_GRAPH gen-reference-graph:: @echo Checking references in $(1) ; \ ${XSLTPROC} --novalid --xinclude expand-rfc2629-pi-rfc-include.xsl $(1) 2>/dev/null | \ ${XSLTPROC} --novalid gen-reference-graph.xslt - | \ dot -Tps2 | ps2pdf - $(basename $(1)).reference-graph.pdf endef $(foreach S,${SOURCES},$(eval $(call GEN_REFERENCE_GRAPH,${S}))) # Lint checker lint: ${XMLLINT} --noout *.xml # Lint references lint-references: find $(subst :, ,${XML_LIBRARY}) -type f -name 'reference.*.xml' | \ xargs ${XMLLINT} --noout # Validation against the RFC2629 DTD. Mostly works, but quirky. # # This doesn't work at all with because xmllint # doesn't understand that. We could run xmllint on the expanded XML, # but then the error messages would refer to the expanded XML rather # than the original source, which would be annoying. # # Validation does mostly work with XInclude, but it spits out a lot of # "No declaration for attribute base of element" errors when used with # XInclude, due to a bad interaction between XInclude and the DTD. # See: # # http://lists.oasis-open.org/archives/docbook/200211/msg00040.html # http://sources.redhat.com/ml/docbook-apps/2003-q4/msg00072.html # # The fix is to add xml:base as an allowed attribute for any element # that could usefully contain an XInclude (ie, all of them). Adding # the xmlns:xi attribute to the DTD as well would make it possible to # for validation to work with the xi namespace defined in the # element; as it is, one has to define it in each XInclude element to # avoid validation errors. validate: ${XMLLINT} --noout --dtdvalid rfc2629.dtd --xinclude ${SOURCES} relaxng: ${XMLLINT} --noout --relaxng rfc2629.rng --xinclude ${SOURCES} # rfcdiff against immediately previous version of a draft. This looks in # both the current directory and ${DRAFTDIR}, if the latter is defined. diff:: define DIFF ifeq ($(findstring -00,$1),) _F0 := $(shell echo $1 | awk 'BEGIN {FS = OFS = "-"} {$$NF = sprintf("%02d", -1 + $$NF); print}').txt ifdef DRAFTDIR _F1 := $$(firstword $$(wildcard $${DRAFTDIR}/$${_F0} $${_F0})) else _F1 := $${_F0} endif _F2 := $1.txt _F3 := $(shell echo $1 | awk 'BEGIN {FS = "-"} {printf "%s-from-%02d.diff.html\n", $$0, -1 + $$NF}') ifneq ($${_F1},) HTML += $${_F3} diff:: $${_F3} $${_F3} : $${_F1} $${_F2} rfcdiff --stdout $${_F1} $${_F2} >$${_F3}.tmp mv $${_F3}.tmp $${_F3} endif endif endef $(foreach T,${TARGETS},$(eval $(call DIFF,${T}))) all:: diff