X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/2872062129ea4b0b33136a5b48c8c51dcd820311..fc4f7a233ec0e3bf4366f784e14b53e92bcc0241:/lisp/json.el diff --git a/lisp/json.el b/lisp/json.el index 24685fdb10..468358ccd1 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -1,17 +1,17 @@ ;;; json.el --- JavaScript Object Notation parser / generator -;; Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. +;; Copyright (C) 2006-2012 Free Software Foundation, Inc. ;; Author: Edward O'Connor -;; Version: 1.2 +;; Version: 1.3 ;; Keywords: convenience ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -19,9 +19,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -49,6 +47,7 @@ ;; other cleanups, bugfixes, and improvements. ;; 2006-12-29 - XEmacs support, from Aidan Kehoe . ;; 2008-02-21 - Installed in GNU Emacs. +;; 2011-10-17 - Patch `json-alist-p' and `json-plist-p' to avoid recursion -tzz ;;; Code: @@ -64,12 +63,12 @@ (defvar json-object-type 'alist "Type to convert JSON objects to. -Must be one of `alist', `plist', or `hash-table'. Consider let-binding +Must be one of `alist', `plist', or `hash-table'. Consider let-binding this around your call to `json-read' instead of `setq'ing it.") (defvar json-array-type 'vector "Type to convert JSON arrays to. -Must be one of `vector' or `list'. Consider let-binding this around +Must be one of `vector' or `list'. Consider let-binding this around your call to `json-read' instead of `setq'ing it.") (defvar json-key-type nil @@ -85,19 +84,19 @@ If nil, `json-read' will guess the type based on the value of `plist' `keyword' Note that values other than `string' might behave strangely for -Sufficiently Weird keys. Consider let-binding this around your call to +Sufficiently Weird keys. Consider let-binding this around your call to `json-read' instead of `setq'ing it.") (defvar json-false :json-false "Value to use when reading JSON `false'. If this has the same value as `json-null', you might not be able to tell -the difference between `false' and `null'. Consider let-binding this +the difference between `false' and `null'. Consider let-binding this around your call to `json-read' instead of `setq'ing it.") (defvar json-null nil "Value to use when reading JSON `null'. If this has the same value as `json-false', you might not be able to -tell the difference between `false' and `null'. Consider let-binding +tell the difference between `false' and `null'. Consider let-binding this around your call to `json-read' instead of `setq'ing it.") @@ -109,27 +108,27 @@ this around your call to `json-read' instead of `setq'ing it.") (mapconcat 'identity strings separator)) (defun json-alist-p (list) - "Non-null iff LIST is an alist." - (or (null list) - (and (consp (car list)) - (json-alist-p (cdr list))))) + "Non-null if and only if LIST is an alist." + (while (consp list) + (setq list (if (consp (car list)) + (cdr list) + 'not-alist))) + (null list)) (defun json-plist-p (list) - "Non-null iff LIST is a plist." - (or (null list) - (and (keywordp (car list)) - (consp (cdr list)) - (json-plist-p (cddr list))))) + "Non-null if and only if LIST is a plist." + (while (consp list) + (setq list (if (and (keywordp (car list)) + (consp (cdr list))) + (cddr list) + 'not-plist))) + (null list)) ;; Reader utilities (defsubst json-advance (&optional n) "Skip past the following N characters." - (unless n (setq n 1)) - (let ((goal (+ (point) n))) - (goto-char goal) - (when (< (point) goal) - (signal 'end-of-file nil)))) + (forward-char n)) (defsubst json-peek () "Return the character at point." @@ -146,8 +145,7 @@ this around your call to `json-read' instead of `setq'ing it.") (defun json-skip-whitespace () "Skip past the whitespace at point." - (while (looking-at "[\t\r\n\f\b ]") - (goto-char (match-end 0)))) + (skip-chars-forward "\t\r\n\f\b ")) @@ -168,7 +166,7 @@ this around your call to `json-read' instead of `setq'ing it.") (put 'json-number-format 'error-conditions '(json-number-format json-error error)) -(put 'json-string-escape 'error-message "Bad unicode escape") +(put 'json-string-escape 'error-message "Bad Unicode escape") (put 'json-string-escape 'error-conditions '(json-string-escape json-error error)) @@ -223,19 +221,27 @@ KEYWORD is the keyword expected." ;; Number parsing -(defun json-read-number () - "Read the JSON number following point. +(defun json-read-number (&optional sign) + "Read the JSON number following point. +The optional SIGN argument is for internal use. + N.B.: Only numbers which can fit in Emacs Lisp's native number representation will be parsed correctly." - (if (char-equal (json-peek) ?-) - (progn - (json-advance) - (- 0 (json-read-number))) - (if (looking-at "[0-9]+\\([.][0-9]+\\)?\\([eE][+-]?[0-9]+\\)?") - (progn + ;; If SIGN is non-nil, the number is explicitly signed. + (let ((number-regexp + "\\([0-9]+\\)?\\(\\.[0-9]+\\)?\\([Ee][+-]?[0-9]+\\)?")) + (cond ((and (null sign) (char-equal (json-peek) ?-)) + (json-advance) + (- (json-read-number t))) + ((and (null sign) (char-equal (json-peek) ?+)) + (json-advance) + (json-read-number t)) + ((and (looking-at number-regexp) + (or (match-beginning 1) + (match-beginning 2))) (goto-char (match-end 0)) (string-to-number (match-string 0))) - (signal 'json-number-format (list (point)))))) + (t (signal 'json-number-format (list (point))))))) ;; Number encoding @@ -472,7 +478,7 @@ become JSON objects." (?\" json-read-string)))) (mapc (lambda (char) (push (list char 'json-read-number) table)) - '(?- ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) + '(?- ?+ ?. ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) table) "Readtable for JSON reader.") @@ -525,5 +531,4 @@ Advances point just past JSON object." (provide 'json) -;; arch-tag: 15f6e4c8-b831-4172-8749-bbc680c50ea1 ;;; json.el ends here