* bug#18557: 24.4.50; move parse-integer and digit-char-p to cl-lib
@ 2014-09-25 8:19 Leo Liu
2014-09-25 13:10 ` Stefan Monnier
0 siblings, 1 reply; 3+ messages in thread
From: Leo Liu @ 2014-09-25 8:19 UTC (permalink / raw)
To: 18557
[-- Attachment #1: Type: text/plain, Size: 39 bytes --]
Any comments on the following patch:
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: parse-integer.diff --]
[-- Type: text/x-patch, Size: 6194 bytes --]
=== modified file 'lisp/calendar/parse-time.el'
--- lisp/calendar/parse-time.el 2014-08-03 15:38:52 +0000
+++ lisp/calendar/parse-time.el 2014-09-25 08:11:25 +0000
@@ -34,21 +34,12 @@
;;; Code:
-(eval-when-compile (require 'cl-lib))
-
-(defvar parse-time-digits (make-vector 256 nil))
+(require 'cl-lib)
;; Byte-compiler warnings
(defvar parse-time-elt)
(defvar parse-time-val)
-(unless (aref parse-time-digits ?0)
- (cl-loop for i from ?0 to ?9
- do (aset parse-time-digits i (- i ?0))))
-
-(defsubst digit-char-p (char)
- (aref parse-time-digits char))
-
(defsubst parse-time-string-chars (char)
(save-match-data
(let (case-fold-search str)
@@ -62,27 +53,6 @@
(put 'parse-error 'error-conditions '(parse-error error))
(put 'parse-error 'error-message "Parsing error")
-(defsubst parse-integer (string &optional start end)
- "[CL] Parse and return the integer in STRING, or nil if none."
- (let ((integer 0)
- (digit 0)
- (index (or start 0))
- (end (or end (length string))))
- (when (< index end)
- (let ((sign (aref string index)))
- (if (or (eq sign ?+) (eq sign ?-))
- (setq sign (parse-time-string-chars sign)
- index (1+ index))
- (setq sign 1))
- (while (and (< index end)
- (setq digit (digit-char-p (aref string index))))
- (setq integer (+ (* integer 10) digit)
- index (1+ index)))
- (if (/= index end)
- (signal 'parse-error `("not an integer"
- ,(substring string (or start 0) end)))
- (* sign integer))))))
-
(defun parse-time-tokenize (string)
"Tokenize STRING into substrings."
(let ((start nil)
@@ -100,7 +70,7 @@
(setq c (parse-time-string-chars (aref string index))))
(setq all-digits (and all-digits (eq c ?0))))
(if (<= index end)
- (push (if all-digits (parse-integer string start index)
+ (push (if all-digits (cl-parse-integer string :start start :end index)
(substring string start index))
list)))
(nreverse list)))
@@ -147,8 +117,8 @@
(= 5 (length parse-time-elt))
(or (= (aref parse-time-elt 0) ?+)
(= (aref parse-time-elt 0) ?-))))
- ,#'(lambda () (* 60 (+ (parse-integer parse-time-elt 3 5)
- (* 60 (parse-integer parse-time-elt 1 3)))
+ ,#'(lambda () (* 60 (+ (cl-parse-integer parse-time-elt :start 3 :end 5)
+ (* 60 (cl-parse-integer parse-time-elt :start 1 :end 3)))
(if (= (aref parse-time-elt 0) ?-) -1 1))))
((5 4 3)
,#'(lambda () (and (stringp parse-time-elt)
@@ -210,9 +180,10 @@
(let ((new-val (if rule
(let ((this (pop rule)))
(if (vectorp this)
- (parse-integer
+ (cl-parse-integer
parse-time-elt
- (aref this 0) (aref this 1))
+ :start (aref this 0)
+ :end (aref this 1))
(funcall this)))
parse-time-val)))
(rplaca (nthcdr (pop slots) time) new-val))))))))
=== modified file 'lisp/emacs-lisp/cl-extra.el'
--- lisp/emacs-lisp/cl-extra.el 2014-03-20 18:16:47 +0000
+++ lisp/emacs-lisp/cl-extra.el 2014-09-25 08:14:57 +0000
@@ -383,6 +383,28 @@
"Return 1 if X is positive, -1 if negative, 0 if zero."
(cond ((> x 0) 1) ((< x 0) -1) (t 0)))
+;;;###autoload
+(cl-defun cl-parse-integer (string &key start end radix junk-allowed)
+ "Parse integer from the substring of STRING from START to END."
+ (let* ((start (or start 0))
+ (end (or end (length string)))
+ (radix (or radix 10)))
+ (or (< start end (1+ (length string)))
+ (error "Bad interval: [%d, %d)" start end))
+ (let ((sign (cl-case (aref string start)
+ (?+ (cl-incf start) +1)
+ (?- (cl-incf start) -1)
+ (t +1)))
+ digit sum)
+ (while (and (< start end)
+ (setq digit (cl-digit-char-p (aref string start) radix)))
+ (setq sum (+ (* (or sum 0) radix) digit)
+ start (1+ start)))
+ (cond ((and junk-allowed (null sum)) sum)
+ (junk-allowed (* sign sum))
+ ((/= start end) (error "Not an integer string: %s" string))
+ (t (* sign sum))))))
+
;; Random numbers.
=== modified file 'lisp/emacs-lisp/cl-lib.el'
--- lisp/emacs-lisp/cl-lib.el 2014-05-21 00:41:21 +0000
+++ lisp/emacs-lisp/cl-lib.el 2014-09-25 07:55:40 +0000
@@ -279,6 +279,25 @@
"Return t if INTEGER is even."
(eq (logand integer 1) 0))
+(defconst cl-digit-char-table
+ (let* ((digits (make-vector 256 nil))
+ (populate (lambda (start end base)
+ (mapc (lambda (i)
+ (aset digits i (+ base (- i start))))
+ (number-sequence start end)))))
+ (funcall populate ?0 ?9 0)
+ (funcall populate ?A ?Z 10)
+ (funcall populate ?a ?z 10)
+ digits))
+
+(defun cl-digit-char-p (char &optional radix)
+ "Test if CHAR is a digit in the specified RADIX (default 10).
+If true return the decimal value of digit CHAR in RADIX."
+ (or (<= 2 (or radix 10) 36)
+ (signal 'args-out-of-range (list 'radix radix '(2 36))))
+ (let ((n (aref cl-digit-char-table char)))
+ (and n (< n (or radix 10)) n)))
+
(defvar cl--random-state
(vector 'cl--random-state-tag -1 30 (cl--random-time)))
=== modified file 'test/automated/cl-lib.el'
--- test/automated/cl-lib.el 2014-04-22 21:32:51 +0000
+++ test/automated/cl-lib.el 2014-09-25 08:16:10 +0000
@@ -223,6 +223,23 @@
(should (= (cl-the integer (cl-incf side-effect)) 1))
(should (= side-effect 1))))
+(ert-deftest cl-digit-char-p ()
+ (should (cl-digit-char-p ?3))
+ (should (cl-digit-char-p ?a 11))
+ (should-not (cl-digit-char-p ?a))
+ (should (cl-digit-char-p ?w 36))
+ (should-error (cl-digit-char-p ?a 37))
+ (should-error (cl-digit-char-p ?a 1)))
+
+(ert-deftest cl-parse-integer ()
+ (should-error (cl-parse-integer "abc"))
+ (should (null (cl-parse-integer "abc" :junk-allowed t)))
+ (should (= 342391 (cl-parse-integer "0123456789" :radix 8 :junk-allowed t)))
+ (should-error (cl-parse-integer "0123456789" :radix 8))
+ (should (= -239 (cl-parse-integer "-efz" :radix 16 :junk-allowed t)))
+ (should-error (cl-parse-integer "efz" :radix 16))
+ (should (= 239 (cl-parse-integer "zzef" :radix 16 :start 2))))
+
(ert-deftest cl-loop-destructuring-with ()
(should (equal (cl-loop with (a b c) = '(1 2 3) return (+ a b c)) 6)))
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-09-26 0:24 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-25 8:19 bug#18557: 24.4.50; move parse-integer and digit-char-p to cl-lib Leo Liu
2014-09-25 13:10 ` Stefan Monnier
2014-09-26 0:24 ` Leo Liu
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.