Mercurial > ~dholland > hg > ag > index.cgi
comparison oldclasslib/source/charsink.cpp @ 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 Parsing | |
3 * Character Sink Class Definitions | |
4 * | |
5 * Copyright 1993 Parsifal Software. All Rights Reserved. | |
6 * | |
7 * This software is provided 'as-is', without any express or implied | |
8 * warranty. In no event will the authors be held liable for any damages | |
9 * arising from the use of this software. | |
10 * | |
11 * Permission is granted to anyone to use this software for any purpose, | |
12 * including commercial applications, and to alter it and redistribute it | |
13 * freely, subject to the following restrictions: | |
14 * | |
15 * 1. The origin of this software must not be misrepresented; you must not | |
16 * claim that you wrote the original software. If you use this software | |
17 * in a product, an acknowledgment in the product documentation would be | |
18 * appreciated but is not required. | |
19 * 2. Altered source versions must be plainly marked as such, and must not be | |
20 * misrepresented as being the original software. | |
21 * 3. This notice may not be removed or altered from any source distribution. | |
22 */ | |
23 | |
24 #include <stdio.h> | |
25 #include <stdarg.h> | |
26 #include <string.h> | |
27 #include <stdlib.h> | |
28 #include <assert.h> | |
29 #include "charsink.h" | |
30 | |
31 | |
32 | |
33 // Output File Class | |
34 | |
35 character_sink &output_file::printf(const char *fmt, ...) { | |
36 va_list argptr; | |
37 | |
38 assert(file != NULL); | |
39 va_start(argptr, fmt); | |
40 vfprintf(file, fmt, argptr); | |
41 va_end(argptr); | |
42 return *this; | |
43 } | |
44 | |
45 | |
46 | |
47 // String Accumulator Class | |
48 | |
49 | |
50 // Constructor | |
51 | |
52 string_accumulator::string_accumulator(int nc, int nx) { | |
53 cs = new char[nc]; // allocate character storage | |
54 xs = new unsigned[nx]; // allocate index storage | |
55 csx = 0; | |
56 xsx = nx; | |
57 csmax = nc - 1; // leave room for a terminating null | |
58 xsmax = nx; | |
59 xs[--xsx] = csx; | |
60 copy_flag = 0; // this is live | |
61 } | |
62 | |
63 | |
64 // Copy constructor | |
65 | |
66 string_accumulator::string_accumulator(const string_accumulator &s) | |
67 : character_sink() | |
68 { | |
69 *this = s; | |
70 copy_flag++; // this is memorex | |
71 } | |
72 | |
73 | |
74 // Destructor | |
75 | |
76 string_accumulator::~string_accumulator() { | |
77 if (copy_flag) return; | |
78 delete[] cs; | |
79 delete[] xs; | |
80 } | |
81 | |
82 | |
83 // Reset string accumulator | |
84 | |
85 string_accumulator &reset(string_accumulator &s) { | |
86 assert(s.copy_flag == 0); | |
87 s.csx = 0; | |
88 s.xsx = s.xsmax; | |
89 s.xs[--s.xsx] = s.csx; | |
90 return s; | |
91 } | |
92 | |
93 // postincrement stack level | |
94 | |
95 string_accumulator string_accumulator::operator ++(int){ | |
96 string_accumulator cpy(*this); // make copy for return value | |
97 assert(copy_flag == 0); | |
98 assert(xsx); | |
99 xs[--xsx] = csx; | |
100 return cpy; | |
101 } | |
102 | |
103 // post decrement stack level | |
104 | |
105 string_accumulator string_accumulator::operator --(int) { | |
106 string_accumulator cpy(*this); // make copy for return value | |
107 assert(copy_flag == 0); | |
108 csx = xs[xsx++]; | |
109 assert(xsx < xsmax); | |
110 return cpy; | |
111 } | |
112 | |
113 // Append data to stack | |
114 | |
115 character_sink &string_accumulator::operator << (const char *str) { | |
116 int k; | |
117 if (str == NULL) return *this; | |
118 k = strlen(str); | |
119 assert(copy_flag == 0); | |
120 assert(csx + k < csmax); // room for string | |
121 strcpy(&cs[csx],str); | |
122 csx += k; | |
123 return *this; | |
124 } | |
125 | |
126 character_sink &string_accumulator::operator << (const unsigned char *str) { | |
127 int k; | |
128 if (str == NULL) return *this; | |
129 k = strlen((char *) str); | |
130 assert(copy_flag == 0); | |
131 assert(csx + k < csmax); | |
132 strcpy(&cs[csx],(char *) str); | |
133 csx += k; | |
134 return *this; | |
135 } | |
136 | |
137 character_sink &string_accumulator::printf(const char *fmt, ...) { | |
138 va_list argptr; | |
139 int n; | |
140 | |
141 assert(copy_flag == 0); | |
142 va_start(argptr, fmt); | |
143 n = vsprintf(&cs[csx], fmt, argptr); | |
144 va_end(argptr); | |
145 assert(csx + n < csmax); | |
146 csx += n; | |
147 return *this; | |
148 } | |
149 | |
150 // Pop character from stack | |
151 | |
152 string_accumulator &string_accumulator::operator >> (int &c) { | |
153 assert(copy_flag == 0); | |
154 assert(csx > xs[xsx]); // not empty | |
155 c = cs[--csx]; // pop character | |
156 return *this; | |
157 } | |
158 | |
159 | |
160 // Access character on stack | |
161 | |
162 char &string_accumulator::operator [](unsigned i) { | |
163 assert(i < csx - xs[xsx]); // index in bounds | |
164 return cs[csx - i - 1]; // identify character | |
165 } | |
166 | |
167 | |
168 // Concatenate strings | |
169 | |
170 string_accumulator &concat(string_accumulator &s) { | |
171 assert(s.copy_flag == 0); | |
172 assert(s.xsx < s.xsmax - 1); // at least two strings | |
173 s.xsx++; | |
174 return s; | |
175 } | |
176 | |
177 | |
178 // Make permanent copy of string | |
179 | |
180 char *copy(const string_accumulator &s) { | |
181 char *c = new char[strlen(s.top())+1]; | |
182 | |
183 strcpy(c,s.top()); | |
184 return c; | |
185 } |