summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Müller <ulm@gentoo.org>2024-08-07 20:24:12 +0200
committerUlrich Müller <ulm@gentoo.org>2024-08-07 20:24:12 +0200
commitc7c6ea6f1a419d2a44dd6e526020ed659d6568c4 (patch)
treec5ca74def3d91ad401de7c7dab8e2de76dab5776
parentNew function ebuild-mode-find-s, visits directory S (diff)
downloadebuild-mode-c7c6ea6f1a419d2a44dd6e526020ed659d6568c4.tar.gz
ebuild-mode-c7c6ea6f1a419d2a44dd6e526020ed659d6568c4.tar.bz2
ebuild-mode-c7c6ea6f1a419d2a44dd6e526020ed659d6568c4.zip
Handle ANSI-C quoted strings in environment file
* ebuild-mode.el (ebuild-mode-unescape-string): New function, decodes backslash and ANSI-C escape sequences in strings. (ebuild-mode-find-s): Call it. Signed-off-by: Ulrich Müller <ulm@gentoo.org>
-rw-r--r--ChangeLog4
-rw-r--r--ebuild-mode.el47
2 files changed, 43 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index d52785e..38f0741 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2024-08-07 Ulrich Müller <ulm@gentoo.org>
+ * ebuild-mode.el (ebuild-mode-unescape-string): New function,
+ decodes backslash and ANSI-C escape sequences in strings.
+ (ebuild-mode-find-s): Call it.
+
* ebuild-mode.el (ebuild-mode-get-builddir): New function, split
off from ebuild-mode-find-workdir.
(ebuild-mode-find-s): New function.
diff --git a/ebuild-mode.el b/ebuild-mode.el
index 35ce0a4..69f7106 100644
--- a/ebuild-mode.el
+++ b/ebuild-mode.el
@@ -605,25 +605,56 @@ With prefix argument OTHER-WINDOW, visit the directory in another window."
(find-file-other-window workdir)
(find-file workdir))))
+(defun ebuild-mode-unescape-string (s &optional ansi-c)
+ "Convert string S by expanding backslash escape sequences.
+With optional argument ANSI-C, expand a string with ANSI C escape
+sequences, instead of a simple double-quoted string.
+
+This function supports only escape sequences that can occur in
+the output of the \"declare -p\" Bash command."
+ (let ((case-fold-search nil)
+ (decode-re (if ansi-c
+ "\\\\\\([abtnvfreE\\'\"?]\\|[0-7]\\{1,3\\}\\)"
+ "\\\\\\([$`\"\\\n]\\)"))
+ (decode-alist '((?a . ?\a) (?b . ?\b) (?t . ?\t) (?n . ?\n) (?v . ?\v)
+ (?f . ?\f) (?r . ?\r) (?e . ?\e) (?E . ?\e)))
+ i)
+ (while (setq i (string-match decode-re s i))
+ (let* ((m (match-string 1 s))
+ (c (aref m 0))
+ (byte (cond ((and (>= c ?0) (< c ?8))
+ ;; no string-to-number with base in XEmacs 21.4
+ (let ((n 0))
+ (dotimes (j (length m))
+ (setq n (+ (* n 8) (- (aref m j) ?0))))
+ (logand n #xff)))
+ ((cdr (assq c decode-alist)))
+ (t c))))
+ (setq s (replace-match
+ (static-if (fboundp 'byte-to-string)
+ (byte-to-string byte)
+ (char-to-string byte))
+ nil t s))
+ (setq i (1+ i))))
+ s))
+
(defun ebuild-mode-find-s (&optional other-window)
"Visit the temporary build directory (S) for the ebuild in this buffer.
With prefix argument OTHER-WINDOW, visit the directory in another window."
(interactive "P")
(let ((builddir (ebuild-mode-get-builddir))
- s i)
+ s)
(condition-case nil
(with-temp-buffer
(insert-file-contents-literally
(concat builddir "/temp/environment"))
- (re-search-forward "^declare -\\S-* S=\"\\(.*\\)\"$")
- (setq s (match-string 1)))
+ (re-search-forward
+ "^declare -\\S-* S=\\(\"\\|\\$'\\)\\(.*\\)[\"']$")
+ (setq s (ebuild-mode-unescape-string
+ (match-string 2)
+ (string-equal (match-string 1) "$'"))))
(file-error (error "Failed to read environment file"))
(search-failed (error "Could not find S in the environment file")))
- ;; Handle simple backslash escapes in double-quoted string.
- ;; ***FIXME*** Must we consider $'STRING' ANSI-C quotes?
- (while (setq i (string-match "\\\\\\([$`\"\\\n]\\)" s i))
- (setq s (replace-match (match-string 1 s) nil t s))
- (setq i (1+ i)))
(ignore-errors
(setq s (decode-coding-string s 'utf-8-unix)))
(unless (file-directory-p s)