Mercurial > ~dholland > hg > ag > index.cgi
comparison oldclasslib/include/charsink.h @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children | 607e3be6bad8 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13d2b8934445 |
---|---|
1 /* | |
2 * AnaGram, a System for Syntax Directed Programming | |
3 * | |
4 * Character Sink Class Definitions | |
5 * | |
6 * Copyright 1993 Parsifal Software. All Rights Reserved. | |
7 * | |
8 * This software is provided 'as-is', without any express or implied | |
9 * warranty. In no event will the authors be held liable for any damages | |
10 * arising from the use of this software. | |
11 * | |
12 * Permission is granted to anyone to use this software for any purpose, | |
13 * including commercial applications, and to alter it and redistribute it | |
14 * freely, subject to the following restrictions: | |
15 * | |
16 * 1. The origin of this software must not be misrepresented; you must not | |
17 * claim that you wrote the original software. If you use this software | |
18 * in a product, an acknowledgment in the product documentation would be | |
19 * appreciated but is not required. | |
20 * 2. Altered source versions must be plainly marked as such, and must not be | |
21 * misrepresented as being the original software. | |
22 * 3. This notice may not be removed or altered from any source distribution. | |
23 */ | |
24 | |
25 #ifndef CHARSINK_H | |
26 #define CHARSINK_H | |
27 | |
28 #include <stdio.h> | |
29 #include <assert.h> | |
30 | |
31 | |
32 // Class Definition for character_sink | |
33 | |
34 class character_sink { | |
35 public: | |
36 virtual ~character_sink() {} | |
37 virtual character_sink& operator << (int c) = 0; | |
38 virtual character_sink& operator << (const char *str) = 0; | |
39 virtual character_sink& operator << (const unsigned char *str) = 0; | |
40 virtual character_sink& printf(const char *, ...) = 0; | |
41 }; | |
42 | |
43 | |
44 // Class Definition for output_file | |
45 | |
46 class output_file : public character_sink { | |
47 private: | |
48 FILE *file; | |
49 char *name; | |
50 int error_flag; | |
51 int copy_flag; // is it live or memorex? | |
52 | |
53 public: | |
54 | |
55 // Constructors | |
56 | |
57 output_file() { | |
58 file = stdout; | |
59 error_flag = copy_flag = 0; | |
60 } | |
61 | |
62 output_file(char *path) : character_sink() { | |
63 name = path; | |
64 if (name == NULL) file = stdout; | |
65 else file = fopen(name = path, "wt"); | |
66 if (file == NULL) file = stdout; | |
67 error_flag = copy_flag = 0; | |
68 } | |
69 | |
70 output_file(output_file &f) : character_sink() { | |
71 *this = f; | |
72 copy_flag++; | |
73 } | |
74 | |
75 | |
76 // Destructor | |
77 | |
78 ~output_file() {if (copy_flag == 0) fclose(file);} | |
79 | |
80 | |
81 // Xmit data to sink | |
82 | |
83 character_sink& operator << (int c) { | |
84 error_flag = putc((char) c,file); | |
85 return *this; | |
86 } | |
87 | |
88 character_sink& operator << (const char *str) { | |
89 fputs(str,file); | |
90 return *this; | |
91 } | |
92 | |
93 character_sink& operator << (const unsigned char *str) { | |
94 fputs((const char *)str, file); | |
95 return *this; | |
96 } | |
97 | |
98 character_sink& printf(const char *, ...); | |
99 | |
100 | |
101 // Check for error | |
102 | |
103 friend int error(output_file &f); | |
104 }; | |
105 | |
106 inline int error(output_file &f) { | |
107 return f.error_flag < 0; | |
108 } | |
109 | |
110 class string_accumulator : public character_sink { | |
111 private: | |
112 char *cs; // character storage | |
113 unsigned *xs; // index storage | |
114 unsigned csx; // next available character | |
115 unsigned xsx; // next available index | |
116 unsigned csmax; // max number of characters | |
117 unsigned xsmax; // max number of indices | |
118 int copy_flag; // is it live or is it memorex? | |
119 | |
120 public: | |
121 | |
122 // Constructor | |
123 | |
124 string_accumulator(int nc, int nx = 1); | |
125 string_accumulator(const string_accumulator &); | |
126 | |
127 | |
128 // Destructor | |
129 | |
130 ~string_accumulator(); | |
131 | |
132 | |
133 // Reset string_accumulator | |
134 | |
135 friend string_accumulator &reset(string_accumulator &); | |
136 | |
137 | |
138 // Change stack level | |
139 | |
140 string_accumulator& operator ++(){ // preincrement stack level | |
141 assert(copy_flag == 0); | |
142 assert(xsx); | |
143 xs[--xsx] = csx; | |
144 return *this; | |
145 } | |
146 | |
147 string_accumulator operator ++ (int); // postincrement stack level | |
148 | |
149 string_accumulator &operator -- () { // predecrement stack level | |
150 assert(copy_flag == 0); | |
151 csx = xs[xsx++]; // discard top string | |
152 assert(xsx < xsmax); | |
153 return *this; | |
154 } | |
155 | |
156 string_accumulator operator -- (int); // post decrement stack level | |
157 | |
158 // Append data to stack | |
159 | |
160 character_sink& operator << (int c) { // append char to top string | |
161 assert(copy_flag == 0); | |
162 assert(csx < csmax); | |
163 cs[csx++] = (char) c; | |
164 return *this; | |
165 } | |
166 | |
167 character_sink &operator << (const char *str); // append string to top string | |
168 | |
169 character_sink &operator << (const unsigned char *str); | |
170 | |
171 character_sink &operator << (string_accumulator &s) { | |
172 assert(this != &s); // prevent disaster | |
173 return *this << s.top(); | |
174 } | |
175 | |
176 character_sink &printf(const char *, ...); | |
177 | |
178 | |
179 // Pop character from stack | |
180 | |
181 string_accumulator &operator >> (int &c); // pop last character | |
182 | |
183 | |
184 // Access character on stack | |
185 | |
186 char &operator [] (unsigned); // inspect character | |
187 | |
188 | |
189 // Retrieve pointer to top string | |
190 | |
191 // See README.txt | |
192 #if 0 | |
193 operator char *() const { // pointer to top string | |
194 cs[csx] = 0; | |
195 return &cs[xs[xsx]]; | |
196 } | |
197 | |
198 operator unsigned char *() const { // pointer to top string | |
199 cs[csx] = 0; | |
200 return (unsigned char *) &cs[xs[xsx]]; | |
201 } | |
202 #else | |
203 char *top() const { | |
204 cs[csx] = 0; | |
205 return &cs[xs[xsx]]; | |
206 } | |
207 #endif | |
208 | |
209 | |
210 // Concatenate strings | |
211 | |
212 friend string_accumulator& concat(string_accumulator &); | |
213 | |
214 | |
215 // Make permanent copy of string | |
216 | |
217 friend char *copy(const string_accumulator &); | |
218 | |
219 | |
220 // Get length of string | |
221 | |
222 friend unsigned size(const string_accumulator &); | |
223 | |
224 }; | |
225 | |
226 inline unsigned size(const string_accumulator &s) { | |
227 assert(s.xsx < s.xsmax); | |
228 return s.csx - s.xs[s.xsx]; | |
229 } | |
230 | |
231 #endif |