From 686c366f8a63c448d06e5f08d604374fb316bc57 Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Sat, 10 Apr 2021 15:10:35 -0400 Subject: [PATCH] Fix calculator-string-to-number yet again (bug#47694) * lisp/calculator.el (calculator-string-to-number): The last bugfix changed the code to just blindly replace ".e". This has some minor problems like making "-." parse as 0.0 instead of -0.0, and ".1.e1" is parsed as 1 instead of 0.1. Instead, replace the first "." that is followed by a non-digit with ".0". Since this has had several problems over the years, add some tests too. (Also, restore the original if-indentation style.) --- lisp/calculator.el | 9 ++++--- test/lisp/calculator-tests.el | 51 +++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 test/lisp/calculator-tests.el diff --git a/lisp/calculator.el b/lisp/calculator.el index 6dd8d9a7ec1..99c9b6290c4 100644 --- a/lisp/calculator.el +++ b/lisp/calculator.el @@ -836,10 +836,11 @@ The result should not exceed the screen width." "Convert the given STR to a number, according to the value of `calculator-input-radix'." (if calculator-input-radix - (string-to-number str (cadr (assq calculator-input-radix - '((bin 2) (oct 8) (hex 16))))) - ;; Allow entry of "1.e3". - (let ((str (replace-regexp-in-string (rx "." (any "eE")) "e" str))) + (string-to-number str (cadr (assq calculator-input-radix + '((bin 2) (oct 8) (hex 16))))) + ;; parse numbers similarly to calculators + ;; (see tests in test/lisp/calculator-tests.el) + (let ((str (replace-regexp-in-string "\\.\\([^0-9].*\\)?$" ".0\\1" str))) (float (string-to-number str))))) (defun calculator-push-curnum () diff --git a/test/lisp/calculator-tests.el b/test/lisp/calculator-tests.el new file mode 100644 index 00000000000..9551b1a4c61 --- /dev/null +++ b/test/lisp/calculator-tests.el @@ -0,0 +1,51 @@ +;;; calculator-tests.el --- Test suite for calculator. -*- lexical-binding: t -*- + +;; Copyright (C) 2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; 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 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 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: +(require 'ert) +(require 'calculator) + +(ert-deftest calculator-test-calculator-string-to-number () + (dolist (x '(("" 0.0) + ("+" 0.0) + ("-" 0.0) + ("." 0.0) + ("+." 0.0) + ("-." -0.0) + (".-" 0.0) + ("--." 0.0) + ("-0.0e" -0.0) + ("1e1" 10.0) + ("1e+1" 10.0) + ("1e-1" 0.1) + ("+1e1" 10.0) + ("-1e1" -10.0) + ("+1e-1" 0.1) + ("-1e-1" -0.1) + (".1.e1" 0.1) + (".1..e1" 0.1) + ("1e+1.1" 10.0) + ("-2e-1.1" -0.2))) + (pcase x + (`(,str ,expected) + (let ((calculator-input-radix nil)) + (should (equal (calculator-string-to-number str) expected))))))) + +(provide 'calculator-tests) +;; calculator-tests.el ends here -- 2.39.2