diff options
author | Mark Walters <markwalters1009@gmail.com> | 2012-10-27 10:34:12 +0100 |
---|---|---|
committer | David Bremner <bremner@debian.org> | 2012-10-28 09:42:18 -0300 |
commit | 42391b405610f48d81a369e899d0be9c9b0ee969 (patch) | |
tree | 0c48e70b58d910dd11583dc157e772680d517b17 /emacs/notmuch-lib.el | |
parent | 294667871a30b86790f7dd19c13a4da6806bf52a (diff) |
emacs: Move the incremental JSON parser to notmuch-lib.el
This just moves the newly split out incremental json parser (together
with its state variables) to lib.
There should be no functional change.
Diffstat (limited to 'emacs/notmuch-lib.el')
-rw-r--r-- | emacs/notmuch-lib.el | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el index eeb005ff..1d0ec174 100644 --- a/emacs/notmuch-lib.el +++ b/emacs/notmuch-lib.el @@ -355,6 +355,16 @@ was called." ;; Incremental JSON parsing +;; These two variables are internal variables to the parsing +;; routines. They are always used buffer local but need to be declared +;; globally to avoid compiler warnings. + +(defvar notmuch-json-parser nil + "Internal incremental JSON parser object: local to the buffer being parsed.") + +(defvar notmuch-json-state nil + "State of the internal JSON parser: local to the buffer being parsed.") + (defun notmuch-json-create-parser (buffer) "Return a streaming JSON parser that consumes input from BUFFER. @@ -549,6 +559,62 @@ of the buffer if there is only trailing whitespace." (unless (eobp) (signal 'json-error (list "Trailing garbage following JSON data"))))) +(defun notmuch-json-parse-partial-list (result-function error-function results-buf) + "Parse a partial JSON list from current buffer. + +This function consumes a JSON list from the current buffer, +applying RESULT-FUNCTION in buffer RESULT-BUFFER to each complete +value in the list. It operates incrementally and should be +called whenever the buffer has been extended with additional +data. + +If there is a syntax error, this will attempt to resynchronize +with the input and will apply ERROR-FUNCTION in buffer +RESULT-BUFFER to any input that was skipped. + +It sets up all the needed internal variables: the caller just +needs to call it with point in the same place that the parser +left it." + (let (done) + (unless (local-variable-p 'notmuch-json-parser) + (set (make-local-variable 'notmuch-json-parser) + (notmuch-json-create-parser (current-buffer))) + (set (make-local-variable 'notmuch-json-state) 'begin)) + (while (not done) + (condition-case nil + (case notmuch-json-state + ((begin) + ;; Enter the results list + (if (eq (notmuch-json-begin-compound + notmuch-json-parser) 'retry) + (setq done t) + (setq notmuch-json-state 'result))) + ((result) + ;; Parse a result + (let ((result (notmuch-json-read notmuch-json-parser))) + (case result + ((retry) (setq done t)) + ((end) (setq notmuch-json-state 'end)) + (otherwise (with-current-buffer results-buf + (funcall result-function result)))))) + ((end) + ;; Any trailing data is unexpected + (notmuch-json-eof notmuch-json-parser) + (setq done t))) + (json-error + ;; Do our best to resynchronize and ensure forward + ;; progress + (let ((bad (buffer-substring (line-beginning-position) + (line-end-position)))) + (forward-line) + (with-current-buffer results-buf + (funcall error-function "%s" bad)))))) + ;; Clear out what we've parsed + (delete-region (point-min) (point)))) + + + + (provide 'notmuch-lib) ;; Local Variables: |