;;; ;;; ---- Extra utilities ;;; Time-stamp: <01/05/07 17:41:12 solsona> ;;; ;;; Copyright (C) 2001 by Francisco Solsona. ;;; ;;; This file is part of mime-plt. ;;; mime-plt is free software; you can redistribute it and/or ;;; modify it under the terms of the GNU Lesser General Public ;;; License as published by the Free Software Foundation; either ;;; version 2.1 of the License, or (at your option) any later version. ;;; mime-plt is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; Lesser General Public License for more details. ;;; You should have received a copy of the GNU Lesser General Public ;;; License along with mime-plt; if not, write to the Free Software ;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ;;; Author: Francisco Solsona ;; ;; ;; Commentary: (module mime-util mzscheme (require (lib "etc.ss")) (provide string-tokenizer trim-all-spaces trim-spaces trim-comments lowercase warning cat) ;; string-index returns the leftmost index in string s ;; that has character c (define string-index (lambda (s c) (let ((n (string-length s))) (let loop ((i 0)) (cond ((>= i n) #f) ((char=? (string-ref s i) c) i) (else (loop (+ i 1)))))))) ;; string-tokenizer breaks string s into substrings separated by character c (define string-tokenizer (lambda (c s) (let loop ((s s)) (if (string=? s "") '() (let ((i (string-index s c))) (if i (cons (substring s 0 i) (loop (substring s (+ i 1) (string-length s)))) (list s))))))) ;; Trim all spaces, except those in quoted strings. (define re:quote-start (regexp "\"")) (define re:space (regexp "[ \t\n\r\v]")) (define trim-all-spaces (lambda (str) ;; Break out alternate quoted and unquoted parts. ;; Initial and final string are unquoted. (let-values ([(unquoted quoted) (let loop ([str str][unquoted null][quoted null]) (let ([m (regexp-match-positions re:quote-start str)]) (if m (let ([prefix (substring str 0 (caar m))] [rest (substring str (add1 (caar m)) (string-length str))]) ;; Find closing quote (let ([m (regexp-match-positions re:quote-start rest)]) (if m (let ([inside (substring rest 0 (caar m))] [rest (substring rest (add1 (caar m)) (string-length rest))]) (loop rest (cons prefix unquoted) (cons (format "\"~a\"" inside) quoted))) ;; No closing quote! (loop "" (cons prefix unquoted) (cons (format "\"~a" rest) quoted))))) (values (reverse! (cons str unquoted)) (reverse! quoted)))))]) ;; Put the pieces back together, stripping spaces for unquoted parts: (apply string-append (let loop ([unquoted unquoted][quoted quoted]) (let ([clean (regexp-replace* re:space (car unquoted) "")]) (if (null? quoted) (list clean) (list* clean (car quoted) (loop (cdr unquoted) (cdr quoted)))))))))) ;; Only trims left and right spaces: (define trim-spaces (lambda (str) (trim-right (trim-left str)))) (define re:left-spaces (regexp "^[ \t\r\n\v]+")) (define trim-left (lambda (str) (regexp-replace re:left-spaces str ""))) (define re:right-spaces (regexp "[ \t\r\n\v]+$")) (define trim-right (lambda (str) (regexp-replace re:right-spaces str ""))) (define re:comments (regexp "^[^\"]*(\"[^\"]*\")*[^\"]*(\\(.*\\))")) (define trim-comments (lambda (str) (let* ((positions (regexp-match-positions re:comments str))) (if positions (string-append (substring str 0 (caaddr positions)) (substring str (cdaddr positions) (string-length str))) str)))) (define lowercase (lambda (str) (let loop ((out "") (rest str) (size (string-length str))) (cond ((zero? size) out) (else (loop (string-append out (string (char-downcase (string-ref rest 0)))) (substring rest 1 size) (sub1 size))))))) (define warning void) #| (lambda (msg . args) (fprintf (current-error-port) (apply format (cons msg args))) (newline (current-error-port)))) |# ;; Copies its input `in' to its ouput port if given, it uses ;; current-output-port if out is not provided. (define cat (opt-lambda (in (out (current-output-port))) (let loop ((ln (read-line in))) (unless (eof-object? ln) (fprintf out "~a~n" ln) (loop (read-line in)))))) ) ;;; mime-util.ss ends here