source: trunk/third/readline/examples/readlinebuf.h @ 17010

Revision 17010, 3.4 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17009, which included commits to RCS files with non-trunk default branches.
Line 
1/*******************************************************************************
2 * $Revision: 1.1.1.1 $
3 * $Date: 2002-02-04 16:45:56 $
4 * $Author: ghudson $
5 *
6 * Contents: A streambuf which uses the GNU readline library for line I/O
7 * (c) 2001 by Dimitris Vyzovitis [vyzo@media.mit.edu]
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22 * MA 02111-1307 USA
23 *
24 ******************************************************************************/
25
26#ifndef _READLINEBUF_H_
27#define _READLINEBUF_H_
28
29#include <iostream>
30#include <cstring>
31#include <cassert>
32#include <cstdlib>
33#include <cstdio>
34
35#include <readline/readline.h>
36#include <readline/history.h>
37
38#if (defined __GNUC__) && (__GNUC__ < 3)
39#include <streambuf.h>
40#else
41#include <streambuf>
42using std::streamsize;
43using std::streambuf;
44#endif
45
46class readlinebuf : public streambuf {
47public:
48#if (defined __GNUC__) && (__GNUC__ < 3)
49        typedef char char_type;
50        typedef int int_type;
51        typedef streampos pos_type;
52        typedef streamoff off_type;
53#endif
54        static const int_type eof = EOF; // this is -1
55        static const int_type not_eof = 0;
56
57private:
58        const char* prompt_;
59        bool history_;
60        char* line_;
61        int low_;
62        int high_;
63
64protected:
65               
66        virtual int_type showmanyc() const { return high_ - low_; }
67               
68        virtual streamsize xsgetn( char_type* buf, streamsize n ) {
69                int rd = n > (high_ - low_)? (high_ - low_) : n;
70                memcpy( buf, line_, rd );
71                low_ += rd;
72                       
73                if ( rd < n ) {
74                        low_ = high_ = 0;
75                        free( line_ ); // free( NULL ) is a noop
76                        line_ = readline( prompt_ );
77                        if ( line_ ) {
78                                high_ = strlen( line_ );
79                                if ( history_ && high_ ) add_history( line_ );
80                                rd += xsgetn( buf + rd, n - rd );
81                        }
82                }
83                       
84                return rd;
85        }
86               
87        virtual int_type underflow() {
88                if ( high_ == low_ ) {
89                        low_ = high_ = 0;
90                        free( line_ ); // free( NULL ) is a noop
91                        line_ = readline( prompt_ );
92                        if ( line_ ) {
93                                high_ = strlen( line_ );
94                                if ( history_ && high_ ) add_history( line_ );
95                        }
96                }
97                       
98                if ( low_ < high_ ) return line_[low_];
99                else return eof;
100        }
101               
102        virtual int_type uflow() {
103                int_type c = underflow();
104                if ( c != eof ) ++low_;
105                return c;
106        }
107               
108        virtual int_type pbackfail( int_type c = eof ) {
109                if ( low_ > 0 ) --low_;
110                else if ( c != eof ) {
111                        if ( high_ > 0 ) {
112                                char* nl = (char*)realloc( line_, high_ + 1 );
113                                if ( nl ) {
114                                        line_ = (char*)memcpy( nl + 1, line_, high_ );
115                                        high_ += 1;
116                                        line_[0] = char( c );
117                                } else return eof;
118                        } else {
119                                assert( !line_ );
120                                line_ = (char*)malloc( sizeof( char ) );
121                                *line_ = char( c );
122                                high_ = 1;
123                        }
124                } else return eof;
125
126                return not_eof;
127        }
128               
129public:
130        readlinebuf( const char* prompt = NULL, bool history = true )
131                : prompt_( prompt ), history_( history ),
132                  line_( NULL ), low_( 0 ), high_( 0 ) {
133                setbuf( 0, 0 );
134        }
135               
136               
137};
138
139#endif
Note: See TracBrowser for help on using the repository browser.