scsh-checkins
[Top] [All Lists]

[Scsh-checkins] CVS: scsh/scsh/lib char-package.scm,NONE,1.1.2.1 cset-li

To: scsh-checkins@lists.sourceforge.net
Subject: [Scsh-checkins] CVS: scsh/scsh/lib char-package.scm,NONE,1.1.2.1 cset-lib.html,NONE,1.1.2.1 cset-lib.scm,NONE,1.1.2.1 cset-lib.txt,NONE,1.1.2.1 cset-obsolete.scm,NONE,1.1.2.1 cset-package.scm,NONE,1.1.2.1 cset-tests.scm,NONE,1.1.2.1 string-package.scm,NONE,1.1.2.1 ccp-pack.scm,1.1,1.1.2.1 ccp.scm,1.1,1.1.2.1 list-lib.scm,1.3,1.3.2.1 srfi-1.html,1.3,1.3.2.1 string-lib.scm,1.2,1.2.2.1
From: Olin Shivers <olin-shivers@usw-pr-cvs1.sourceforge.net>
Date: Sat, 10 Mar 2001 19:47:03 -0800
List-id: <scsh-checkins.lists.sourceforge.net>
Sender: scsh-checkins-admin@lists.sourceforge.net
Update of /cvsroot/scsh/scsh/scsh/lib
In directory usw-pr-cvs1:/tmp/cvs-serv11197/scsh/lib

Modified Files:
      Tag: srfi13and14_integration_2000_3_10
        ccp-pack.scm ccp.scm list-lib.scm srfi-1.html string-lib.scm 
Added Files:
      Tag: srfi13and14_integration_2000_3_10
        char-package.scm cset-lib.html cset-lib.scm cset-lib.txt 
        cset-obsolete.scm cset-package.scm cset-tests.scm 
        string-package.scm 
Log Message:
Integrated srfi-13 (string lib)& srfi-14 (char-set lib)
- Ported sources to use these libs instead of older string & cset libs
- Wrote backwards-compatibility libs for now-deprecated procs in the
  scsh API
- Hacked the makefile/package/interfaces glue
Whew.


--- NEW FILE ---
;;; These defs are things for characters *not* in SRFIs 13 & 14.
;;; It includes some R5RS defs that are not correct in S48 in a Latin-1 world.

(define-interface char-set-predicates-interface
  (export
   ((char-lower-case?           ; R5RS
     char-upper-case?           ; R5RS
     char-alphabetic?           ; R5RS
     char-numeric?              ; R5RS
     char-whitespace?           ; R5RS

     char-alphanumeric?         ; For compatibility w/old code

     char-letter?               ; Scsh
     char-digit?
     char-letter+digit?
     char-graphic?
     char-printing?
     char-blank?
     char-iso-control?
     char-punctuation?
     char-symbol?
     char-hex-digit?
     char-ascii?)               (proc (:char) :boolean))))


(define-structure char-set-predicates-lib char-set-predicates-interface
  (open error-package   ; ERROR
        scsh-utilities  ; DEPRECATED-PROC
        char-set-lib
        scheme)

  (begin
    ;; These are R5RS. We can't use the native S48 ones, because they
    ;; don't handle full Latin-1.
    (define (char-lower-case? c) (char-set-contains? char-set:lower-case c))
    (define (char-upper-case? c) (char-set-contains? char-set:upper-case c))
    (define (char-alphabetic? c) (char-set-contains? char-set:letter c))
    (define (char-numeric?    c) (char-set-contains? char-set:digit    c))
    (define (char-whitespace? c) (char-set-contains? char-set:whitespace c))

    ;; These are scsh extensions to R5RS.
    (define (char-letter?       c) (char-set-contains? char-set:letter       c))
    (define (char-digit?        c) (char-set-contains? char-set:digit        c))
    (define (char-letter+digit? c) (char-set-contains? char-set:letter+digit c))
    (define (char-graphic?      c) (char-set-contains? char-set:graphic      c))
    (define (char-printing?     c) (char-set-contains? char-set:printing     c))
    (define (char-blank?        c) (char-set-contains? char-set:blank        c))
    (define (char-iso-control?  c) (char-set-contains? char-set:iso-control  c))
    (define (char-punctuation?  c) (char-set-contains? char-set:punctuation  c))
    (define (char-symbol?       c) (char-set-contains? char-set:symbol       c))
    (define (char-hex-digit?    c) (char-set-contains? char-set:hex-digit    c))
    (define (char-ascii?        c) (char-set-contains? char-set:ascii        c))

    ;; Obsolete scsh.
    (define char-alphanumeric?
      (deprecated-proc char-letter+digit? 'char-alphanumeric?
                       "Use CHAR-LETTER+DIGIT? instead.")))
  (optimize auto-integrate))

--- NEW FILE ---
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
            "http://www.w3.org/TR/html4/loose.dtd";>
<!-- 
 - Do a paragraph check <p>
 - The Unicode char tables are messed up, but it can't be fixed w/o CSS2
   support, which I do not currently find in web browsers.
 - Can I have bangs, plusses, or slashes in #tags? Spaces?
        Yes: plus, bang, star   No: space  Yes: slash, question, ampersand
        You can't put sharp in a path, so anything goes, really.
        Nonetheless, some of these confuse Netscape, so I'll avoid them.
 -->

<!--========================================================================-->
<html lang=en-US>
  <head>
    <meta name="keywords" content="Scheme, programming language, list 
processing, SRFI, underage lesbian sluts">
    <link rev=made href="mailto:shivers@ai.mit.edu";>
    <title>SRFI 14: Character-set Library</title>

[...1977 lines suppressed...]
  LocalWords:  elba elbA ary consed XXXX ac bc kons knil ans plusses 
  LocalWords:  catamorphism lp eof lis cdr knull kar kdr anamorphism
  LocalWords:  abcdefg sfrom sto TCL perl slen rv exp initialisation
  LocalWords:  plen SJ PJ si sj pj IPORT iport patlen DF buf Bevan
  LocalWords:  Denheyer scsh Paolo Amoroso Arvestad Bawden Dybvig
  LocalWords:  Bornstein Bothner Egorov Feeley Matthias Felleisen
  LocalWords:  Flatt ucs Gleckler Goetter Sven Hartrumpf Hilsdale
  LocalWords:  Kiselyov Bengt Korb Kleberg Kolbly Shriram  bignum
  LocalWords:  Krishnamurthi Lucier Schilling Sobel Mikael Staldal
  LocalWords:  Tsyshevsky documentors Jaffer Sperber cltl AE fixnum
  LocalWords:  CommonLisp HyperSpec Clinger Rees SIGPLAN uniquified
  LocalWords:  cset EA DrScheme IEC conformant JIS xor diff Posix URL
  LocalWords:  FFF DIAERESIS abcdefghijklmnopqrstuvwxyz EB EC EF ETH
  LocalWords:  FA FB FC FD FF Ll AA diaeresis isLowerCase BA CB CC CE
  LocalWords:  CF DA DC Lt CARON PSILI Lu PROSGEGRAMMENI DASIA VARIA
  LocalWords:  OXIA PERISPOMENI FAA FAB FAC FAE FAF FBC FFC Lm Lo
  LocalWords:  abcdefABCDEF Zs Zl Zp OGHAM IDEOGRAPHIC Pc recognised
  LocalWords:  tokenizers iso Pd Ps Pe Pf AB BB BF Sm Sc Sk AF MACRON
  LocalWords:  PILCROW soh nul ops Shiro Kawai subform
-->

--- NEW FILE ---
;;; SRFI-14 character-sets library                              -*- Scheme -*-
;;;
;;; - Ported from MIT Scheme runtime by Brian D. Carlstrom.
;;; - Massively rehacked & extended by Olin Shivers 6/98.
;;; - Massively redesigned and rehacked 5/2000 during SRFI process.
;;; At this point, the code bears the following relationship to the
;;; MIT Scheme code: "This is my grandfather's axe. My father replaced
;;; the head, and I have replaced the handle." Nonetheless, we preserve
;;; the MIT Scheme copyright:
;;;     Copyright (c) 1988-1995 Massachusetts Institute of Technology
;;; The MIT Scheme license is a "free software" license. See the end of
;;; this file for the tedious details. 

;;; Exports:
;;; char-set? char-set= char-set<=
;;; char-set-hash 
;;; char-set-cursor char-set-ref char-set-cursor-next end-of-char-set?
;;; char-set-fold char-set-unfold char-set-unfold!
;;; char-set-for-each char-set-map
;;; char-set-copy char-set
;;;
;;; list->char-set  string->char-set 
;;; list->char-set! string->char-set! 
;;;
;;; filterchar-set  ucs-range->char-set  ->char-set
;;; filterchar-set! ucs-range->char-set!
;;;
;;; char-set->list char-set->string
;;;
;;; char-set-size char-set-count char-set-contains?
;;; char-set-every char-set-any
;;;
;;; char-set-adjoin  char-set-delete 
;;; char-set-adjoin! char-set-delete!
;;; 

;;; char-set-complement  char-set-union  char-set-intersection  
;;; char-set-complement! char-set-union! char-set-intersection! 
;;;
;;; char-set-difference  char-set-xor  char-set-diff+intersection
;;; char-set-difference! char-set-xor! char-set-diff+intersection!
;;;
;;; char-set:lower-case         char-set:upper-case     char-set:title-case
;;; char-set:letter             char-set:digit          char-set:letter+digit
;;; char-set:graphic            char-set:printing       char-set:whitespace
;;; char-set:iso-control        char-set:punctuation    char-set:symbol
;;; char-set:hex-digit          char-set:blank          char-set:ascii
;;; char-set:empty              char-set:full

;;; Imports
;;; This code has the following non-R5RS dependencies:
;;; - ERROR
;;; - %LATIN1->CHAR %CHAR->LATIN1
;;; - LET-OPTIONALS* and :OPTIONAL macros for parsing, checking & defaulting
;;;   optional arguments from rest lists.
;;; - BITWISE-AND for CHAR-SET-HASH
;;; - The SRFI-19 DEFINE-RECORD-TYPE record macro
;;; - A simple CHECK-ARG procedure: 
;;;   (lambda (pred val caller) (if (not (pred val)) (error val caller)))

;;; This is simple code, not great code. Char sets are represented as 256-char
;;; strings. If char I is ASCII/Latin-1 0, then it isn't in the set; if char I
;;; is ASCII/Latin-1 1, then it is in the set.
;;; - Should be rewritten to use bit strings or byte vecs.
;;; - Is Latin-1 specific. Would certainly have to be rewritten for Unicode.

;;; See the end of the file for porting and performance-tuning notes.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define-record-type :char-set
  (make-char-set s)
  char-set?
  (s char-set:s))


(define (%string-copy s) (substring s 0 (string-length s)))

;;; Parse, type-check & default a final optional BASE-CS parameter from
;;; a rest argument. Return a *fresh copy* of the underlying string.
;;; The default is the empty set. The PROC argument is to help us
;;; generate informative error exceptions.

