Mercurial > ~dholland > hg > ag > index.cgi
view oldclasslib/include/charsink.h @ 21:1c9dac05d040
Add lint-style FALLTHROUGH annotations to fallthrough cases.
(in the parse engine and thus the output code)
Document this, because the old output causes warnings with gcc10.
author | David A. Holland |
---|---|
date | Mon, 13 Jun 2022 00:04:38 -0400 |
parents | 607e3be6bad8 |
children |
line wrap: on
line source
/* * AnaGram, a System for Syntax Directed Programming * * 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. */ #ifndef CHARSINK_H #define CHARSINK_H #include <stdio.h> #include <assert.h> // Class Definition for character_sink class character_sink { public: virtual ~character_sink() {} virtual character_sink& operator << (int c) = 0; virtual character_sink& operator << (const char *str) = 0; virtual character_sink& operator << (const unsigned char *str) = 0; virtual character_sink& printf(const char *, ...) = 0; }; // Class Definition for output_file class output_file : public character_sink { private: FILE *file; char *name; int error_flag; int copy_flag; // is it live or memorex? public: // Constructors output_file() { file = stdout; error_flag = copy_flag = 0; } output_file(char *path) : character_sink() { name = path; if (name == NULL) file = stdout; else file = fopen(name = path, "wt"); if (file == NULL) file = stdout; error_flag = copy_flag = 0; } void operator = (const output_file &f) { file = f.file; name = f.name; error_flag = f.error_flag; copy_flag = f.copy_flag; } output_file(const output_file &f) : character_sink() { *this = f; copy_flag++; } // Destructor ~output_file() {if (copy_flag == 0) fclose(file);} // Xmit data to sink character_sink& operator << (int c) { error_flag = putc((char) c,file); return *this; } character_sink& operator << (const char *str) { fputs(str,file); return *this; } character_sink& operator << (const unsigned char *str) { fputs((const char *)str, file); return *this; } character_sink& printf(const char *, ...); // Check for error friend int error(output_file &f); }; inline int error(output_file &f) { return f.error_flag < 0; } class string_accumulator : public character_sink { private: char *cs; // character storage unsigned *xs; // index storage unsigned csx; // next available character unsigned xsx; // next available index unsigned csmax; // max number of characters unsigned xsmax; // max number of indices int copy_flag; // is it live or is it memorex? public: // Constructor string_accumulator(int nc, int nx = 1); string_accumulator(const string_accumulator &); void operator = (const string_accumulator &); // Destructor ~string_accumulator(); // Reset string_accumulator friend string_accumulator &reset(string_accumulator &); // Change stack level string_accumulator& operator ++(){ // preincrement stack level assert(copy_flag == 0); assert(xsx); xs[--xsx] = csx; return *this; } string_accumulator operator ++ (int); // postincrement stack level string_accumulator &operator -- () { // predecrement stack level assert(copy_flag == 0); csx = xs[xsx++]; // discard top string assert(xsx < xsmax); return *this; } string_accumulator operator -- (int); // post decrement stack level // Append data to stack character_sink& operator << (int c) { // append char to top string assert(copy_flag == 0); assert(csx < csmax); cs[csx++] = (char) c; return *this; } character_sink &operator << (const char *str); // append string to top string character_sink &operator << (const unsigned char *str); character_sink &operator << (string_accumulator &s) { assert(this != &s); // prevent disaster return *this << s.top(); } character_sink &printf(const char *, ...); // Pop character from stack string_accumulator &operator >> (int &c); // pop last character // Access character on stack char &operator [] (unsigned); // inspect character // Retrieve pointer to top string // See README.txt #if 0 operator char *() const { // pointer to top string cs[csx] = 0; return &cs[xs[xsx]]; } operator unsigned char *() const { // pointer to top string cs[csx] = 0; return (unsigned char *) &cs[xs[xsx]]; } #else char *top() const { cs[csx] = 0; return &cs[xs[xsx]]; } #endif // Concatenate strings friend string_accumulator& concat(string_accumulator &); // Make permanent copy of string friend char *copy(const string_accumulator &); // Get length of string friend unsigned size(const string_accumulator &); }; inline unsigned size(const string_accumulator &s) { assert(s.xsx < s.xsmax); return s.csx - s.xs[s.xsx]; } #endif