Subject: bug#27952: closed (Re: bug#27952: 26.0.50; Combine archive-int-to-mode and tar-grind-file-mode)

From: [email-masked] (GNU bug Tracking System)
Date: Thu, 14 May 2020 16:48:02 +0000

Your bug report

#27952: 26.0.50; Combine archive-int-to-mode and tar-grind-file-mode

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
27952: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=27952
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#27952: 26.0.50; Combine archive-int-to-mode and tar-grind-file-mode
From: Tino Calancha <[email-masked]>
To: [email-masked]
Date: Thu, 14 May 2020 18:47:34 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Stefan Monnier <[email-masked]> writes:

> LGTM.

Fixed in master branch as commit
'Combine archive-int-to-mode and tar-grind-file-mode'
(3a284e578625e617fdc6085ae11da2b4e41bb59b)

Subject: 26.0.50; Combine archive-int-to-mode and tar-grind-file-mode
From: Tino Calancha <[email-masked]>
To: [email-masked]
Date: Fri, 04 Aug 2017 21:32:24 +0900
List-Id: <debbugs-submit.debbugs.gnu.org>

Severity: wishlist
Tag: patch
X-Debbugs-CC: Stefan Monnier <[email-masked]>

These functions are almost identical; archive-int-to-mode has a FIXME
suggesting merging it with tar-grind-file-mode.

--8<-----------------------------cut here---------------start------------->8---
commit c6d36b04de7f6442653af7e4699bdad44ee57201
Author: Tino Calancha <[email-masked]>
Date:   Fri Aug 4 21:25:44 2017 +0900

    Combine archive-int-to-mode and tar-grind-file-mode
    
    These functions are almost identical.  Add a new function
    file-modes-number-to-symbolic; use it to define the other two.
    * lisp/files.el (file-modes-number-to-symbolic-1)
    (file-modes-number-to-symbolic): New defuns.
    * lisp/arc-mode.el (archive-int-to-mode): Define as a alias of
    file-modes-number-to-symbolic.
    * lisp/tar-mode.el (tar-grind-file-mode): Fix docstring.
    Use file-modes-number-to-symbolic.

diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el
index bd7548b704..8f3691b337 100644
--- a/lisp/arc-mode.el
+++ b/lisp/arc-mode.el
@@ -549,26 +549,7 @@ archive-l-e
 		      (aref str (- len i)))))
     result))
 
-(defun archive-int-to-mode (mode)
-  "Turn an integer like 0700 (i.e., 448) into a mode string like -rwx------."
-  ;; FIXME: merge with tar-grind-file-mode.
-  (string
-    (if (zerop (logand  8192 mode))
-	(if (zerop (logand 16384 mode)) ?- ?d)
-      ?c) ; completeness
-    (if (zerop (logand   256 mode)) ?- ?r)
-    (if (zerop (logand   128 mode)) ?- ?w)
-    (if (zerop (logand    64 mode))
-	(if (zerop (logand  1024 mode)) ?- ?S)
-      (if (zerop (logand  1024 mode)) ?x ?s))
-    (if (zerop (logand    32 mode)) ?- ?r)
-    (if (zerop (logand    16 mode)) ?- ?w)
-    (if (zerop (logand     8 mode))
-	(if (zerop (logand  2048 mode)) ?- ?S)
-      (if (zerop (logand  2048 mode)) ?x ?s))
-    (if (zerop (logand     4 mode)) ?- ?r)
-    (if (zerop (logand     2 mode)) ?- ?w)
-    (if (zerop (logand     1 mode)) ?- ?x)))
+(defalias 'archive-int-to-mode 'file-modes-number-to-symbolic)
 
 (defun archive-calc-mode (oldmode newmode &optional error)
   "From the integer OLDMODE and the string NEWMODE calculate a new file mode.
diff --git a/lisp/files.el b/lisp/files.el
index 89f6f9f44d..e776b00b91 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -7188,6 +7188,65 @@ file-modes-symbolic-to-number
 	  (error "Parse error in modes near `%s'" (substring modes 0))))
       num-modes)))
 