(define (%default-base maybe-base proc)
  (if (pair? maybe-base)
      (let ((bcs  (car maybe-base))
            (tail (cdr maybe-base)))
        (if (null? tail)
            (if (char-set? bcs) (%string-copy (char-set:s bcs))
                (error "BASE-CS parameter not a char-set" proc bcs))
            (error "Expected final base char set -- too many parameters"
                   proc maybe-base)))
      (make-string 256 (%latin1->char 0))))

;;; If CS is really a char-set, do CHAR-SET:S, otw report an error msg on
;;; behalf of our caller, PROC. This procedure exists basically to provide
;;; explicit error-checking & reporting.

(define (%char-set:s/check cs proc)
  (let lp ((cs cs))
    (if (char-set? cs) (char-set:s cs)
        (lp (error "Not a char-set" cs proc)))))



;;; These internal functions hide a lot of the dependency on the
;;; underlying string representation of char sets. They should be
;;; inlined if possible.

(define (si=0? s i) (zero? (%char->latin1 (string-ref s i))))
(define (si=1? s i) (not (si=0? s i)))
(define c0 (%latin1->char 0))
(define c1 (%latin1->char 1))
(define (si s i) (%char->latin1 (string-ref s i)))
(define (%set0! s i) (string-set! s i c0))
(define (%set1! s i) (string-set! s i c1))

;;; These do various "s[i] := s[i] op val" operations -- see 
;;; %CHAR-SET-ALGEBRA. They are used to implement the various
;;; set-algebra procedures.
(define (setv!   s i v) (string-set! s i (%latin1->char v))) ; SET to a Value.
(define (%not!   s i v) (setv! s i (- 1 v)))
(define (%and!   s i v) (if (zero? v) (%set0! s i)))
(define (%or!    s i v) (if (not (zero? v)) (%set1! s i)))
(define (%minus! s i v) (if (not (zero? v)) (%set0! s i)))
(define (%xor!   s i v) (if (not (zero? v)) (setv! s i (- 1 (si s i)))))


(define (char-set-copy cs)
  (make-char-set (%string-copy (%char-set:s/check cs char-set-copy))))

(define (char-set= . rest)
  (or (null? rest)
      (let* ((cs1  (car rest))
             (rest (cdr rest))
             (s1 (%char-set:s/check cs1 char-set=)))
        (let lp ((rest rest))
          (or (not (pair? rest))
              (and (string=? s1 (%char-set:s/check (car rest) char-set=))
                   (lp (cdr rest))))))))

(define (char-set<= . rest)
  (or (null? rest)
      (let ((cs1  (car rest))
            (rest (cdr rest)))
        (let lp ((s1 (%char-set:s/check cs1 char-set<=))  (rest rest))
          (or (not (pair? rest))
              (let ((s2 (%char-set:s/check (car rest) char-set<=))
                    (rest (cdr rest)))
                (if (eq? s1 s2) (lp s2 rest)    ; Fast path
                    (let lp2 ((i 255))          ; Real test
                      (if (< i 0) (lp s2 rest)
                          (and (<= (si s1 i) (si s2 i))
                               (lp2 (- i 1))))))))))))

