unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
blob fca604cfa2212b23e7c52233abd6af2c4d4c964a 5970 bytes (raw)
name: lisp/num-base-converters.el 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
 
;;; num-base-converters.el --- Convert integers between different numeric bases  -*- lexical-binding: t -*-

;; Copyright (C) 2017 Free Software Foundation, Inc.

;; Author: Tino Calancha <tino.calancha@gmail.com>
;; Keywords: convenience, numbers, converters, tools
;; Created: Tue Aug 15 02:04:55 JST 2017
;; Version: 0.1

;; 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 this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:
 
;; This library defines the command `nbc-number-base-converter' to
;; convert a given integer in a numeric base to a different base.
;;
;; For instance, 10 in hexadecimal is 'A':
;; (nbc-number-base-converter "10" 10 16)
;; => "A"
;;
;; In addition, this file adds the following commands to convert
;; between the most common bases (2, 8, 10, 16):
;; `nbc-hex2dec', `nbc-hex2oct', `nbc-hex2bin'
;; `nbc-dec2hex', `nbc-dec2oct', `nbc-dec2bin'
;; `nbc-oct2hex', `nbc-oct2dec', `nbc-oct2bin'
;; `nbc-bin2hex', `nbc-bin2dec', `nbc-bin2oct'.

;;; Code:
 

(require 'calc-bin)
(eval-when-compile (require 'rx))

(defgroup num-base-converters nil
  "Convert integers between different numeric bases."
  :group 'nbc)

(defcustom nbc-define-aliases nil
  "If non-nil, create aliases without prefix 'nbc' for the converters."
  :type 'boolean
  :group 'nbc)

 

(defun nbc-number-base-converter (num base-in base-out)
  "Translate NUM, a string representing an integer, to a different base.
BASE-IN, an integer, is the basis of the input NUM.
BASE-OUT, an integer, is the basis to display NUM."
  (interactive
   (let ((num (read-string "Number: "))
         (base-in (read-number "Base input: "))
         (base-out (read-number "Base output: ")))
     (list num base-in base-out)))
  (unless (stringp num)
    (signal 'wrong-type-argument (list 'stringp num)))
  (unless (and (>= base-in 2) (<= base-in 36) (>= base-out 2) (<= base-out 36))
    (user-error "Base `b' must satisfy 2 <= b <= 36: base-in `%d' base-out `%d'"
                base-in base-out))
  (let* ((case-fold-search nil)
         (input (progn
                  (pcase num ; Drop base info from NUMB.
                    ((rx (and string-start
                              (let _u (or "b" "0x" "o")
                                   (let v (one-or-more not-newline)) string-end)))
                     (setq num v))
                    ((rx (and string-start "#"
                              (let _u (or "b" "x" "o" (and (one-or-more digit) "r")))
                              (let v (one-or-more not-newline)) string-end))
                     (setq num v)))
                  (condition-case nil
                      ;; Translate to canonical syntaxis: #(base)r(number).
                      (read (format "#%dr%s" base-in num))
	                (invalid-read-syntax
                     (user-error "Wrong input: `%s' for base `%s'"
                                 num base-in))))))
    (condition-case nil
        (let* ((calc-number-radix base-out)
               (output (math-format-radix input)))
          (pcase output
            ((rx (and string-start
                      (let _u (zero-or-one (and (zero-or-more digit) "#"))
                           (let v (and (one-or-more not-newline) string-end)))))
             (setq output v))) ; Drop base info from OUTPUT.
          (message "%s base %s = %s base %s" num base-in output base-out)
          output)
      (wrong-type-argument
       (user-error "Wrong input: `%s' for base `%s'" num base-in)))))

 
;;; Add translatros for the most common basis: decimal, hexadecimal,
;;  octal and binary.
(eval-when-compile
  (defmacro nbc--create-converters-1 ()
    (let ((bases (list "hex" "dec" "oct" "bin"))
          forms)
      (dolist (base-out bases)
        (dolist (base-in bases)
          (if (equal base-out base-in)
              nil
            (push `(nbc--create-command ,base-in ,base-out) forms))))
      `(progn ,@forms)))

  (defmacro nbc--create-command (base-in base-out)
    (let* ((input-fn
            (lambda (x)
              (pcase x
                (`"hex" (cons "hexadecimal" 16))
                (`"dec" (cons "decimal" 10))
                (`"oct" (cons "octal" 8))
                (`"bin" (cons "binary" 2)))))
           (in-lst (funcall input-fn base-in))
           (base-in-name (car in-lst))
           (out-lst (funcall input-fn base-out))
           (func-name (format "nbc-%s2%s" base-in
                              (substring (car out-lst) 0 3)))
           (prefix-len (length "nbc-"))
           (docstring (format "Translate NUM, a string, from %s to %s."
                              (car in-lst) (car out-lst)))
           (ispec (format "sNumber in %s: " (car in-lst))))
      `(progn
         (when (bound-and-true-p nbc-define-aliases)
           (defalias (intern ,(substring func-name prefix-len))
             (intern ,func-name)))
         (defun ,(intern func-name) ,(list 'num)
           ,docstring (interactive ,ispec)
           (let ((res (nbc-number-base-converter
                       num ,(cdr in-lst) ,(cdr out-lst))))
             (message "%s %s = %s %s"
                      num ,base-in-name res ,(car out-lst))
             res))))))

(defun nbc--create-converters ()
  "Create converters between the bases 2, 8, 10 and 16."
  (nbc--create-converters-1))

(nbc--create-converters)

(provide 'num-base-converters)
;;; num-base-converters.el ends here

debug log:

solving dd31d13d2b ...
found dd31d13d2b in https://yhetil.org/emacs-devel/alpine.DEB.2.20.1708150225001.30658@calancha-pc/

applying [1/1] https://yhetil.org/emacs-devel/alpine.DEB.2.20.1708150225001.30658@calancha-pc/
diff --git a/lisp/num-base-converters.el b/lisp/num-base-converters.el
new file mode 100644
index 0000000000..dd31d13d2b

1:32: trailing whitespace.
 
1:48: trailing whitespace.
 
1:62: trailing whitespace.
 
1:108: trailing whitespace.
 
Checking patch lisp/num-base-converters.el...
Applied patch lisp/num-base-converters.el cleanly.
warning: 4 lines add whitespace errors.

index at:
100644 fca604cfa2212b23e7c52233abd6af2c4d4c964a	lisp/num-base-converters.el

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).