5 ;;; String utilities of various kinds
7 ;;; (c) 2005 Straylight/Edgeware
10 ;;;----- Licensing notice ---------------------------------------------------
12 ;;; This program is free software; you can redistribute it and/or modify
13 ;;; it under the terms of the GNU General Public License as published by
14 ;;; the Free Software Foundation; either version 2 of the License, or
15 ;;; (at your option) any later version.
17 ;;; This program is distributed in the hope that it will be useful,
18 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;;; GNU General Public License for more details.
22 ;;; You should have received a copy of the GNU General Public License
23 ;;; along with this program; if not, write to the Free Software Foundation,
24 ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 (:use #:common-lisp #:mdw.base)
28 (:export #:join-strings #:str-next-word #:str-split-words))
29 (in-package #:mdw.str)
31 (defun join-strings (del strs)
32 "Join together the strings STRS with DEL between them. All the arguments
33 are first converted to strings, as if by `stringify'. Otherwise, this is
34 like Perl's join operator."
35 (setf del (stringify del))
36 (with-output-to-string (s)
39 (princ (stringify (pop strs)) s)
44 (defun str-next-word (string &key quotedp start end)
45 "Extract a whitespace-delimited word from STRING, returning it and the
46 index to continue parsing from. If no word is found, return nil twice.
47 If QUOTEDP, then allow quoting and backslashifying; otherwise don't. The
48 START and END arguments limit the portion of the string to be processed;
49 the default to 0 and nil (end of string), as usual."
50 (setf-default start 0 end (length string))
55 :element-type 'character
59 ;; Find the start of the next word.
62 (return-from str-next-word (values nil nil)))
63 (let ((ch (char string i)))
64 (unless (whitespace-char-p ch)
68 ;; Now pull off a word.
72 (let ((ch (char string i)))
73 (cond ((and quotedp (eql ch #\\))
76 (vector-push-extend ch w)
81 (vector-push-extend ch w))
82 ((whitespace-char-p ch)
85 (vector-push-extend ch w))
92 (vector-push-extend ch w))))
99 (let ((ch (char string i)))
100 (unless (whitespace-char-p ch)
105 (values (make-array (length w)
106 :element-type 'character
110 (defun str-split-words (string &key quotedp start end max)
111 "Break STRING into words, like str-next-word does, returning the list of
112 the individual words. If QUOTEDP, then allow quoting and backslashifying;
113 otherwise don't. No more than MAX `words' are returned: if the maximum is
114 hit, then the last `word' is unbroken, and may still contain quotes and
115 escape characters. The START and END arguments limit the portion of the
116 string to be processed in the usual way."
118 (return-from str-split-words nil))
123 (str-next-word string
129 (when (and max (= (1+ n) max))
130 (push (subseq string start end) l)
132 (setf start nextstart)
137 ;;;----- That's all, folks --------------------------------------------------