;;; -*- Mode:LISP; Package:USER; Base:10 -*- ;;; $Header: /ct/ctlisp/ctstrl.l,v 1.5 84/02/10 11:03:34 bill Exp $ ;;; $Log: /ct/ctlisp/ctstrl.l,v $ ;;;Revision 1.5 84/02/10 11:03:34 bill ;;;Fixed ct_string_article and ct_string_words to accept the null string. ;;;Fixed ct_character to detect the null string on Franz. ;;; ;;;Revision 1.4 83/11/22 17:31:20 bill ;;;Removed cons'ing involved in uses of substringn to get a single character. ;;; ;;;Revision 1.3 83/10/21 15:08:21 bill ;;;Fixed ct_nthchar to understand null strings better. Touched up ct_character. ;;; ;;;Revision 1.2 83/10/18 10:37:17 bill ;;;Changed the loading of the c code to be done with an interface file. Cleaned ;;;up ct_character and ct_nthchar. ;;; ;;;Revision 1.1 83/10/06 10:46:25 bill ;;;Initial revision ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; ctstrl.l ;;; ;;; ;;; ;;; William Brew 9-15-83 ;;; ;;; ;;; ;;; Compatable string package for ct lisp dialects. The string ;;; ;;; functions are based very closely on the LM-2 string functions. ;;; ;;; The reader is refered to the LM-2 manual for details of the ;;; ;;; use of the functions. ;;; ;;; ;;; ;;; This file is part of a proprietary software project. Source ;;; ;;; code and documentation describing implementation details are ;;; ;;; available on a confidential, non-disclosure basis only. These ;;; ;;; materials, including this file in particular, are trade secrets ;;; ;;; of Computer * Thought Corporation. ;;; ;;; ;;; ;;; (c) Copyright 1982 and 1983, Computer Thought Corporation. ;;; ;;; All Rights Reserved. ;;; ;;; ;;; ;;; Reference materials: ;;; ;;; Foderaro and Sklower, The FRANZ LISP Manual, September 1981. ;;; ;;; Weinreb and Moon, LISP MACHINE MANUAL, Symbolics, July 1981. ;;; ;;; Charniak et al., 1980. Artificial Intelligence Programming. ;;; ;;; Miller, 1982. The C*T Ada Tutor: Guide to the Implementation. ;;; ;;; ;;; ;;; The following code assumes familiarity with these materials. ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Ensure presence of needed files. (comment Assumes ct_load and some suitable file_map are present) (eval-when (compile load eval) (ct_load 'aip)) ;AIP macros pkg. (eval-when (compile load eval) (ct_load 'compat)) ;Franz/LM compat pkg. #+franz (eval-when (load eval) (ct_load 'ctstrlc)) ;Lisp interface to c code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Compiler Declarations and Global Variables -- #+franz (declare (macros t)) #+franz (defvar alphabetic_case_affects_string_comparison nil "Case flag for comparisons. Nil -> ignore case. T -> use case." ) #+franz (defconst *caseshift* (- #/a #/A) "The difference between a lower and upper case letter." ) #+franz (defconst *up_pattern* nil "A translate pattern for shifting to upper case (initialized later)." ) #+franz (defconst *down_pattern* nil "A translate pattern for shifting to lower case (initialized later)." ) #+franz (defconst *change_pattern* nil "A translate pattern for shifting to the other case (initialized later)." ) (defconst *ms* 99999999 "The maximum length strings." ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Macro definitions -- ; Case flag for the c functions #+franz (defmacro ccasef () '(ct_if alphabetic_case_affects_string_comparison 1 0) ) ; Find the differance between two characters using the case flag. #+franz (defmacro chardiff (ch1 ch2 flag) `(ct_if ,flag (- ,ch1 ,ch2) (- ,ch1 (ct_char_samecase ,ch1 ,ch2)) ) ) ; Check if a character is lower case #+franz (defmacro char_lowerp (ch) `(and (< #/` ,ch) (< ,ch #/{)) ) #+lispm (defmacro char_lowerp (ch) `(= ,ch (char-downcase ,ch)) ) ; Check if a character is upper case #+franz (defmacro char_upperp (ch) `(and (< #/@ ,ch) (< ,ch #/[)) ) #+lispm (defmacro char_upperp (ch) `(= ,ch (char-upcase ,ch)) ) ; Check if a character is a vowel (defmacro vowelp (ch) `(memq (ct_character ,ch) '(#/a #/e #/i #/o #/u #/y #/A #/E #/I #/O #/U #/Y)) ) ; Return an index from a c function #+franz (defmacro return_index (form) `(let ((index ,form)) (ct_if (= index -1) nil index) ) ) ; Get a fresh copy of a string. String coersion is applied. #+franz (defmacro fresh_string (thing) `(get_pname (uconcat (ct_string ,thing))) ) #+lispm (defmacro fresh_string (thing) `(string-append ,thing) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Flavor definitions -- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Externally Callable Functions/Methods -- ;;;;;;;;;;;;;; ; Some basics ;;;;;;;;;;;;;; ; ; Make get pname work in both dialects with both an underscore and a hyphen ; #+franz (eval-when (compile load eval) (putd 'get-pname (getd 'get_pname))) #+lispm (eval-when (compile load eval) (fset 'get_pname (fsymeval 'get-pname))) ;;;;;;;;;;;;; ; Characters ;;;;;;;;;;;;; ; ; Check if a fixnum is a legal character ; #+franz (defun ct_characterp (thing) (and (fixp thing) (< -1 thing) (< thing 128)) ) #+lispm (defun ct_characterp (thing) (and (fixp thing) (< -1 thing) (< thing 256)) ) ; ; Coerce a thing to a single fixnum character ; #+franz (defun ct_character (ch) (cond ((ct_characterp ch) ch) ((symbolp ch) (substringn ch 1 0)) ((and (stringp ch) (substringn ch 1 0))) (t (error ch "cannot be coerced to a character")) ) ) #+lispm-on-a-clear-day-you-can-see-forever-damnit (eval-when (compile load eval) (fset 'ct_character (fsymeval 'character))) #+Lispm (defun ct_character (ch) (cond ((ct_characterp ch) ch) ((symbolp ch) (aref (string ch) 0)) ((stringp ch) (aref ch 0)) (t (ferror "Object cannot be coerced to a character: ~S" ch)))) ; ; Get the nth character of a string. ; #+franz (defun ct_nthchar (string n) (substringn (ct_string string) (1+ n) 0) ) #+lispm (defun ct_nthchar (string n) (aref (string string) n) ) ; ; Compare two characters for equality. Uses the case flag. ; #+franz (defun ct_char_equal (ch1 ch2) (setq ch1 (ct_character ch1)) (setq ch2 (ct_character ch2)) (= (chardiff ch1 ch2 alphabetic_case_affects_string_comparison) 0) ) #+lispm (eval-when (compile load eval) (fset 'ct_char_equal (fsymeval 'char-equal))) ; ; Compare two characters for less then. Uses the case flag. ; #+franz (defun ct_char_lessp (ch1 ch2) (setq ch1 (ct_character ch1)) (setq ch2 (ct_character ch2)) (< (chardiff ch1 ch2 alphabetic_case_affects_string_comparison) 0) ) #+lispm (eval-when (compile load eval) (fset 'ct_char_lessp (fsymeval 'char-lessp))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Upper and lower case letters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Convert a character to upper case. ; #+franz (defun ct_char_upcase (ch) (setq ch (ct_character ch)) (ct_if (char_lowerp ch) (- ch *caseshift*) ch ) ) #+lispm (eval-when (compile load eval) (fset 'ct_char_upcase (fsymeval 'char-upcase))) ; ; Convert a character to lower case. ; #+franz (defun ct_char_downcase (ch) (setq ch (ct_character ch)) (ct_if (char_upperp ch) (+ ch *caseshift*) ch ) ) #+lispm (eval-when (compile load eval) (fset 'ct_char_downcase (fsymeval 'char-downcase))) ; ; Convert a character to the opposite case. ; (defun ct_char_changecase (ch) (setq ch (ct_character ch)) (ct_if (char_lowerp ch) (ct_char_upcase ch) (ct_char_downcase ch) ) ) ; ; Convert ch2 to the same case as ch1. ; (defun ct_char_samecase (ch1 ch2) (setq ch1 (ct_character ch1)) (cond ((char_lowerp ch1) (ct_char_downcase ch2)) ((char_upperp ch1) (ct_char_upcase ch2)) (t ch2) ) ) ; ; Convert a string to upper case via the string translate function. First ; we get a new string via substring. ; #+franz (defun ct_string_upcase (string &optional (from 0) (to *ms*)) (nstrtranslate (ct_substring string from to) *up_pattern* 0 *ms*) ) #+lispm (defun ct_string_upcase (string &optional (from 0) (to nil)) (string-upcase (substring string from to)) ) ; ; Convert a string to lower case via the string translate function. First ; we get a new string via substring. ; #+franz (defun ct_string_downcase (string &optional (from 0) (to *ms*)) (nstrtranslate (ct_substring string from to) *down_pattern* 0 *ms*) ) #+lispm (defun ct_string_downcase (string &optional (from 0) (to nil)) (string-downcase (substring string from to)) ) ; ; Convert a string to opposite case via the string translate function. First ; we get a new string via substring. ; #+franz (defun ct_string_changecase (string &optional (from 0) (to *ms*)) (nstrtranslate (ct_substring string from to) *change_pattern* 0 *ms*) ) #+lispm (defun ct_string_changecase (string &optional (from 0) (to nil)) (ct_string_nchangecase (substring string from to)) ) ; ; Convert a string to the same case as ch. Substring it if necessary. ; (defun ct_string_samecase (ch string &optional (from 0) (to #+franz *ms* #+lispm nil)) (cond ((char_lowerp ch) (ct_string_downcase string from to)) ((char_upperp ch) (ct_string_upcase string from to)) (t (ct_substring string from to)) ) ) ; ; Convert the string to upper case. Over write the affected portion of the string. ; #+franz (defun ct_string_nupcase (string &optional (from 0) (to *ms*)) (cond ((stringp string) (nstrtranslate string *up_pattern* from to)) ((ct_characterp string) (ct_char_upcase string)) (t (error string "cannot be up cased in place")) ) ) #+lispm (defun ct_string_nupcase (string &optional (from 0) (to nil)) (and (null to) (setq to *ms*)) (cond ((stringp string) (loop for i from from to (min to (1- (string-length string))) do (aset (char-upcase (aref string i)) string i) ) string ) ((ct_characterp string) (string-upcase string)) (t (error "cannot string up case in place") ) ) ) ; ; Convert the string to lower case. Over write the affected portion of the string. ; #+franz (defun ct_string_ndowncase (string &optional (from 0) (to *ms*)) (cond ((stringp string) (nstrtranslate string *down_pattern* from to)) ((ct_characterp string) (ct_char_downcase string)) (t (error string "cannot be down cased in place")) ) ) #+lispm (defun ct_string_ndowncase (string &optional (from 0) (to nil)) (and (null to) (setq to *ms*)) (cond ((stringp string) (loop for i from from to (min to (1- (string-length string))) do (aset (char-downcase (aref string i)) string i) ) string ) ((ct_characterp string) (string-downcase string)) (t (error "cannot string down case in place")) ) ) ; ; Convert the string to opposite case. Over write the affected portion of ; the string. ; #+franz (defun ct_string_nchangecase (string &optional (from 0) (to *ms*)) (cond ((stringp string) (nstrtranslate string *change_pattern* from to)) ((ct_characterp string) (ct_char_changecase string)) (t (error string "cannot be up cased in place")) ) ) #+lispm (defun ct_string_nchangecase (string &optional (from 0) (to nil)) (and (null to) (setq to *ms*)) (cond ((stringp string) (loop for i from from to (min to (1- (string-length string))) do (aset (ct_char_changecase (aref string i)) string i) ) string ) ((ct_characterp string) (string (ct_char_changecase string))) (t (error "cannot string change case in place")) ) ) ; ; Convert the string to the same case as ch. Overwrite the affected portion. ; (defun ct_string_nsamecase (ch string &optional (from 0) (to #+franz *ms* #+lispm nil)) (cond ((char_lowerp ch) (ct_string_ndowncase string from to)) ((char_upperp ch) (ct_string_nupcase string from to)) (t (ct_string string)) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;; ; Basic string operations ;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Define a ct version of stringp ; #+franz (eval-when (compile load eval) (putd 'ct_stringp (getd 'stringp))) #+lispm (eval-when (compile load eval) (fset 'ct_stringp (fsymeval 'stringp))) ; ; Coerce a thing to a string. ; #+franz (defun ct_string (&optional (thing "")) (cond ((stringp thing) thing) ((symbolp thing) (get_pname thing)) ((ct_characterp thing) (get_pname (ascii thing))) (t (error thing "cannot be coerced to a string")) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string (fsymeval 'string))) ; ; Get the length of a string. ; #+franz (defun ct_string_length (str) (flatc (ct_string str)) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_length (fsymeval 'string-length))) ; ; Compare two strings for equality. Use the case flag. Substring if necessary. ; #+franz (defun ct_string_equal (str1 str2 &optional (idx1 0) (idx2 0) (lim1 *ms*) (lim2 *ms*)) (= 0 (strdiff (ct_string str1) (ct_string str2) (fix idx1) (fix idx2) (fix lim1) (fix lim2) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_equal (fsymeval 'string-equal))) ; ; Compare two strings for less than. Use the case flag. Substring if necessary. ; #+franz (defun ct_string_lessp (str1 str2 &optional (idx1 0) (idx2 0) (lim1 *ms*) (lim2 *ms*)) (> 0 (strdiff (ct_string str1) (ct_string str2) (fix idx1) (fix idx2) (fix lim1) (fix lim2) (ccasef) ) ) ) #+lispm (defun ct_string_lessp (str1 str2 &optional (idx1 0) (idx2 0) (lim1 nil) (lim2 nil)) (string-lessp (substring str1 idx1 lim1) (substring str2 idx2 lim2)) ) ; ; Get the portion of the string from from up to but not including to. ; Return the null string if out of range. ; #+franz (defun ct_substring (string from &optional (to *ms*)) (cond ((substring (ct_string string) (1+ from) (- to from))) (t "") ) ) #+lispm (eval-when (compile load eval) (fset 'ct_substring (fsymeval 'substring))) ; ; Append a bunch of string coercable things into one big string. ; #+franz (defun ct_string_append (&rest args) (get_pname (apply 'uconcat (mapcar 'ct_string args))) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_append (fsymeval 'string-append))) ; ; Trim the characters in char_set from both ends of string. Return a new ; substring. ; #+franz (defun ct_string_trim (char_set string &optional (from 0) (to *ms*)) (ct_string_right_trim char_set (ct_string_left_trim char_set string from to)) ) #+lispm (defun ct_string_trim (char_set string &optional (from 0) (to nil)) (string-trim char_set (substring string from to)) ) ; ; Trim the characters in char_set from the left end of string. Return a new ; substring. ; #+franz (defun ct_string_left_trim (char_set string &optional (from 0) (to *ms*)) (setq string (ct_string string)) (let ((index (ct_string_search_not_set char_set string from to))) (ct_if index (substring string (1+ index) (- to index)) "" ) ) ) #+lispm (defun ct_string_left_trim (char_set string &optional (from 0) (to nil)) (string-left-trim char_set (substring string from to)) ) ; ; Trim the characters in char_set from the right end of string. Return a ; new substring. (note the reversed nature of from and to) ; #+franz (defun ct_string_right_trim (char_set string &optional (from *ms*) (to 0)) (setq string (ct_string string)) (let ((index (ct_string_reverse_search_not_set char_set string from to))) (ct_if index (substring string (1+ to) (- index to -1)) "" ) ) ) #+lispm (defun ct_string_right_trim (char_set string &optional (from nil) (to 0)) (string-right-trim char_set (substring string to from)) ) ; ; Return a new string which is the reverse of string. ; #+franz (defun ct_string_reverse (string &optional (from 0) (to *ms*)) (nstrreverse (fresh_string string) (fix from) (fix to)) ) #+lispm (defun ct_string_reverse (string &optional (from 0) (to nil)) (string-reverse (substring string from to)) ) ; ; Reverse a string in place. ; #+franz (defun ct_string_nreverse (string &optional (from 0) (to *ms*)) (cond ((stringp string) (nstrreverse string (fix from) (fix to))) ((ct_characterp string) string) (t (error string "cannot be reversed in place")) ) ) ; --NB note, this does not limit the range of the reversal as does the franz ; version #+lispm (eval-when (compile load eval) (fset 'ct_string_nreverse (fsymeval 'string-nreverse)) ) ; ; Return a new string which is the pluaral of string. ; #+franz (defun ct_string_pluralize (string) (setq string (ct_string string)) (and (equal string "") (error "the null string cannot be pluralized")) (let* (flush add (old_case_flag alphabetic_case_affects_string_comparison) (last_char_raw (substringn string -1 0)) (last_char (ct_char_upcase last_char_raw)) (penult_char (and (> (ct_string_length string) 1) (ct_char_upcase (substringn string -2 0)) ) ) (last_3 (substring string -3 3)) ) (unwind-protect (progn (setq alphabetic_case_affects_string_comparison nil) (cond ((and (= last_char #/Y) (not (memq penult_char '(#/A #/E #/I #/O #/U)))) (setq flush 1 add "ies")) ((or (ct_string_equal string "ox") (ct_string_equal string "vax") ) (setq add "en")) ((or (and (= last_char #/H) (memq penult_char '(#/C #/S))) (memq last_char '(#/S #/Z #/X))) (setq add "es")) ((ct_string_equal last_3 "man") (setq flush 2 add "en")) ((ct_string_equal last_3 "ife") (setq flush 2 add "ves")) (t (setq add "s"))) (and flush (setq string (substring string 1 (- (ct_string_length string) flush)) ) ) (ct_string_append string (ct_string_samecase last_char_raw add)) ) (setq alphabetic_case_affects_string_comparison old_case_flag) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_pluralize (fsymeval 'string-pluralize)) ) ; ; Return the article which is appropriate for putting in front of string. Special ; case for the null string. ; (defun ct_string_article (string) (cond ((equal string "") "") ((vowelp string) "an") (t "a") ) ) ; ; Return a new string like string but with the first letter upper case. ; (defun ct_string_capitalize (string) (ct_string_nupcase (fresh_string string) 0 1) ) ; ; Put a bunch of words together into a string. Do the right thing with ; punctuation and spacing. ; (defun ct_string_words (&rest word_list) (apply 'ct_string_append (loop with squoted = nil with dquoted = nil for word in word_list for wordstr = (ct_string word) for this = (sp_type wordstr squoted dquoted) and last = 'noafter then this unless (or (eq this 'nobefore) (eq this 'never) (eq last 'noafter) (eq last 'never) ) collect " " collect wordstr ) ) ) ;;;;;;;;;;;;;;;;;;; ; String searching ;;;;;;;;;;;;;;;;;;; ; ; Return the index of the first occurence of char in string. Use the case flag. ; #+franz (defun ct_string_search_char (char string &optional (from 0) (to *ms*)) (return_index (charindexf (ct_character char) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_search_char (fsymeval 'string-search-char)) ) ; ; Return the index of the first non occurence of char in string. Use the caseflag. ; #+franz (defun ct_string_search_not_char (char string &optional (from 0) (to *ms*)) (return_index (charindexfn (ct_character char) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_search_not_char (fsymeval 'string-search-not-char)) ) ; ; Return the index of the first occurence of the key in string. Use the case ; flag. ; #+franz (defun ct_string_search (key string &optional (from 0) (to *ms*)) (return_index (strindexf (ct_string key) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_search (fsymeval 'string-search)) ) ; ; Return the first occurence of any char in char set in the string string. Use the ; case flag. ; #+franz (defun ct_string_search_set (char_set string &optional (from 0) (to *ms*)) (and (listp char_set) (setq char_set (maknam (mapcar 'ct_character char_set)))) (return_index (charsetindexf (ct_string char_set) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_search_set (fsymeval 'string-search-set)) ) ; ; Return the index of the first occurence of any character not in char set ; in the string string. Use the case flag. ; #+franz (defun ct_string_search_not_set (char_set string &optional (from 0) (to *ms*)) (and (listp char_set) (setq char_set (maknam (mapcar 'ct_character char_set)))) (return_index (charsetindexfn (ct_string char_set) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_search_not_set (fsymeval 'string-search-not-set)) ) ; ; Return the index of the last occurence of char in string. Use the case flag. ; Note the reversed nature of from and to. ; #+franz (defun ct_string_reverse_search_char (char string &optional (from *ms*) (to 0)) (return_index (charindexr (ct_character char) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_reverse_search_char (fsymeval 'string-reverse-search-char) ) ) ; ; Return the last non occurence of char in string. Use the case flag. ; Note the reversed nature of from and to. #+franz (defun ct_string_reverse_search_not_char (char string &optional (from *ms*) (to 0)) (return_index (charindexrn (ct_character char) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_reverse_search_not_char (fsymeval 'string-reverse-search-not-char) ) ) ; ; Return the last occurence of key in string. Use the caseflag. Note the ; reversed nature of from and to. ; #+franz (defun ct_string_reverse_search (key string &optional (from *ms*) (to 0)) (return_index (strindexr (ct_string key) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_reverse_search (fsymeval 'string-reverse-search)) ) ; ; Return the last occurence of any char in char set in string. Use the case flag. ; Note the reversed nature of from and to. ; #+franz (defun ct_string_reverse_search_set (char_set string &optional (from *ms*) (to 0)) (and (listp char_set) (setq char_set (maknam (mapcar 'ct_character char_set)))) (return_index (charsetindexr (ct_string char_set) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_reverse_search_set (fsymeval 'string-reverse-search-set) ) ) ; ; Return the last occurence of any char not in char set in string. Use the case ; flag. Note the reversed nature of from and to. ; #+franz (defun ct_string_reverse_search_not_set (char_set string &optional (from *ms*) (to 0)) (and (listp char_set) (setq char_set (maknam (mapcar 'ct_character char_set)))) (return_index (charsetindexrn (ct_string char_set) (ct_string string) (fix from) (fix to) (ccasef) ) ) ) #+lispm (eval-when (compile load eval) (fset 'ct_string_reverse_search_not_set (fsymeval 'string-reverse-search-not-set) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Internal Use Only Functions/Methods -- ; Put these here because they use the char_??? functions. #+franz (setq *up_pattern* (get_pname (maknam (cons 1 (loop for i from 1 to 127 collect (ct_char_upcase i) ) ) ) ) ) #+franz (setq *down_pattern* (get_pname (maknam (cons 1 (loop for i from 1 to 127 collect (ct_char_downcase i) ) ) ) ) ) #+franz (setq *change_pattern* (get_pname (maknam (cons 1 (loop for i from 1 to 127 collect (ct_char_changecase i) ) ) ) ) ) ; Look for the type of spacing which is appropriate for a character. sq and ; dq are single and double quote counters respectively. (binary counters) (defun sp_type (chstr sq dq) (setq chstr (and (not (equal chstr "")) (ct_character chstr))) (cond ((null chstr) 'never) ((memq chstr '(#/. #/, #/; #/: #/? #/! #/% #/) #/] #/})) 'nobefore) ((memq chstr '(#/( #/[ #/{ #/$ #/` #/#)) 'noafter) ((= chstr #/_) 'never) ((= chstr #/') (setq sq (not sq)) (ct_if sq 'noafter 'nobefore) ) ((= chstr #/") (setq dq (not dq)) (ct_if dq 'noafter 'nobefore) ) ) ) ;;; eof ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;