Commit | Line | Data |
---|---|---|
abdf50aa MW |
1 | ;;; -*-lisp-*- |
2 | ;;; | |
dea4d055 | 3 | ;;; Additional stream protocol. |
abdf50aa MW |
4 | ;;; |
5 | ;;; (c) 2009 Straylight/Edgeware | |
6 | ;;; | |
7 | ||
8 | ;;;----- Licensing notice --------------------------------------------------- | |
9 | ;;; | |
e0808c47 | 10 | ;;; This file is part of the Sensible Object Design, an object system for C. |
abdf50aa MW |
11 | ;;; |
12 | ;;; SOD is free software; you can redistribute it and/or modify | |
13 | ;;; it under the terms of the GNU General Public License as published by | |
14 | ;;; the Free Software Foundation; either version 2 of the License, or | |
15 | ;;; (at your option) any later version. | |
16 | ;;; | |
17 | ;;; SOD is distributed in the hope that it will be useful, | |
18 | ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ;;; GNU General Public License for more details. | |
21 | ;;; | |
22 | ;;; You should have received a copy of the GNU General Public License | |
23 | ;;; along with SOD; if not, write to the Free Software Foundation, | |
24 | ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
25 | ||
dea4d055 | 26 | (cl:in-package #:sod-parser) |
abdf50aa | 27 | |
dea4d055 | 28 | ;;;-------------------------------------------------------------------------- |
d2f1db72 | 29 | ;;; Discovery of file names and stream positions. |
abdf50aa | 30 | |
dea4d055 MW |
31 | (export 'stream-pathname) |
32 | (defgeneric stream-pathname (stream) | |
33 | (:documentation | |
34 | "Returns the pathname of the file that STREAM is open on. | |
abdf50aa | 35 | |
dea4d055 | 36 | If STREAM is open on a file, then return the pathname of that file. |
3109662a | 37 | Otherwise return nil.") |
dea4d055 MW |
38 | |
39 | ;; Provide some default methods. Most streams don't have a pathname. | |
40 | ;; File-based streams provide a pathname, but it's usually been merged with | |
ea578bb4 | 41 | ;; `*default-pathname-defaults*' or some such, which has made it absolute, |
dea4d055 MW |
42 | ;; which isn't ideal. We'll hack around this in more useful classes later. |
43 | (:method ((stream stream)) nil) | |
44 | (:method ((stream file-stream)) (pathname stream))) | |
abdf50aa | 45 | |
d2f1db72 MW |
46 | (export 'stream-line-and-column) |
47 | (defgeneric stream-line-and-column (stream) | |
48 | (:documentation | |
49 | "Returns the current stream position of STREAM as line/column numbers. | |
50 | ||
51 | Returns two values: the line and column numbers of STREAM's input | |
52 | position, or nil if the stream isn't capable of tracking these things.") | |
53 | (:method ((stream stream)) | |
54 | (values nil nil))) | |
55 | ||
56 | ;;;-------------------------------------------------------------------------- | |
57 | ;;; Enhanced stream classes. | |
58 | ||
59 | (export '(position-aware-stream | |
85aa8b3e MW |
60 | position-aware-stream-file position-aware-stream-line |
61 | position-aware-stream-column)) | |
d2f1db72 MW |
62 | (defclass position-aware-stream (proxy-stream) |
63 | ((file :initarg :file :initform nil | |
64 | :type (or pathname null) :accessor position-aware-stream-file) | |
65 | (line :initarg :line :initform 1 | |
66 | :type fixnum :accessor position-aware-stream-line) | |
67 | (column :initarg :column :initform 0 | |
68 | :type fixnum :accessor position-aware-stream-column)) | |
69 | (:documentation | |
70 | "Character stream which keeps track of the line and column position. | |
71 | ||
72 | A position-aware-stream wraps an existing character stream and tracks the | |
73 | line and column position of the current stream position. A newline | |
74 | character increases the line number by one and resets the column number to | |
75 | zero; most characters advance the column number by one, but tab advances | |
76 | to the next multiple of eight. (This is consistent with Emacs, at least.) | |
77 | The position can be read using `stream-line-and-column'. | |
78 | ||
79 | This is a base class; you probably want `position-aware-input-stream' or | |
80 | `position-aware-output-stream'.")) | |
81 | ||
82 | (export 'position-aware-input-stream) | |
83 | (defclass position-aware-input-stream | |
84 | (position-aware-stream proxy-character-input-stream) | |
85 | () | |
86 | (:documentation | |
87 | "A character input stream which tracks the input position. | |
88 | ||
89 | This is particularly useful for parsers and suchlike, which want to | |
90 | produce accurate error-location information.")) | |
91 | ||
92 | (export 'position-aware-output-stream) | |
93 | (defclass position-aware-output-stream | |
94 | (position-aware-stream proxy-character-output-stream) | |
95 | () | |
96 | (:documentation | |
97 | "A character output stream which tracks the output position. | |
98 | ||
99 | This is particularly useful when generating C code: the position can be | |
100 | used to generate `#line' directives referring to the generated code after | |
101 | insertion of some user code.")) | |
102 | ||
abdf50aa | 103 | ;;;----- That's all, folks -------------------------------------------------- |