Fixed time and space usage in cases where entity references
follow each other (thanks to Ivan Shvedunov for the report). * xml/xml-parse.lisp (P/CONTENT): Removed useless call to append. Use loop instead of tail recursion.
This commit is contained in:
@ -2800,45 +2800,39 @@
|
|||||||
|
|
||||||
(defun p/content (input)
|
(defun p/content (input)
|
||||||
;; [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
|
;; [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
|
||||||
(multiple-value-bind (cat sem) (peek-token input)
|
(loop
|
||||||
(case cat
|
(multiple-value-bind (cat sem) (peek-token input)
|
||||||
((:stag :ztag)
|
(case cat
|
||||||
(p/element input)
|
((:stag :ztag)
|
||||||
(p/content input))
|
(p/element input))
|
||||||
((:CDATA)
|
((:CDATA)
|
||||||
(process-characters input sem)
|
(process-characters input sem)
|
||||||
(sax:characters (handler *ctx*) sem)
|
(sax:characters (handler *ctx*) sem))
|
||||||
(p/content input))
|
((:ENTITY-REF)
|
||||||
((:ENTITY-REF)
|
(let ((name sem))
|
||||||
(let ((name sem))
|
(consume-token input)
|
||||||
(consume-token input)
|
(recurse-on-entity input name :general
|
||||||
(append
|
(lambda (input)
|
||||||
(recurse-on-entity input name :general
|
(prog1
|
||||||
(lambda (input)
|
(etypecase (checked-get-entdef name :general)
|
||||||
(prog1
|
(internal-entdef (p/content input))
|
||||||
(etypecase (checked-get-entdef name :general)
|
(external-entdef (p/ext-parsed-ent input)))
|
||||||
(internal-entdef (p/content input))
|
(unless (eq (peek-token input) :eof)
|
||||||
(external-entdef (p/ext-parsed-ent input)))
|
(wf-error input "Trailing garbage. - ~S"
|
||||||
(unless (eq (peek-token input) :eof)
|
(peek-token input))))))))
|
||||||
(wf-error input "Trailing garbage. - ~S"
|
((:<!\[)
|
||||||
(peek-token input))))))
|
(let ((data (process-cdata-section input)))
|
||||||
(p/content input))))
|
(sax:start-cdata (handler *ctx*))
|
||||||
((:<!\[)
|
(sax:characters (handler *ctx*) data)
|
||||||
(let ((data (process-cdata-section input)))
|
(sax:end-cdata (handler *ctx*))))
|
||||||
(sax:start-cdata (handler *ctx*))
|
((:PI)
|
||||||
(sax:characters (handler *ctx*) data)
|
(consume-token input)
|
||||||
(sax:end-cdata (handler *ctx*)))
|
(sax:processing-instruction (handler *ctx*) (car sem) (cdr sem)))
|
||||||
(p/content input))
|
((:COMMENT)
|
||||||
((:PI)
|
(consume-token input)
|
||||||
(consume-token input)
|
(sax:comment (handler *ctx*) sem))
|
||||||
(sax:processing-instruction (handler *ctx*) (car sem) (cdr sem))
|
(otherwise
|
||||||
(p/content input))
|
(return))))))
|
||||||
((:COMMENT)
|
|
||||||
(consume-token input)
|
|
||||||
(sax:comment (handler *ctx*) sem)
|
|
||||||
(p/content input))
|
|
||||||
(otherwise
|
|
||||||
nil))))
|
|
||||||
|
|
||||||
;; [78] extParsedEnt ::= TextDecl? contentw
|
;; [78] extParsedEnt ::= TextDecl? contentw
|
||||||
;; [79] extPE ::= TextDecl? extSubsetDecl
|
;; [79] extPE ::= TextDecl? extSubsetDecl
|
||||||
|
|||||||
Reference in New Issue
Block a user