|
|
1.1 ! root 1: /* This is part of libio/iostream, providing -*- C++ -*- input/output. ! 2: Copyright (C) 1993 Free Software Foundation ! 3: ! 4: This file is part of the GNU IO Library. This library is free ! 5: software; you can redistribute it and/or modify it under the ! 6: terms of the GNU General Public License as published by the ! 7: Free Software Foundation; either version 2, or (at your option) ! 8: any later version. ! 9: ! 10: This library is distributed in the hope that it will be useful, ! 11: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 13: GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with GNU CC; see the file COPYING. If not, write to ! 17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 18: ! 19: As a special exception, if you link this library with files ! 20: compiled with a GNU compiler to produce an executable, this does not cause ! 21: the resulting executable to be covered by the GNU General Public License. ! 22: This exception does not however invalidate any other reasons why ! 23: the executable file might be covered by the GNU General Public License. ! 24: ! 25: Written by Per Bothner ([email protected]). */ ! 26: ! 27: #ifndef PARSESTREAM_H ! 28: #define PARSESTREAM_H ! 29: #ifdef __GNUG__ ! 30: #pragma interface ! 31: #pragma cplusplus ! 32: #endif ! 33: #include "streambuf.h" ! 34: ! 35: // A parsebuf is a streambuf optimized for scanning text files. ! 36: // It keeps track of line and column numbers. ! 37: // It is guaranteed to remember the entire current line, ! 38: // as well the '\n'-s on either side of it (if they exist). ! 39: // You can arbitrarily seek (or unget) within this extended line. ! 40: // Other backward seeks are not supported. ! 41: // Normal read semantics are supported (and hence istream operators like >>). ! 42: ! 43: class parsebuf : public streambuf { ! 44: protected: ! 45: _IO_fpos_t pos_at_line_start; ! 46: long _line_length; ! 47: unsigned long __line_number; ! 48: char *buf_start; ! 49: char *buf_end; ! 50: ! 51: public: ! 52: parsebuf *chain; ! 53: ! 54: // Return column number (raw - don't handle tabs etc). ! 55: // Retult can be -1, meaning: at '\n' before current line. ! 56: virtual int tell_in_line(); ! 57: ! 58: // seek to (raw) column I in current line. ! 59: // Result is new (raw) column position - differs from I if unable to seek. ! 60: // Seek to -1 tries to seek to before previous LF. ! 61: virtual int seek_in_line(int i); ! 62: ! 63: // Note: there is no "current line" initially, until something is read. ! 64: ! 65: // Current line number, starting with 0. ! 66: // If tell_in_line()==-1, then line number of next line. ! 67: int line_number() { return __line_number; } ! 68: ! 69: // Length of current line, not counting either '\n'. ! 70: int line_length() { return _line_length; } ! 71: // Current line - not a copy, so file ops may trash it. ! 72: virtual char* current_line(); ! 73: virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out); ! 74: virtual streambuf* setbuf(char* p, int len); ! 75: protected: ! 76: parsebuf() { chain= NULL; ! 77: __line_number = 0; pos_at_line_start = 0; _line_length = -1; } ! 78: virtual int pbackfail(int c); ! 79: }; ! 80: ! 81: // A string_parsebuf is a parsebuf whose source is a fixed string. ! 82: ! 83: class string_parsebuf : public parsebuf { ! 84: public: ! 85: int do_delete; ! 86: string_parsebuf(char *str, int len, int delete_at_close=0); ! 87: virtual int underflow(); ! 88: virtual char* current_line(); ! 89: virtual int seek_in_line(int i); ! 90: virtual int tell_in_line(); ! 91: char *left() const { return base(); } ! 92: char *right() const { return ebuf(); } ! 93: // streampos seekoff(streamoff, _seek_dir, int); ! 94: }; ! 95: ! 96: // A func_parsebuf calls a given function to get new input. ! 97: // Each call returns an entire NUL-terminated line (without the '\n'). ! 98: // That line has been allocated with malloc(), not new. ! 99: // The interface is tailored to the GNU readline library. ! 100: // Example: ! 101: // char* DoReadLine(void* arg) ! 102: // { ! 103: // char *line = readline((char*)arg); /* 'arg' is used as prompt. */ ! 104: // if line == NULL) { putc('\n', stderr); return NULL; } ! 105: // if (line[0] != '\0') add_history(line); ! 106: // return line; ! 107: // } ! 108: // char PromptBuffer[100] = "> "; ! 109: // func_parsebuf my_stream(DoReadLine, PromptBuffer); ! 110: ! 111: typedef char *(*CharReader)(void *arg); ! 112: class istream; ! 113: ! 114: class func_parsebuf : public parsebuf { ! 115: public: ! 116: void *arg; ! 117: CharReader read_func; ! 118: int backed_up_to_newline; ! 119: func_parsebuf(CharReader func, void *argm = NULL); ! 120: int underflow(); ! 121: virtual int tell_in_line(); ! 122: virtual int seek_in_line(int i); ! 123: virtual char* current_line(); ! 124: }; ! 125: ! 126: // A general_parsebuf is a parsebuf which gets its input from some ! 127: // other streambuf. It explicitly buffers up an entire line. ! 128: ! 129: class general_parsebuf : public parsebuf { ! 130: public: ! 131: streambuf *sbuf; ! 132: int delete_buf; // Delete sbuf when destroying this. ! 133: general_parsebuf(streambuf *buf, int delete_arg_buf = 0); ! 134: int underflow(); ! 135: virtual int tell_in_line(); ! 136: virtual int seek_in_line(int i); ! 137: ~general_parsebuf(); ! 138: virtual char* current_line(); ! 139: }; ! 140: ! 141: #if 0 ! 142: class parsestream : public istream { ! 143: streammarker marks[2]; ! 144: short _first; // of the two marks; either 0 or 1 ! 145: int _lineno; ! 146: int first() { return _first; } ! 147: int second() { return 1-_first; } ! 148: int line_length() { marks[second].delta(marks[first]); } ! 149: int line_length() { marks[second].delta(marks[first]); } ! 150: int seek_in_line(int i); ! 151: int tell_in_line(); ! 152: int line_number(); ! 153: }; ! 154: #endif ! 155: #endif /*!defined(PARSESTREAM_H)*/
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.