+(defun file-modes-number-to-symbolic-1 (mode)
+  (string
+   (if (zerop (logand  8192 mode))
+       (if (zerop (logand 16384 mode)) ?- ?d)
+     ?c) ; completeness
+   (if (zerop (logand   256 mode)) ?- ?r)
+   (if (zerop (logand   128 mode)) ?- ?w)
+   (if (zerop (logand    64 mode))
+       (if (zerop (logand  1024 mode)) ?- ?S)
+     (if (zerop (logand  1024 mode)) ?x ?s))
+   (if (zerop (logand    32 mode)) ?- ?r)
+   (if (zerop (logand    16 mode)) ?- ?w)
+   (if (zerop (logand     8 mode))
+       (if (zerop (logand  2048 mode)) ?- ?S)
+     (if (zerop (logand  2048 mode)) ?x ?s))
+   (if (zerop (logand     4 mode)) ?- ?r)
+   (if (zerop (logand     2 mode)) ?- ?w)
+   (if (zerop (logand     1 mode)) ?- ?x)))
+
+(defun file-modes-number-to-symbolic (mode &optional detailed from)
+  "Turn an integer like 0700 (i.e., 448) into a mode string like -rwx------.
+If optional arg DETAILED is non-nil, then use the format 'u=rwx,g=,o='.
+If optional argument FROM is non-nil, then it's the original file mode
+ to compare with MODE.  FROM is ignored unless DETAILED is non-nil.
+
+For instance, if MODE is 448, DETAILED is non-nil, and FROM is 400,
+the output is 'u+x,g-w'."
+  (let ((mode (file-modes-number-to-symbolic-1 mode))
+        (from (and from (substring (file-modes-number-to-symbolic-1 from) 1))))
+    (if (not detailed)
+        mode
+      (setq mode (substring mode 1))
+      (cond (from
+             (let ((res "u"))
+               (dotimes (i (length mode))
+                 (let ((x (aref mode i))
+                       (y (aref from i)))
+                   (when (= i 3) (setq res (concat res ",g")))
+                   (when (= i 6) (setq res (concat res ",o")))
+                   (setq res (concat res
+                                     (cond ((eq x y) "")
+                                           ((eq x ?-) (string ?- y))
+                                           ((eq y ?-) (string ?+ x)))))))
+               (replace-regexp-in-string
+                ",\\'" ""
+                (replace-regexp-in-string
+                 "u," ""
+                 (replace-regexp-in-string
+                  "g," ""
+                  (replace-regexp-in-string
+                   "o\\'" "" res))))))
+            (t
+             (replace-regexp-in-string
+              "-" ""
+              (format "u=%s,g=%s,o=%s"
+                      (substring mode 0 3)
+                      (substring mode 3 6)
+                      (substring mode 6))))))))
+
 (defun read-file-modes (&optional prompt orig-file)
   "Read file modes in octal or symbolic notation and return its numeric value.
 PROMPT is used as the prompt, default to \"File modes (octal or symbolic): \".
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el
index 1d453d2980..f41cc25532 100644
--- a/lisp/tar-mode.el
+++ b/lisp/tar-mode.el
@@ -469,24 +469,12 @@ tar-clip-time-string
     (concat " " (substring str 4 16) (format-time-string " %Y" time))))
 
 (defun tar-grind-file-mode (mode)
-  "Construct a `-rw--r--r--' string indicating MODE.
+  "Construct a `rw-r--r--' string indicating MODE.
 MODE should be an integer which is a file mode value."
-  (string
-   (if (zerop (logand 256 mode)) ?- ?r)
-   (if (zerop (logand 128 mode)) ?- ?w)
-   (if (zerop (logand 2048 mode))
-       (if (zerop (logand  64 mode)) ?- ?x)
-     (if (zerop (logand  64 mode)) ?S ?s))
-   (if (zerop (logand  32 mode)) ?- ?r)
-   (if (zerop (logand  16 mode)) ?- ?w)
-   (if (zerop (logand 1024 mode))
-       (if (zerop (logand   8 mode)) ?- ?x)
-     (if (zerop (logand   8 mode)) ?S ?s))
-   (if (zerop (logand   4 mode)) ?- ?r)
-   (if (zerop (logand   2 mode)) ?- ?w)
-   (if (zerop (logand 512 mode))
-       (if (zerop (logand   1 mode)) ?- ?x)
-     (if (zerop (logand   1 mode)) ?T ?t))))
+  (let ((str (substring (file-modes-number-to-symbolic mode) 1)))
+    (unless (zerop (logand 512 mode))
+      (aset mode 8 (if (zerop (logand 1 mode)) ?T ?t)))
+    str))
 
 (defun tar-header-block-summarize (tar-hblock &optional mod-p)
   "Return a line similar to the output of `tar -vtf'."

--8<-----------------------------cut here---------------end--------------->8---
In GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11)
 of 2017-08-04
Repository revision: db5d38ddb0de83d8f920b7a128fe3fd5156fdf85