Annotation of embedaddon/readline/examples/readlinebuf.h, revision 1.1.1.1

1.1       misho       1: /*******************************************************************************
                      2:  * $Revision: 1.2 $
                      3:  * $Date: 2001/09/11 06:19:36 $
                      4:  * $Author: vyzo $
                      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>
                     42: using std::streamsize;
                     43: using std::streambuf;
                     44: #endif
                     45: 
                     46: class readlinebuf : public streambuf {
                     47: public:
                     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: 
                     57: private:
                     58:        const char* prompt_;
                     59:        bool history_;
                     60:        char* line_;
                     61:        int low_;
                     62:        int high_;
                     63: 
                     64: protected:
                     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:                
                    129: public:
                    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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>