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 }