diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000000..59e3eea719 --- /dev/null +++ b/src/input.h @@ -0,0 +1,134 @@ +#include + +#ifndef INPUT_H +#define INPUT_H + +// input ////////////////////////////////////////////////////////////////////// + +class Input { + public: + virtual ~Input() { } + + virtual void dispose() = 0; + + virtual int peek() = 0; + + virtual int read() = 0; + + virtual unsigned line() = 0; + + virtual unsigned column() = 0; + + void skipSpace() { + bool quit = false; + while (not quit) { + int c = peek(); + switch (c) { + case ' ': case '\t': case '\n': + read(); + break; + + default: quit = true; + } + } + } +}; + +// file input ///////////////////////////////////////////////////////////////// + +class FileInput : public Input { + public: + const char* file; + FILE* stream; + unsigned line_; + unsigned column_; + bool close; + + FileInput(const char* file, FILE* stream = 0, bool close = true): + file(file), stream(stream), line_(1), column_(1), close(close) + { } + + virtual ~FileInput() { + dispose(); + } + + virtual void dispose() { + if (stream and close) { + fclose(stream); + stream = 0; + } + } + + virtual int peek() { + int c = getc(stream); + ungetc(c, stream); + return c; + } + + virtual int read() { + int c = getc(stream); + if (c == '\n') { + ++ line_; + column_ = 1; + } else { + ++ column_; + } + return c; + } + + virtual unsigned line() { + return line_; + } + + virtual unsigned column() { + return column_; + } +}; + +// string input /////////////////////////////////////////////////////////////// + +class StringInput : public Input { + public: + const char* string; + unsigned position; + unsigned limit; + unsigned line_; + unsigned column_; + + StringInput(const char* string); + + virtual ~StringInput() { } + + virtual void dispose() { + // do nothing + } + + virtual int peek() { + if (position == limit) return -1; + return string[position]; + } + + virtual int read() { + int c = peek(); + if (c >= 0) { + if (c == '\n') { + ++ line_; + column_ = 1; + } else { + ++ column_; + } + ++ position; + } + return c; + } + + virtual unsigned line() { + return line_; + } + + virtual unsigned column() { + return column_; + } +}; + +#endif//INPUT_H diff --git a/src/output.h b/src/output.h new file mode 100644 index 0000000000..06b6fac40e --- /dev/null +++ b/src/output.h @@ -0,0 +1,60 @@ +#include +#include + +#ifndef OUTPUT_H +#define OUTPUT_H + +#define UNUSED __attribute__((unused)) + +// output ///////////////////////////////////////////////////////////////////// + +class Output { + public: + virtual ~Output() { } + + virtual void dispose() = 0; + + virtual void write(const char* s) = 0; + + void write(int i) { + static const int Size = 32; + char s[Size]; + int c UNUSED = snprintf(s, Size, "%d", i); + assert(c > 0 and c < Size); + write(s); + } +}; + +// file output //////////////////////////////////////////////////////////////// + +class FileOutput : public Output { + public: + const char* file; + FILE* stream; + bool close; + + FileOutput(const char* file, FILE* stream = 0, bool close = true): + file(file), stream(stream), close(close) + { } + + virtual ~FileOutput() { + dispose(); + } + + virtual void dispose() { + if (stream and close) { + fclose(stream); + stream = 0; + } + } + + virtual void write(const char* s) { + fputs(s, stream); + } + + const char* filename() { + return file; + } +}; + +#endif//OUTPUT_H