klacks fixes
This commit is contained in:
2
cxml.asd
2
cxml.asd
@ -127,7 +127,7 @@
|
|||||||
"test/"
|
"test/"
|
||||||
(make-pathname :name nil :type nil :defaults *load-truename*))
|
(make-pathname :name nil :type nil :defaults *load-truename*))
|
||||||
:components ((:file "domtest") (:file "xmlconf"))
|
:components ((:file "domtest") (:file "xmlconf"))
|
||||||
:depends-on (:cxml-xml :cxml-dom))
|
:depends-on (:cxml-xml :cxml-klacks :cxml-dom))
|
||||||
|
|
||||||
(asdf:defsystem :cxml
|
(asdf:defsystem :cxml
|
||||||
:components ()
|
:components ()
|
||||||
|
|||||||
@ -215,4 +215,11 @@ NIL</pre>
|
|||||||
Call <tt>klacks:close-source</tt> to close the source after
|
Call <tt>klacks:close-source</tt> to close the source after
|
||||||
exiting <tt>body</tt>, whether normally or abnormally.
|
exiting <tt>body</tt>, whether normally or abnormally.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h3>Bridging Klacks and SAX</h3>
|
||||||
|
<p>
|
||||||
|
<div class="def">Function KLACKS:SERIALIZE-SOURCE (source handler)</div>
|
||||||
|
Read all klacks events from <tt>source</tt> and send them as SAX
|
||||||
|
events to the SAX <tt>handler</tt>.
|
||||||
|
</p>
|
||||||
</documentation>
|
</documentation>
|
||||||
|
|||||||
@ -37,10 +37,11 @@
|
|||||||
(setf (document handler) document)
|
(setf (document handler) document)
|
||||||
(push document (element-stack handler))))
|
(push document (element-stack handler))))
|
||||||
|
|
||||||
|
;; fixme
|
||||||
|
(defmethod sax::dtd ((handler dom-builder) dtd)
|
||||||
|
(setf (slot-value (document handler) 'dtd) dtd))
|
||||||
|
|
||||||
(defmethod sax:end-document ((handler dom-builder))
|
(defmethod sax:end-document ((handler dom-builder))
|
||||||
(setf (slot-value (document handler) 'dtd)
|
|
||||||
;; FIXME!
|
|
||||||
(and cxml::*ctx* (cxml::dtd cxml::*ctx*)))
|
|
||||||
(let ((doctype (dom:doctype (document handler))))
|
(let ((doctype (dom:doctype (document handler))))
|
||||||
(when doctype
|
(when doctype
|
||||||
(setf (slot-value (dom:entities doctype) 'read-only-p) t)
|
(setf (slot-value (dom:entities doctype) 'read-only-p) t)
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
(current-values)
|
(current-values)
|
||||||
(current-attributes)
|
(current-attributes)
|
||||||
(cdata-section-p :reader klacks:current-cdata-section-p)
|
(cdata-section-p :reader klacks:current-cdata-section-p)
|
||||||
;; extra with-source magic
|
;; extra WITH-SOURCE magic
|
||||||
(data-behaviour :initform :DTD)
|
(data-behaviour :initform :DTD)
|
||||||
(namespace-stack :initform (list *initial-namespace-bindings*))
|
(namespace-stack :initform (list *initial-namespace-bindings*))
|
||||||
(temporary-streams :initform nil)
|
(temporary-streams :initform nil)
|
||||||
@ -126,13 +126,18 @@
|
|||||||
(apply #'make-source xstream args)))
|
(apply #'make-source xstream args)))
|
||||||
(pathname
|
(pathname
|
||||||
(let* ((xstream
|
(let* ((xstream
|
||||||
(make-xstream (open input :element-type '(unsigned-byte 8))))
|
(make-xstream (open input :element-type '(unsigned-byte 8)))))
|
||||||
(source (apply #'make-source
|
(setf (xstream-name xstream)
|
||||||
|
(make-stream-name
|
||||||
|
:entity-name "main document"
|
||||||
|
:entity-kind :main
|
||||||
|
:uri (pathname-to-uri (merge-pathnames input))))
|
||||||
|
(let ((source (apply #'make-source
|
||||||
xstream
|
xstream
|
||||||
:pathname input
|
:pathname input
|
||||||
args)))
|
args)))
|
||||||
(push xstream (slot-value source 'temporary-streams))
|
(push xstream (slot-value source 'temporary-streams))
|
||||||
source))
|
source)))
|
||||||
(rod
|
(rod
|
||||||
(let ((xstream (string->xstream input)))
|
(let ((xstream (string->xstream input)))
|
||||||
(setf (xstream-name xstream)
|
(setf (xstream-name xstream)
|
||||||
@ -152,8 +157,7 @@
|
|||||||
(check-type entity-resolver (or null function symbol))
|
(check-type entity-resolver (or null function symbol))
|
||||||
(check-type disallow-internal-subset boolean)
|
(check-type disallow-internal-subset boolean)
|
||||||
(let* ((context
|
(let* ((context
|
||||||
(make-context :handler nil
|
(make-context :main-zstream input
|
||||||
:main-zstream input
|
|
||||||
:entity-resolver entity-resolver
|
:entity-resolver entity-resolver
|
||||||
:disallow-internal-subset disallow-internal-subset))
|
:disallow-internal-subset disallow-internal-subset))
|
||||||
(source
|
(source
|
||||||
@ -167,6 +171,7 @@
|
|||||||
:scratch-pad-2 *scratch-pad-2*
|
:scratch-pad-2 *scratch-pad-2*
|
||||||
:scratch-pad-3 *scratch-pad-3*
|
:scratch-pad-3 *scratch-pad-3*
|
||||||
:scratch-pad-4 *scratch-pad-4*)))
|
:scratch-pad-4 *scratch-pad-4*)))
|
||||||
|
(setf (handler context) (make-instance 'klacks-dtd-handler :source source))
|
||||||
(setf (slot-value source 'continuation)
|
(setf (slot-value source 'continuation)
|
||||||
(lambda () (klacks/xmldecl source input)))
|
(lambda () (klacks/xmldecl source input)))
|
||||||
source))
|
source))
|
||||||
@ -208,25 +213,26 @@
|
|||||||
(defun klacks/doctype (source input)
|
(defun klacks/doctype (source input)
|
||||||
(with-source (source current-key current-values validate dtd)
|
(with-source (source current-key current-values validate dtd)
|
||||||
(let ((cont (lambda () (klacks/finish-doctype source input)))
|
(let ((cont (lambda () (klacks/finish-doctype source input)))
|
||||||
ignoreme name extid)
|
l)
|
||||||
(prog1
|
(prog1
|
||||||
(cond
|
(cond
|
||||||
((eq (peek-token input) :<!DOCTYPE)
|
((eq (peek-token input) :<!DOCTYPE)
|
||||||
(setf (values ignoreme name extid)
|
(setf l (cdr (p/doctype-decl input dtd)))
|
||||||
(p/doctype-decl input dtd))
|
|
||||||
(lambda () (klacks/misc*-2 source input cont)))
|
(lambda () (klacks/misc*-2 source input cont)))
|
||||||
(dtd
|
(dtd
|
||||||
(setf (values ignoreme name extid)
|
(setf l (cdr (synthesize-doctype dtd input)))
|
||||||
(synthesize-doctype dtd input))
|
|
||||||
cont)
|
cont)
|
||||||
((and validate (not dtd))
|
((and validate (not dtd))
|
||||||
(validity-error "invalid document: no doctype"))
|
(validity-error "invalid document: no doctype"))
|
||||||
(t
|
(t
|
||||||
(return-from klacks/doctype
|
(return-from klacks/doctype
|
||||||
(funcall cont))))
|
(funcall cont))))
|
||||||
|
(destructuring-bind (&optional name extid) l
|
||||||
(setf current-key :dtd)
|
(setf current-key :dtd)
|
||||||
(setf current-values
|
(setf current-values
|
||||||
(list name (extid-public extid) (extid-system extid)))))))
|
(list name
|
||||||
|
(and extid (extid-public extid))
|
||||||
|
(and extid (extid-system extid)))))))))
|
||||||
|
|
||||||
(defun klacks/finish-doctype (source input)
|
(defun klacks/finish-doctype (source input)
|
||||||
(with-source (source current-key current-values root data-behaviour)
|
(with-source (source current-key current-values root data-behaviour)
|
||||||
@ -323,7 +329,7 @@
|
|||||||
(klacks/entity-reference source input name recurse)))
|
(klacks/entity-reference source input name recurse)))
|
||||||
((:<!\[)
|
((:<!\[)
|
||||||
(setf current-key :characters)
|
(setf current-key :characters)
|
||||||
(setf current-values (list (process-cdata-section input sem)))
|
(setf current-values (list (process-cdata-section input)))
|
||||||
(setf cdata-section-p t)
|
(setf cdata-section-p t)
|
||||||
recurse)
|
recurse)
|
||||||
((:PI)
|
((:PI)
|
||||||
@ -376,6 +382,58 @@
|
|||||||
(set-full-speed input)
|
(set-full-speed input)
|
||||||
(klacks/content source input cont)))
|
(klacks/content source input cont)))
|
||||||
|
|
||||||
|
|
||||||
|
;;;; terrible kludges
|
||||||
|
|
||||||
|
(defclass klacks-dtd-handler ()
|
||||||
|
((handler-source :initarg :source :reader handler-source)
|
||||||
|
(internal-subset-p :initform nil :accessor handler-internal-subset-p)))
|
||||||
|
|
||||||
|
(defmethod sax:start-internal-subset ((handler klacks-dtd-handler))
|
||||||
|
(setf (slot-value (handler-source handler) 'internal-declarations) '())
|
||||||
|
(setf (handler-internal-subset-p handler) t))
|
||||||
|
|
||||||
|
(defmethod sax:end-internal-subset ((handler klacks-dtd-handler))
|
||||||
|
(setf (handler-internal-subset-p handler) nil))
|
||||||
|
|
||||||
|
(defmethod sax:entity-resolver ((handler klacks-dtd-handler) fn)
|
||||||
|
(setf (slot-value (handler-source handler) 'dom-impl-entity-resolver) fn))
|
||||||
|
|
||||||
|
(defmethod sax::dtd ((handler klacks-dtd-handler) dtd)
|
||||||
|
(setf (slot-value (handler-source handler) 'dom-impl-dtd) dtd))
|
||||||
|
|
||||||
|
(defmethod sax:end-dtd ((handler klacks-dtd-handler))
|
||||||
|
(let ((source (handler-source handler)))
|
||||||
|
(when (slot-boundp source 'internal-declarations)
|
||||||
|
(setf (slot-value source 'internal-declarations)
|
||||||
|
(reverse (slot-value source 'internal-declarations)))
|
||||||
|
(setf (slot-value source 'external-declarations)
|
||||||
|
(reverse (slot-value source 'external-declarations))))))
|
||||||
|
|
||||||
|
(macrolet
|
||||||
|
((defhandler (name &rest args)
|
||||||
|
`(defmethod ,name ((handler klacks-dtd-handler) ,@args)
|
||||||
|
(let ((source (handler-source handler))
|
||||||
|
(spec (list ',name ,@args)))
|
||||||
|
(if (handler-internal-subset-p handler)
|
||||||
|
(push spec (slot-value source 'internal-declarations))
|
||||||
|
(push spec (slot-value source 'external-declarations)))))))
|
||||||
|
(defhandler sax:unparsed-entity-declaration
|
||||||
|
name public-id system-id notation-name)
|
||||||
|
(defhandler sax:external-entity-declaration
|
||||||
|
kind name public-id system-id)
|
||||||
|
(defhandler sax:internal-entity-declaration
|
||||||
|
kind name value)
|
||||||
|
(defhandler sax:notation-declaration
|
||||||
|
name public-id system-id)
|
||||||
|
(defhandler sax:element-declaration
|
||||||
|
name model)
|
||||||
|
(defhandler sax:attribute-declaration
|
||||||
|
element-name attribute-name type default))
|
||||||
|
|
||||||
|
|
||||||
|
;;;; debugging
|
||||||
|
|
||||||
#+(or)
|
#+(or)
|
||||||
(trace CXML::KLACKS/DOCTYPE
|
(trace CXML::KLACKS/DOCTYPE
|
||||||
CXML::KLACKS/EXT-PARSED-ENT
|
CXML::KLACKS/EXT-PARSED-ENT
|
||||||
|
|||||||
@ -18,7 +18,13 @@
|
|||||||
|
|
||||||
(in-package :cxml)
|
(in-package :cxml)
|
||||||
|
|
||||||
(defclass klacks:source () ())
|
(defclass klacks:source ()
|
||||||
|
(
|
||||||
|
;; fixme, terrible DTD kludges
|
||||||
|
(internal-declarations)
|
||||||
|
(external-declarations :initform nil)
|
||||||
|
(dom-impl-dtd :initform nil)
|
||||||
|
(dom-impl-entity-resolver :initform nil)))
|
||||||
|
|
||||||
(defgeneric klacks:close-source (source))
|
(defgeneric klacks:close-source (source))
|
||||||
|
|
||||||
@ -83,7 +89,19 @@
|
|||||||
(sax:comment handler a))
|
(sax:comment handler a))
|
||||||
(:dtd
|
(:dtd
|
||||||
(sax:start-dtd handler a b c)
|
(sax:start-dtd handler a b c)
|
||||||
(sax:end-dtd handler))
|
(when (slot-boundp source 'internal-declarations)
|
||||||
|
(sax:start-internal-subset handler)
|
||||||
|
(serialize-declaration-kludge
|
||||||
|
(slot-value source 'internal-declarations)
|
||||||
|
handler)
|
||||||
|
(sax:end-internal-subset handler))
|
||||||
|
(serialize-declaration-kludge
|
||||||
|
(slot-value source 'external-declarations)
|
||||||
|
handler)
|
||||||
|
(sax:end-dtd handler)
|
||||||
|
(sax:entity-resolver handler
|
||||||
|
(slot-value source 'dom-impl-entity-resolver))
|
||||||
|
(sax::dtd handler (slot-value source 'dom-impl-dtd)))
|
||||||
(:start-element
|
(:start-element
|
||||||
(sax:start-element handler a b c (klacks:list-attributes source)))
|
(sax:start-element handler a b c (klacks:list-attributes source)))
|
||||||
(:end-element
|
(:end-element
|
||||||
@ -93,3 +111,8 @@
|
|||||||
(t
|
(t
|
||||||
(error "unexpected klacks key: ~A" key)))
|
(error "unexpected klacks key: ~A" key)))
|
||||||
(klacks:consume source))))
|
(klacks:consume source))))
|
||||||
|
|
||||||
|
(defun serialize-declaration-kludge (list handler)
|
||||||
|
(loop
|
||||||
|
for (fn . args) in list
|
||||||
|
do (apply fn handler args)))
|
||||||
|
|||||||
@ -75,8 +75,19 @@
|
|||||||
:if-exists :supersede)
|
:if-exists :supersede)
|
||||||
(run-all-tests directory))))
|
(run-all-tests directory))))
|
||||||
|
|
||||||
(defun run-all-tests (directory)
|
(defvar *parser-fn* 'sax-test)
|
||||||
(let* ((pathname (merge-pathnames "xmlconf.xml" directory))
|
|
||||||
|
(defun sax-test (filename handler &rest args)
|
||||||
|
(apply #'cxml:parse-file filename handler :recode nil args))
|
||||||
|
|
||||||
|
(defun klacks-test (filename handler &rest args)
|
||||||
|
(klacks:with-open-source
|
||||||
|
(s (apply #'cxml:make-source (pathname filename) args))
|
||||||
|
(klacks:serialize-source s handler)))
|
||||||
|
|
||||||
|
(defun run-all-tests (parser-fn directory)
|
||||||
|
(let* ((*parser-fn* parser-fn)
|
||||||
|
(pathname (merge-pathnames "xmlconf.xml" directory))
|
||||||
(builder (rune-dom:make-dom-builder))
|
(builder (rune-dom:make-dom-builder))
|
||||||
(xmlconf (cxml:parse-file pathname builder :recode nil))
|
(xmlconf (cxml:parse-file pathname builder :recode nil))
|
||||||
(ntried 0)
|
(ntried 0)
|
||||||
@ -123,10 +134,9 @@
|
|||||||
|
|
||||||
(defmethod run-test ((class null) pathname output description &rest args)
|
(defmethod run-test ((class null) pathname output description &rest args)
|
||||||
(declare (ignore description))
|
(declare (ignore description))
|
||||||
(let ((document (apply #'cxml:parse-file
|
(let ((document (apply *parser-fn*
|
||||||
pathname
|
pathname
|
||||||
(rune-dom:make-dom-builder)
|
(rune-dom:make-dom-builder)
|
||||||
:recode nil
|
|
||||||
args)))
|
args)))
|
||||||
(cond
|
(cond
|
||||||
((null output)
|
((null output)
|
||||||
@ -163,9 +173,9 @@
|
|||||||
(handler-case
|
(handler-case
|
||||||
(progn
|
(progn
|
||||||
(format t " [validating:]")
|
(format t " [validating:]")
|
||||||
(cxml:parse-file pathname
|
(funcall *parser-fn*
|
||||||
|
pathname
|
||||||
(rune-dom:make-dom-builder)
|
(rune-dom:make-dom-builder)
|
||||||
:recode nil
|
|
||||||
:validate t)
|
:validate t)
|
||||||
(error "validity error not detected")
|
(error "validity error not detected")
|
||||||
nil)
|
nil)
|
||||||
@ -179,9 +189,9 @@
|
|||||||
(handler-case
|
(handler-case
|
||||||
(progn
|
(progn
|
||||||
(format t " [not validating:]")
|
(format t " [not validating:]")
|
||||||
(cxml:parse-file pathname
|
(funcall *parser-fn*
|
||||||
|
pathname
|
||||||
(rune-dom:make-dom-builder)
|
(rune-dom:make-dom-builder)
|
||||||
:recode nil
|
|
||||||
:validate nil)
|
:validate nil)
|
||||||
(error "well-formedness violation not detected")
|
(error "well-formedness violation not detected")
|
||||||
nil)
|
nil)
|
||||||
@ -191,9 +201,9 @@
|
|||||||
(handler-case
|
(handler-case
|
||||||
(progn
|
(progn
|
||||||
(format t " [validating:]")
|
(format t " [validating:]")
|
||||||
(cxml:parse-file pathname
|
(funcall *parser-fn*
|
||||||
|
pathname
|
||||||
(rune-dom:make-dom-builder)
|
(rune-dom:make-dom-builder)
|
||||||
:recode nil
|
|
||||||
:validate t)
|
:validate t)
|
||||||
(error "well-formedness violation not detected")
|
(error "well-formedness violation not detected")
|
||||||
nil)
|
nil)
|
||||||
@ -206,4 +216,9 @@
|
|||||||
t)))
|
t)))
|
||||||
|
|
||||||
#+(or)
|
#+(or)
|
||||||
(xmlconf::run-all-tests "/home/david/2001/XML-Test-Suite/xmlconf/")
|
(xmlconf::run-all-tests 'xmlconf::sax-test
|
||||||
|
"/home/david/2001/XML-Test-Suite/xmlconf/")
|
||||||
|
|
||||||
|
#+(or)
|
||||||
|
(xmlconf::run-all-tests 'xmlconf::klacks-test
|
||||||
|
"/home/david/2001/XML-Test-Suite/xmlconf/")
|
||||||
|
|||||||
Reference in New Issue
Block a user