;;; Hash
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Compute (c + 37 c + 37^2 c + ...) modulo BOUND, with sleaze thrown in
;;; to keep the intermediate values small. (We do the calculation with just
;;; enough bits to represent BOUND, masking off high bits at each step in
;;; calculation. If this screws up any important properties of the hash
;;; function I'd like to hear about it. -Olin)
;;;
;;; If you keep BOUND small enough, the intermediate calculations will 
;;; always be fixnums. How small is dependent on the underlying Scheme system; 
;;; we use a default BOUND of 2^22 = 4194304, which should hack it in
;;; Schemes that give you at least 29 signed bits for fixnums. The core 
;;; calculation that you don't want to overflow is, worst case,
;;;     (+ 65535 (* 37 (- bound 1)))
;;; where 65535 is the max character code. Choose the default BOUND to be the
;;; biggest power of two that won't cause this expression to fixnum overflow, 
;;; and everything will be copacetic.

(define (char-set-hash cs . maybe-bound)
  (let* ((bound (:optional maybe-bound 4194304 (lambda (n) (and (integer? n)
                                                                (exact? n)
                                                                (<= 0 n)))))
         (bound (if (zero? bound) 4194304 bound))       ; 0 means default.
         (s (%char-set:s/check cs char-set-hash))
         ;; Compute a 111...1 mask that will cover BOUND-1:
         (mask (let lp ((i #x10000)) ; Let's skip first 16 iterations, eh?
                 (if (>= i bound) (- i 1) (lp (+ i i))))))

      (let lp ((i 255) (ans 0))
        (if (< i 0) (modulo ans bound)
            (lp (- i 1)
                (if (si=0? s i) ans
                    (bitwise-and mask (+ (* 37 ans) i))))))))


(define (char-set-contains? cs char)
  (si=1? (%char-set:s/check cs char-set-contains?)
         (%char->latin1 (check-arg char? char char-set-contains?))))

(define (char-set-size cs)
  (let ((s (%char-set:s/check cs char-set-size)))
    (let lp ((i 255) (size 0))
      (if (< i 0) size
          (lp (- i 1) (+ size (si s i)))))))

(define (char-set-count pred cset)
  (check-arg procedure? pred char-set-count)
  (let ((s (%char-set:s/check cset char-set-count)))
    (let lp ((i 255) (count 0))
      (if (< i 0) count
          (lp (- i 1)
              (if (and (si=1? s i) (pred (%latin1->char i)))
                  (+ count 1)
                  count))))))


;;; -- Adjoin & delete

(define (%set-char-set set proc cs chars)
  (let ((s (%string-copy (%char-set:s/check cs proc))))
    (for-each (lambda (c) (set s (%char->latin1 c)))
              chars)
    (make-char-set s)))

(define (%set-char-set! set proc cs chars)
  (let ((s (%char-set:s/check cs proc)))
    (for-each (lambda (c) (set s (%char->latin1 c)))
              chars))
  cs)

(define (char-set-adjoin cs . chars)
  (%set-char-set  %set1! char-set-adjoin cs chars))
(define (char-set-adjoin! cs . chars)
  (%set-char-set! %set1! char-set-adjoin! cs chars))
(define (char-set-delete cs . chars)
  (%set-char-set  %set0! char-set-delete cs chars))
(define (char-set-delete! cs . chars)
  (%set-char-set! %set0! char-set-delete! cs chars))


;;; Cursors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Simple implementation. A cursors is an integer index into the
;;; mark vector, and -1 for the end-of-char-set cursor.
;;;
;;; If we represented char sets as a bit set, we could do the following
;;; trick to pick the lowest bit out of the set: 
;;;   (count-bits (xor (- cset 1) cset))
;;; (But first mask out the bits already scanned by the cursor first.)

(define (char-set-cursor cset)
  (%char-set-cursor-next cset 256 char-set-cursor))
  
(define (end-of-char-set? cursor) (< cursor 0))

(define (char-set-ref cset cursor) (%latin1->char cursor))

(define (char-set-cursor-next cset cursor)
  (check-arg (lambda (i) (and (integer? i) (exact? i) (<= 0 i 255))) cursor
             char-set-cursor-next)
  (%char-set-cursor-next cset cursor char-set-cursor-next))

(define (%char-set-cursor-next cset cursor proc)        ; Internal
  (let ((s (%char-set:s/check cset proc)))
    (let lp ((cur cursor))
      (let ((cur (- cur 1)))
        (if (or (< cur 0) (si=1? s cur)) cur
            (lp cur))))))


;;; -- for-each map fold unfold every any

(define (char-set-for-each proc cs)
  (check-arg procedure? proc char-set-for-each)
  (let ((s (%char-set:s/check cs char-set-for-each)))
    (let lp ((i 255))
      (cond ((>= i 0)
             (if (si=1? s i) (proc (%latin1->char i)))
             (lp (- i 1)))))))

(define (char-set-map proc cs)
  (check-arg procedure? proc char-set-map)
  (let ((s (%char-set:s/check cs char-set-map))
        (ans (make-string 256 c0)))
    (let lp ((i 255))
      (cond ((>= i 0)
             (if (si=1? s i)
                 (%set1! ans (%char->latin1 (proc (%latin1->char i)))))
             (lp (- i 1)))))
    (make-char-set ans)))

(define (char-set-fold kons knil cs)
  (check-arg procedure? kons char-set-fold)
  (let ((s (%char-set:s/check cs char-set-fold)))
    (let lp ((i 255) (ans knil))
      (if (< i 0) ans
          (lp (- i 1)
              (if (si=0? s i) ans
                  (kons (%latin1->char i) ans)))))))

(define (char-set-every pred cs)
  (check-arg procedure? pred char-set-every)
  (let ((s (%char-set:s/check cs char-set-every)))
    (let lp ((i 255))
      (or (< i 0)
          (and (or (si=0? s i) (pred (%latin1->char i)))
               (lp (- i 1)))))))

(define (char-set-any pred cs)
  (check-arg procedure? pred char-set-any)
  (let ((s (%char-set:s/check cs char-set-any)))
    (let lp ((i 255))
      (and (>= i 0)
           (or (and (si=1? s i) (pred (%latin1->char i)))
               (lp (- i 1)))))))


(define (%char-set-unfold! proc p f g s seed)
  (check-arg procedure? p proc)
  (check-arg procedure? f proc)
  (check-arg procedure? g proc)
  (let lp ((seed seed))
    (cond ((not (p seed))                       ; P says we are done.
           (%set1! s (%char->latin1 (f seed)))  ; Add (F SEED) to set.
           (lp (g seed))))))                    ; Loop on (G SEED).

(define (char-set-unfold p f g seed . maybe-base)
  (let ((bs (%default-base maybe-base char-set-unfold)))
    (%char-set-unfold! char-set-unfold p f g bs seed)
    (make-char-set bs)))

(define (char-set-unfold! p f g seed base-cset)
  (%char-set-unfold! char-set-unfold! p f g
                     (%char-set:s/check base-cset char-set-unfold!)
                     seed)
  base-cset)



;;; list <--> char-set

(define (%list->char-set! chars s)
  (for-each (lambda (char) (%set1! s (%char->latin1 char)))
            chars))

(define (char-set . chars)
  (let ((s (make-string 256 c0)))
    (%list->char-set! chars s)
    (make-char-set s)))

(define (list->char-set chars . maybe-base)
  (let ((bs (%default-base maybe-base list->char-set)))
    (%list->char-set! chars bs)
    (make-char-set bs)))

(define (list->char-set! chars base-cs)
  (%list->char-set! chars (%char-set:s/check base-cs list->char-set!))
  base-cs)


(define (char-set->list cs)
  (let ((s (%char-set:s/check cs char-set->list)))
    (let lp ((i 255) (ans '()))
      (if (< i 0) ans
          (lp (- i 1)
              (if (si=0? s i) ans
                  (cons (%latin1->char i) ans)))))))



;;; string <--> char-set

(define (%string->char-set! str bs proc)
  (check-arg string? str proc)
  (do ((i (- (string-length str) 1) (- i 1)))
      ((< i 0))
    (%set1! bs (%char->latin1 (string-ref str i)))))

(define (string->char-set str . maybe-base)
  (let ((bs (%default-base maybe-base string->char-set)))
    (%string->char-set! str bs string->char-set)
    (make-char-set bs)))

(define (string->char-set! str base-cs)
  (%string->char-set! str (%char-set:s/check base-cs string->char-set!)
                      string->char-set!)
  base-cs)


(define (char-set->string cs)
  (let* ((s (%char-set:s/check cs char-set->string))
         (ans (make-string (char-set-size cs))))
    (let lp ((i 255) (j 0))
      (if (< i 0) ans
          (let ((j (if (si=0? s i) j
                       (begin (string-set! ans j (%latin1->char i))
                              (+ j 1)))))
            (lp (- i 1) j))))))


;;; -- UCS-range -> char-set

(define (%ucs-range->char-set! lower upper error? bs proc)
  (check-arg (lambda (x) (and (integer? x) (exact? x) (<= 0 x))) lower proc)
  (check-arg (lambda (x) (and (integer? x) (exact? x) (<= lower x))) upper proc)

  (if (and (< lower upper) (< 256 upper) error?)
      (error "Requested UCS range contains unavailable characters -- this 
implementation only supports Latin-1"
             proc lower upper))

  (let lp ((i (- (min upper 256) 1)))
    (cond ((<= lower i) (%set1! bs i) (lp (- i 1))))))

(define (ucs-range->char-set lower upper . rest)
  (let-optionals* rest ((error? #f) rest)
    (let ((bs (%default-base rest ucs-range->char-set)))
      (%ucs-range->char-set! lower upper error? bs ucs-range->char-set)
      (make-char-set bs))))

(define (ucs-range->char-set! lower upper error? base-cs)
  (%ucs-range->char-set! lower upper error?
                         (%char-set:s/check base-cs ucs-range->char-set!)
                         ucs-range->char-set)
  base-cs)


;;; -- predicate -> char-set

(define (%char-set-filter! pred ds bs proc)
  (check-arg procedure? pred proc)
  (let lp ((i 255))
    (cond ((>= i 0)
           (if (and (si=1? ds i) (pred (%latin1->char i)))
               (%set1! bs i))
           (lp (- i 1))))))

(define (char-set-filter predicate domain . maybe-base)
  (let ((bs (%default-base maybe-base char-set-filter)))
    (%char-set-filter! predicate
                       (%char-set:s/check domain char-set-filter!)
                       bs
                       char-set-filter)
    (make-char-set bs)))

(define (char-set-filter! predicate domain base-cs)
  (%char-set-filter! predicate
                     (%char-set:s/check domain char-set-filter!)
                     (%char-set:s/check base-cs char-set-filter!)
                     char-set-filter!)
  base-cs)


;;; {string, char, char-set, char predicate} -> char-set

(define (->char-set x)
  (cond ((char-set? x) x)
        ((string? x) (string->char-set x))
        ((char? x) (char-set x))
        (else (error "->char-set: Not a charset, string or char." x))))



;;; Set algebra
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; The exported ! procs are "linear update" -- allowed, but not required, to
;;; side-effect their first argument when computing their result. In other
;;; words, you must use them as if they were completely functional, just like
;;; their non-! counterparts, and you must additionally ensure that their
;;; first arguments are "dead" at the point of call. In return, we promise a
;;; more efficient result, plus allowing you to always assume char-sets are
;;; unchangeable values.

;;; Apply P to each index and its char code in S: (P I VAL).
;;; Used by the set-algebra ops.

(define (%string-iter p s)
  (let lp ((i (- (string-length s) 1)))
    (cond ((>= i 0)
           (p i (%char->latin1 (string-ref s i)))
           (lp (- i 1))))))

;;; String S represents some initial char-set. (OP s i val) does some
;;; kind of s[i] := s[i] op val update. Do
;;;     S := S OP CSETi
;;; for all the char-sets in the list CSETS. The n-ary set-algebra ops
;;; all use this internal proc.

(define (%char-set-algebra s csets op proc)
  (for-each (lambda (cset)
              (let ((s2 (%char-set:s/check cset proc)))
                (let lp ((i 255))
                  (cond ((>= i 0)
                         (op s i (si s2 i))
                         (lp (- i 1)))))))
            csets))


;;; -- Complement

(define (char-set-complement cs)
  (let ((s (%char-set:s/check cs char-set-complement))
        (ans (make-string 256)))
    (%string-iter (lambda (i v) (%not! ans i v)) s)
    (make-char-set ans)))

(define (char-set-complement! cset)
  (let ((s (%char-set:s/check cset char-set-complement!)))
    (%string-iter (lambda (i v) (%not! s i v)) s))
  cset)


;;; -- Union

(define (char-set-union! cset1 . csets)
  (%char-set-algebra (%char-set:s/check cset1 char-set-union!)
                     csets %or! char-set-union!)
  cset1)

(define (char-set-union . csets)
  (if (pair? csets)
      (let ((s (%string-copy (%char-set:s/check (car csets) char-set-union))))
        (%char-set-algebra s (cdr csets) %or! char-set-union)
        (make-char-set s))
      (char-set-copy char-set:empty)))


;;; -- Intersection

(define (char-set-intersection! cset1 . csets)
  (%char-set-algebra (%char-set:s/check cset1 char-set-intersection!)
                     csets %and! char-set-intersection!)
  cset1)

(define (char-set-intersection . csets)
  (if (pair? csets)
      (let ((s (%string-copy (%char-set:s/check (car csets) 
char-set-intersection))))
        (%char-set-algebra s (cdr csets) %and! char-set-intersection)
        (make-char-set s))
      (char-set-copy char-set:full)))


;;; -- Difference

(define (char-set-difference! cset1 . csets)
  (%char-set-algebra (%char-set:s/check cset1 char-set-difference!)
                     csets %minus! char-set-difference!)
  cset1)

(define (char-set-difference cs1 . csets)
  (if (pair? csets)
      (let ((s (%string-copy (%char-set:s/check cs1 char-set-difference))))
        (%char-set-algebra s csets %minus! char-set-difference)
        (make-char-set s))
      (char-set-copy cs1)))


;;; -- Xor

(define (char-set-xor! cset1 . csets)
  (%char-set-algebra (%char-set:s/check cset1 char-set-xor!)
                      csets %xor! char-set-xor!)
  cset1)

(define (char-set-xor . csets)
  (if (pair? csets)
      (let ((s (%string-copy (%char-set:s/check (car csets) char-set-xor))))
        (%char-set-algebra s (cdr csets) %xor! char-set-xor)
        (make-char-set s))
      (char-set-copy char-set:empty)))


;;; -- Difference & intersection

(define (%char-set-diff+intersection! diff int csets proc)
  (for-each (lambda (cs)
              (%string-iter (lambda (i v)
                              (if (not (zero? v))
                                  (cond ((si=1? diff i)
                                         (%set0! diff i)
                                         (%set1! int  i)))))
                            (%char-set:s/check cs proc)))
            csets))

(define (char-set-diff+intersection! cs1 cs2 . csets)
  (let ((s1 (%char-set:s/check cs1 char-set-diff+intersection!))
        (s2 (%char-set:s/check cs2 char-set-diff+intersection!)))
    (%string-iter (lambda (i v) (if (zero? v)
                                    (%set0! s2 i)
                                    (if (si=1? s2 i) (%set0! s1 i))))
                  s1)
    (%char-set-diff+intersection! s1 s2 csets char-set-diff+intersection!))
  (values cs1 cs2))

(define (char-set-diff+intersection cs1 . csets)
  (let ((diff (string-copy (%char-set:s/check cs1 char-set-diff+intersection)))
        (int  (make-string 256 c0)))
    (%char-set-diff+intersection! diff int csets char-set-diff+intersection)
    (values (make-char-set diff) (make-char-set int))))


;;;; System character sets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; These definitions are for Latin-1.
;;;
;;; If your Scheme implementation allows you to mark the underlying strings
;;; as immutable, you should do so -- it would be very, very bad if a client's
;;; buggy code corrupted these constants.

(define char-set:empty (char-set))
(define char-set:full (char-set-complement char-set:empty))

(define char-set:lower-case
  (let* ((a-z (ucs-range->char-set #x61 #x7B))
         (latin1 (ucs-range->char-set! #xdf #xf7  #t a-z))
         (latin2 (ucs-range->char-set! #xf8 #x100 #t latin1)))
    (char-set-adjoin! latin2 (%latin1->char #xb5))))

(define char-set:upper-case
  (let ((A-Z (ucs-range->char-set #x41 #x5B)))
    ;; Add in the Latin-1 upper-case chars.
    (ucs-range->char-set! #xd8 #xdf #t
                          (ucs-range->char-set! #xc0 #xd7 #t A-Z))))

(define char-set:title-case char-set:empty)

(define char-set:letter
  (let ((u/l (char-set-union char-set:upper-case char-set:lower-case)))
    (char-set-adjoin! u/l
                      (%latin1->char #xaa)      ; FEMININE ORDINAL INDICATOR
                      (%latin1->char #xba))))   ; MASCULINE ORDINAL INDICATOR

(define char-set:digit     (string->char-set "0123456789"))
(define char-set:hex-digit (string->char-set "0123456789abcdefABCDEF"))

(define char-set:letter+digit
  (char-set-union char-set:letter char-set:digit))

(define char-set:punctuation
  (let ((ascii (string->char-set "!\"#%&'()*,-./:;?@[\\]_{}"))
        (latin-1-chars (map %latin1->char '(#xA1 ; INVERTED EXCLAMATION MARK
                                            #xAB ; LEFT-POINTING DOUBLE ANGLE 
QUOTATION MARK
                                            #xAD ; SOFT HYPHEN
                                            #xB7 ; MIDDLE DOT
                                            #xBB ; RIGHT-POINTING DOUBLE ANGLE 
QUOTATION MARK
                                            #xBF)))) ; INVERTED QUESTION MARK
    (list->char-set! latin-1-chars ascii)))

(define char-set:symbol
  (let ((ascii (string->char-set "$+<=>^`|~"))
        (latin-1-chars (map %latin1->char '(#x00A2 ; CENT SIGN
                                            #x00A3 ; POUND SIGN
                                            #x00A4 ; CURRENCY SIGN
                                            #x00A5 ; YEN SIGN
                                            #x00A6 ; BROKEN BAR
                                            #x00A7 ; SECTION SIGN
                                            #x00A8 ; DIAERESIS
                                            #x00A9 ; COPYRIGHT SIGN
                                            #x00AC ; NOT SIGN
                                            #x00AE ; REGISTERED SIGN
                                            #x00AF ; MACRON
                                            #x00B0 ; DEGREE SIGN
                                            #x00B1 ; PLUS-MINUS SIGN
                                            #x00B4 ; ACUTE ACCENT
                                            #x00B6 ; PILCROW SIGN
                                            #x00B8 ; CEDILLA
                                            #x00D7 ; MULTIPLICATION SIGN
                                            #x00F7)))) ; DIVISION SIGN
    (list->char-set! latin-1-chars ascii)))
  

(define char-set:graphic
  (char-set-union char-set:letter+digit char-set:punctuation char-set:symbol))

(define char-set:whitespace
  (list->char-set (map %latin1->char '(#x09 ; HORIZONTAL TABULATION
                                       #x0A ; LINE FEED         
                                       #x0B ; VERTICAL TABULATION
                                       #x0C ; FORM FEED
                                       #x0D ; CARRIAGE RETURN
                                       #x20 ; SPACE
                                       #xA0))))

(define char-set:printing (char-set-union char-set:whitespace 
char-set:graphic)) ; NO-BREAK SPACE

(define char-set:blank
  (list->char-set (map %latin1->char '(#x09 ; HORIZONTAL TABULATION
                                       #x20 ; SPACE
                                       #xA0)))) ; NO-BREAK SPACE


(define char-set:iso-control
  (ucs-range->char-set! #x7F #xA0 #t (ucs-range->char-set 0 32)))

(define char-set:ascii (ucs-range->char-set 0 128))


;;; Porting & performance-tuning notes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; See the section at the beginning of this file on external dependencies.
;;;
;;; First and foremost, rewrite this code to use bit vectors of some sort.
;;; This will give big speedup and memory savings.
;;;
;;; - LET-OPTIONALS* macro.
;;; This is only used once. You can rewrite the use, port the hairy macro
;;; definition (which is implemented using a Clinger-Rees low-level
;;; explicit-renaming macro system), or port the simple, high-level
;;; definition, which is less efficient.
;;;
;;; - :OPTIONAL macro
;;; Very simply defined using an R5RS high-level macro.
;;;
;;; Implementations that can arrange for the base char sets to be immutable
;;; should do so. (E.g., Scheme 48 allows one to mark a string as immutable,
;;; which can be used to protect the underlying strings.) It would be very,
;;; very bad if a client's buggy code corrupted these constants.
;;;
;;; There is a fair amount of argument checking. This is, strictly speaking,
;;; unnecessary -- the actual body of the procedures will blow up if an
;;; illegal value is passed in. However, the error message will not be as good
;;; as if the error were caught at the "higher level." Also, a very, very
;;; smart Scheme compiler may be able to exploit having the type checks done
;;; early, so that the actual body of the procedures can assume proper values.
;;; This isn't likely; this kind of compiler technology isn't common any
;;; longer.
;;; 
;;; The overhead of optional-argument parsing is irritating. The optional
;;; arguments must be consed into a rest list on entry, and then parsed out.
;;; Function call should be a matter of a few register moves and a jump; it
;;; should not involve heap allocation! Your Scheme system may have a superior
;;; non-R5RS optional-argument system that can eliminate this overhead. If so,
;;; then this is a prime candidate for optimising these procedures,
;;; *especially* the many optional BASE-CS parameters.
;;;
;;; Note that optional arguments are also a barrier to procedure integration.
;;; If your Scheme system permits you to specify alternate entry points
;;; for a call when the number of optional arguments is known in a manner
;;; that enables inlining/integration, this can provide performance 
;;; improvements.
;;;
;;; There is enough *explicit* error checking that *all* internal operations
;;; should *never* produce a type or index-range error. Period. Feel like
;;; living dangerously? *Big* performance win to be had by replacing string
;;; and record-field accessors and setters with unsafe equivalents in the
;;; code. Similarly, fixnum-specific operators can speed up the arithmetic
;;; done on the index values in the inner loops. The only arguments that are
;;; not completely error checked are
;;;   - string lists (complete checking requires time proportional to the
;;;     length of the list)
;;;   - procedure arguments, such as char->char maps & predicates.
;;;     There is no way to check the range & domain of procedures in Scheme.
;;; Procedures that take these parameters cannot fully check their
;;; arguments. But all other types to all other procedures are fully
;;; checked.
;;;
;;; This does open up the alternate possibility of simply *removing* these 
;;; checks, and letting the safe primitives raise the errors. On a dumb
;;; Scheme system, this would provide speed (by eliminating the redundant
;;; error checks) at the cost of error-message clarity.
;;;
;;; In an interpreted Scheme, some of these procedures, or the internal
;;; routines with % prefixes, are excellent candidates for being rewritten
;;; in C.
;;;
;;; It would also be nice to have the ability to mark some of these
;;; routines as candidates for inlining/integration.
;;; 
;;; See the comments preceding the hash function code for notes on tuning
;;; the default bound so that the code never overflows your implementation's
;;; fixnum size into bignum calculation.
;;;
;;; All the %-prefixed routines in this source code are written
;;; to be called internally to this library. They do *not* perform
;;; friendly error checks on the inputs; they assume everything is
;;; proper. They also do not take optional arguments. These two properties
;;; save calling overhead and enable procedure integration -- but they
;;; are not appropriate for exported routines.

;;; Copyright notice
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Copyright (c) 1988-1995 Massachusetts Institute of Technology
;;; 
;;; This material was developed by the Scheme project at the Massachusetts
;;; Institute of Technology, Department of Electrical Engineering and
;;; Computer Science.  Permission to copy and modify this software, to
;;; redistribute either the original software or a modified version, and
;;; to use this software for any purpose is granted, subject to the
;;; following restrictions and understandings.
;;; 
;;; 1. Any copy made of this software must include this copyright notice
;;; in full.
;;; 
;;; 2. Users of this software agree to make their best efforts (a) to
;;; return to the MIT Scheme project any improvements or extensions that
;;; they make, so that these may be included in future releases; and (b)
;;; to inform MIT of noteworthy uses of this software.
;;; 
;;; 3. All materials developed as a consequence of the use of this
;;; software shall duly acknowledge such use, in accordance with the usual
;;; standards of acknowledging credit in academic research.
;;; 
;;; 4. MIT has made no warrantee or representation that the operation of
;;; this software will be error-free, and MIT is under no obligation to
;;; provide any services, by way of maintenance, update, or otherwise.
;;; 
;;; 5. In conjunction with products arising from the use of this material,
;;; there shall be no use of the name of the Massachusetts Institute of
;;; Technology nor of any adaptation thereof in any advertising,
;;; promotional, or sales literature without prior written consent from
;;; MIT in each case.

--- NEW FILE ---
The SRFI 14 character-set library                               -*- outline -*-
Olin Shivers
98/11/8
Last Update: 2000/7/4

Emacs should display this document in outline mode. Say c-h m for
instructions on how to move through it by sections (e.g., c-c c-n, c-c c-p).

* Table of contents
-------------------
Abstract
Variable index
Rationale
  Linear-update operations
  Extra-SRFI recommendations
Specification
  General procedures
  Iterating over character sets
  Creating character sets
[...1232 lines suppressed...]
----------------------------------

Ispell dumps "buffer local" words here. Please ignore.

 LocalWords:  SRFI Unicode API RS lib ARG ascii xor diff defs Generalise cs CSi
 LocalWords:  kons knil proc upcase cset lp eof lis cdr pred ary CHARi Posix op
 LocalWords:  uniquified DrScheme soh nul HTML srfi html txt scm Clinger Rees
 LocalWords:  SIGPLAN refs ucs iso CS's downcase IEC conformant JIS ASCII URL
 LocalWords:  FFF abcdefghijklmnopqrstuvwxyz DF DIAERESIS AE EA EB EC EE EF ETH
 LocalWords:  FA FB FC FD FF SS diaeresis isLowerCase Ll AA BA titlecase CA CB
 LocalWords:  CC CD CE CF DA DC DD Lt CARON PSILI PROSGEGRAMMENI DASIA VARIA Lu
 LocalWords:  OXIA PERISPOMENI FAA FAB FAC FAE FAF FBC FFC Lm Lo abcdefABCDEF
 LocalWords:  Zs Zl Zp OGHAM IDEOGRAPHIC recognised isspace isWhitespace Pc Pd
 LocalWords:  tokenizers IsISOControl Ps Pe Pf AB BB BF Sm Sc Sk AC AF MACRON
 LocalWords:  PILCROW obj EQ scsh ops UnicodeData Paolo Amoroso Arvestad Bawden
 LocalWords:  Bornstein Bothner Denheyer Dybvig Egorov Feeley Matthias Flatt eq
 LocalWords:  Felleisen Gleckler Goetter Sven Hartrumpf Hilsdale Shiro Kawai
 LocalWords:  Kiselyov Bengt Kleberg Kolbly Korb Shriram Krishnamurthi Lucier
 LocalWords:  Schilling Sobel Mikael Staldal Tsyshevsky documentors Jaffer ans
 LocalWords:  Sperber bignum fixnum ref init doc dict subform

--- NEW FILE ---
;;; Support for obsolete, deprecated 0.5.2 char-set procedures.
;;; Will go away in a future release.

(define-interface obsolete-char-set-interface
  (export char-set-members              ; char-set->list
          chars->char-set               ; list->char-set
          ascii-range->char-set         ; ucs-range->char-set (not exact)
          predicate->char-set           ; char-set-filter (not exact)
          ->char-set                    ; no longer handles a predicate
          char-set-every?               ; char-set-every

          char-set-invert               ; char-set-complement
          char-set-invert!              ; char-set-complement!

          char-set:alphabetic           ; char-set:letter
          char-set:numeric              ; char-set:digit
          char-set:alphanumeric         ; char-set:letter+digit
          char-set:control))            ; char-set:iso-control


(define-structure obsolete-char-set-lib obsolete-char-set-interface
  (open scsh-utilities char-set-lib scheme)
  (begin
    
    (define char-set-members
      (deprecated-proc char-set->list 'char-set-members
                       "Use CHAR-SET->LIST instead."))
    (define chars->char-set
      (deprecated-proc list->char-set 'chars->char-set
                       "Use LIST->CHAR-SET instead."))
    (define ascii-range->char-set
      (deprecated-proc (lambda (lower upper) (ucs-range->char-set lower upper 
#t))
                       'ascii-range->char-set
                       "Use UCS-RANGE->CHAR-SET instead."))
    (define predicate->char-set
      (deprecated-proc (lambda (pred) (char-set-filter pred char-set:full))
                       'predicate->char-set
                       "Change code to use CHAR-SET-FILTER."))
    (define char-set-every?
      (deprecated-proc char-set-every 'char-set-every?
                       "Use CHAR-SET-EVERYyn instead."))
    (define char-set-invert
      (deprecated-proc char-set-complement 'char-set-invert
                       "Use CHAR-SET-COMPLEMENTyn instead."))
    (define char-set-invert!
      (deprecated-proc char-set-complement! 'char-set-invert!
                       "Use CHAR-SET-COMPLEMENT!yn instead."))

    (define char-set:alphabetic         char-set:letter)
    (define char-set:numeric            char-set:digit)
    (define char-set:alphanumeric       char-set:letter+digit)
    (define char-set:control            char-set:iso-control)))

--- NEW FILE ---
;;; SRFI-14 interface for Scheme48                              -*- Scheme -*-
;;; 
;;; Complete interface spec for the SRFI-14 char-set-lib library in the
;;; Scheme48 interface and module language. The interface is fully typed, in
;;; the Scheme48 type notation. The structure definitions also provide a
;;; formal description of the external dependencies of the source code.

(define-interface char-set-interface
  (export (char-set? (proc (:value) :boolean))
          ((char-set= char-set<=) (proc (&rest :value) :boolean))

          (char-set-hash (proc (:value &opt :exact-integer) :exact-integer))

          ;; Cursors are exact integers in the reference implementation.
          ;; These typings would be different with a different cursor
          ;; implementation.
          ;; Too bad Scheme doesn't have abstract data types.
          (char-set-cursor      (proc (:value) :exact-integer))
          (char-set-ref         (proc (:value :exact-integer) :char))
          (char-set-cursor-next (proc (:value :exact-integer) :exact-integer))
          (end-of-char-set?     (proc (:value) :boolean))

          (char-set-fold (proc ((proc (:char :value) :value) :value :value)
                               :value))
          (char-set-unfold (proc ((proc (:value) :boolean)
                                  (proc (:value) :value)
                                  (proc (:value) :value)
                                  :value
                                  &opt :value)
                                 :value))

          (char-set-unfold! (proc ((proc (:value) :boolean)
                                   (proc (:value) :value)
                                   (proc (:value) :value)
                                   :value :value)
                                  :value))

          (char-set-for-each (proc ((proc (:char) :values) :value) :unspecific))
          (char-set-map (proc ((proc (:char) :char) :value) :value))

          (char-set-copy (proc (:value) :value))

          (char-set (proc (&rest :char) :value))

          (list->char-set (proc (:value &opt :value) :value))
          (list->char-set! (proc (:value :value) :value))

          (string->char-set  (proc (:value &opt :value) :value))
          (string->char-set! (proc (:value :value) :value))

          (ucs-range->char-set (proc (:exact-integer :exact-integer &opt
                                      :boolean :value)
                                     :value))
          (ucs-range->char-set! (proc (:exact-integer :exact-integer
                                      :boolean :value)
                                     :value))

          (char-set-filter  (proc ((proc (:char) :boolean) :value &opt :value) 
:value))
          (char-set-filter! (proc ((proc (:char) :boolean) :value :value) 
:value))

          (->char-set (proc (:value) :value))

          (char-set-size (proc (:value) :exact-integer))
          (char-set-count (proc ((proc (:char) :boolean) :value) 
:exact-integer))
          (char-set-contains? (proc (:char :value) :boolean))

          (char-set-every (proc ((proc (:char) :boolean) :value) :boolean))
          (char-set-any (proc ((proc (:char) :boolean) :value) :value))

          ((char-set-adjoin  char-set-delete
            char-set-adjoin! char-set-delete!)
           (proc (:value &rest :char) :value))

          (char-set->list   (proc (:value) :value))
          (char-set->string (proc (:value) :string))

          (char-set-complement (proc (:value) :value))
          ((char-set-union char-set-intersection char-set-xor)
           (proc (&rest :value) :value))
          
          (char-set-difference (proc (:value &opt :value) :value))

          (char-set-diff+intersection (proc (:value &rest :value)
                                            (some-values :value :value)))

          (char-set-complement! (proc (:value) :value))

          ((char-set-union! char-set-intersection!
            char-set-xor! char-set-difference!)
           (proc (:value &opt :value) :value))

          (char-set-diff+intersection! (proc (:value :value &rest :value)
                                             (some-values :value :value)))

          char-set:lower-case
          char-set:upper-case
          char-set:letter
          char-set:digit
          char-set:letter+digit
          char-set:graphic
          char-set:printing
          char-set:whitespace
          char-set:blank
          char-set:iso-control
          char-set:punctuation
          char-set:symbol
          char-set:hex-digit
          char-set:ascii
          char-set:empty
          char-set:full
          ))

; rdelim.scm gets into the innards of char-sets.
(define-interface scsh-char-set-low-level-interface
  (export (char-set:s (proc (:value) :string))))

(define-structures ((char-set-lib char-set-interface)
                    (scsh-char-set-low-level-lib 
scsh-char-set-low-level-interface))
  (open error-package   ; ERROR procedure
        let-opt         ; LET-OPTIONALS* and :OPTIONAL
        ascii           ; CHAR->ASCII ASCII->CHAR
        bitwise         ; BITWISE-AND
        jar-d-r-t-package ; DEFINE-RECORD-TYPE/JAR macro.
        scheme)

  (begin (define (check-arg pred val caller)
           (let lp ((val val))
             (if (pred val) val (lp (error "Bad argument" val pred caller)))))

         (define %latin1->char ascii->char)     ; Works for S48
         (define %char->latin1 char->ascii)     ; Works for S48

         ;; Here's a SRFI-19 d-r-t defined in terms of jar's almost-identical
         ;; d-r-t.
         (define-syntax define-record-type
           (syntax-rules ()
             ((define-record-type ?name ?stuff ...)
              (define-record-type/jar ?name ?name ?stuff ...)))))

  (files cset-lib)
  (optimize auto-integrate))

;;; Import jar's DEFINE-RECORD-TYPE macro, and export it under the
;;; name DEFINE-RECORD-TYPE/JAR.
(define-structure jar-d-r-t-package (export (define-record-type/jar :syntax))
  (open define-record-types ; JAR's record macro
        scheme)
  (begin (define-syntax define-record-type/jar
           (syntax-rules ()
             ((define-record-type/jar ?stuff ...)
              (define-record-type ?stuff ...))))))

--- NEW FILE ---
;;; This is a regression testing suite for the SRFI-14 char-set library.
;;; Olin Shivers

(let-syntax ((test (syntax-rules ()
                     ((test form ...)
                      (cond ((not form) (error "Test failed" 'form)) ...
                            (else 'OK))))))
  (let ((vowel (lambda (c) (member c '(#\a #\e #\i #\o #\u)))))

(test
 (not (char-set? 5))

 (char-set? (char-set #\a #\e #\i #\o #\u))

 (char-set=)
 (char-set= (char-set))

 (char-set= (char-set #\a #\e #\i #\o #\u)
            (string->char-set "ioeauaiii"))

 (not (char-set= (char-set #\e #\i #\o #\u)
                 (string->char-set "ioeauaiii")))

 (char-set<=)
 (char-set<= (char-set))

 (char-set<= (char-set #\a #\e #\i #\o #\u)
             (string->char-set "ioeauaiii"))

 (char-set<= (char-set #\e #\i #\o #\u)
             (string->char-set "ioeauaiii"))

 (<= 0 (char-set-hash char-set:graphic 100) 99)

 (= 4 (char-set-fold (lambda (c i) (+ i 1)) 0
                     (char-set #\e #\i #\o #\u #\e #\e)))

 (char-set= (string->char-set "eiaou2468013579999")
            (char-set-unfold null? car cdr '(#\a #\e #\i #\o #\u #\u #\u)
                             char-set:digit))

 (char-set= (string->char-set "eiaou246801357999")
            (char-set-unfold! null? car cdr '(#\a #\e #\i #\o #\u)
                              (string->char-set "0123456789")))

 (not (char-set= (string->char-set "eiaou246801357")
                 (char-set-unfold! null? car cdr '(#\a #\e #\i #\o #\u)
                                   (string->char-set "0123456789"))))

 (let ((cs (string->char-set "0123456789")))
   (char-set-for-each (lambda (c) (set! cs (char-set-delete cs c)))
                      (string->char-set "02468000"))
   (char-set= cs (string->char-set "97531")))

 (not (let ((cs (string->char-set "0123456789")))
        (char-set-for-each (lambda (c) (set! cs (char-set-delete cs c)))
                           (string->char-set "02468"))
        (char-set= cs (string->char-set "7531"))))

 (char-set= (char-set-map char-upcase (string->char-set "aeiou"))
            (string->char-set "IOUAEEEE"))

 (not (char-set= (char-set-map char-upcase (string->char-set "aeiou"))
                 (string->char-set "OUAEEEE")))

 (char-set= (char-set-copy (string->char-set "aeiou"))
            (string->char-set "aeiou"))

 (char-set= (char-set #\x #\y) (string->char-set "xy"))
 (not (char-set= (char-set #\x #\y #\z) (string->char-set "xy")))

 (char-set= (string->char-set "xy") (list->char-set '(#\x #\y)))
 (not (char-set= (string->char-set "axy") (list->char-set '(#\x #\y))))

 (char-set= (string->char-set "xy12345")
            (list->char-set '(#\x #\y) (string->char-set "12345")))
 (not (char-set= (string->char-set "y12345")
                 (list->char-set '(#\x #\y) (string->char-set "12345"))))

 (char-set= (string->char-set "xy12345")
            (list->char-set! '(#\x #\y) (string->char-set "12345")))
 (not (char-set= (string->char-set "y12345")
                 (list->char-set! '(#\x #\y) (string->char-set "12345"))))

 (char-set= (string->char-set "aeiou12345")
            (char-set-filter vowel? char-set:ascii (string->char-set "12345")))
 (not (char-set= (string->char-set "aeou12345")
                 (char-set-filter vowel? char-set:ascii (string->char-set 
"12345"))))

 (char-set= (string->char-set "aeiou12345")
            (char-set-filter! vowel? char-set:ascii (string->char-set "12345")))
 (not (char-set= (string->char-set "aeou12345")
                 (char-set-filter! vowel? char-set:ascii (string->char-set 
"12345"))))


 (char-set= (string->char-set "abcdef12345")
            (ucs-range->char-set 97 103 #t (string->char-set "12345")))
 (not (char-set= (string->char-set "abcef12345")
                 (ucs-range->char-set 97 103 #t (string->char-set "12345"))))

 (char-set= (string->char-set "abcdef12345")
            (ucs-range->char-set! 97 103 #t (string->char-set "12345")))
 (not (char-set= (string->char-set "abcef12345")
                 (ucs-range->char-set! 97 103 #t (string->char-set "12345"))))


 (char-set= (->char-set #\x)
            (->char-set "x")
            (->char-set (char-set #\x)))

 (not (char-set= (->char-set #\x)
                 (->char-set "y")
                 (->char-set (char-set #\x))))

 (= 10 (char-set-size (char-set-intersection char-set:ascii char-set:digit)))

 (= 5 (char-set-count vowel? char-set:ascii))

 (equal? '(#\x) (char-set->list (char-set #\x)))
 (not (equal? '(#\X) (char-set->list (char-set #\x))))

 (equal? "x" (char-set->string (char-set #\x)))
 (not (equal? "X" (char-set->string (char-set #\x))))

 (char-set-contains? (->char-set "xyz") #\x)
 (not (char-set-contains? (->char-set "xyz") #\a))

 (char-set-every char-lower-case? (->char-set "abcd"))
 (not (char-set-every char-lower-case? (->char-set "abcD")))
 (char-set-any char-lower-case? (->char-set "abcd"))
 (not (char-set-any char-lower-case? (->char-set "ABCD")))

 (char-set= (->char-set "ABCD")
            (let ((cs (->char-set "abcd")))
              (let lp ((cur (char-set-cursor cs)) (ans '()))
                (if (end-of-char-set? cur) (list->char-set ans)
                    (lp (char-set-cursor-next cs cur)
                        (cons (char-upcase (char-set-ref cs cur)) ans))))))


 (char-set= (char-set-adjoin (->char-set "123") #\x #\a)
            (->char-set "123xa"))
 (not (char-set= (char-set-adjoin (->char-set "123") #\x #\a)
                 (->char-set "123x")))
 (char-set= (char-set-adjoin! (->char-set "123") #\x #\a)
            (->char-set "123xa"))
 (not (char-set= (char-set-adjoin! (->char-set "123") #\x #\a)
                 (->char-set "123x")))

 (char-set= (char-set-delete (->char-set "123") #\2 #\a #\2)
            (->char-set "13"))
 (not (char-set= (char-set-delete (->char-set "123") #\2 #\a #\2)
                 (->char-set "13a")))
 (char-set= (char-set-delete! (->char-set "123") #\2 #\a #\2)
            (->char-set "13"))
 (not (char-set= (char-set-delete! (->char-set "123") #\2 #\a #\2)
                 (->char-set "13a")))

 (char-set= (char-set-intersection char-set:hex-digit (char-set-complement 
char-set:digit))
            (->char-set "abcdefABCDEF"))
 (char-set= (char-set-intersection! (char-set-complement! (->char-set 
"0123456789"))
                                    char-set:hex-digit)
            (->char-set "abcdefABCDEF"))

 (char-set= (char-set-union char-set:hex-digit
                            (->char-set "abcdefghijkl"))
            (->char-set "abcdefABCDEFghijkl0123456789"))
 (char-set= (char-set-union! (->char-set "abcdefghijkl")
                             char-set:hex-digit)
            (->char-set "abcdefABCDEFghijkl0123456789"))

 (char-set= (char-set-difference (->char-set "abcdefghijklmn")
                                 char-set:hex-digit)
            (->char-set "ghijklmn"))
 (char-set= (char-set-difference! (->char-set "abcdefghijklmn")
                                  char-set:hex-digit)
            (->char-set "ghijklmn"))

 (char-set= (char-set-xor (->char-set "0123456789")
                          char-set:hex-digit)
            (->char-set "abcdefABCDEF"))
 (char-set= (char-set-xor! (->char-set "0123456789")
                           char-set:hex-digit)
            (->char-set "abcdefABCDEF"))

 (call-with-values (lambda ()
                     (char-set-diff+intersection char-set:hex-digit
                                                 char-set:letter))
   (lambda (d i)
     (and (char-set= d (->char-set "0123456789"))
          (char-set= i (->char-set "abcdefABCDEF")))))

 (call-with-values (lambda ()
                     (char-set-diff+intersection! (char-set-copy 
char-set:hex-digit)
                                                  (char-set-copy 
char-set:letter)))
   (lambda (d i)
     (and (char-set= d (->char-set "0123456789"))
          (char-set= i (->char-set "abcdefABCDEF"))))))

))

--- NEW FILE ---
;;; Complete interface spec for the SRFI-13 string-lib and      -*- Scheme -*-
;;; string-lib-internals libraries in the Scheme48 interface
;;; and module language. The interfaces are fully typed, in
;;; the Scheme48 type notation. The structure definitions also
;;; provide a formal description of the external dependencies
;;; of the source code.

;;; string-lib
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; string-map string-map!
;;; string-fold       string-unfold
;;; string-fold-right string-unfold-right 
;;; string-tabulate string-for-each string-for-each-index
;;; string-every string-any
;;; string-hash string-hash-ci
;;; string-compare string-compare-ci
;;; string=    string<    string>    string<=    string>=    string<>
;;; string-ci= string-ci< string-ci> string-ci<= string-ci>= string-ci<> 
;;; string-downcase  string-upcase  string-titlecase  
;;; string-downcase! string-upcase! string-titlecase! 
;;; string-take string-take-right
;;; string-drop string-drop-right
;;; string-pad string-pad-right
;;; string-trim string-trim-right string-trim-both
;;; string-filter string-delete
;;; string-index string-index-right 
;;; string-skip  string-skip-right
;;; string-count
;;; string-prefix-length string-prefix-length-ci
;;; string-suffix-length string-suffix-length-ci
;;; string-prefix? string-prefix-ci?
;;; string-suffix? string-suffix-ci?
;;; string-contains string-contains-ci
;;; string-fill! string-copy! 
;;; string-copy substring/shared
;;; string-reverse string-reverse! reverse-list->string
;;; string->list
;;; string-concatenate string-concatenate/shared
;;; string-concatenate-reverse string-concatenate-reverse/shared
;;; string-append/shared
;;; xsubstring string-xcopy!
;;; string-null?
;;; string-join
;;; string-tokenize
;;; string-replace
;;; 
;;; string? make-string string string-length string-ref string-set! 
;;; string-append list->string
;;;
;;; make-kmp-restart-vector string-kmp-partial-search kmp-step
;;; string-parse-start+end
;;; string-parse-final-start+end
;;; let-string-start+end
;;; check-substring-spec
;;; substring-spec-ok?

(define-interface string-lib-interface
  (export
   ;; string-map proc s [start end] -> s
   (string-map (proc ((proc (:char) :char)
                      :string
                      &opt :exact-integer :exact-integer)
                     :string))

   ;; string-map! proc s [start end] -> unspecific
   (string-map! (proc ((proc (:char) :values)
                       :string
                       &opt :exact-integer :exact-integer)
                      :unspecific))

   ;; string-fold       kons knil s [start end] -> value
   ;; string-fold-right kons knil s [start end] -> value
   ((string-fold string-fold-right)
    (proc ((proc (:char :value) :value)
           :value :string
           &opt :exact-integer :exact-integer)
          :value))

   ;; string-unfold       p f g seed [base make-final] -> string
   ;; string-unfold-right p f g seed [base make-final] -> string
   ((string-unfold string-unfold)
    (proc ((proc (:value) :boolean)
           (proc (:value) :char)
           (proc (:value) :value)
           :value
           &opt :string (proc (:value) :string))
          :string))

;   Enough is enough.
;   ;; string-unfoldn p f g seed ... -> string
;   (string-unfoldn (proc ((procedure :values :boolean)
;                          (procedure :values :char)
;                          (procedure :values :values)
;                          &rest :value)
;                         :string))

   ;; string-tabulate proc len -> string
   (string-tabulate (proc ((proc (:exact-integer) :char) :exact-integer)
                          :string))

   ;; string-for-each       proc s [start end] -> unspecific
   ;; string-for-each-index proc s [start end] -> unspecific
   ((string-for-each string-for-each-index)
    (proc ((proc (:char) :values) :string &opt :exact-integer :exact-integer)
          :unspecific))

   ;; string-every pred s [start end]
   ;; string-any   pred s [start end]
   (string-every
    (proc ((proc (:char) :boolean) :string &opt :exact-integer :exact-integer)
          :boolean))
   (string-any
    (proc ((proc (:char) :boolean) :string &opt :exact-integer :exact-integer)
          :value))

   ;; string-hash    s [bound start end]
   ;; string-hash-ci s [bound start end]
   ((string-hash string-hash-ci)
    (proc (:string &opt :exact-integer :exact-integer :exact-integer)
          :exact-integer))

   ;; string-compare    string1 string2 lt-proc eq-proc gt-proc [start end]
   ;; string-compare-ci string1 string2 lt-proc eq-proc gt-proc [start end]
   ((string-compare string-compare-ci)
    (proc (:string :string (proc (:exact-integer) :values)
                           (proc (:exact-integer) :values)
                           (proc (:exact-integer) :values)
                           &opt :exact-integer :exact-integer)
          :values))

   ;; string< string1 string2 [start1 end1 start2 end2]
   ((string= string< string> string<= string>= string<>
     string-ci= string-ci< string-ci> string-ci<= string-ci>= string-ci<>)
    (proc (:string :string &opt :exact-integer :exact-integer
                                :exact-integer :exact-integer)
          :boolean))

   ;; string-titlecase  string [start end]
   ;; string-upcase     string [start end]
   ;; string-downcase   string [start end]
   ;; string-titlecase! string [start end]
   ;; string-upcase!    string [start end]
   ;; string-downcase!  string [start end]
   ((string-titlecase  string-upcase  string-downcase)
    (proc (:string &opt :exact-integer :exact-integer) :string))
   ((string-titlecase! string-upcase! string-downcase!)
    (proc (:string &opt :exact-integer :exact-integer) :unspecific))

   ;; string-take       string nchars
   ;; string-drop       string nchars
   ;; string-take-right string nchars
   ;; string-drop-right string nchars
   ((string-take string-drop string-take-right string-drop-right)
    (proc (:string :exact-integer) :string))

   ;; string-pad       string k [char start end] 
   ;; string-pad-right string k [char start end] 
   ((string-pad string-pad-right)
    (proc (:string :exact-integer &opt :char :exact-integer :exact-integer)
          :string))

   ;; string-trim       string [char/char-set/pred start end] 
   ;; string-trim-right string [char/char-set/pred start end] 
   ;; string-trim-both  string [char/char-set/pred start end] 
   ((string-trim string-trim-right string-trim-both)
    (proc (:string &opt :value :exact-integer :exact-integer)
          :string))

   ;; string-filter char/char-set/pred string [start end]
   ;; string-delete char/char-set/pred string [start end]
   ((string-filter string-delete)
    (proc (:value :string &opt :exact-integer :exact-integer) :string))

   ;; string-index       string char/char-set/pred [start end]
   ;; string-index-right string char/char-set/pred [end start]
   ;; string-skip        string char/char-set/pred [start end]
   ;; string-skip-right  string char/char-set/pred [end start]
   ((string-index string-index-right string-skip string-skip-right)
    (proc (:string :value &opt :exact-integer :exact-integer)
          :value))

   ;; string-count string char/char-set/pred [start end]
   (string-count (proc (:string :value &opt :exact-integer :exact-integer)
                       :exact-integer))

   ;; string-prefix-length    string1 string2 [start1 end1 start2 end2]
   ;; string-suffix-length    string1 string2 [start1 end1 start2 end2]
   ;; string-prefix-length-ci string1 string2 [start1 end1 start2 end2]
   ;; string-suffix-length-ci string1 string2 [start1 end1 start2 end2]
   ((string-prefix-length string-prefix-length-ci
     string-suffix-length string-suffix-length-ci)
    (proc (:string :string &opt
                   :exact-integer :exact-integer :exact-integer :exact-integer)
          :exact-integer))

   ;; string-prefix?    string1 string2 [start1 end1 start2 end2]
   ;; string-suffix?    string1 string2 [start1 end1 start2 end2]
   ;; string-prefix-ci? string1 string2 [start1 end1 start2 end2]
   ;; string-suffix-ci? string1 string2 [start1 end1 start2 end2]
   ((string-prefix? string-prefix-ci?
     string-suffix? string-suffix-ci?)
    (proc (:string :string &opt
                   :exact-integer :exact-integer :exact-integer :exact-integer)
          :boolean))

   ;; string-contains    string pattern [s-start s-end p-start p-end]
   ;; string-contains-ci string pattern [s-start s-end p-start p-end]
   ((string-contains string-contains-ci)
    (proc (:string :string &opt :exact-integer :exact-integer
                                :exact-integer :exact-integer)
          :value))

   ;; string-fill! string char [start end]
   (string-fill! (proc (:string :char &opt :exact-integer :exact-integer)
                       :unspecific))

   ;; string-copy! to tstart from [fstart fend]
   (string-copy! (proc (:string :exact-integer :string
                                &opt :exact-integer :exact-integer)
                       :unspecific))

   ;; string-copy        s [start end] -> string
   ;; substring/shared   s start [end] -> string
   (string-copy      (proc (:string &opt :exact-integer :exact-integer) 
:string))
   (substring/shared (proc (:string :exact-integer &opt :exact-integer) 
:string))

   ;; string-reverse  s [start end]
   ;; string-reverse! s [start end]
   (string-reverse  (proc (:string &opt :exact-integer :exact-integer) :string))
   (string-reverse! (proc (:string &opt :exact-integer :exact-integer) 
:unspecific))

   ;; reverse-list->string char-list
   ;; string->list s [start end]
   ;; string-concatenate        string-list
   ;; string-concatenate/shared string-list
   ;; string-append/shared s ...
   (reverse-list->string (proc (:value) :string))
   (string->list (proc (:string &opt :exact-integer :exact-integer) :value))
   ((string-concatenate string-concatenate/shared) (proc (:value) :string))
   (string-append/shared (proc (&rest :string) :string))

   ;; string-concatenate-reverse        string-list [final-string end]
   ;; string-concatenate-reverse/shared string-list [final-string end]
   ((string-concatenate-reverse string-concatenate-reverse/shared)
    (proc (:value &opt :string :exact-integer) :string))

   ;; xsubstring s from [to start end]
   ;; string-xcopy! target tstart s from [to start end]
   (xsubstring (proc (:string :exact-integer &opt
                              :exact-integer :exact-integer :exact-integer)
                     :string))
   (string-xcopy! (proc (:string :exact-integer :string :exact-integer &opt
                                 :exact-integer :exact-integer :exact-integer)
                        :unspecific))

   ;; string-null? s
   (string-null? (proc (:string) :boolean))

   ;; string-join string-list [delim grammar]
   (string-join (proc (:value &opt :string :symbol) :string))

   ;; string-tokenize string [token-chars start end]
   (string-tokenize (proc (:string &opt :value :exact-integer :exact-integer)
                          :value))

   ;; string-replace s1 s2 start1 end1 [start2 end2]
   (string-replace (proc (:string :string :exact-integer :exact-integer
                                  &opt :exact-integer :exact-integer)
                         :string))

   ;; Here are the R4RS/R5RS procs
   (string? (proc (:value) :boolean))
   (make-string (proc (:exact-integer &opt :char) :string))
   (string (proc (&rest :char) :string))
   (string-length (proc (:string) :exact-integer))
   (string-ref (proc (:string :exact-integer) :char))
   (string-set! (proc (:string :exact-integer :char) :unspecific))
   (string-append (proc (&rest :string) :string))
   (list->string (proc (:value) :string))

   ;; These are the R4RS types for STRING-COPY, STRING-FILL!, and
   ;; STRING->LIST. The string-lib types are different -- extended.
   ;(string-copy (proc (:string) :string))
   ;(string-fill! (proc (:string :char) :unspecific))
   ;(string->list (proc (:string) :value))

   ))


;;; make-kmp-restart-vector
;;; string-kmp-partial-search
;;; kmp-step
;;; string-parse-start+end
;;; string-parse-final-start+end
;;; let-string-start+end
;;; check-substring-spec
;;; substring-spec-ok?

(define-interface string-lib-internals-interface
  (export
   (let-string-start+end :syntax)
   (string-parse-start+end (proc ((procedure :values :values) :string :value)
                                 (some-values :exact-integer :exact-integer 
:value)))
   (string-parse-final-start+end (proc ((procedure :values :values) :string 
:value)
                                       (some-values :exact-integer 
:exact-integer)))
   (check-substring-spec (proc ((procedure :values :values) :string 
:exact-integer :exact-integer)
                               :unspecific))
   (substring-spec-ok? (proc ((procedure :values :values) :string 
:exact-integer :exact-integer)
                             :boolean))

   ;; string-kmp-partial-search pat rv s i [c= p-start s-start s-end] -> integer
   (string-kmp-partial-search (proc (:string :vector :string :exact-integer
                                     &opt (proc (:char :char) :boolean)
                                          :exact-integer :exact-integer 
:exact-integer)
                                    :exact-integer))

   ;; make-kmp-restart-vector s [c= start end] -> vector
   (make-kmp-restart-vector (proc (:string &opt (proc (:char :char) :boolean)
                                                :exact-integer :exact-integer)
                                  :vector))

   ;; kmp-step pat rv c i c= p-start -> integer
   (kmp-step (proc (:string :vector :char :exact-integer
                            (proc (:char :char) :boolean)
                            :exact-integer)
                   :exact-integer))
   ))


(define-structures ((string-lib string-lib-interface)
                    (string-lib-internals string-lib-internals-interface))
  (access scheme)       ; Get at R5RS SUBSTRING
  (open receiving       ; RECEIVE
        char-set-lib    ; Various
        bitwise         ; BITWISE-AND for hashing
        error-package   ; ERROR
        let-opt         ; LET-OPTIONALS* :OPTIONAL
        scheme)

  ;; A few cheesy S48/scsh definitions for string-lib dependencies:
  (begin (define (check-arg pred val caller)
           (let lp ((val val))
             (if (pred val) val (lp (error "Bad argument" val pred caller)))))

         ;; These two internal procedures are correctly defined for ASCII or
         ;; Latin-1. They are *not* correct for Unicode.
         (define (char-cased? c) (char-set-contains? char-set:letter c))
         (define (char-titlecase c) (char-upcase c)))

  (files string-lib))

Index: ccp-pack.scm
===================================================================
RCS file: /cvsroot/scsh/scsh/scsh/lib/ccp-pack.scm,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -C2 -r1.1 -r1.1.2.1
*** ccp-pack.scm        1999/09/13 17:46:05     1.1
--- ccp-pack.scm        2001/03/11 03:47:00     1.1.2.1
***************
*** 94,98 ****
  
  (define-structure ccp-lib ccp-lib-interface
!   (open char-set-package
        ascii
        defrec-package
--- 94,98 ----
  
  (define-structure ccp-lib ccp-lib-interface
!   (open char-set-lib
        ascii
        defrec-package

Index: ccp.scm
===================================================================
RCS file: /cvsroot/scsh/scsh/scsh/lib/ccp.scm,v
retrieving revision 1.1
retrieving revision 1.1.2.1
diff -C2 -r1.1 -r1.1.2.1
*** ccp.scm     1999/09/15 14:27:23     1.1
--- ccp.scm     2001/03/11 03:47:00     1.1.2.1
***************
*** 96,104 ****
             (and (char-set= domain (ccp:domain ccp2))
                  (let ((cmap2 (ccp:map ccp2)))
!                   (char-set-every? (lambda (c)
!                                      (let ((i (char->ascii c)))
!                                        (char=? (string-ref cmap  i)
!                                                (string-ref cmap2 i))))
!                                    domain))))
           rest)))
  
--- 96,104 ----
             (and (char-set= domain (ccp:domain ccp2))
                  (let ((cmap2 (ccp:map ccp2)))
!                   (char-set-every (lambda (c)
!                                     (let ((i (char->ascii c)))
!                                       (char=? (string-ref cmap  i)
!                                               (string-ref cmap2 i))))
!                                   domain))))
           rest)))
  
***************
*** 117,125 ****
          (and (char-set<= domain1 domain2)
               (let ((cmap2 (ccp:map ccp2)))
!                (char-set-every? (lambda (c)
!                                   (let ((i (char->ascii c)))
!                                     (char=? (string-ref cmap1 i)
!                                             (string-ref cmap2 i))))
!                                 domain1))
               (lp domain2 cmap2 rest))))))
  
--- 117,125 ----
          (and (char-set<= domain1 domain2)
               (let ((cmap2 (ccp:map ccp2)))
!                (char-set-every (lambda (c)
!                                  (let ((i (char->ascii c)))
!                                    (char=? (string-ref cmap1 i)
!                                            (string-ref cmap2 i))))
!                                domain1))
               (lp domain2 cmap2 rest))))))
  

Index: list-lib.scm
===================================================================
RCS file: /cvsroot/scsh/scsh/scsh/lib/list-lib.scm,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -C2 -r1.3 -r1.3.2.1
*** list-lib.scm        1999/10/04 17:33:43     1.3
--- list-lib.scm        2001/03/11 03:47:00     1.3.2.1
***************
*** 17,20 ****
--- 17,25 ----
  ;;; for SRFI-1. See the porting notes below for more information.
  
+ ;;; Revision history
+ ;;;;;;;;;;;;;;;;;;;;
+ ;;; This is version 1.1. 12/18/2000
+ ;;; Fixes a small bug in DELETE-DUPLICATES!.
+ 
  ;;; Exported:
  ;;; xcons tree-copy make-list list-tabulate cons* list-copy 
***************
*** 385,389 ****
    (cond ((pair? l) #f)
        ((null? l) #t)
!       (else (error "null-pair?: argument out of domain" l))))
             
  
--- 390,394 ----
    (cond ((pair? l) #f)
        ((null? l) #t)
!       (else (error "null-list?: argument out of domain" l))))
             
  
***************
*** 1240,1244 ****
            (if (eq? tail new-tail) lis (cons x new-tail)))))))
  
! (define (delete-duplicates! lis maybe-=)
    (let ((elt= (:optional maybe-= equal?)))
      (check-arg procedure? elt= delete-duplicates!)
--- 1245,1249 ----
            (if (eq? tail new-tail) lis (cons x new-tail)))))))
  
! (define (delete-duplicates! lis . maybe-=)
    (let ((elt= (:optional maybe-= equal?)))
      (check-arg procedure? elt= delete-duplicates!)

Index: srfi-1.html
===================================================================
RCS file: /cvsroot/scsh/scsh/scsh/lib/srfi-1.html,v
retrieving revision 1.3
retrieving revision 1.3.2.1
diff -C2 -r1.3 -r1.3.2.1
*** srfi-1.html 1999/10/04 17:33:44     1.3
--- srfi-1.html 2001/03/11 03:47:00     1.3.2.1
***************
*** 1,3 ****
! <!doctype html public '-//W3C//DTD HTML 4.0//EN'
    'http://www.w3.org/TR/REC-html40/strict.dtd'>
  
--- 1,3 ----
! <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
    'http://www.w3.org/TR/REC-html40/strict.dtd'>
  
***************
*** 37,43 ****
           pre.code-example { margin-left: 2em; } /* Indent code examples. */
  
           /* This stuff is for definition lists of defined procedures.
             ** A proc-def2 is used when you want a stack of procs to go
!          ** with one <dd> ... </dd> body. In this case, make the first
           ** proc a proc-def1, following ones proc-defi's, and the last one
             ** a proc-defn.
--- 37,49 ----
           pre.code-example { margin-left: 2em; } /* Indent code examples. */
  
+          /* "Continue" class marks text that isn't really the start
+          ** of a new paragraph -- e.g., continuing a para after a 
+          ** code sample.
+          */
+          p.continue { text-indent: 0em; margin-top: 0em}
+ 
           /* This stuff is for definition lists of defined procedures.
             ** A proc-def2 is used when you want a stack of procs to go
!          ** with one dd body. In this case, make the first
           ** proc a proc-def1, following ones proc-defi's, and the last one
             ** a proc-defn.
***************
*** 102,106 ****
      </style>
  
!     <style type="text/css"; media=all>
           /* Nastiness: Here, I'm using a bug to work around a bug.
           ** Netscape rendering bugs mean you need bogus <dt> and <dd>
--- 108,112 ----
      </style>
  
!     <style type="text/css" media=all>
           /* Nastiness: Here, I'm using a bug to work around a bug.
           ** Netscape rendering bugs mean you need bogus <dt> and <dd>
***************
*** 141,151 ****
  
  
<!--========================================================================-->
! <h1>Author</H1>
      <address>
!        <a href="http://www.ai.mit.edu/~shivers/";>Olin Shivers</A> /
!        <a href="mailto:shivers@ai.mit.edu";>shivers@ai.mit.edu</A>
      </address>
  
  
<!--========================================================================-->
  <h1>Table of contents</H1>
  
--- 147,173 ----
  
  
<!--========================================================================-->
! <H1>Author</H1>
! <p>
! Olin Shivers
! 
      <address>
!       <a 
href="http://www.ai.mit.edu/~shivers/";>http://www.ai.mit.edu/~shivers/</A> /
!       <a href="mailto:shivers@ai.mit.edu";>shivers@ai.mit.edu</A>
      </address>
  
  
<!--========================================================================-->
+ <H1>Status</H1>
+ <p>
+ This SRFI is currently in ``final status.  To see an explanation of each 
status that a SRFI can hold, see <A 
HREF="http://srfi.schemers.org/srfi-process.html";>here</A>.
+ You can access the discussion via <A HREF=mail-archive/maillist.html>the 
archive of the mailing list</A>.
+ <P>
+ <UL>
+     <LI>Received: 1998/11/08</LI>
+     <LI>Draft: 1998/12/22-1999/03/09</LI>
+     <LI>Revised: several times</LI>
+     <LI>Final: 1999/10/09</LI>
+ </UL>
+ 
+ 
<!--========================================================================-->
  <h1>Table of contents</H1>
  
***************
*** 155,159 ****
  <ul id=toc-table>
  <li><a href="#Abstract">Abstract</a>
! <li><a href="#Introduction">Introduction</a>
  <li><a href="#ProcedureIndex">Procedure index</a>
  <li><a href="#GeneralDiscussion">General discussion</a>
--- 177,181 ----
  <ul id=toc-table>
  <li><a href="#Abstract">Abstract</a>
! <li><a href="#Rationale">Rationale</a>
  <li><a href="#ProcedureIndex">Procedure index</a>
  <li><a href="#GeneralDiscussion">General discussion</a>
***************
*** 197,208 ****
  </ul>
  
- <strong><em>Note: This is a working draft, and tends to lag the plain-text 
version in terms of actual content.
- See <a href="ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1.txt";>
-     ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1.txt</a>
- for the latest copy of the plain-text draft.
- </em></strong>
- 
  
<!--========================================================================-->
! <h1><a name="Introduction">Introduction</a></h1>
  <p>
  The set of basic list and pair operations provided by R4RS/<abbr 
title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> Scheme is far
--- 219,224 ----
  </ul>
  
  
<!--========================================================================-->
! <h1><a name="Rationale">Rationale</a></h1>
  <p>
  The set of basic list and pair operations provided by R4RS/<abbr 
title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> Scheme is far
***************
*** 279,285 ****
  <p>
  Here is a short list of the procedures provided by the list-lib package.
! <a href="#R5RS">R5RS</a></abbr> procedures are shown in 
! <span class=r5rs-proc>bold</span class=r5rs-proc>;
! extended <a href="#R5RS">R5RS</a></abbr> 
           procedures, in <span class=r5rs-procx>bold italic</span>.
  <div class=indent>
--- 295,301 ----
  <p>
  Here is a short list of the procedures provided by the list-lib package.
! <abbr title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> 
procedures are shown in 
! <span class=r5rs-proc>bold</span>;
! extended <abbr title="Revised^5 Report on Scheme"><a 
href="#R5RS">R5RS</a></abbr> 
           procedures, in <span class=r5rs-procx>bold italic</span>.
  <div class=indent>
***************
*** 1034,1040 ****
  ==== car cdr
  
============================================================================-->
  <a name="car"></a>
  <a name="cdr"></a>
! <dt class=proc-def1><code class=proc-def>car</code><var> pair -&gt; 
value</var>
  <dt class=proc-defn><code class=proc-def>cdr</code><var> pair -&gt; 
value</var>
  <dd class=proc-def>
--- 1050,1057 ----
  ==== car cdr
  
============================================================================-->
+ <dt class=proc-def1>
  <a name="car"></a>
  <a name="cdr"></a>
! <code class=proc-def>car</code><var> pair -&gt; value</var>
  <dt class=proc-defn><code class=proc-def>cdr</code><var> pair -&gt; 
value</var>
  <dd class=proc-def>
***************
*** 2787,2790 ****
--- 2804,2808 ----
          <code>(eq? <var>x</var> <var>y</var>)</code> => <code>(<var>=</var> 
<var>x</var> <var>y</var>)</code>.
  </div>
+ <p class=continue>
  Note that this implies, in turn, that two lists that are <code>eq?</code> are
  also set-equal by any legal comparison procedure. This allows for
***************
*** 3143,3147 ****
  <p>
  I am also grateful the authors, implementors and documentors of all the 
systems
! mentioned in the introduction. Aubrey Jaffer and Kent Pitman should be noted
  for their work in producing Web-accessible versions of the R5RS and 
  <a href="#CommonLisp">Common Lisp</a> spec, which was a tremendous aid.
--- 3161,3165 ----
  <p>
  I am also grateful the authors, implementors and documentors of all the 
systems
! mentioned in the rationale.  Aubrey Jaffer and Kent Pitman should be noted
  for their work in producing Web-accessible versions of the R5RS and 
  <a href="#CommonLisp">Common Lisp</a> spec, which was a tremendous aid.
***************
*** 3157,3185 ****
  <dl>
  <dt class=biblio>This document, in HTML:
! <dd><a href="http://srfi.schemers.org/srfi-1/srfi-1.html";>
      http://srfi.schemers.org/srfi-1/srfi-1.html</a>
  
-     <br><a class=draft
-            href="ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1.html";>
-     ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1.html (draft)</a>
- 
- <dt class=biblio>This document, in simple text format:
- <dd><a href="http://srfi.schemers.org/srfi-1/srfi-1.txt";>
-     http://srfi.schemers.org/srfi-1/srfi-1.txt</a>
- 
-     <br><a class=draft
-            href="ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1.txt";>
-     ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1.txt (draft)</a>
- 
  <dt class=biblio>Source code for the reference implementation:
! <dd><a HREF="http://srfi.schemers.org/srfi-1/srfi-1-reference.scm";>
      http://srfi.schemers.org/srfi-1/srfi-1-reference.scm</a>
  
-     <br><a class=draft
-            
href="ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1-reference.scm";>
-     ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1-reference.scm 
(draft)</a>
- 
  <dt class=biblio>Archive of SRFI-1 discussion-list email:
! <dd><a href="http://srfi.schemers.org/srfi-1/mail-archive/maillist.html";>
      http://srfi.schemers.org/srfi-1/mail-archive/maillist.html</a>
  
--- 3175,3187 ----
  <dl>
  <dt class=biblio>This document, in HTML:
! <dd><a href="srfi-1.html">
      http://srfi.schemers.org/srfi-1/srfi-1.html</a>
  
  <dt class=biblio>Source code for the reference implementation:
! <dd><a HREF="srfi-1-reference.scm">
      http://srfi.schemers.org/srfi-1/srfi-1-reference.scm</a>
  
  <dt class=biblio>Archive of SRFI-1 discussion-list email:
! <dd><a href="mail-archive/maillist.html">
      http://srfi.schemers.org/srfi-1/mail-archive/maillist.html</a>
  

Index: string-lib.scm
===================================================================
RCS file: /cvsroot/scsh/scsh/scsh/lib/string-lib.scm,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -C2 -r1.2 -r1.2.2.1
*** string-lib.scm      1999/11/03 20:19:12     1.2
--- string-lib.scm      2001/03/11 03:47:00     1.2.2.1
***************
*** 1,52 ****
! ;;; Scheme Underground string-processing library              -*- Scheme -*-
! ;;; Olin Shivers 11/98
! 
! ;;; SRFI DRAFT -- SRFI DRAFT -- SRFI DRAFT -- SRFI DRAFT -- SRFI DRAFT
! ;;; This is *draft* code for a SRFI proposal. If you see this notice in 
! ;;; production code, you've got obsolete, bad source -- go find the final 
! ;;; non-draft code on the Net.
! ;;; SRFI DRAFT -- SRFI DRAFT -- SRFI DRAFT -- SRFI DRAFT -- SRFI DRAFT
! 
! ;;; Some of this code had (extremely distant) origins in MIT Scheme's string
[...3148 lines suppressed...]
+ ;;; modification, are permitted provided that the following conditions
+ ;;; are met:
+ ;;; 1. Redistributions of source code must retain the above copyright
+ ;;;    notice, this list of conditions and the following disclaimer.
+ ;;; 2. Redistributions in binary form must reproduce the above copyright
+ ;;;    notice, this list of conditions and the following disclaimer in the
+ ;;;    documentation and/or other materials provided with the distribution.
+ ;;; 3. The name of the authors may not be used to endorse or promote products
+ ;;;    derived from this software without specific prior written permission.
+ ;;; 
+ ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ ;;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ ;;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ ;;; IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ ;;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ ;;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ;;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ;;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ;;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ ;;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



<Prev in Thread] Current Thread [Next in Thread>
  • [Scsh-checkins] CVS: scsh/scsh/lib char-package.scm,NONE,1.1.2.1 cset-lib.html,NONE,1.1.2.1 cset-lib.scm,NONE,1.1.2.1 cset-lib.txt,NONE,1.1.2.1 cset-obsolete.scm,NONE,1.1.2.1 cset-package.scm,NONE,1.1.2.1 cset-tests.scm,NONE,1.1.2.1 string-package.scm,NONE,1.1.2.1 ccp-pack.scm,1.1,1.1.2.1 ccp.scm,1.1,1.1.2.1 list-lib.scm,1.3,1.3.2.1 srfi-1.html,1.3,1.3.2.1 string-lib.scm,1.2,1.2.2.1, Olin Shivers <=