root/trunk/thirdparty/chunga/util.lisp

Revision 3186, 3.8 kB (checked in by edi, 8 months ago)

Import current Chunga dev version from laptop

Previous history at http://trac.common-lisp.net/tbnl/browser/branches/chunga

Line 
1 ;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: CHUNGA; Base: 10 -*-
2 ;;; $Header: /usr/local/cvsrep/chunga/util.lisp,v 1.12 2008/05/25 10:53:48 edi Exp $
3
4 ;;; Copyright (c) 2006-2008, Dr. Edmund Weitz.  All rights reserved.
5
6 ;;; Redistribution and use in source and binary forms, with or without
7 ;;; modification, are permitted provided that the following conditions
8 ;;; are met:
9
10 ;;;   * Redistributions of source code must retain the above copyright
11 ;;;     notice, this list of conditions and the following disclaimer.
12
13 ;;;   * Redistributions in binary form must reproduce the above
14 ;;;     copyright notice, this list of conditions and the following
15 ;;;     disclaimer in the documentation and/or other materials
16 ;;;     provided with the distribution.
17
18 ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
19 ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ;;; ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 (in-package :chunga)
31
32 #-:lispworks
33 (defmacro when-let ((var expr) &body body)
34   "Evaluates EXPR, binds it to VAR, and executes BODY if VAR has
35 a true value."
36   `(let ((,var ,expr))
37      (when ,var ,@body)))
38
39 (defun ends-with-p (seq suffix &key (test #'char-equal))
40   "Returns true if the sequence SEQ ends with the sequence
41 SUFFIX.  Individual elements are compared with TEST."
42   (let ((mismatch (mismatch seq suffix :from-end t :test test)))
43     (or (null mismatch)
44         (= mismatch (- (length seq) (length suffix))))))
45
46 (defun make-keyword (string destructivep)
47   "Converts the string STRING to a keyword where all characters are
48 uppercase or lowercase, taking into account the current readtable
49 case.  Destructively modifies STRING if DESTRUCTIVEP is true."
50   (intern (funcall
51            (if destructivep
52              (if (eq (readtable-case *readtable*) :upcase)
53                #'nstring-upcase
54                #'nstring-downcase)
55              (if (eq (readtable-case *readtable*) :upcase)
56                #'string-upcase
57                #'string-downcase))
58            string)
59           :keyword))
60
61 (defun read-char* (stream &optional eof-error-p eof-value)
62   "The streams we're dealing with are all binary with element type
63 \(UNSIGNED-BYTE 8) and we're only interested in ISO-8859-1, so we use
64 this to `simulate' READ-CHAR."
65   (cond (*char-buffer*
66          (prog1 *char-buffer*
67            (setq *char-buffer* nil)))
68         (t
69          ;; this assumes that character codes are identical to Unicode code
70          ;; points, at least for Latin1
71          (let ((char-code (read-byte stream eof-error-p eof-value)))
72            (and char-code
73                 (code-char char-code))))))
74
75 (defun unread-char* (char)
76   "Were simulating UNREAD-CHAR by putting the character into
77 *CHAR-BUFFER*."
78   ;; no error checking, only used internally
79   (setq *char-buffer* char)
80   nil)
81  
82 (defun peek-char* (stream &optional eof-error-p eof-value)
83   "We're simulating PEEK-CHAR by reading a character and putting it
84 into *CHAR-BUFFER*."
85   ;; no error checking, only used internally 
86   (setq *char-buffer* (read-char* stream eof-error-p eof-value)))
87
88 (defmacro with-character-stream-semantics (&body body)
89   "Binds *CHAR-BUFFER* around BODY so that within BODY we can use
90 READ-CHAR* and friends \(see above) to simulate a character stream
91 although we're reading from a binary stream."
92   `(let ((*char-buffer* nil))
93      ,@body))
Note: See TracBrowser for help on using the browser.