Mercurial > ~dholland > hg > ag > index.cgi
view oldclasslib/source/charsink.cpp @ 12:aab9ff6af791
Strengthen the build hack for non-DOS targets.
author | David A. Holland |
---|---|
date | Tue, 31 May 2022 00:58:42 -0400 |
parents | 607e3be6bad8 |
children |
line wrap: on
line source
/* * 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 void string_accumulator::operator = (const string_accumulator &s) { cs = s.cs; xs = s.xs; csx = s.csx; xsx = s.xsx; csmax = s.csmax; xsmax = s.xsmax; copy_flag = s.copy_flag; } 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; }