|
|
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.