aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2020-07-10 10:45:14 +0200
committerMichael Albinus2020-07-10 10:45:14 +0200
commit7caf570662e41dd7cb90efaf8a335918cf1ac0da (patch)
tree55413db0575cac14e76f372b9c7710c6ac413217
parent62725e87f25f0049612d251a3cf105ba469c5b91 (diff)
downloademacs-7caf570662e41dd7cb90efaf8a335918cf1ac0da.tar.gz
emacs-7caf570662e41dd7cb90efaf8a335918cf1ac0da.zip
Tramp code cleanup
* lisp/net/tramp.el (tramp-shell-prompt-pattern) (tramp-wrong-passwd-regexp, tramp-method-regexp-alist) (tramp-domain-regexp, tramp-host-regexp, tramp-ipv6-regexp) (tramp-port-regexp, tramp-debug-outline-regexp) (tramp-drop-volume-letter, tramp-parse-shostkeys) (tramp-handle-file-name-case-insensitive-p): * lisp/net/tramp-adb.el (tramp-adb-send-command-and-check): * lisp/net/tramp-ftp.el (tramp-ftp-enable-ange-ftp): * lisp/net/tramp-gvfs.el (tramp-gvfs-monitor-process-filter): * lisp/net/tramp-sh.el (tramp-display-escape-sequence-regexp) (tramp-device-escape-sequence-regexp): * lisp/net/tramp-smb.el (tramp-smb-do-file-attributes-with-stat) (tramp-smb-handle-set-file-acl, tramp-smb-read-file-entry): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-file-selinux-context): Use character classes in regexp. * lisp/net/tramp-adb.el (tramp-adb-ls-date-year-regexp) (tramp-adb-ls-date-time-regexp): New defconst. (tramp-adb-ls-date-regexp, tramp-adb-ls-toolbox-regexp) (tramp-adb-sh-fix-ls-output): Use them. (tramp-adb-handle-set-file-times, tramp-adb-maybe-open-connection): Apply `eval-when-compile' on constant concat data. (tramp-do-parse-file-attributes-with-ls): Suppress `signal-hook-function'. (tramp-adb--gnu-switches-to-ash): Remove unused function. (tramp-adb-handle-set-file-modes): Qhote argument. (tramp-adb-maybe-open-connection): Set file property rather than flush. * lisp/net/tramp-cmds.el (tramp-rename-these-files): Apply `eval-when-compile' on constant concat data. * lisp/net/tramp-gvfs.el (tramp-gvfs-file-attributes) (tramp-gvfs-file-attributes-with-gvfs-ls-regexp): Embed them in `eval-and-compile'. (tramp-gvfs-get-directory-attributes): Apply `eval-when-compile' on constant concat data.
-rw-r--r--lisp/net/tramp-adb.el86
-rw-r--r--lisp/net/tramp-cmds.el5
-rw-r--r--lisp/net/tramp-ftp.el4
-rw-r--r--lisp/net/tramp-gvfs.el67
-rw-r--r--lisp/net/tramp-sh.el10
-rw-r--r--lisp/net/tramp-smb.el52
-rw-r--r--lisp/net/tramp-sudoedit.el4
-rw-r--r--lisp/net/tramp.el36
8 files changed, 154 insertions, 110 deletions
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index a7a5047ed49..3c97efa9a5b 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -62,8 +62,21 @@ It is used for TCP/IP devices."
62 :version "24.4" 62 :version "24.4"
63 :group 'tramp) 63 :group 'tramp)
64 64
65(eval-and-compile
66 (defconst tramp-adb-ls-date-year-regexp
67 "[[:digit:]]\\{4\\}-[[:digit:]]\\{2\\}-[[:digit:]]\\{2\\}"
68 "Regexp for date year format in ls output."))
69
70(eval-and-compile
71 (defconst tramp-adb-ls-date-time-regexp
72 "[[:digit:]]\\{2\\}:[[:digit:]]\\{2\\}"
73 "Regexp for date time format in ls output."))
74
65(defconst tramp-adb-ls-date-regexp 75(defconst tramp-adb-ls-date-regexp
66 "[[:space:]][0-9]\\{4\\}-[0-9][0-9]-[0-9][0-9][[:space:]][0-9][0-9]:[0-9][0-9][[:space:]]" 76 (concat
77 "[[:space:]]" tramp-adb-ls-date-year-regexp
78 "[[:space:]]" tramp-adb-ls-date-time-regexp
79 "[[:space:]]")
67 "Regexp for date format in ls output.") 80 "Regexp for date format in ls output.")
68 81
69(defconst tramp-adb-ls-toolbox-regexp 82(defconst tramp-adb-ls-toolbox-regexp
@@ -73,7 +86,8 @@ It is used for TCP/IP devices."
73 "[[:space:]]*\\([^[:space:]]+\\)" ; \2 username 86 "[[:space:]]*\\([^[:space:]]+\\)" ; \2 username
74 "[[:space:]]+\\([^[:space:]]+\\)" ; \3 group 87 "[[:space:]]+\\([^[:space:]]+\\)" ; \3 group
75 "[[:space:]]+\\([[:digit:]]+\\)" ; \4 size 88 "[[:space:]]+\\([[:digit:]]+\\)" ; \4 size
76 "[[:space:]]+\\([-[:digit:]]+[[:space:]][:[:digit:]]+\\)" ; \5 date 89 "[[:space:]]+\\(" tramp-adb-ls-date-year-regexp
90 "[[:space:]]" tramp-adb-ls-date-time-regexp "\\)" ; \5 date
77 "[[:space:]]\\(.*\\)$") ; \6 filename 91 "[[:space:]]\\(.*\\)$") ; \6 filename
78 "Regexp for ls output.") 92 "Regexp for ls output.")
79 93
@@ -272,7 +286,9 @@ ARGUMENTS to pass to the OPERATION."
272 (if (eq id-format 'integer) 0 uid) 286 (if (eq id-format 'integer) 0 uid)
273 (if (eq id-format 'integer) 0 gid) 287 (if (eq id-format 'integer) 0 gid)
274 tramp-time-dont-know ; atime 288 tramp-time-dont-know ; atime
275 (date-to-time date) ; mtime 289 ;; `date-to-time' checks `iso8601-parse', which might fail.
290 (let (signal-hook-function)
291 (date-to-time date)) ; mtime
276 tramp-time-dont-know ; ctime 292 tramp-time-dont-know ; ctime
277 size 293 size
278 mod-string 294 mod-string
@@ -351,21 +367,6 @@ ARGUMENTS to pass to the OPERATION."
351 "ls --color=never") 367 "ls --color=never")
352 (t "ls")))) 368 (t "ls"))))
353 369
354(defun tramp-adb--gnu-switches-to-ash (switches)
355 "Almquist shell can't handle multiple arguments.
356Convert (\"-al\") to (\"-a\" \"-l\"). Remove arguments like \"--dired\"."
357 (split-string
358 (apply #'concat
359 (mapcar (lambda (s)
360 (replace-regexp-in-string
361 "\\(.\\)" " -\\1" (replace-regexp-in-string "^-" "" s)))
362 ;; FIXME: Warning about removed switches (long and non-dash).
363 (delq nil
364 (mapcar
365 (lambda (s)
366 (and (not (string-match-p "\\(^--\\|^[^-]\\)" s)) s))
367 switches))))))
368
369(defun tramp-adb-sh-fix-ls-output (&optional sort-by-time) 370(defun tramp-adb-sh-fix-ls-output (&optional sort-by-time)
370 "Insert dummy 0 in empty size columns. 371 "Insert dummy 0 in empty size columns.
371Android's \"ls\" command doesn't insert size column for directories: 372Android's \"ls\" command doesn't insert size column for directories:
@@ -375,10 +376,16 @@ Emacs dired can't find files."
375 (goto-char (point-min)) 376 (goto-char (point-min))
376 (while 377 (while
377 (search-forward-regexp 378 (search-forward-regexp
378 "[[:space:]]\\([[:space:]][0-9]\\{4\\}-[0-9][0-9]-[0-9][0-9][[:space:]]\\)" nil t) 379 (eval-when-compile
380 (concat
381 "[[:space:]]"
382 "\\([[:space:]]" tramp-adb-ls-date-year-regexp "[[:space:]]\\)"))
383 nil t)
379 (replace-match "0\\1" "\\1" nil) 384 (replace-match "0\\1" "\\1" nil)
380 ;; Insert missing "/". 385 ;; Insert missing "/".
381 (when (looking-at-p "[0-9][0-9]:[0-9][0-9][[:space:]]+$") 386 (when (looking-at-p
387 (eval-when-compile
388 (concat tramp-adb-ls-date-time-regexp "[[:space:]]+$")))
382 (end-of-line) 389 (end-of-line)
383 (insert "/"))) 390 (insert "/")))
384 ;; Sort entries. 391 ;; Sort entries.
@@ -577,7 +584,7 @@ But handle the case, if the \"test\" command is not available."
577 (unless (and (eq flag 'nofollow) (file-symlink-p filename)) 584 (unless (and (eq flag 'nofollow) (file-symlink-p filename))
578 (tramp-flush-file-properties v localname) 585 (tramp-flush-file-properties v localname)
579 (tramp-adb-send-command-and-check 586 (tramp-adb-send-command-and-check
580 v (format "chmod %o %s" mode localname))))) 587 v (format "chmod %o %s" mode (tramp-shell-quote-argument localname))))))
581 588
582(defun tramp-adb-handle-set-file-times (filename &optional time flag) 589(defun tramp-adb-handle-set-file-times (filename &optional time flag)
583 "Like `set-file-times' for Tramp files." 590 "Like `set-file-times' for Tramp files."
@@ -595,15 +602,17 @@ But handle the case, if the \"test\" command is not available."
595 ;; fails. Also, fall back on old POSIX 'touch -t' if 'touch -d' 602 ;; fails. Also, fall back on old POSIX 'touch -t' if 'touch -d'
596 ;; (introduced in POSIX.1-2008) fails. 603 ;; (introduced in POSIX.1-2008) fails.
597 (tramp-adb-send-command-and-check 604 (tramp-adb-send-command-and-check
598 v (format (concat "touch -d %s %s %s 2>/dev/null || " 605 v (format
599 "touch -d %s %s %s 2>/dev/null || " 606 (eval-when-compile
600 "touch -t %s %s %s") 607 (concat "touch -d %s %s %s 2>/dev/null || "
601 (format-time-string "%Y-%m-%dT%H:%M:%S.%NZ" time t) 608 "touch -d %s %s %s 2>/dev/null || "
602 nofollow quoted-name 609 "touch -t %s %s %s"))
603 (format-time-string "%Y-%m-%dT%H:%M:%S" time t) 610 (format-time-string "%Y-%m-%dT%H:%M:%S.%NZ" time t)
604 nofollow quoted-name 611 nofollow quoted-name
605 (format-time-string "%Y%m%d%H%M.%S" time t) 612 (format-time-string "%Y-%m-%dT%H:%M:%S" time t)
606 nofollow quoted-name))))) 613 nofollow quoted-name
614 (format-time-string "%Y%m%d%H%M.%S" time t)
615 nofollow quoted-name)))))
607 616
608(defun tramp-adb-handle-copy-file 617(defun tramp-adb-handle-copy-file
609 (filename newname &optional ok-if-already-exists keep-date 618 (filename newname &optional ok-if-already-exists keep-date
@@ -1108,7 +1117,7 @@ the exit status."
1108 (format "%s; echo tramp_exit_status $?" command) 1117 (format "%s; echo tramp_exit_status $?" command)
1109 "echo tramp_exit_status $?")) 1118 "echo tramp_exit_status $?"))
1110 (with-current-buffer (tramp-get-connection-buffer vec) 1119 (with-current-buffer (tramp-get-connection-buffer vec)
1111 (unless (tramp-search-regexp "tramp_exit_status [0-9]+") 1120 (unless (tramp-search-regexp "tramp_exit_status [[:digit:]]+")
1112 (tramp-error 1121 (tramp-error
1113 vec 'file-error "Couldn't find exit status of `%s'" command)) 1122 vec 'file-error "Couldn't find exit status of `%s'" command))
1114 (skip-chars-forward "^ ") 1123 (skip-chars-forward "^ ")
@@ -1217,7 +1226,12 @@ connection if a previous connection has died for some reason."
1217 ;; connection properties. We start again. 1226 ;; connection properties. We start again.
1218 (tramp-message vec 5 "Checking system information") 1227 (tramp-message vec 5 "Checking system information")
1219 (tramp-adb-send-command 1228 (tramp-adb-send-command
1220 vec "echo \\\"`getprop ro.product.model` `getprop ro.product.version` `getprop ro.build.version.release`\\\"") 1229 vec
1230 (eval-when-compile
1231 (concat
1232 "echo \\\"`getprop ro.product.model` "
1233 "`getprop ro.product.version` "
1234 "`getprop ro.build.version.release`\\\"")))
1221 (let ((old-getprop 1235 (let ((old-getprop
1222 (tramp-get-connection-property vec "getprop" nil)) 1236 (tramp-get-connection-property vec "getprop" nil))
1223 (new-getprop 1237 (new-getprop
@@ -1241,7 +1255,8 @@ connection if a previous connection has died for some reason."
1241 (tramp-adb-send-command vec (format "su %s" user)) 1255 (tramp-adb-send-command vec (format "su %s" user))
1242 (unless (tramp-adb-send-command-and-check vec nil) 1256 (unless (tramp-adb-send-command-and-check vec nil)
1243 (delete-process p) 1257 (delete-process p)
1244 (tramp-flush-file-property vec "" "su-command-p") 1258 ;; Do not flush, we need the nil value.
1259 (tramp-set-file-property vec "" "su-command-p" nil)
1245 (tramp-error 1260 (tramp-error
1246 vec 'file-error "Cannot switch to user `%s'" user))) 1261 vec 'file-error "Cannot switch to user `%s'" user)))
1247 1262
@@ -1275,4 +1290,9 @@ connection if a previous connection has died for some reason."
1275 1290
1276(provide 'tramp-adb) 1291(provide 'tramp-adb)
1277 1292
1293;;; TODO:
1294;;
1295;; * Support file names with multibyte codepoints. Use as fallback
1296;; "adb shell COMMAND".
1297;;
1278;;; tramp-adb.el ends here 1298;;; tramp-adb.el ends here
diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el
index 2805f6648ce..0ca560a1630 100644
--- a/lisp/net/tramp-cmds.el
+++ b/lisp/net/tramp-cmds.el
@@ -448,8 +448,9 @@ For details, see `tramp-rename-files'."
448 (tramp-user-error 448 (tramp-user-error
449 nil 449 nil
450 (substitute-command-keys 450 (substitute-command-keys
451 (concat "Current buffer is not remote. " 451 (eval-when-compile
452 "Consider `\\[tramp-rename-files]' instead."))) 452 (concat "Current buffer is not remote. "
453 "Consider `\\[tramp-rename-files]' instead."))))
453 (setq target 454 (setq target
454 (when (null current-prefix-arg) 455 (when (null current-prefix-arg)
455 ;; The source remote connection shall not trigger any action. 456 ;; The source remote connection shall not trigger any action.
diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el
index 95ae1569dc9..33d49aa67ff 100644
--- a/lisp/net/tramp-ftp.el
+++ b/lisp/net/tramp-ftp.el
@@ -79,9 +79,9 @@ present for backward compatibility."
79 ;;; This regexp recognizes absolute filenames with only one component 79 ;;; This regexp recognizes absolute filenames with only one component
80 ;;; on Windows, for the sake of hostname completion. 80 ;;; on Windows, for the sake of hostname completion.
81 (and (memq system-type '(ms-dos windows-nt)) 81 (and (memq system-type '(ms-dos windows-nt))
82 (or (assoc "^[a-zA-Z]:/[^/:]*\\'" file-name-handler-alist) 82 (or (assoc "^[[:alpha:]]:/[^/:]*\\'" file-name-handler-alist)
83 (setq file-name-handler-alist 83 (setq file-name-handler-alist
84 (cons '("^[a-zA-Z]:/[^/:]*\\'" . 84 (cons '("^[:alpha:]]:/[^/:]*\\'" .
85 ange-ftp-completion-hook-function) 85 ange-ftp-completion-hook-function)
86 file-name-handler-alist))))) 86 file-name-handler-alist)))))
87 87
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index dce6edd19c4..4193faabb27 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -697,32 +697,34 @@ It has been changed in GVFS 1.14.")
697 "List of cons cells, mapping \"gvfs-<command>\" to \"gio <command>\".") 697 "List of cons cells, mapping \"gvfs-<command>\" to \"gio <command>\".")
698 698
699;; <http://www.pygtk.org/docs/pygobject/gio-constants.html> 699;; <http://www.pygtk.org/docs/pygobject/gio-constants.html>
700(defconst tramp-gvfs-file-attributes 700(eval-and-compile
701 '("name" 701 (defconst tramp-gvfs-file-attributes
702 "type" 702 '("name"
703 "standard::display-name" 703 "type"
704 "standard::symlink-target" 704 "standard::display-name"
705 "standard::is-volatile" 705 "standard::symlink-target"
706 "unix::nlink" 706 "standard::is-volatile"
707 "unix::uid" 707 "unix::nlink"
708 "owner::user" 708 "unix::uid"
709 "unix::gid" 709 "owner::user"
710 "owner::group" 710 "unix::gid"
711 "time::access" 711 "owner::group"
712 "time::modified" 712 "time::access"
713 "time::changed" 713 "time::modified"
714 "standard::size" 714 "time::changed"
715 "unix::mode" 715 "standard::size"
716 "access::can-read" 716 "unix::mode"
717 "access::can-write" 717 "access::can-read"
718 "access::can-execute" 718 "access::can-write"
719 "unix::inode" 719 "access::can-execute"
720 "unix::device") 720 "unix::inode"
721 "GVFS file attributes.") 721 "unix::device")
722 722 "GVFS file attributes."))
723(defconst tramp-gvfs-file-attributes-with-gvfs-ls-regexp 723
724 (concat "[[:blank:]]" (regexp-opt tramp-gvfs-file-attributes t) "=\\(.+?\\)") 724(eval-and-compile
725 "Regexp to parse GVFS file attributes with `gvfs-ls'.") 725 (defconst tramp-gvfs-file-attributes-with-gvfs-ls-regexp
726 (concat "[[:blank:]]" (regexp-opt tramp-gvfs-file-attributes t) "=\\(.+?\\)")
727 "Regexp to parse GVFS file attributes with `gvfs-ls'."))
726 728
727(defconst tramp-gvfs-file-attributes-with-gvfs-info-regexp 729(defconst tramp-gvfs-file-attributes-with-gvfs-info-regexp
728 (concat "^[[:blank:]]*" 730 (concat "^[[:blank:]]*"
@@ -1181,10 +1183,11 @@ file names."
1181 (with-current-buffer (tramp-get-connection-buffer v) 1183 (with-current-buffer (tramp-get-connection-buffer v)
1182 (goto-char (point-min)) 1184 (goto-char (point-min))
1183 (while (looking-at 1185 (while (looking-at
1184 (concat "^\\(.+\\)[[:blank:]]" 1186 (eval-when-compile
1185 "\\([[:digit:]]+\\)[[:blank:]]" 1187 (concat "^\\(.+\\)[[:blank:]]"
1186 "(\\(.+?\\))" 1188 "\\([[:digit:]]+\\)[[:blank:]]"
1187 tramp-gvfs-file-attributes-with-gvfs-ls-regexp)) 1189 "(\\(.+?\\))"
1190 tramp-gvfs-file-attributes-with-gvfs-ls-regexp)))
1188 (let ((item (list (cons "type" (match-string 3)) 1191 (let ((item (list (cons "type" (match-string 3))
1189 (cons "standard::size" (match-string 2)) 1192 (cons "standard::size" (match-string 2))
1190 (cons "name" (match-string 1))))) 1193 (cons "name" (match-string 1)))))
@@ -1475,11 +1478,11 @@ If FILE-SYSTEM is non-nil, return file system attributes."
1475 ;; File names are returned as URL paths. We must convert them. 1478 ;; File names are returned as URL paths. We must convert them.
1476 (when (string-match ddu file) 1479 (when (string-match ddu file)
1477 (setq file (replace-match dd nil nil file))) 1480 (setq file (replace-match dd nil nil file)))
1478 (while (string-match-p "%\\([0-9A-F]\\{2\\}\\)" file) 1481 (while (string-match-p "%\\([[:xdigit:]]\\{2\\}\\)" file)
1479 (setq file (url-unhex-string file))) 1482 (setq file (url-unhex-string file)))
1480 (when (string-match ddu (or file1 "")) 1483 (when (string-match ddu (or file1 ""))
1481 (setq file1 (replace-match dd nil nil file1))) 1484 (setq file1 (replace-match dd nil nil file1)))
1482 (while (string-match-p "%\\([0-9A-F]\\{2\\}\\)" (or file1 "")) 1485 (while (string-match-p "%\\([[:xdigit:]]\\{2\\}\\)" (or file1 ""))
1483 (setq file1 (url-unhex-string file1))) 1486 (setq file1 (url-unhex-string file1)))
1484 ;; Remove watch when file or directory to be watched is deleted. 1487 ;; Remove watch when file or directory to be watched is deleted.
1485 (when (and (member action '(moved deleted)) 1488 (when (and (member action '(moved deleted))
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 89e5dc9e658..370244fd469 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -90,10 +90,10 @@ the default storage location, e.g. \"$HOME/.sh_history\"."
90 (string :tag "Redirect to a file"))) 90 (string :tag "Redirect to a file")))
91 91
92;;;###tramp-autoload 92;;;###tramp-autoload
93(defconst tramp-display-escape-sequence-regexp "\e[[;0-9]+m" 93(defconst tramp-display-escape-sequence-regexp "\e[[:digit:];[]+m"
94 "Terminal control escape sequences for display attributes.") 94 "Terminal control escape sequences for display attributes.")
95 95
96(defconst tramp-device-escape-sequence-regexp "\e[[0-9]+n" 96(defconst tramp-device-escape-sequence-regexp "\e[[:digit:][]+n"
97 "Terminal control escape sequences for device status.") 97 "Terminal control escape sequences for device status.")
98 98
99;; ksh on OpenBSD 4.5 requires that $PS1 contains a `#' character for 99;; ksh on OpenBSD 4.5 requires that $PS1 contains a `#' character for
@@ -1515,8 +1515,8 @@ ID-FORMAT valid values are `string' and `integer'."
1515 (with-tramp-file-property v localname "file-selinux-context" 1515 (with-tramp-file-property v localname "file-selinux-context"
1516 (let ((context '(nil nil nil nil)) 1516 (let ((context '(nil nil nil nil))
1517 (regexp (eval-when-compile 1517 (regexp (eval-when-compile
1518 (concat "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\):" 1518 (concat "\\([[:alnum:]_]+\\):" "\\([[:alnum:]_]+\\):"
1519 "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\)")))) 1519 "\\([[:alnum:]_]+\\):" "\\([[:alnum]_]+\\)"))))
1520 (when (and (tramp-remote-selinux-p v) 1520 (when (and (tramp-remote-selinux-p v)
1521 (tramp-send-command-and-check 1521 (tramp-send-command-and-check
1522 v (format 1522 v (format
@@ -5223,7 +5223,7 @@ the exit status."
5223 "echo tramp_exit_status $?" 5223 "echo tramp_exit_status $?"
5224 (if subshell " )" ""))) 5224 (if subshell " )" "")))
5225 (with-current-buffer (tramp-get-connection-buffer vec) 5225 (with-current-buffer (tramp-get-connection-buffer vec)
5226 (unless (tramp-search-regexp "tramp_exit_status [0-9]+") 5226 (unless (tramp-search-regexp "tramp_exit_status [[:digit:]]+")
5227 (tramp-error 5227 (tramp-error
5228 vec 'file-error "Couldn't find exit status of `%s'" command)) 5228 vec 'file-error "Couldn't find exit status of `%s'" command))
5229 (skip-chars-forward "^ ") 5229 (skip-chars-forward "^ ")
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 947e6a767c7..b1205164b7c 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -875,23 +875,34 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
875 (while (not (eobp)) 875 (while (not (eobp))
876 (cond 876 (cond
877 ((looking-at 877 ((looking-at
878 "Size:\\s-+\\([0-9]+\\)\\s-+Blocks:\\s-+[0-9]+\\s-+\\(\\w+\\)") 878 (eval-when-compile
879 (concat
880 "Size:\\s-+\\([[:digit:]]+\\)\\s-+"
881 "Blocks:\\s-+[[:digit:]]+\\s-+\\(\\w+\\)")))
879 (setq size (string-to-number (match-string 1)) 882 (setq size (string-to-number (match-string 1))
880 id (if (string-equal "directory" (match-string 2)) t 883 id (if (string-equal "directory" (match-string 2)) t
881 (if (string-equal "symbolic" (match-string 2)) "")))) 884 (if (string-equal "symbolic" (match-string 2)) ""))))
882 ((looking-at 885 ((looking-at
883 "Inode:\\s-+\\([0-9]+\\)\\s-+Links:\\s-+\\([0-9]+\\)") 886 "Inode:\\s-+\\([[:digit:]]+\\)\\s-+Links:\\s-+\\([[:digit:]]+\\)")
884 (setq inode (string-to-number (match-string 1)) 887 (setq inode (string-to-number (match-string 1))
885 link (string-to-number (match-string 2)))) 888 link (string-to-number (match-string 2))))
886 ((looking-at 889 ((looking-at
887 "Access:\\s-+([0-9]+/\\(\\S-+\\))\\s-+Uid:\\s-+\\([0-9]+\\)\\s-+Gid:\\s-+\\([0-9]+\\)") 890 (eval-when-compile
891 (concat
892 "Access:\\s-+([[:digit:]]+/\\(\\S-+\\))\\s-+"
893 "Uid:\\s-+\\([[:digit:]]+\\)\\s-+"
894 "Gid:\\s-+\\([[:digit:]]+\\)")))
888 (setq mode (match-string 1) 895 (setq mode (match-string 1)
889 uid (if (equal id-format 'string) (match-string 2) 896 uid (if (equal id-format 'string) (match-string 2)
890 (string-to-number (match-string 2))) 897 (string-to-number (match-string 2)))
891 gid (if (equal id-format 'string) (match-string 3) 898 gid (if (equal id-format 'string) (match-string 3)
892 (string-to-number (match-string 3))))) 899 (string-to-number (match-string 3)))))
893 ((looking-at 900 ((looking-at
894 "Access:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") 901 (eval-when-compile
902 (concat
903 "Access:\\s-+"
904 "\\([[:digit:]]+\\)-\\([[:digit:]]+\\)-\\([[:digit:]]+\\)\\s-+"
905 "\\([[:digit:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)")))
895 (setq atime 906 (setq atime
896 (encode-time 907 (encode-time
897 (string-to-number (match-string 6)) ;; sec 908 (string-to-number (match-string 6)) ;; sec
@@ -901,7 +912,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
901 (string-to-number (match-string 2)) ;; month 912 (string-to-number (match-string 2)) ;; month
902 (string-to-number (match-string 1))))) ;; year 913 (string-to-number (match-string 1))))) ;; year
903 ((looking-at 914 ((looking-at
904 "Modify:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") 915 (eval-when-compile
916 (concat
917 "Modify:\\s-+"
918 "\\([[:digit:]]+\\)-\\([[:digit:]]+\\)-\\([[:digit:]]+\\)\\s-+"
919 "\\([[:digit:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)")))
905 (setq mtime 920 (setq mtime
906 (encode-time 921 (encode-time
907 (string-to-number (match-string 6)) ;; sec 922 (string-to-number (match-string 6)) ;; sec
@@ -911,7 +926,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
911 (string-to-number (match-string 2)) ;; month 926 (string-to-number (match-string 2)) ;; month
912 (string-to-number (match-string 1))))) ;; year 927 (string-to-number (match-string 1))))) ;; year
913 ((looking-at 928 ((looking-at
914 "Change:\\s-+\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\)\\s-+\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)") 929 (eval-when-compile
930 (concat
931 "Change:\\s-+"
932 "\\([[:digit:]]+\\)-\\([[:digit:]]+\\)-\\([[:digit:]]+\\)\\s-+"
933 "\\([[:digit:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)")))
915 (setq ctime 934 (setq ctime
916 (encode-time 935 (encode-time
917 (string-to-number (match-string 6)) ;; sec 936 (string-to-number (match-string 6)) ;; sec
@@ -1474,7 +1493,7 @@ component is used as the target of the symlink."
1474 ;; This is meant for traces, and returning from the 1493 ;; This is meant for traces, and returning from the
1475 ;; function. No error is propagated outside, due to 1494 ;; function. No error is propagated outside, due to
1476 ;; the `ignore-errors' closure. 1495 ;; the `ignore-errors' closure.
1477 (unless (tramp-search-regexp "tramp_exit_status [0-9]+") 1496 (unless (tramp-search-regexp "tramp_exit_status [[:digit:]]+")
1478 (tramp-error 1497 (tramp-error
1479 v 'file-error 1498 v 'file-error
1480 "Couldn't find exit status of `%s'" tramp-smb-acl-program)) 1499 "Couldn't find exit status of `%s'" tramp-smb-acl-program))
@@ -1719,21 +1738,21 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)."
1719;; Entries provided by smbclient DIR aren't fully regular. 1738;; Entries provided by smbclient DIR aren't fully regular.
1720;; They should have the format 1739;; They should have the format
1721;; 1740;;
1722;; \s-\{2,2} - leading spaces 1741;; \s-\{2,2\} - leading spaces
1723;; \S-\(.*\S-\)\s-* - file name, 30 chars, left bound 1742;; \S-\(.*\S-\)\s-* - file name, 30 chars, left bound
1724;; \s-+[ADHRSV]* - permissions, 7 chars, right bound 1743;; \s-+[ADHRSV]* - permissions, 7 chars, right bound
1725;; \s- - space delimiter 1744;; \s- - space delimiter
1726;; \s-+[0-9]+ - size, 8 chars, right bound 1745;; \s-+[[:digit:]]+ - size, 8 chars, right bound
1727;; \s-\{2,2\} - space delimiter 1746;; \s-\{2,2\} - space delimiter
1728;; \w\{3,3\} - weekday 1747;; \w\{3,3\} - weekday
1729;; \s- - space delimiter 1748;; \s- - space delimiter
1730;; \w\{3,3\} - month 1749;; \w\{3,3\} - month
1731;; \s- - space delimiter 1750;; \s- - space delimiter
1732;; [ 12][0-9] - day 1751;; [ 12][[:digit:]] - day
1733;; \s- - space delimiter 1752;; \s- - space delimiter
1734;; [0-9]\{2,2\}:[0-9]\{2,2\}:[0-9]\{2,2\} - time 1753;; [[:digit:]]\{2,2\}:[[:digit:]]\{2,2\}:[[:digit:]]\{2,2\} - time
1735;; \s- - space delimiter 1754;; \s- - space delimiter
1736;; [0-9]\{4,4\} - year 1755;; [[:digit:]]\{4,4\} - year
1737;; 1756;;
1738;; samba/src/client.c (http://samba.org/doxygen/samba/client_8c-source.html) 1757;; samba/src/client.c (http://samba.org/doxygen/samba/client_8c-source.html)
1739;; has function display_finfo: 1758;; has function display_finfo:
@@ -1781,13 +1800,14 @@ are listed. Result is the list (LOCALNAME MODE SIZE MTIME)."
1781 (cl-block nil 1800 (cl-block nil
1782 1801
1783 ;; year. 1802 ;; year.
1784 (if (string-match "\\([0-9]+\\)$" line) 1803 (if (string-match "\\([[:digit:]]+\\)$" line)
1785 (setq year (string-to-number (match-string 1 line)) 1804 (setq year (string-to-number (match-string 1 line))
1786 line (substring line 0 -5)) 1805 line (substring line 0 -5))
1787 (cl-return)) 1806 (cl-return))
1788 1807
1789 ;; time. 1808 ;; time.
1790 (if (string-match "\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\)$" line) 1809 (if (string-match
1810 "\\([[:digit:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\)$" line)
1791 (setq hour (string-to-number (match-string 1 line)) 1811 (setq hour (string-to-number (match-string 1 line))
1792 min (string-to-number (match-string 2 line)) 1812 min (string-to-number (match-string 2 line))
1793 sec (string-to-number (match-string 3 line)) 1813 sec (string-to-number (match-string 3 line))
@@ -1795,7 +1815,7 @@ are listed. Result is the list (LOCALNAME MODE SIZE MTIME)."
1795 (cl-return)) 1815 (cl-return))
1796 1816
1797 ;; day. 1817 ;; day.
1798 (if (string-match "\\([0-9]+\\)$" line) 1818 (if (string-match "\\([[:digit:]]+\\)$" line)
1799 (setq day (string-to-number (match-string 1 line)) 1819 (setq day (string-to-number (match-string 1 line))
1800 line (substring line 0 -3)) 1820 line (substring line 0 -3))
1801 (cl-return)) 1821 (cl-return))
@@ -1812,7 +1832,7 @@ are listed. Result is the list (LOCALNAME MODE SIZE MTIME)."
1812 (cl-return)) 1832 (cl-return))
1813 1833
1814 ;; size. 1834 ;; size.
1815 (if (string-match "\\([0-9]+\\)$" line) 1835 (if (string-match "\\([[:digit:]]+\\)$" line)
1816 (let ((length (- (max 10 (1+ (length (match-string 1 line))))))) 1836 (let ((length (- (max 10 (1+ (length (match-string 1 line)))))))
1817 (setq size (string-to-number (match-string 1 line))) 1837 (setq size (string-to-number (match-string 1 line)))
1818 (when (string-match 1838 (when (string-match
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index 05242ffd970..29d419e7c28 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -489,8 +489,8 @@ the result will be a local, non-Tramp, file name."
489 (with-tramp-file-property v localname "file-selinux-context" 489 (with-tramp-file-property v localname "file-selinux-context"
490 (let ((context '(nil nil nil nil)) 490 (let ((context '(nil nil nil nil))
491 (regexp (eval-when-compile 491 (regexp (eval-when-compile
492 (concat "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\):" 492 (concat "\\([[:alnum:]_]+\\):" "\\([[:alnum:]_]+\\):"
493 "\\([a-z0-9_]+\\):" "\\([a-z0-9_]+\\)")))) 493 "\\([[:alnum:]_]+\\):" "\\([[:alnum:]_]+\\)"))))
494 (when (and (tramp-sudoedit-remote-selinux-p v) 494 (when (and (tramp-sudoedit-remote-selinux-p v)
495 (tramp-sudoedit-send-command 495 (tramp-sudoedit-send-command
496 v "ls" "-d" "-Z" 496 v "ls" "-d" "-Z"
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 1566162feaf..1e7f2b53da2 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -560,7 +560,7 @@ Sometimes the prompt is reported to look like \"login as:\"."
560 ;; Allow also [] style prompts. They can appear only during 560 ;; Allow also [] style prompts. They can appear only during
561 ;; connection initialization; Tramp redefines the prompt afterwards. 561 ;; connection initialization; Tramp redefines the prompt afterwards.
562 (concat "\\(?:^\\|\r\\)" 562 (concat "\\(?:^\\|\r\\)"
563 "[^]#$%>\n]*#?[]#$%>] *\\(\e\\[[0-9;]*[a-zA-Z] *\\)*") 563 "[^]#$%>\n]*#?[]#$%>] *\\(\e\\[[[:digit:];]*[[:alpha:]] *\\)*")
564 "Regexp to match prompts from remote shell. 564 "Regexp to match prompts from remote shell.
565Normally, Tramp expects you to configure `shell-prompt-pattern' 565Normally, Tramp expects you to configure `shell-prompt-pattern'
566correctly, but sometimes it happens that you are connecting to a 566correctly, but sometimes it happens that you are connecting to a
@@ -601,7 +601,7 @@ The `sudo' program appears to insert a `^@' character into the prompt."
601 "\\|" 601 "\\|"
602 "^.*\\(" 602 "^.*\\("
603 ;; Here comes a list of regexes, separated by \\| 603 ;; Here comes a list of regexes, separated by \\|
604 "Received signal [0-9]+" 604 "Received signal [[:digit:]]+"
605 "\\).*") 605 "\\).*")
606 "Regexp matching a `login failed' message. 606 "Regexp matching a `login failed' message.
607The regexp should match at end of buffer." 607The regexp should match at end of buffer."
@@ -797,9 +797,9 @@ Used in `tramp-make-tramp-file-name'.")
797Should always start with \"^\". Derived from `tramp-prefix-format'.") 797Should always start with \"^\". Derived from `tramp-prefix-format'.")
798 798
799(defconst tramp-method-regexp-alist 799(defconst tramp-method-regexp-alist
800 '((default . "[a-zA-Z0-9-]+") 800 '((default . "[[:alnum:]-]+")
801 (simplified . "") 801 (simplified . "")
802 (separate . "[a-zA-Z0-9-]*")) 802 (separate . "[[:alnum:]-]*"))
803 "Alist mapping Tramp syntax to regexps matching methods identifiers.") 803 "Alist mapping Tramp syntax to regexps matching methods identifiers.")
804 804
805(defun tramp-build-method-regexp () 805(defun tramp-build-method-regexp ()
@@ -843,7 +843,7 @@ Derived from `tramp-postfix-method-format'.")
843 "Regexp matching delimiter between user and domain names. 843 "Regexp matching delimiter between user and domain names.
844Derived from `tramp-prefix-domain-format'.") 844Derived from `tramp-prefix-domain-format'.")
845 845
846(defconst tramp-domain-regexp "[a-zA-Z0-9_.-]+" 846(defconst tramp-domain-regexp "[[:alnum:]_.-]+"
847 "Regexp matching domain names.") 847 "Regexp matching domain names.")
848 848
849(defconst tramp-user-with-domain-regexp 849(defconst tramp-user-with-domain-regexp
@@ -860,7 +860,7 @@ Used in `tramp-make-tramp-file-name'.")
860 "Regexp matching delimiter between user and host names. 860 "Regexp matching delimiter between user and host names.
861Derived from `tramp-postfix-user-format'.") 861Derived from `tramp-postfix-user-format'.")
862 862
863(defconst tramp-host-regexp "[a-zA-Z0-9_.%-]+" 863(defconst tramp-host-regexp "[[:alnum:]_.%-]+"
864 "Regexp matching host names.") 864 "Regexp matching host names.")
865 865
866(defconst tramp-prefix-ipv6-format-alist 866(defconst tramp-prefix-ipv6-format-alist
@@ -888,7 +888,7 @@ Derived from `tramp-prefix-ipv6-format'.")
888;; The following regexp is a bit sloppy. But it shall serve our 888;; The following regexp is a bit sloppy. But it shall serve our
889;; purposes. It covers also IPv4 mapped IPv6 addresses, like in 889;; purposes. It covers also IPv4 mapped IPv6 addresses, like in
890;; "::ffff:192.168.0.1". 890;; "::ffff:192.168.0.1".
891(defconst tramp-ipv6-regexp "\\(?:[a-zA-Z0-9]*:\\)+[a-zA-Z0-9.]+" 891(defconst tramp-ipv6-regexp "\\(?:[[:alnum:]]*:\\)+[[:alnum:].]+"
892 "Regexp matching IPv6 addresses.") 892 "Regexp matching IPv6 addresses.")
893 893
894(defconst tramp-postfix-ipv6-format-alist 894(defconst tramp-postfix-ipv6-format-alist
@@ -920,7 +920,7 @@ Derived from `tramp-postfix-ipv6-format'.")
920 "Regexp matching delimiter between host names and port numbers. 920 "Regexp matching delimiter between host names and port numbers.
921Derived from `tramp-prefix-port-format'.") 921Derived from `tramp-prefix-port-format'.")
922 922
923(defconst tramp-port-regexp "[0-9]+" 923(defconst tramp-port-regexp "[[:digit:]]+"
924 "Regexp matching port numbers.") 924 "Regexp matching port numbers.")
925 925
926(defconst tramp-host-with-port-regexp 926(defconst tramp-host-with-port-regexp
@@ -1684,11 +1684,10 @@ version, the function does nothing."
1684 (format "*debug tramp/%s %s*" method host-port)))) 1684 (format "*debug tramp/%s %s*" method host-port))))
1685 1685
1686(defconst tramp-debug-outline-regexp 1686(defconst tramp-debug-outline-regexp
1687 (eval-when-compile 1687 (concat
1688 (concat 1688 "[[:digit:]]+:[[:digit:]]+:[[:digit:]]+\\.[[:digit:]]+ " ;; Timestamp.
1689 "[0-9]+:[0-9]+:[0-9]+\\.[0-9]+ " ;; Timestamp. 1689 "\\(?:\\(#<thread .+>\\) \\)?" ;; Thread.
1690 "\\(?:\\(#<thread .+>\\) \\)?" ;; Thread. 1690 "[[:alnum:]-]+ (\\([[:digit:]]+\\)) #") ;; Function name, verbosity.
1691 "[a-z0-9-]+ (\\([0-9]+\\)) #")) ;; Function name, verbosity.
1692 "Used for highlighting Tramp debug buffers in `outline-mode'.") 1691 "Used for highlighting Tramp debug buffers in `outline-mode'.")
1693 1692
1694(defconst tramp-debug-font-lock-keywords 1693(defconst tramp-debug-font-lock-keywords
@@ -2074,7 +2073,7 @@ letter into the file name. This function removes it."
2074 (save-match-data 2073 (save-match-data
2075 (let ((quoted (tramp-compat-file-name-quoted-p name 'top)) 2074 (let ((quoted (tramp-compat-file-name-quoted-p name 'top))
2076 (result (tramp-compat-file-name-unquote name 'top))) 2075 (result (tramp-compat-file-name-unquote name 'top)))
2077 (setq result (if (string-match "\\`[a-zA-Z]:/" result) 2076 (setq result (if (string-match "\\`[[:alpha:]]:/" result)
2078 (replace-match "/" nil t result) result)) 2077 (replace-match "/" nil t result) result))
2079 (if quoted (tramp-compat-file-name-quote result 'top) result)))) 2078 (if quoted (tramp-compat-file-name-quote result 'top) result))))
2080 2079
@@ -2938,7 +2937,7 @@ User is always nil."
2938 "Return a list of (user host) tuples allowed to access. 2937 "Return a list of (user host) tuples allowed to access.
2939User is always nil." 2938User is always nil."
2940 (tramp-parse-shostkeys-sknownhosts 2939 (tramp-parse-shostkeys-sknownhosts
2941 dirname (concat "^key_[0-9]+_\\(" tramp-host-regexp "\\)\\.pub$"))) 2940 dirname (concat "^key_[[:digit:]]+_\\(" tramp-host-regexp "\\)\\.pub$")))
2942 2941
2943(defun tramp-parse-sknownhosts (dirname) 2942(defun tramp-parse-sknownhosts (dirname)
2944 "Return a list of (user host) tuples allowed to access. 2943 "Return a list of (user host) tuples allowed to access.
@@ -3255,12 +3254,13 @@ User is always nil."
3255 (let ((candidate 3254 (let ((candidate
3256 (tramp-compat-file-name-unquote 3255 (tramp-compat-file-name-unquote
3257 (directory-file-name filename))) 3256 (directory-file-name filename)))
3257 case-fold-search
3258 tmpfile) 3258 tmpfile)
3259 ;; Check, whether we find an existing file with 3259 ;; Check, whether we find an existing file with
3260 ;; lower case letters. This avoids us to create a 3260 ;; lower case letters. This avoids us to create a
3261 ;; temporary file. 3261 ;; temporary file.
3262 (while (and (string-match-p 3262 (while (and (string-match-p
3263 "[a-z]" (tramp-file-local-name candidate)) 3263 "[[:lower:]]" (tramp-file-local-name candidate))
3264 (not (file-exists-p candidate))) 3264 (not (file-exists-p candidate)))
3265 (setq candidate 3265 (setq candidate
3266 (directory-file-name 3266 (directory-file-name
@@ -3269,8 +3269,8 @@ User is always nil."
3269 ;; for comparison. `make-nearby-temp-file' is added 3269 ;; for comparison. `make-nearby-temp-file' is added
3270 ;; to Emacs 26+ like `file-name-case-insensitive-p', 3270 ;; to Emacs 26+ like `file-name-case-insensitive-p',
3271 ;; so there is no compatibility problem calling it. 3271 ;; so there is no compatibility problem calling it.
3272 (unless 3272 (unless (string-match-p
3273 (string-match-p "[a-z]" (tramp-file-local-name candidate)) 3273 "[[:lower:]]" (tramp-file-local-name candidate))
3274 (setq tmpfile 3274 (setq tmpfile
3275 (let ((default-directory 3275 (let ((default-directory
3276 (file-name-directory filename))) 3276 (file-name-directory filename)))