diff options
| author | Gemini Lasswell | 2017-08-30 07:11:41 -0700 |
|---|---|---|
| committer | Gemini Lasswell | 2017-09-09 09:06:00 -0700 |
| commit | 68b7ecbac1dcb5bfcace5505a4d354777147dd54 (patch) | |
| tree | 3b9875c47e0deeac4e5a029369381edd69a4cf44 | |
| parent | 2b84c1666274edcb6b810649fa0d6fc09e9e7a66 (diff) | |
| download | emacs-68b7ecbac1dcb5bfcace5505a4d354777147dd54.tar.gz emacs-68b7ecbac1dcb5bfcace5505a4d354777147dd54.zip | |
Reduce Tramp's memory usage
Construct Tramp syntax strings and regular expressions once instead
of every time they are used, and store them in alists keyed by Tramp
syntax.
* tramp.el (tramp-build-remote-file-name-spec-regexp)
(tramp-build-file-name-structure): New functions.
(tramp-prefix-format-alist, tramp-prefix-regexp-alist)
(tramp-method-regexp-alist)
(tramp-postfix-method-format-alist)
(tramp-postfix-method-regexp-alist)
(tramp-prefix-ipv6-format-alist, tramp-prefix-ipv6-regexp-alist)
(tramp-postfix-ipv6-format-alist)
(tramp-postfix-ipv6-regexp-alist)
(tramp-postfix-host-format-alist)
(tramp-postfix-host-regexp-alist)
(tramp-remote-file-name-spec-regexp-alist)
(tramp-file-name-structure-alist): New constants.
(tramp-lookup-syntax): New function.
(tramp-prefix-format, tramp-prefix-regexp, tramp-method-regexp)
(tramp-postfix-method-format, tramp-postfix-method-regexp)
(tramp-prefix-ipv6-format, tramp-prefix-ipv6-regexp)
(tramp-postfix-ipv6-format, tramp-postfix-ipv6-regexp)
(tramp-postfix-host-format, tramp-postfix-host-regexp)
(tramp-remote-file-name-spec-regexp, tramp-file-name-structure):
Use it.
| -rw-r--r-- | lisp/net/tramp.el | 172 |
1 files changed, 127 insertions, 45 deletions
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index f4b69dbc66b..118960be5ed 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -700,40 +700,69 @@ Do not change the value by `setq', it must be changed only by | |||
| 700 | (setq values (mapcar 'last values) | 700 | (setq values (mapcar 'last values) |
| 701 | values (mapcar 'car values)))) | 701 | values (mapcar 'car values)))) |
| 702 | 702 | ||
| 703 | (defun tramp-lookup-syntax (alist) | ||
| 704 | "Look up a syntax string in ALIST according to `tramp-compat-tramp-syntax.' | ||
| 705 | Raise an error if `tramp-syntax' is invalid." | ||
| 706 | (or (cdr (assq (tramp-compat-tramp-syntax) alist)) | ||
| 707 | (error "Wrong `tramp-syntax' %s" tramp-syntax))) | ||
| 708 | |||
| 709 | (defconst tramp-prefix-format-alist | ||
| 710 | '((default . "/") | ||
| 711 | (simplified . "/") | ||
| 712 | (separate . "/[")) | ||
| 713 | "Alist mapping Tramp syntax to strings beginning Tramp file names.") | ||
| 714 | |||
| 703 | (defun tramp-prefix-format () | 715 | (defun tramp-prefix-format () |
| 704 | "String matching the very beginning of Tramp file names. | 716 | "String matching the very beginning of Tramp file names. |
| 705 | Used in `tramp-make-tramp-file-name'." | 717 | Used in `tramp-make-tramp-file-name'." |
| 706 | (cond ((eq (tramp-compat-tramp-syntax) 'default) "/") | 718 | (tramp-lookup-syntax tramp-prefix-format-alist)) |
| 707 | ((eq (tramp-compat-tramp-syntax) 'simplified) "/") | 719 | |
| 708 | ((eq (tramp-compat-tramp-syntax) 'separate) "/[") | 720 | (defconst tramp-prefix-regexp-alist |
| 709 | (t (error "Wrong `tramp-syntax' %s" tramp-syntax)))) | 721 | (mapcar (lambda (x) |
| 722 | (cons (car x) (concat "^" (regexp-quote (cdr x))))) | ||
| 723 | tramp-prefix-format-alist) | ||
| 724 | "Alist of regexps matching the beginnings of Tramp file names. | ||
| 725 | Keyed by Tramp syntax. Derived from `tramp-prefix-format-alist'.") | ||
| 710 | 726 | ||
| 711 | (defun tramp-prefix-regexp () | 727 | (defun tramp-prefix-regexp () |
| 712 | "Regexp matching the very beginning of Tramp file names. | 728 | "Regexp matching the very beginning of Tramp file names. |
| 713 | Should always start with \"^\". Derived from `tramp-prefix-format'." | 729 | Should always start with \"^\". Derived from `tramp-prefix-format'." |
| 714 | (concat "^" (regexp-quote (tramp-prefix-format)))) | 730 | (tramp-lookup-syntax tramp-prefix-regexp-alist)) |
| 731 | |||
| 732 | (defconst tramp-method-regexp-alist | ||
| 733 | '((default . "[a-zA-Z0-9-]+") | ||
| 734 | (simplified . "") | ||
| 735 | (separate . "[a-zA-Z0-9-]*")) | ||
| 736 | "Alist mapping Tramp syntax to regexps matching methods identifiers.") | ||
| 715 | 737 | ||
| 716 | (defun tramp-method-regexp () | 738 | (defun tramp-method-regexp () |
| 717 | "Regexp matching methods identifiers. | 739 | "Regexp matching methods identifiers. |
| 718 | The `ftp' syntax does not support methods." | 740 | The `ftp' syntax does not support methods." |
| 719 | (cond ((eq (tramp-compat-tramp-syntax) 'default) "[a-zA-Z0-9-]+") | 741 | (tramp-lookup-syntax tramp-method-regexp-alist)) |
| 720 | ((eq (tramp-compat-tramp-syntax) 'simplified) "") | 742 | |
| 721 | ((eq (tramp-compat-tramp-syntax) 'separate) "[a-zA-Z0-9-]*") | 743 | (defconst tramp-postfix-method-format-alist |
| 722 | (t (error "Wrong `tramp-syntax' %s" tramp-syntax)))) | 744 | '((default . ":") |
| 745 | (simplified . "") | ||
| 746 | (separate . "/")) | ||
| 747 | "Alist mapping Tramp syntax to the delimiter after the method.") | ||
| 723 | 748 | ||
| 724 | (defun tramp-postfix-method-format () | 749 | (defun tramp-postfix-method-format () |
| 725 | "String matching delimiter between method and user or host names. | 750 | "String matching delimiter between method and user or host names. |
| 726 | The `ftp' syntax does not support methods. | 751 | The `ftp' syntax does not support methods. |
| 727 | Used in `tramp-make-tramp-file-name'." | 752 | Used in `tramp-make-tramp-file-name'." |
| 728 | (cond ((eq (tramp-compat-tramp-syntax) 'default) ":") | 753 | (tramp-lookup-syntax tramp-postfix-method-format-alist)) |
| 729 | ((eq (tramp-compat-tramp-syntax) 'simplified) "") | 754 | |
| 730 | ((eq (tramp-compat-tramp-syntax) 'separate) "/") | 755 | (defconst tramp-postfix-method-regexp-alist |
| 731 | (t (error "Wrong `tramp-syntax' %s" tramp-syntax)))) | 756 | (mapcar (lambda (x) |
| 757 | (cons (car x) (regexp-quote (cdr x)))) | ||
| 758 | tramp-postfix-method-format-alist) | ||
| 759 | "Alist mapping Tramp syntax to regexp matching delimiter after method. | ||
| 760 | Derived from `tramp-postfix-method-format-alist'.") | ||
| 732 | 761 | ||
| 733 | (defun tramp-postfix-method-regexp () | 762 | (defun tramp-postfix-method-regexp () |
| 734 | "Regexp matching delimiter between method and user or host names. | 763 | "Regexp matching delimiter between method and user or host names. |
| 735 | Derived from `tramp-postfix-method-format'." | 764 | Derived from `tramp-postfix-method-format'." |
| 736 | (regexp-quote (tramp-postfix-method-format))) | 765 | (tramp-lookup-syntax tramp-postfix-method-regexp-alist)) |
| 737 | 766 | ||
| 738 | (defconst tramp-user-regexp "[^/|: \t]+" | 767 | (defconst tramp-user-regexp "[^/|: \t]+" |
| 739 | "Regexp matching user names.") | 768 | "Regexp matching user names.") |
| @@ -769,18 +798,28 @@ Derived from `tramp-postfix-user-format'.") | |||
| 769 | (defconst tramp-host-regexp "[a-zA-Z0-9_.-]+" | 798 | (defconst tramp-host-regexp "[a-zA-Z0-9_.-]+" |
| 770 | "Regexp matching host names.") | 799 | "Regexp matching host names.") |
| 771 | 800 | ||
| 801 | (defconst tramp-prefix-ipv6-format-alist | ||
| 802 | '((default . "[") | ||
| 803 | (simplified . "[") | ||
| 804 | (separate . "")) | ||
| 805 | "Alist mapping Tramp syntax to strings prefixing IPv6 addresses.") | ||
| 806 | |||
| 772 | (defun tramp-prefix-ipv6-format () | 807 | (defun tramp-prefix-ipv6-format () |
| 773 | "String matching left hand side of IPv6 addresses. | 808 | "String matching left hand side of IPv6 addresses. |
| 774 | Used in `tramp-make-tramp-file-name'." | 809 | Used in `tramp-make-tramp-file-name'." |
| 775 | (cond ((eq (tramp-compat-tramp-syntax) 'default) "[") | 810 | (tramp-lookup-syntax tramp-prefix-ipv6-format-alist)) |
| 776 | ((eq (tramp-compat-tramp-syntax) 'simplified) "[") | 811 | |
| 777 | ((eq (tramp-compat-tramp-syntax) 'separate) "") | 812 | (defconst tramp-prefix-ipv6-regexp-alist |
| 778 | (t (error "Wrong `tramp-syntax' %s" tramp-syntax)))) | 813 | (mapcar (lambda (x) |
| 814 | (cons (car x) (regexp-quote (cdr x)))) | ||
| 815 | tramp-prefix-ipv6-format-alist) | ||
| 816 | "Alist mapping Tramp syntax to regexp matching prefix of IPv6 addresses. | ||
| 817 | Derived from `tramp-prefix-ipv6-format-alist'") | ||
| 779 | 818 | ||
| 780 | (defun tramp-prefix-ipv6-regexp () | 819 | (defun tramp-prefix-ipv6-regexp () |
| 781 | "Regexp matching left hand side of IPv6 addresses. | 820 | "Regexp matching left hand side of IPv6 addresses. |
| 782 | Derived from `tramp-prefix-ipv6-format'." | 821 | Derived from `tramp-prefix-ipv6-format'." |
| 783 | (regexp-quote (tramp-prefix-ipv6-format))) | 822 | (tramp-lookup-syntax tramp-prefix-ipv6-regexp-alist)) |
| 784 | 823 | ||
| 785 | ;; The following regexp is a bit sloppy. But it shall serve our | 824 | ;; The following regexp is a bit sloppy. But it shall serve our |
| 786 | ;; purposes. It covers also IPv4 mapped IPv6 addresses, like in | 825 | ;; purposes. It covers also IPv4 mapped IPv6 addresses, like in |
| @@ -789,18 +828,28 @@ Derived from `tramp-prefix-ipv6-format'." | |||
| 789 | "\\(?:\\(?:[a-zA-Z0-9]+\\)?:\\)+[a-zA-Z0-9.]+" | 828 | "\\(?:\\(?:[a-zA-Z0-9]+\\)?:\\)+[a-zA-Z0-9.]+" |
| 790 | "Regexp matching IPv6 addresses.") | 829 | "Regexp matching IPv6 addresses.") |
| 791 | 830 | ||
| 831 | (defconst tramp-postfix-ipv6-format-alist | ||
| 832 | '((default . "]") | ||
| 833 | (simplified . "]") | ||
| 834 | (separate . "")) | ||
| 835 | "Alist mapping Tramp syntax to suffix for IPv6 addresses.") | ||
| 836 | |||
| 792 | (defun tramp-postfix-ipv6-format () | 837 | (defun tramp-postfix-ipv6-format () |
| 793 | "String matching right hand side of IPv6 addresses. | 838 | "String matching right hand side of IPv6 addresses. |
| 794 | Used in `tramp-make-tramp-file-name'." | 839 | Used in `tramp-make-tramp-file-name'." |
| 795 | (cond ((eq (tramp-compat-tramp-syntax) 'default) "]") | 840 | (tramp-lookup-syntax tramp-postfix-ipv6-format-alist)) |
| 796 | ((eq (tramp-compat-tramp-syntax) 'simplified) "]") | 841 | |
| 797 | ((eq (tramp-compat-tramp-syntax) 'separate) "") | 842 | (defconst tramp-postfix-ipv6-regexp-alist |
| 798 | (t (error "Wrong `tramp-syntax' %s" tramp-syntax)))) | 843 | (mapcar (lambda (x) |
| 844 | (cons (car x) (regexp-quote (cdr x)))) | ||
| 845 | tramp-postfix-ipv6-format-alist) | ||
| 846 | "Alist mapping Tramp syntax to regexps matching IPv6 suffixes. | ||
| 847 | Derived from `tramp-postfix-ipv6-format-alist'.") | ||
| 799 | 848 | ||
| 800 | (defun tramp-postfix-ipv6-regexp () | 849 | (defun tramp-postfix-ipv6-regexp () |
| 801 | "Regexp matching right hand side of IPv6 addresses. | 850 | "Regexp matching right hand side of IPv6 addresses. |
| 802 | Derived from `tramp-postfix-ipv6-format'." | 851 | Derived from `tramp-postfix-ipv6-format'." |
| 803 | (regexp-quote (tramp-postfix-ipv6-format))) | 852 | (tramp-lookup-syntax tramp-postfix-ipv6-format-alist)) |
| 804 | 853 | ||
| 805 | (defconst tramp-prefix-port-format "#" | 854 | (defconst tramp-prefix-port-format "#" |
| 806 | "String matching delimiter between host names and port numbers.") | 855 | "String matching delimiter between host names and port numbers.") |
| @@ -827,18 +876,28 @@ Derived from `tramp-prefix-port-format'.") | |||
| 827 | "Regexp matching delimiter after ad-hoc hop definitions. | 876 | "Regexp matching delimiter after ad-hoc hop definitions. |
| 828 | Derived from `tramp-postfix-hop-format'.") | 877 | Derived from `tramp-postfix-hop-format'.") |
| 829 | 878 | ||
| 879 | (defconst tramp-postfix-host-format-alist | ||
| 880 | '((default . ":") | ||
| 881 | (simplified . ":") | ||
| 882 | (separate . "]")) | ||
| 883 | "Alist mapping Tramp syntax to strings between host and local names.") | ||
| 884 | |||
| 830 | (defun tramp-postfix-host-format () | 885 | (defun tramp-postfix-host-format () |
| 831 | "String matching delimiter between host names and localnames. | 886 | "String matching delimiter between host names and localnames. |
| 832 | Used in `tramp-make-tramp-file-name'." | 887 | Used in `tramp-make-tramp-file-name'." |
| 833 | (cond ((eq (tramp-compat-tramp-syntax) 'default) ":") | 888 | (tramp-lookup-syntax tramp-postfix-host-format-alist)) |
| 834 | ((eq (tramp-compat-tramp-syntax) 'simplified) ":") | 889 | |
| 835 | ((eq (tramp-compat-tramp-syntax) 'separate) "]") | 890 | (defconst tramp-postfix-host-regexp-alist |
| 836 | (t (error "Wrong `tramp-syntax' %s" tramp-syntax)))) | 891 | (mapcar (lambda (x) |
| 892 | (cons (car x) (regexp-quote (cdr x)))) | ||
| 893 | tramp-postfix-host-format-alist) | ||
| 894 | "Alist mapping Tramp syntax to regexp matching name delimiters. | ||
| 895 | Derived from `tramp-postfix-host-format-alist'.") | ||
| 837 | 896 | ||
| 838 | (defun tramp-postfix-host-regexp () | 897 | (defun tramp-postfix-host-regexp () |
| 839 | "Regexp matching delimiter between host names and localnames. | 898 | "Regexp matching delimiter between host names and localnames. |
| 840 | Derived from `tramp-postfix-host-format'." | 899 | Derived from `tramp-postfix-host-format'." |
| 841 | (regexp-quote (tramp-postfix-host-format))) | 900 | (tramp-lookup-syntax tramp-postfix-host-regexp-alist)) |
| 842 | 901 | ||
| 843 | (defconst tramp-localname-regexp ".*$" | 902 | (defconst tramp-localname-regexp ".*$" |
| 844 | "Regexp matching localnames.") | 903 | "Regexp matching localnames.") |
| @@ -851,16 +910,46 @@ Derived from `tramp-postfix-host-format'." | |||
| 851 | 910 | ||
| 852 | ;;; File name format: | 911 | ;;; File name format: |
| 853 | 912 | ||
| 913 | (defun tramp-build-remote-file-name-spec-regexp (syntax) | ||
| 914 | "Construct a regexp matching a Tramp file name for a Tramp SYNTAX." | ||
| 915 | (let ((tramp-syntax syntax)) | ||
| 916 | (concat | ||
| 917 | "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) | ||
| 918 | "\\(?:" "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp "\\)?" | ||
| 919 | "\\(" "\\(?:" tramp-host-regexp "\\|" | ||
| 920 | (tramp-prefix-ipv6-regexp) | ||
| 921 | "\\(?:" tramp-ipv6-regexp "\\)?" | ||
| 922 | (tramp-postfix-ipv6-regexp) "\\)?" | ||
| 923 | "\\(?:" tramp-prefix-port-regexp tramp-port-regexp "\\)?" "\\)?"))) | ||
| 924 | |||
| 925 | (defconst tramp-remote-file-name-spec-regexp-alist | ||
| 926 | `((default . ,(tramp-build-remote-file-name-spec-regexp 'default)) | ||
| 927 | (simplified . ,(tramp-build-remote-file-name-spec-regexp 'simplified)) | ||
| 928 | (separate . ,(tramp-build-remote-file-name-spec-regexp 'separate))) | ||
| 929 | "Alist mapping Tramp syntax to regexps matching Tramp file names.") | ||
| 930 | |||
| 854 | (defun tramp-remote-file-name-spec-regexp () | 931 | (defun tramp-remote-file-name-spec-regexp () |
| 855 | "Regular expression matching a Tramp file name between prefix and postfix." | 932 | "Regular expression matching a Tramp file name between prefix and postfix." |
| 856 | (concat | 933 | (tramp-lookup-syntax tramp-remote-file-name-spec-regexp-alist)) |
| 857 | "\\(" (tramp-method-regexp) "\\)" (tramp-postfix-method-regexp) | 934 | |
| 858 | "\\(?:" "\\(" tramp-user-regexp "\\)" tramp-postfix-user-regexp "\\)?" | 935 | (defun tramp-build-file-name-structure (syntax) |
| 859 | "\\(" "\\(?:" tramp-host-regexp "\\|" | 936 | "Construct the Tramp file name structure for SYNTAX. |
| 860 | (tramp-prefix-ipv6-regexp) | 937 | See `tramp-file-name-structure'." |
| 861 | "\\(?:" tramp-ipv6-regexp "\\)?" | 938 | (let ((tramp-syntax syntax)) |
| 862 | (tramp-postfix-ipv6-regexp) "\\)?" | 939 | (list |
| 863 | "\\(?:" tramp-prefix-port-regexp tramp-port-regexp "\\)?" "\\)?")) | 940 | (concat |
| 941 | (tramp-prefix-regexp) | ||
| 942 | "\\(" "\\(?:" (tramp-remote-file-name-spec-regexp) | ||
| 943 | tramp-postfix-hop-regexp "\\)+" "\\)?" | ||
| 944 | (tramp-remote-file-name-spec-regexp) (tramp-postfix-host-regexp) | ||
| 945 | "\\(" tramp-localname-regexp "\\)") | ||
| 946 | 5 6 7 8 1))) | ||
| 947 | |||
| 948 | (defconst tramp-file-name-structure-alist | ||
| 949 | `((default . ,(tramp-build-file-name-structure 'default)) | ||
| 950 | (simplified . ,(tramp-build-file-name-structure 'simplified)) | ||
| 951 | (separate . ,(tramp-build-file-name-structure 'separate))) | ||
| 952 | "Alist mapping Tramp syntax to the file name structure for that syntax.") | ||
| 864 | 953 | ||
| 865 | (defun tramp-file-name-structure () | 954 | (defun tramp-file-name-structure () |
| 866 | "List of six elements (REGEXP METHOD USER HOST FILE HOP), detailing \ | 955 | "List of six elements (REGEXP METHOD USER HOST FILE HOP), detailing \ |
| @@ -881,14 +970,7 @@ These numbers are passed directly to `match-string', which see. That | |||
| 881 | means the opening parentheses are counted to identify the pair. | 970 | means the opening parentheses are counted to identify the pair. |
| 882 | 971 | ||
| 883 | See also `tramp-file-name-regexp'." | 972 | See also `tramp-file-name-regexp'." |
| 884 | (list | 973 | (tramp-lookup-syntax tramp-file-name-structure-alist)) |
| 885 | (concat | ||
| 886 | (tramp-prefix-regexp) | ||
| 887 | "\\(" "\\(?:" (tramp-remote-file-name-spec-regexp) | ||
| 888 | tramp-postfix-hop-regexp "\\)+" "\\)?" | ||
| 889 | (tramp-remote-file-name-spec-regexp) (tramp-postfix-host-regexp) | ||
| 890 | "\\(" tramp-localname-regexp "\\)") | ||
| 891 | 5 6 7 8 1)) | ||
| 892 | 974 | ||
| 893 | (defun tramp-file-name-regexp () | 975 | (defun tramp-file-name-regexp () |
| 894 | "Regular expression matching file names handled by Tramp. | 976 | "Regular expression matching file names handled by Tramp. |