X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=emacs%2Fnotmuch-parser.el;h=f04b07c2e51b28e34f03469b88205d279c45a587;hb=03366a3c5aa313de41bddd61dedc5b5c002e0469;hp=dc9fbe2f33911ec48294804de1098269a0f03426;hpb=11ac932a4503872c19987b843d58513c4b9ef76f;p=notmuch diff --git a/emacs/notmuch-parser.el b/emacs/notmuch-parser.el index dc9fbe2f..f04b07c2 100644 --- a/emacs/notmuch-parser.el +++ b/emacs/notmuch-parser.el @@ -1,4 +1,4 @@ -;;; notmuch-parser.el --- streaming S-expression parser +;;; notmuch-parser.el --- streaming S-expression parser -*- lexical-binding: t -*- ;; ;; Copyright © Austin Clements ;; @@ -21,7 +21,9 @@ ;;; Code: -(eval-when-compile (require 'cl-lib)) +(require 'cl-lib) +(require 'pcase) +(require 'subr-x) (defun notmuch-sexp-create-parser () "Return a new streaming S-expression parser. @@ -38,14 +40,10 @@ can return 'retry to indicate that not enough input is available. The parser always consumes input from point in the current buffer. Hence, the caller is allowed to delete any data before point and may resynchronize after an error by moving point." - (vector 'notmuch-sexp-parser - ;; List depth - 0 - ;; Partial parse position marker - nil - ;; Partial parse state - nil)) + 0 ; List depth + nil ; Partial parse position marker + nil)) ; Partial parse state (defmacro notmuch-sexp--depth (sp) `(aref ,sp 1)) (defmacro notmuch-sexp--partial-pos (sp) `(aref ,sp 2)) @@ -60,7 +58,6 @@ parser is currently inside a list and the next token ends the list, this moves point just past the terminator and returns 'end. Otherwise, this moves point to just past the end of the value and returns the value." - (skip-chars-forward " \n\r\t") (cond ((eobp) 'retry) ((= (char-after) ?\)) @@ -80,7 +77,7 @@ returns the value." ;; parse, extend the partial parse to figure out when we ;; have a complete list. (catch 'return - (when (null (notmuch-sexp--partial-state sp)) + (unless (notmuch-sexp--partial-state sp) (let ((start (point))) (condition-case nil (throw 'return (read (current-buffer))) @@ -134,7 +131,6 @@ a list, it moves point past the token that opens the list and returns t. Later calls to `notmuch-sexp-read' will return the elements inside the list. If the input in buffer is not the beginning of a list, throw invalid-read-syntax." - (skip-chars-forward " \n\r\t") (cond ((eobp) 'retry) ((= (char-after) ?\() @@ -146,16 +142,6 @@ beginning of a list, throw invalid-read-syntax." (forward-char) (signal 'invalid-read-syntax (list (string (char-before))))))) -(defun notmuch-sexp-eof (sp) - "Signal an error if there is more data in SP's buffer. - -Moves point to the beginning of any trailing data or to the end -of the buffer if there is only trailing whitespace." - - (skip-chars-forward " \n\r\t") - (unless (eobp) - (error "Trailing garbage following expression"))) - (defvar notmuch-sexp--parser nil "The buffer-local notmuch-sexp-parser instance. @@ -173,12 +159,10 @@ complete value in the list. It operates incrementally and should be called whenever the input buffer has been extended with additional data. The caller just needs to ensure it does not move point in the input buffer." - ;; Set up the initial state (unless (local-variable-p 'notmuch-sexp--parser) - (set (make-local-variable 'notmuch-sexp--parser) - (notmuch-sexp-create-parser)) - (set (make-local-variable 'notmuch-sexp--state) 'begin)) + (setq-local notmuch-sexp--parser (notmuch-sexp-create-parser)) + (setq-local notmuch-sexp--state 'begin)) (let (done) (while (not done) (cl-case notmuch-sexp--state @@ -196,8 +180,11 @@ move point in the input buffer." (t (with-current-buffer result-buffer (funcall result-function result)))))) (end - ;; Any trailing data is unexpected - (notmuch-sexp-eof notmuch-sexp--parser) + ;; Skip over trailing whitespace. + (skip-chars-forward " \n\r\t") + ;; Any trailing data is unexpected. + (unless (eobp) + (error "Trailing garbage following expression")) (setq done t))))) ;; Clear out what we've parsed (delete-region (point-min) (point)))