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;
+}