; -*- Scheme -*-
;
; $Id: string35.scm,v 1.1 1998/03/16 07:59:51 foner Exp $

;+doc
; procedure: substring:split-by-char-no-dups
; arguments: string start end char 
; signature: string x int x int x char -> list[string]
; pre:       (<= 0 start end (string-length string))
;
; Returns a list of words delimited by CHAR in STRING between START
; (inclusive) and END (exclusive).  If STRING is empty or contains
; only CHAR, then the empty list is returned
;
; This is based on the split function in Python, which I believe is
; based on the Perl/Awk one.
;
; > (substring:split-by-char-no-dups ":abc:d:e:f:" 0 12 #\:)
; ("abc" "d" "e" "f")
;
; > (substring:split-by-char-no-dups ":abc:d:e:f:" 3 12 #\:)
; ("bc" "d" "e" "f")
;-doc

(define substring:split-by-char-no-dups
  (lambda (s ss se c)

    (define skip-char
      (lambda (s i)
	(cond
	 ((= ss i) i)
	 ((char=? c (string-ref s (- i 1))) (skip-char s (- i 1)))
	 (else i))))
    
    (define skip-non-char
      (lambda (s i)
	(cond
	 ((= ss i) i)
	 ((char=? c (string-ref s (- i 1))) i)
	 (else (skip-non-char s (- i 1))))))

    (let ((result '()) (sl (- se ss)))
      (if (zero? sl)
	  result
	  (let loop ((s s) (sp se) (r result))
	    (let ((nwp (skip-char s sp)))
	      (if (= ss nwp)
		  r
		  (let* ((nsp (skip-non-char s nwp))
			 (nr (cons (substring s nsp nwp) r)))
		    (if (= ss nsp) nr (loop s (- nsp 1) nr))))))))))


; This could be written in terms of STRING:FIND-CHARS, but don't
; bother unless you can manage to make it tail recursive like the
; above.

; eof
