1 ! :folding=indent:collapseFolds=1:
5 ! Copyright (C) 2003, 2004 Slava Pestov.
7 ! Redistribution and use in source and binary forms, with or without
8 ! modification, are permitted provided that the following conditions are met:
10 ! 1. Redistributions of source code must retain the above copyright notice,
11 ! this list of conditions and the following disclaimer.
13 ! 2. Redistributions in binary form must reproduce the above copyright notice,
14 ! this list of conditions and the following disclaimer in the documentation
15 ! and/or other materials provided with the distribution.
17 ! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 ! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 ! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 ! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 ! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 ! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 ! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 ! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 : f-or-"" ( obj -- ? )
37 dup not swap "" = or ;
39 : str-length< ( str str -- boolean )
40 #! Compare string lengths.
41 [ str-length ] 2apply < ;
43 : cat ( [ "a" "b" "c" ] -- "abc" )
44 ! If f appears in the list, it is not appended to the
46 80 <sbuf> swap [ [ over sbuf-append ] when* ] each sbuf>str ;
48 : cat2 ( "a" "b" -- "ab" )
55 : cat3 ( "a" "b" "c" -- "abc" )
56 [ ] cons cons cons cat ;
58 : cat4 ( "a" "b" "c" "d" -- "abcd" )
59 [ ] cons cons cons cons cat ;
61 : cat5 ( "a" "b" "c" "d" "e" -- "abcde" )
62 [ ] cons cons cons cons cons cat ;
64 : index-of ( string substring -- index )
67 : str-lexi> ( str1 str2 -- ? )
68 ! Returns if the first string lexicographically follows str2
71 : str-head ( str index -- str )
72 #! Returns a new string, from the beginning of the string
73 #! until the given index.
76 : str-contains? ( substr str -- ? )
77 swap index-of -1 = not ;
79 : str-tail ( str index -- str )
80 #! Returns a new string, from the given index until the end
82 over str-length rot substring ;
84 : str/ ( str index -- str str )
85 #! Returns 2 strings, that when concatenated yield the
87 2dup str-tail [ str-head ] dip ;
89 : str// ( str index -- str str )
90 #! Returns 2 strings, that when concatenated yield the
91 #! original string, without the character at the given
93 2dup succ str-tail [ str-head ] dip ;
95 : >title ( str -- str )
96 1 str/ [ >upper ] dip >lower cat2 ;
98 : str-headcut ( str begin -- str str )
101 : str-head? ( str begin -- str )
102 #! If the string starts with begin, return the rest of the
103 #! string after begin. Otherwise, return f.
111 : str-tailcut ( str end -- str str )
112 str-length [ dup str-length ] dip - str/ ;
114 : str-tail? ( str end -- str )
115 #! If the string ends with end, return the start of the
116 #! string before end. Otherwise, return f.
120 tuck str-tailcut swap
124 : split ( string split -- list )
125 2dup index-of dup -1 = [
126 2drop dup str-length 0 = [
132 swap [ str// ] dip split cons
135 : split1 ( string split -- pair )
136 #! The car of the pair is the string up to the first
137 #! occurrence of split; the cdr is the remainder of
139 dupd index-of dup -1 = [
140 drop dup str-length 0 = [
149 : max-str-length ( list -- len )
150 #! Returns the length of the longest string in the given
152 0 swap [ str-length max ] each ;
154 : ends-with-newline? ( string -- string )
155 #! Test if the string ends with a newline or not.
158 : str-each ( str [ code ] -- )
159 #! Execute the code, with each character of the string
160 #! pushed onto the stack.
162 -rot 2dup [ [ str-nth ] dip call ] 2dip
165 : str-sort ( list -- sorted )
166 #! Sorts the list into ascending lexicographical string
171 " \t\n\r" str-contains? ;