Plug in missing brelse calls as to fix a bug in the FFS reload code.
[dragonfly.git] / contrib / libio / parsestream.h
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 this library; see the file COPYING.  If not, write to the Free
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 (bothner@cygnus.com). */
26
27 #ifndef PARSESTREAM_H
28 #define PARSESTREAM_H
29 #ifdef __GNUG__
30 #pragma interface
31 #endif
32 #include "streambuf.h"
33
34 extern "C++" {
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_off_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 } // extern "C++"
156 #endif /*!defined(PARSESTREAM_H)*/