* (filename-resolve-user filename) resolves ~ and ~user in string filename * (filename-resolve-variables filename) resolves variables in string filename Please comment! I used the LGPL v2 or later to add the option to include into Guile later on. I would like to hear your opinions on that. --- src/Makefile.am | 1 + src/string/posix.scm | 79 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/string/posix.scm diff --git a/src/Makefile.am b/src/Makefile.am index 889a575..0425bd8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -93,6 +93,7 @@ SOURCES = \ scheme/kwargs.scm \ search/basic.scm \ string/completion.scm \ + string/posix.scm \ string/soundex.scm \ string/transform.scm \ string/wrap.scm \ diff --git a/src/string/posix.scm b/src/string/posix.scm new file mode 100644 index 0000000..5370657 --- /dev/null +++ b/src/string/posix.scm @@ -0,0 +1,79 @@ +;;; (string posix) -- posix string operations + +;; Copyright (C) 2020 Dr. Arne Babenhauserheide and Leo Prikler + +;; This library is free software; you can redistribute it and/or +;; modify it under the terms of the GNU Lesser General Public +;; License as published by the Free Software Foundation; either +;; version 2 of the License, or (at your option) any later version. + +;; This library is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; Lesser General Public License for more details. + +;; You should have received a copy of the GNU Lesser General Public +;; License along with this library. If not, see +;; . +#! +;;; Commentary: +Resolving ~ in filenames following POSIX rules. +;;; Code: +!# + +(define-module (string posix) + #:export (filename-resolve-user filename-resolve-variables) + #:use-module (ice-9 regex)) + +(define (filename-resolve-user filename) + "Replaces ~ and ~user in string FILENAME as by posix rules. + +@lisp + (filename-resolve-user \"~\") +=> (getenv \"HOME\") or /home/user or ~ + (filename-resolve-user \"~other\") +=> \"/home/other\" (or whatever dir entry other has in passwd +@end lisp +" + (cond + ((string= filename "~") + (or (getenv "HOME") + (passwd:dir (getpw (getlogin))) + "~")) + ((string-prefix? "~/" filename) + (string-replace filename + (filename-resolve-user "~") + 0 1)) + ((string-prefix? "~" filename) + (let ((matched (string-match "~([^/]*)" filename))) + (string-replace filename + (passwd:dir (getpw (match:substring matched 1))) + 0 (match:end matched)))) + (else filename))) + +(define (filename-resolve-variables filename) + "Resolve environment variables in string FILENAME + +@lisp + (filename-resolve-variables \"$HOME\") +=> the home directory + (filename-resolve-user \"foo-$PWD-bar\") +=> \"foo-thepwd-bar\" (with thepwd the working directory +@end lisp + +" + (regexp-substitute/global #f "\\$([A-Za-z0-9_]+)" filename + 'pre + (lambda (m) + (or (getenv (match:substring m 1)) + (error "Environment variable ~s not set" + (match:substring m 1)))) + 'post)) + +;; (define (test s) +;; (format #t "~a -> ~a~%" s (filename-resolve-user s))) +;; +;; (test "~") +;; (test "~/") +;; (test "~gdm") +;; (test "~gdm/") -- 2.28.0 -- Unpolitisch sein heißt politisch sein ohne es zu merken