Mercurial > ~dholland > hg > ag > index.cgi
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oldclasslib/source/charsink.cpp Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,185 @@ +/* + * AnaGram, a System for Syntax Directed Parsing + * Character Sink Class Definitions + * + * Copyright 1993 Parsifal Software. All Rights Reserved. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> +#include "charsink.h" + + + +// Output File Class + +character_sink &output_file::printf(const char *fmt, ...) { + va_list argptr; + + assert(file != NULL); + va_start(argptr, fmt); + vfprintf(file, fmt, argptr); + va_end(argptr); + return *this; +} + + + +// String Accumulator Class + + +// Constructor + +string_accumulator::string_accumulator(int nc, int nx) { + cs = new char[nc]; // allocate character storage + xs = new unsigned[nx]; // allocate index storage + csx = 0; + xsx = nx; + csmax = nc - 1; // leave room for a terminating null + xsmax = nx; + xs[--xsx] = csx; + copy_flag = 0; // this is live +} + + +// Copy constructor + +string_accumulator::string_accumulator(const string_accumulator &s) + : character_sink() +{ + *this = s; + copy_flag++; // this is memorex +} + + +// Destructor + +string_accumulator::~string_accumulator() { + if (copy_flag) return; + delete[] cs; + delete[] xs; +} + + +// Reset string accumulator + +string_accumulator &reset(string_accumulator &s) { + assert(s.copy_flag == 0); + s.csx = 0; + s.xsx = s.xsmax; + s.xs[--s.xsx] = s.csx; + return s; +} + +// postincrement stack level + +string_accumulator string_accumulator::operator ++(int){ + string_accumulator cpy(*this); // make copy for return value + assert(copy_flag == 0); + assert(xsx); + xs[--xsx] = csx; + return cpy; +} + +// post decrement stack level + +string_accumulator string_accumulator::operator --(int) { + string_accumulator cpy(*this); // make copy for return value + assert(copy_flag == 0); + csx = xs[xsx++]; + assert(xsx < xsmax); + return cpy; +} + +// Append data to stack + +character_sink &string_accumulator::operator << (const char *str) { + int k; + if (str == NULL) return *this; + k = strlen(str); + assert(copy_flag == 0); + assert(csx + k < csmax); // room for string + strcpy(&cs[csx],str); + csx += k; + return *this; +} + +character_sink &string_accumulator::operator << (const unsigned char *str) { + int k; + if (str == NULL) return *this; + k = strlen((char *) str); + assert(copy_flag == 0); + assert(csx + k < csmax); + strcpy(&cs[csx],(char *) str); + csx += k; + return *this; +} + +character_sink &string_accumulator::printf(const char *fmt, ...) { + va_list argptr; + int n; + + assert(copy_flag == 0); + va_start(argptr, fmt); + n = vsprintf(&cs[csx], fmt, argptr); + va_end(argptr); + assert(csx + n < csmax); + csx += n; + return *this; +} + +// Pop character from stack + +string_accumulator &string_accumulator::operator >> (int &c) { + assert(copy_flag == 0); + assert(csx > xs[xsx]); // not empty + c = cs[--csx]; // pop character + return *this; +} + + +// Access character on stack + +char &string_accumulator::operator [](unsigned i) { + assert(i < csx - xs[xsx]); // index in bounds + return cs[csx - i - 1]; // identify character +} + + +// Concatenate strings + +string_accumulator &concat(string_accumulator &s) { + assert(s.copy_flag == 0); + assert(s.xsx < s.xsmax - 1); // at least two strings + s.xsx++; + return s; +} + + +// Make permanent copy of string + +char *copy(const string_accumulator &s) { + char *c = new char[strlen(s.top())+1]; + + strcpy(c,s.top()); + return c; +}