klacks fixes

This commit is contained in:
dlichteblau
2007-02-18 14:35:14 +00:00
parent 0d67d0719d
commit 2623586d4c
6 changed files with 146 additions and 42 deletions

View File

@ -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 ()

View File

@ -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>

View File

@ -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)

View File

@ -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

View File

@ -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)))

View File

@ -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/")