| 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 |
(require 'url-methods) |
|---|
| 27 |
(require 'url-util) |
|---|
| 28 |
(require 'url-parse) |
|---|
| 29 |
|
|---|
| 30 |
(defun url-expander-remove-relative-links (name) |
|---|
| 31 |
|
|---|
| 32 |
(let ((new (if (not (string-match "^/" name)) |
|---|
| 33 |
(concat "/" name) |
|---|
| 34 |
name))) |
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 |
(if (string-match "/\\.+$" new) |
|---|
| 40 |
(setq new (concat new "/"))) |
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
(while (string-match "/\\(\\./\\)" new) |
|---|
| 44 |
(setq new (concat (substring new 0 (match-beginning 1)) |
|---|
| 45 |
(substring new (match-end 1))))) |
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
(while (string-match "/\\([^/]*/\\.\\./\\)" new) |
|---|
| 49 |
(setq new (concat (substring new 0 (match-beginning 1)) |
|---|
| 50 |
(substring new (match-end 1))))) |
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
|
|---|
| 54 |
(while (string-match "^/\\.\\.\\(/\\)" new) |
|---|
| 55 |
(setq new (substring new (match-beginning 1) nil))) |
|---|
| 56 |
new)) |
|---|
| 57 |
|
|---|
| 58 |
(defun url-expand-file-name (url &optional default) |
|---|
| 59 |
"Convert URL to a fully specified URL, and canonicalize it. |
|---|
| 60 |
Second arg DEFAULT is a URL to start with if URL is relative. |
|---|
| 61 |
If DEFAULT is nil or missing, the current buffer's URL is used. |
|---|
| 62 |
Path components that are `.' are removed, and |
|---|
| 63 |
path components followed by `..' are removed, along with the `..' itself." |
|---|
| 64 |
(if (and url (not (string-match "^#" url))) |
|---|
| 65 |
|
|---|
| 66 |
|
|---|
| 67 |
(setq url (mapconcat (function (lambda (x) |
|---|
| 68 |
(if (memq x '(? ?\n ?\r)) |
|---|
| 69 |
"" |
|---|
| 70 |
(char-to-string x)))) |
|---|
| 71 |
url ""))) |
|---|
| 72 |
|
|---|
| 73 |
|
|---|
| 74 |
(setq default (cond |
|---|
| 75 |
((vectorp default) |
|---|
| 76 |
|
|---|
| 77 |
default) |
|---|
| 78 |
(default |
|---|
| 79 |
|
|---|
| 80 |
(url-generic-parse-url default)) |
|---|
| 81 |
(url-current-object |
|---|
| 82 |
|
|---|
| 83 |
url-current-object) |
|---|
| 84 |
((string-match url-nonrelative-link url) |
|---|
| 85 |
|
|---|
| 86 |
nil) |
|---|
| 87 |
(t |
|---|
| 88 |
|
|---|
| 89 |
(error "url-expand-file-name confused - no default?")))) |
|---|
| 90 |
|
|---|
| 91 |
(cond |
|---|
| 92 |
((= (length url) 0) |
|---|
| 93 |
(url-recreate-url default)) |
|---|
| 94 |
((string-match "^#" url) |
|---|
| 95 |
url) |
|---|
| 96 |
((string-match url-nonrelative-link url) |
|---|
| 97 |
url) |
|---|
| 98 |
(t |
|---|
| 99 |
(let* ((urlobj (url-generic-parse-url url)) |
|---|
| 100 |
(inhibit-file-name-handlers t) |
|---|
| 101 |
(expander (url-scheme-get-property (url-type default) 'expand-file-name))) |
|---|
| 102 |
(if (string-match "^//" url) |
|---|
| 103 |
(setq urlobj (url-generic-parse-url (concat (url-type default) ":" |
|---|
| 104 |
url)))) |
|---|
| 105 |
(funcall expander urlobj default) |
|---|
| 106 |
(url-recreate-url urlobj))))) |
|---|
| 107 |
|
|---|
| 108 |
(defun url-identity-expander (urlobj defobj) |
|---|
| 109 |
(url-set-type urlobj (or (url-type urlobj) (url-type defobj)))) |
|---|
| 110 |
|
|---|
| 111 |
(defun url-default-expander (urlobj defobj) |
|---|
| 112 |
|
|---|
| 113 |
(if (url-type urlobj) |
|---|
| 114 |
|
|---|
| 115 |
nil |
|---|
| 116 |
(url-set-type urlobj (or (url-type urlobj) (url-type defobj))) |
|---|
| 117 |
(url-set-port urlobj (or (url-port urlobj) |
|---|
| 118 |
(and (string= (url-type urlobj) |
|---|
| 119 |
(url-type defobj)) |
|---|
| 120 |
(url-port defobj)))) |
|---|
| 121 |
(if (not (string= "file" (url-type urlobj))) |
|---|
| 122 |
(url-set-host urlobj (or (url-host urlobj) (url-host defobj)))) |
|---|
| 123 |
(if (string= "ftp" (url-type urlobj)) |
|---|
| 124 |
(url-set-user urlobj (or (url-user urlobj) (url-user defobj)))) |
|---|
| 125 |
(if (string= (url-filename urlobj) "") |
|---|
| 126 |
(url-set-filename urlobj "/")) |
|---|
| 127 |
(if (string-match "^/" (url-filename urlobj)) |
|---|
| 128 |
nil |
|---|
| 129 |
(let ((query nil) |
|---|
| 130 |
(file nil) |
|---|
| 131 |
(sepchar nil)) |
|---|
| 132 |
(if (string-match "[?#]" (url-filename urlobj)) |
|---|
| 133 |
(setq query (substring (url-filename urlobj) (match-end 0)) |
|---|
| 134 |
file (substring (url-filename urlobj) 0 (match-beginning 0)) |
|---|
| 135 |
sepchar (substring (url-filename urlobj) (match-beginning 0) (match-end 0))) |
|---|
| 136 |
(setq file (url-filename urlobj))) |
|---|
| 137 |
(setq file (url-expander-remove-relative-links |
|---|
| 138 |
(expand-file-name file |
|---|
| 139 |
(url-file-directory (url-filename defobj))))) |
|---|
| 140 |
(url-set-filename urlobj (if query (concat file sepchar query) file)))))) |
|---|
| 141 |
|
|---|
| 142 |
(provide 'url-expand) |
|---|
| 143 |
|
|---|
| 144 |
|
|---|
| 145 |
|
|---|
| 146 |
|
|---|