(FILECREATED " 5-Dec-85 04:17:27" {ERIS}<LISPCORE>LIBRARY>CMLSTRING.;11 27040 changes to: (FNS STRING-LESSP STRING-GREATERP STRING-NOT-GREATERP STRING-NOT-LESSP STRING-NOT-EQUAL STRING-LEFT-TRIM STRING-RIGHT-TRIM STRING-TRIM \SP-STRING-COMPARE NSTRING-UPCASE NSTRING-DOWNCASE NSTRING-CAPITALIZE STRING> STRING<= STRING>= STRING/= STRING<* STRING>* STRING<=* STRING>=* STRING-UPCASE STRING-DOWNCASE STRING-CAPITALIZE) (MACROS FOR-SUBSTRING WITH-ONE-STRING WITH-STRING WITH-TWO-STRINGS STRING<>=*-BODY) (VARS CMLKBRSTRINGCOMS) previous date: " 5-Dec-85 00:35:05" {ERIS}<LISPCORE>LIBRARY>CMLSTRING.;7) (* Copyright (c) 1985 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT CMLSTRINGCOMS) (RPAQQ CMLSTRINGCOMS [(MACROS FOR-SUBSTRING \STRING WITH-ONE-STRING WITH-STRING WITH-TWO-STRINGS STRING<>=*-BODY) (FNS STRING \SP-STRING-COMPARE STRING=* STRING/=* STRING<* STRING>* STRING<=* STRING>=* STRING< STRING> STRING<= STRING>= STRING= STRING/= STRING-LESSP STRING-GREATERP STRING-NOT-GREATERP STRING-NOT-LESSP STRING-NOT-EQUAL MAKE-STRING STRING-UPCASE STRING-DOWNCASE STRING-CAPITALIZE NSTRING-UPCASE NSTRING-DOWNCASE NSTRING-CAPITALIZE STRING-LEFT-TRIM STRING-RIGHT-TRIM STRING-TRIM) (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDVARS (NLAMA) (NLAML) (LAMA NSTRING-CAPITALIZE NSTRING-DOWNCASE NSTRING-UPCASE STRING-CAPITALIZE STRING-DOWNCASE STRING-UPCASE MAKE-STRING STRING-NOT-EQUAL STRING-NOT-LESSP STRING-NOT-GREATERP STRING-GREATERP STRING-LESSP STRING/= STRING= STRING>= STRING<= STRING> STRING<]) (DECLARE: EVAL@COMPILE [DEFMACRO FOR-SUBSTRING (STRING START END NEW INDEX &REST FORMS) (* * Creates a new string to hold the old string and iterates the body over the positions START to END with INDEX * *) (BQUOTE (LET* ((SLEN (CL:LENGTH (\, STRING))) ((\, NEW) (MAKE-STRING SLEN))) (for INDEX from 0 to (1- (\, START)) do (SETF (CHAR (\, NEW) INDEX) (CHAR (\, STRING) INDEX))) (for (\, INDEX) from (\, START) to (1- (\, END)) do (\,@ FORMS)) (for INDEX from (\, END) to (1- SLEN) do (SETF (CHAR (\, NEW) INDEX) (CHAR (\, STRING) INDEX))) (\, NEW] [DEFMACRO \STRING (THING) (* \String returns its arg if it is a string, otherwise calls String. *) (BQUOTE (COND ((STRINGP (\, THING)) (\, THING)) (T (STRING (\, THING] [DEFMACRO WITH-ONE-STRING (STRING START END &REST FORMS) (* WITH-ONE-STRING is used to set up some string hacking things. The keywords are parsed, and the string is hacked into a simple-string. *) (BQUOTE (PROGN [COND ((SYMBOLP (\, STRING)) (SETQ (\, STRING) (SYMBOL-NAME (\, STRING] [COND ((NULL (\, END)) (SETQ (\, END) (CL:LENGTH (\, STRING] (\,@ FORMS] [DEFMACRO WITH-STRING (STRING &REST FORMS) (* WITH-STRING is like WITH-ONE-STRING, but doesn't parse keywords. *) (BQUOTE (LET ((START 0) END) [COND ((SYMBOLP (\, STRING)) (SETQ (\, STRING) (SYMBOL-NAME (\, STRING] (SETQ END (CL:LENGTH (\, STRING))) (\,@ FORMS] [DEFMACRO WITH-TWO-STRINGS (STRING1 STRING2 START1 END1 START2 END2 &REST FORMS) (* WITH-TWO-STRINGS is used to set up string comparison operations. The keywords are parsed, and symbols are hacked into strings *) (BQUOTE (PROGN [COND ((SYMBOLP (\, STRING1)) (SETQ (\, STRING1) (SYMBOL-NAME (\, STRING1] [COND ((NULL (\, END1)) (SETQ (\, END1) (CL:LENGTH (\, STRING1] [COND ((SYMBOLP (\, STRING2)) (SETQ (\, STRING2) (SYMBOL-NAME (\, STRING2] [COND ((NULL (\, END2)) (SETQ (\, END2) (CL:LENGTH (\, STRING2] (\,@ FORMS] [DEFMACRO STRING<>=*-BODY (LESSP EQUALP) (BQUOTE (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((INDEX (\SP-STRING-COMPARE STRING1 START1 END1 STRING2 START2 END2))) (COND (INDEX (COND ([= INDEX (\, (COND (LESSP (QUOTE END1)) (T (QUOTE END2] INDEX) ([= INDEX (\, (COND (LESSP (QUOTE END2)) (T (QUOTE END1] NIL) ([[\, (COND (LESSP (QUOTE CHAR<)) (T (QUOTE CHAR>] (CHAR STRING1 INDEX) (CHAR STRING2 (+ INDEX (- START2 START1] INDEX) (T NIL))) (T (\, (COND (EQUALP (QUOTE (- END1 START1))) (T (QUOTE NIL] ) (DEFINEQ (STRING [LAMBDA (X) (* kbr: " 4-Oct-85 11:14") (* Coerces X into a string. If X is a string, X is returned. If X is a symbol, X's pname is returned. If X is a character then a one element string containing that character is returned. If X cannot be coerced into a string, an error occurs. *) (COND ((STRINGP X) X) ((SYMBOLP X) (SYMBOL-NAME X)) ((CHARACTERP X) (ALLOCSTRING 1 (CHAR-INT X))) (T (CL:ERROR "~S cannot be coerced to a string." X]) (\SP-STRING-COMPARE [LAMBDA (STRING1 START1 END1 STRING2 START2 END2) (* raf " 5-Dec-85 03:14") (* First INDEX at which compared portions of STRING1 and STRING2 differ. *) (for I1 from START1 to (1- (OR END1 (CL:LENGTH STRING1))) as I2 from START2 to (1- (OR END2 (CL:LENGTH STRING2))) as I from 0 when (NOT (EQ (CHAR STRING1 I1) (CHAR STRING2 I2))) do (RETURN I]) (STRING=* [CL:LAMBDA (STRING1 STRING2 START1 END1 START2 END2) (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (NOT (\SP-STRING-COMPARE STRING1 START1 END1 STRING2 START2 END2]) (STRING/=* (CL:LAMBDA (STRING1 STRING2 START1 END1 START2 END2) (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (\SP-STRING-COMPARE STRING1 START1 END1 STRING2 START2 END2)))) (STRING<* [CL:LAMBDA (STRING1 STRING2 START1 END1 START2 END2) (* raf " 4-Dec-85 23:19") (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((INDEX (\SP-STRING-COMPARE STRING1 START1 END1 STRING2 START2 END2))) (COND (INDEX (COND ((= INDEX END1) INDEX) ((= INDEX END2) NIL) ([CHAR< (CHAR STRING1 INDEX) (CHAR STRING2 (+ INDEX (- START2 START1] INDEX) (T NIL))) (T NIL]) (STRING>* [CL:LAMBDA (STRING1 STRING2 START1 END1 START2 END2) (* raf " 4-Dec-85 23:20") (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((INDEX (\SP-STRING-COMPARE STRING1 START1 END1 STRING2 START2 END2))) (COND (INDEX (COND ((= INDEX END2) INDEX) ((= INDEX END1) NIL) ([CHAR> (CHAR STRING1 INDEX) (CHAR STRING2 (+ INDEX (- START2 START1] INDEX) (T NIL))) (T NIL]) (STRING<=* [CL:LAMBDA (STRING1 STRING2 START1 END1 START2 END2) (* raf " 4-Dec-85 23:20") (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((INDEX (\SP-STRING-COMPARE STRING1 START1 END1 STRING2 START2 END2))) (COND (INDEX (COND ((= INDEX END1) INDEX) ((= INDEX END2) NIL) ([CHAR< (CHAR STRING1 INDEX) (CHAR STRING2 (+ INDEX (- START2 START1] INDEX) (T NIL))) (T (- END1 START1]) (STRING>=* [CL:LAMBDA (STRING1 STRING2 START1 END1 START2 END2) (* raf " 4-Dec-85 23:21") (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((INDEX (\SP-STRING-COMPARE STRING1 START1 END1 STRING2 START2 END2))) (COND (INDEX (COND ((= INDEX END2) INDEX) ((= INDEX END1) NIL) ([CHAR> (CHAR STRING1 INDEX) (CHAR STRING2 (+ INDEX (- START2 START1] INDEX) (T NIL))) (T (- END1 START1]) (STRING< (CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* kbr: " 4-Oct-85 11:30") (* Given two strings, if the first string is lexicographically less than the second string, returns the longest common prefix (using char=) of the two strings. Otherwise, returns NIL . *) (STRING<* STRING1 STRING2 START1 END1 START2 END2))) (STRING> (CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* kbr: " 4-Oct-85 11:30") (* Given two strings, if the first string is lexicographically greater than the second string, returns the longest common prefix (using char=) of the two strings. Otherwise, returns NIL . *) (STRING>* STRING1 STRING2 START1 END1 START2 END2))) (STRING<= (CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* kbr: " 4-Oct-85 11:31") (* Given two strings, if the first string is lexicographically less than or equal to the second string, returns the longest common prefix (using char=) of the two strings. Otherwise, returns NIL . *) (STRING<=* STRING1 STRING2 START1 END1 START2 END2))) (STRING>= (CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* kbr: " 4-Oct-85 11:31") (* Given two strings, if the first string is lexicographically greater than or equal to the second string, returns the longest common prefix (using char=) of the two strings. Otherwise, returns NIL . *) (STRING>=* STRING1 STRING2 START1 END1 START2 END2))) (STRING= (CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* kbr: " 4-Oct-85 10:54") (* Given two strings (string1 and string2), and optional integers start1, start2, end1 and end2, compares characters in string1 to characters in string2 (using char=) . *) (STRING=* STRING1 STRING2 START1 END1 START2 END2))) (STRING/= (CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* kbr: " 4-Oct-85 11:32") (* Given two strings, if the first string is not lexicographically equal to the second string, returns the longest common prefix (using char=) of the two strings. Otherwise, returns NIL . *) (STRING/=* STRING1 STRING2 START1 END1 START2 END2))) (STRING-LESSP [CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* raf " 5-Dec-85 04:11") (* Given two strings, if the first string is lexicographically less than the second string, returns the longest common prefix (using char-equal) of the two strings. Otherwise, returns NIL . *) (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((SLEN1 (- END1 START1)) (SLEN2 (- END2 START2))) (DECLARE (TYPE FIXNUM SLEN1 SLEN2)) (* prevent endless looping later. *) (COND ((OR (MINUSP SLEN1) (MINUSP SLEN2)) (CL:ERROR "Improper bounds for string comparison.")) (T NIL)) (CL:DO ((INDEX1 START1 (1+ INDEX1)) (INDEX2 START2 (1+ INDEX2)) (CHAR1) (CHAR2)) ((OR (= INDEX1 END1) (= INDEX2 END2)) (* return index if string1 shorter, NIL if they're the same *) (COND ((NOT (= SLEN1 SLEN2)) INDEX1) (T NIL))) (DECLARE (TYPE FIXNUM INDEX1 INDEX2)) (SETQ CHAR1 (CHAR STRING1 INDEX1)) (SETQ CHAR2 (CHAR STRING2 INDEX2)) (COND [(NOT (CHAR-EQUAL CHAR1 CHAR2)) (COND ((CHAR-LESSP CHAR1 CHAR2) (RETURN INDEX1)) (T (RETURN NIL] (T NIL]) (STRING-GREATERP [CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* raf " 5-Dec-85 04:11") (* Given two strings, if the first string is lexicographically greater than the second string, returns the longest common prefix (using char-equal) of the two strings. Otherwise, returns NIL . *) (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((SLEN1 (- END1 START1)) (SLEN2 (- END2 START2))) (DECLARE (TYPE FIXNUM SLEN1 SLEN2)) (* prevent endless looping later. *) (COND ((OR (MINUSP SLEN1) (MINUSP SLEN2)) (CL:ERROR "Improper bounds for string comparison.")) (T NIL)) (CL:DO ((INDEX1 START1 (1+ INDEX1)) (INDEX2 START2 (1+ INDEX2)) (CHAR1) (CHAR2)) ((OR (= INDEX1 END1) (= INDEX2 END2)) (* return index if string1 shorter, NIL if they're the same *) (COND ((NOT (= SLEN1 SLEN2)) INDEX1) (T NIL))) (DECLARE (TYPE FIXNUM INDEX1 INDEX2)) (SETQ CHAR1 (CHAR STRING1 INDEX1)) (SETQ CHAR2 (CHAR STRING2 INDEX2)) (COND [(NOT (CHAR-EQUAL CHAR1 CHAR2)) (COND ((CHAR-GREATERP CHAR1 CHAR2) (RETURN INDEX1)) (T (RETURN NIL] (T NIL]) (STRING-NOT-GREATERP [CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* raf " 5-Dec-85 04:12") (* Given two strings, if the first string is lexicographically less than or equal to the second string, returns the longest common prefix (using char-equal) of the two strings. Otherwise, returns NIL . *) (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((SLEN1 (- END1 START1)) (SLEN2 (- END2 START2))) (DECLARE (TYPE FIXNUM SLEN1 SLEN2)) (* prevent endless looping later. *) (COND ((OR (MINUSP SLEN1) (MINUSP SLEN2)) (CL:ERROR "Improper bounds for string comparison.")) (T NIL)) (CL:DO ((INDEX1 START1 (1+ INDEX1)) (INDEX2 START2 (1+ INDEX2)) (CHAR1) (CHAR2)) ((OR (= INDEX1 END1) (= INDEX2 END2)) (* return index if string1 shorter, NIL if they're the same *) INDEX1) (DECLARE (TYPE FIXNUM INDEX1 INDEX2)) (SETQ CHAR1 (CHAR STRING1 INDEX1)) (SETQ CHAR2 (CHAR STRING2 INDEX2)) (COND [(NOT (CHAR-EQUAL CHAR1 CHAR2)) (COND ((NOT (CHAR-GREATERP CHAR1 CHAR2)) (RETURN INDEX1)) (T (RETURN NIL] (T NIL]) (STRING-NOT-LESSP [CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* raf " 5-Dec-85 04:12") (* Given two strings, if the first string is lexicographically greater than or equal to the second string, returns the longest common prefix (using char-equal) of the two strings. Otherwise, returns NIL . *) (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((SLEN1 (- END1 START1)) (SLEN2 (- END2 START2))) (DECLARE (TYPE FIXNUM SLEN1 SLEN2)) (* prevent endless looping later. *) (COND ((OR (MINUSP SLEN1) (MINUSP SLEN2)) (CL:ERROR "Improper bounds for string comparison.")) (T NIL)) (CL:DO ((INDEX1 START1 (1+ INDEX1)) (INDEX2 START2 (1+ INDEX2)) (CHAR1) (CHAR2)) ((OR (= INDEX1 END1) (= INDEX2 END2)) (* return index if string1 shorter, NIL if they're the same *) INDEX1) (DECLARE (TYPE FIXNUM INDEX1 INDEX2)) (SETQ CHAR1 (CHAR STRING1 INDEX1)) (SETQ CHAR2 (CHAR STRING2 INDEX2)) (COND [(NOT (CHAR-EQUAL CHAR1 CHAR2)) (COND ((NOT (CHAR-LESSP CHAR1 CHAR2)) (RETURN INDEX1)) (T (RETURN NIL] (T NIL]) (STRING-NOT-EQUAL [CL:LAMBDA (STRING1 STRING2 &KEY (START1 0) END1 (START2 0) END2) (* raf " 5-Dec-85 04:13") (* Given two strings, if the first string is not lexicographically equal to the second string, returns the longest common prefix (using char-equal) of the two strings. Otherwise, returns NIL . *) (WITH-TWO-STRINGS STRING1 STRING2 START1 END1 START2 END2 (LET ((SLEN1 (- END1 START1)) (SLEN2 (- END2 START2))) (DECLARE (TYPE FIXNUM SLEN1 SLEN2)) (* prevent endless looping later. *) (COND ((OR (MINUSP SLEN1) (MINUSP SLEN2)) (CL:ERROR "Improper bounds for string comparison.")) (T NIL)) (COND ((OR (MINUSP SLEN1) (OR (MINUSP SLEN2))) (CL:ERROR "Improper substring for comparison.")) [(= SLEN1 SLEN2) (CL:DO ((INDEX1 START1 (1+ INDEX1)) (INDEX2 START2 (1+ INDEX2))) ((= INDEX1 END1) NIL) (DECLARE (TYPE FIXNUM INDEX1 INDEX2)) (COND ((NOT (CHAR-EQUAL (CHAR STRING1 INDEX1) (CHAR STRING2 INDEX2))) (RETURN INDEX1)) (T NIL] [(< SLEN1 SLEN2) (CL:DO ((INDEX1 START1 (1+ INDEX1)) (INDEX2 START2 (1+ INDEX2))) ([OR (= INDEX1 END1) (NOT (CHAR-EQUAL (CHAR STRING1 INDEX1) (CHAR STRING2 INDEX2] INDEX1) (DECLARE (TYPE FIXNUM INDEX1 INDEX2] (T (CL:DO ((INDEX1 START1 (1+ INDEX1)) (INDEX2 START2 (1+ INDEX2))) ([OR (= INDEX2 END2) (NOT (CHAR-EQUAL (CHAR STRING1 INDEX1) (CHAR STRING2 INDEX2] INDEX1) (DECLARE (TYPE FIXNUM INDEX1 INDEX2]) (MAKE-STRING [CL:LAMBDA (SIZE &KEY INITIAL-ELEMENT) (* lmm " 5-Sep-85 02:36") (ALLOCSTRING SIZE (AND INITIAL-ELEMENT (CHAR-INT INITIAL-ELEMENT]) (STRING-UPCASE [CL:LAMBDA (STRING &KEY (START 0) END) (* raf " 4-Dec-85 23:59") (* Given a string, returns a new string that is a copy of it with all lower case alphabetic characters converted to uppercase. *) (WITH-ONE-STRING STRING START END (FOR-SUBSTRING STRING START END NEWSTRING INDEX (SETF (CHAR NEWSTRING INDEX) (CHAR-UPCASE (CHAR STRING INDEX]) (STRING-DOWNCASE [CL:LAMBDA (STRING &KEY (START 0) END) (* raf " 4-Dec-85 23:59") (* Given a string, returns a new string that is a copy of it with all upper case alphabetic characters converted to lowercase. *) (WITH-ONE-STRING STRING START END (FOR-SUBSTRING STRING START END NEWSTRING INDEX (SETF (CHAR NEWSTRING INDEX) (CHAR-DOWNCASE (CHAR STRING INDEX]) (STRING-CAPITALIZE [CL:LAMBDA (STRING &KEY (START 0) END) (* raf " 4-Dec-85 23:59") (* Given a string, returns a copy of the string with the first character of each ``word'' converted to upper-case, and remaining chars in the word converted to lower case. A ``word'' is defined to be a string of case-modifiable characters delimited by non-case-modifiable chars. *) (WITH-ONE-STRING STRING START END (LET ((NEWWORD T) CHAR) (FOR-SUBSTRING STRING START END NEWSTRING INDEX (SETQ CHAR (CHAR STRING INDEX)) [COND ((NOT (ALPHANUMERICP CHAR)) (SETQ NEWWORD T)) (NEWWORD (* char is first case-modifiable after non-case-modifiable *) (SETQ CHAR (CHAR-UPCASE CHAR)) (SETQ NEWWORD NIL)) (T (* char is case-modifiable, but not first *) (SETQ CHAR (CHAR-DOWNCASE CHAR] (SETF (CHAR NEWSTRING INDEX) CHAR]) (NSTRING-UPCASE (CL:LAMBDA (STRING &KEY (START 0) END) (* raf " 5-Dec-85 03:21") (* Given a string, returns that string with all lower case alphabetic characters converted to uppercase. *) (WITH-ONE-STRING STRING START END [for INDEX from START to (1- END) do (SETF (CHAR STRING INDEX) (CHAR-UPCASE (CHAR STRING INDEX] STRING))) (NSTRING-DOWNCASE (CL:LAMBDA (STRING &KEY (START 0) END) (* raf " 5-Dec-85 03:21") (* Given a string, returns that string with all upper case alphabetic characters converted to lowercase. *) (WITH-ONE-STRING STRING START END [for INDEX from START to (1- END) do (SETF (CHAR STRING INDEX) (CHAR-DOWNCASE (CHAR STRING INDEX] STRING))) (NSTRING-CAPITALIZE (CL:LAMBDA (STRING &KEY (START 0) END) (* raf " 5-Dec-85 03:22") (* Given a string, returns that string with the first character of each ``word'' converted to upper-case, and remaining chars in the word converted to lower case. A ``word'' is defined to be a string of case-modifiable characters delimited by non-case-modifiable chars. *) (WITH-ONE-STRING STRING START END (LET (CHAR (NEWWORD T)) (for INDEX from START to (1- END) do (SETQ CHAR (CHAR STRING INDEX)) [COND ((NOT (ALPHANUMERICP CHAR)) (SETQ NEWWORD T)) (NEWWORD (* char is first case-modifiable after non-case-modifiable *) (SETQ CHAR (CHAR-UPCASE CHAR)) (SETQ NEWWORD NIL)) (T (* char is case-modifiable, but not first *) (SETQ CHAR (CHAR-DOWNCASE CHAR] (SETF (CHAR STRING INDEX) CHAR)) STRING)))) (STRING-LEFT-TRIM [CL:LAMBDA (CHAR-BAG STRING) (* raf " 5-Dec-85 04:13") (* Given a set of characters (a list or string) and a string, returns a copy of the string with the characters in the set removed from the left end. *) (WITH-STRING STRING (CL:DO ((INDEX START (1+ INDEX))) ((OR (= INDEX END) (NOT (CL:FIND (CHAR STRING INDEX) CHAR-BAG))) (SUBSEQ (THE STRING STRING) INDEX END)) (DECLARE (TYPE FIXNUM INDEX]) (STRING-RIGHT-TRIM [CL:LAMBDA (CHAR-BAG STRING) (* raf " 5-Dec-85 04:13") (* Given a set of characters (a list or string) and a string, returns a copy of the string with the characters in the set removed from the right end. *) (WITH-STRING STRING (CL:DO ((INDEX (1- END) (1- INDEX))) ((OR (< INDEX START) (NOT (CL:FIND (CHAR STRING INDEX) CHAR-BAG))) (SUBSEQ (THE STRING STRING) START (1+ INDEX))) (DECLARE (TYPE FIXNUM INDEX]) (STRING-TRIM [CL:LAMBDA (CHAR-BAG STRING) (* raf " 5-Dec-85 04:13") (* Given a set of characters (a list or string) and a string, returns a copy of the string with the characters in the set removed from both ends. *) (WITH-STRING STRING (LET ((LEFT-END) (RIGHT-END)) (DECLARE (TYPE FIXNUM LEFT-END RIGHT-END)) (CL:DO ((INDEX START (1+ INDEX))) ((OR (= INDEX END) (NOT (CL:FIND (CHAR STRING INDEX) CHAR-BAG))) (SETQ LEFT-END INDEX)) (DECLARE (TYPE FIXNUM INDEX))) (CL:DO ((INDEX (1- END) (1- INDEX))) ((OR (< INDEX LEFT-END) (NOT (CL:FIND (CHAR STRING INDEX) CHAR-BAG))) (SETQ RIGHT-END INDEX)) (DECLARE (TYPE FIXNUM INDEX))) (SUBSEQ (THE STRING STRING) LEFT-END (1+ RIGHT-END]) ) (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDTOVAR NLAMA ) (ADDTOVAR NLAML ) (ADDTOVAR LAMA NSTRING-CAPITALIZE NSTRING-DOWNCASE NSTRING-UPCASE STRING-CAPITALIZE STRING-DOWNCASE STRING-UPCASE MAKE-STRING STRING-NOT-EQUAL STRING-NOT-LESSP STRING-NOT-GREATERP STRING-GREATERP STRING-LESSP STRING/= STRING= STRING>= STRING<= STRING> STRING<) ) (PUTPROPS CMLSTRING COPYRIGHT ("Xerox Corporation" 1985)) (DECLARE: DONTCOPY (FILEMAP (NIL (4595 26557 (STRING 4605 . 5199) (\SP-STRING-COMPARE 5201 . 5781) (STRING=* 5783 . 5996) (STRING/=* 5998 . 6227) (STRING<* 6229 . 6768) (STRING>* 6770 . 7309) (STRING<=* 7311 . 7866) ( STRING>=* 7868 . 8423) (STRING< 8425 . 8867) (STRING> 8869 . 9314) (STRING<= 9316 . 9771) (STRING>= 9773 . 10232) (STRING= 10234 . 10660) (STRING/= 10662 . 11109) (STRING-LESSP 11111 . 12742) ( STRING-GREATERP 12744 . 14384) (STRING-NOT-GREATERP 14386 . 15968) (STRING-NOT-LESSP 15970 . 17550) ( STRING-NOT-EQUAL 17552 . 19594) (MAKE-STRING 19596 . 19786) (STRING-UPCASE 19788 . 20333) ( STRING-DOWNCASE 20335 . 20884) (STRING-CAPITALIZE 20886 . 22124) (NSTRING-UPCASE 22126 . 22667) ( NSTRING-DOWNCASE 22669 . 23214) (NSTRING-CAPITALIZE 23216 . 24397) (STRING-LEFT-TRIM 24399 . 24961) ( STRING-RIGHT-TRIM 24963 . 25565) (STRING-TRIM 25567 . 26555))))) STOP