Use '$IFS' as a string when splitting words

We used to model 'IFS' as a character set, but when handling special
parameters, the order of the characters matters.  Since it is also an
environment variable, it makes sense to treat as a string (rather than
a list).

* geesh/word.scm (split-fields): Treat 'ifs' as a string instead of a
character set.
(expand-word): Get 'ifs' from the environment if available or use a
default string otherwise.
This commit is contained in:
Timothy Sample 2018-11-09 16:35:06 -05:00
parent 3fad06a756
commit 7fe940e852
1 changed files with 13 additions and 8 deletions

View File

@ -65,22 +65,23 @@ guaranteed to be a list."
(loop (cdr xs) (cons (car xs) small-acc) big-acc)))))
(define (split-fields qword ifs)
"Split @var{qword} into a list of qwords delimited by the character
set @var{ifs}."
"Split @var{qword} into a list of qwords delimited by any character
in the string @var{ifs}."
(define (wedge-apart qword-part ifs)
(define ifs? (cut string-index ifs <>))
(define (wedge-apart qword-part)
(match qword-part
(('<sh-quote> _) (list qword-part))
("" '(""))
(str (let ((str-parts (string-split str ifs)))
(str (let ((str-parts (string-split str ifs?)))
(if (every string-null? str-parts)
'(wedge)
(filter (lambda (x)
(or (eq? x 'wedge) (not (string-null? x))))
(infix 'wedge str-parts)))))))
(let ((wedged (append-map (cut wedge-apart <> ifs)
(normalize-word qword))))
(let ((wedged (append-map wedge-apart (normalize-word qword))))
(filter pair? (list-split wedged 'wedge))))
(define (remove-quotes qword)
@ -168,8 +169,12 @@ and arithmetic substitions using the environment @var{env}."
(define* (expand-word env word #:key (split? #t) (rhs-tildes? #f))
"Expand @var{word} into a list of fields using the environment
@var{env}."
(let ((qword (word->qword env word)))
;; The value of '$IFS' may depend on side-effects performed during
;; 'word->qword', so use 'let*' here.
(let* ((qword (word->qword env word))
(ifs (or (and env (var-ref env "IFS"))
(string #\space #\tab #\newline))))
(if split?
(map remove-quotes
(split-fields qword (char-set #\newline #\tab #\space)))
(split-fields qword ifs))
(remove-quotes qword))))