OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/tags/gdb/gdb-6.8/gdb-6.8.openrisc-2.1/readline/examples
    from Rev 24 to Rev 33
    Reverse comparison

Rev 24 → Rev 33

/ChangeLog.gdb
0,0 → 1,14
2006-04-24 Daniel Jacobowitz <dan@codesourcery.com>
 
Imported readline 5.1, and upstream patches 001-004.
 
2002-02-24 Elena Zannoni <ezannoni@redhat.com>
 
* ChangeLog.gdb: Rename from ChangeLog.Cygnus.
 
2000-07-09 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
 
* Import of readline 4.1.
 
New files: excallback.c, rlfe.c.
 
/histexamp.c
0,0 → 1,124
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
 
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
 
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
 
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
 
#include <stdio.h>
 
#ifdef READLINE_LIBRARY
# include "history.h"
#else
# include <readline/history.h>
#endif
 
#include <string.h>
 
main (argc, argv)
int argc;
char **argv;
{
char line[1024], *t;
int len, done;
 
line[0] = 0;
done = 0;
 
using_history ();
while (!done)
{
printf ("history$ ");
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
}
 
if (!t)
strcpy (line, "quit");
 
if (line[0])
{
char *expansion;
int result;
 
using_history ();
 
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
 
if (result < 0 || result == 2)
{
free (expansion);
continue;
}
 
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
}
 
if (strcmp (line, "quit") == 0)
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
else if (strcmp (line, "list") == 0)
{
register HIST_ENTRY **the_list;
register int i;
time_t tt;
char timestr[128];
 
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
{
tt = history_get_time (the_list[i]);
if (tt)
strftime (timestr, sizeof (timestr), "%a %R", localtime(&tt));
else
strcpy (timestr, "??");
printf ("%d: %s: %s\n", i + history_base, timestr, the_list[i]->line);
}
}
else if (strncmp (line, "delete", 6) == 0)
{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
{
free (entry->line);
free (entry);
}
}
else
{
fprintf (stderr, "non-numeric arg given to `delete'\n");
}
}
}
}
histexamp.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: Inputrc =================================================================== --- Inputrc (nonexistent) +++ Inputrc (revision 33) @@ -0,0 +1,81 @@ +# My ~/.inputrc file is in -*- text -*- for easy editing with Emacs. +# +# Notice the various bindings which are conditionalized depending +# on which program is running, or what terminal is active. +# + +# Copyright (C) 1989-2002 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. + +# In all programs, all terminals, make sure this is bound. +"\C-x\C-r": re-read-init-file + +# Hp terminals (and some others) have ugly default behaviour for C-h. +"\C-h": backward-delete-char +"\e\C-h": backward-kill-word +"\C-xd": dump-functions + +# In xterm windows, make the arrow keys do the right thing. +$if TERM=xterm +"\e[A": previous-history +"\e[B": next-history +"\e[C": forward-char +"\e[D": backward-char + +# alternate arrow key prefix +"\eOA": previous-history +"\eOB": next-history +"\eOC": forward-char +"\eOD": backward-char + +# Under Xterm in Bash, we bind local Function keys to do something useful. +$if Bash +"\e[11~": "Function Key 1" +"\e[12~": "Function Key 2" +"\e[13~": "Function Key 3" +"\e[14~": "Function Key 4" +"\e[15~": "Function Key 5" + +# I know the following escape sequence numbers are 1 greater than +# the function key. Don't ask me why, I didn't design the xterm terminal. +"\e[17~": "Function Key 6" +"\e[18~": "Function Key 7" +"\e[19~": "Function Key 8" +"\e[20~": "Function Key 9" +"\e[21~": "Function Key 10" +$endif +$endif + +# For Bash, all terminals, add some Bash specific hacks. +$if Bash +"\C-xv": show-bash-version +"\C-x\C-e": shell-expand-line + +# Here is one for editing my path. +"\C-xp": "$PATH\C-x\C-e\C-e\"\C-aPATH=\":\C-b" + +# Make C-x r read my mail in emacs. +# "\C-xr": "emacs -f rmail\C-j" +$endif + +# For FTP, different hacks: +$if Ftp +"\C-xg": "get \M-?" +"\C-xt": "put \M-?" +"\M-.": yank-last-arg +$endif + +" ": self-insert Index: rl-fgets.c =================================================================== --- rl-fgets.c (nonexistent) +++ rl-fgets.c (revision 33) @@ -0,0 +1,374 @@ +/* +Date: Tue, 16 Mar 2004 19:38:40 -0800 +From: Harold Levy +Subject: fgets(stdin) --> readline() redirector +To: chet@po.cwru.edu + +Hi Chet, + +Here is something you may find useful enough to include in the readline +distribution. It is a shared library that redirects calls to fgets(stdin) +to readline() via LD_PRELOAD, and it supports a custom prompt and list of +command names. Many people have asked me for this file, so I thought I'd +pass it your way in hope of just including it with readline to begin with. + +Best Regards, + +-Harold +*/ + +/****************************************************************************** +******************************************************************************* + + FILE NAME: fgets.c TARGET: libfgets.so + AUTHOR: Harold Levy VERSION: 1.0 + hlevy@synopsys.com + + ABSTRACT: Customize fgets() behavior via LD_PRELOAD in the following ways: + + -- If fgets(stdin) is called, redirect to GNU readline() to obtain + command-line editing, file-name completion, history, etc. + + -- A list of commands for command-name completion can be configured by + setting the environment-variable FGETS_COMMAND_FILE to a file containing + the list of commands to be used. + + -- Command-line editing with readline() works best when the prompt string + is known; you can set this with the FGETS_PROMPT environment variable. + + -- There special strings that libfgets will interpret as internal commands: + + _fgets_reset_ reset the command list + + _fgets_dump_ dump status + + _fgets_debug_ toggle debug messages + + HOW TO BUILD: Here are examples of how to build libfgets.so on various + platforms; you will have to add -I and -L flags to configure access to + the readline header and library files. + + (32-bit builds with gcc) + AIX: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lreadline -ltermcap + HP-UX: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldld -lreadline + Linux: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lreadline + SunOS: gcc -fPIC fgets.c -shared -o libfgets.so -lc -ldl -lgen -lreadline + + (64-bit builds without gcc) + SunOS: SUNWspro/bin/cc -D_LARGEFILE64_SOURCE=1 -xtarget=ultra -xarch=v9 \ + -KPIC fgets.c -Bdynamic -lc -ldl -lgen -ltermcap -lreadline + + HOW TO USE: Different operating systems have different levels of support + for the LD_PRELOAD concept. The generic method for 32-bit platforms is to + put libtermcap.so, libfgets.so, and libreadline.so (with absolute paths) + in the LD_PRELOAD environment variable, and to put their parent directories + in the LD_LIBRARY_PATH environment variable. Unfortunately there is no + generic method for 64-bit platforms; e.g. for 64-bit SunOS, you would have + to build both 32-bit and 64-bit libfgets and libreadline libraries, and + use the LD_FLAGS_32 and LD_FLAGS_64 environment variables with preload and + library_path configurations (a mix of 32-bit and 64-bit calls are made under + 64-bit SunOS). + + EXAMPLE WRAPPER: Here is an example shell script wrapper around the + program "foo" that uses fgets() for command-line input: + + #!/bin/csh + #### replace this with the libtermcap.so directory: + set dir1 = "/usr/lib" + #### replace this with the libfgets.so directory: + set dir2 = "/usr/fgets" + #### replace this with the libreadline.so directory: + set dir3 = "/usr/local/lib" + set lib1 = "${dir1}/libtermcap.so" + set lib2 = "${dir2}/libfgets.so" + set lib3 = "${dir3}/libreadline.so" + if ( "${?LD_PRELOAD}" ) then + setenv LD_PRELOAD "${lib1}:${lib2}:${lib3}:${LD_PRELOAD}" + else + setenv LD_PRELOAD "${lib1}:${lib2}:${lib3}" + endif + if ( "${?LD_LIBRARY_PATH}" ) then + setenv LD_LIBRARY_PATH "${dir1}:${dir2}:${dir3}:${LD_LIBRARY_PATH}" + else + setenv LD_LIBRARY_PATH "${dir1}:${dir2}:${dir3}" + endif + setenv FGETS_COMMAND_FILE "${dir2}/foo.commands" + setenv FGETS_PROMPT "foo> " + exec "foo" $* + + Copyright (C)©2003-2004 Harold Levy. + + This code links to the GNU readline library, and as such is bound by the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 2 or (at your option) any later version. + + The GNU General Public License is often shipped with GNU software, and is + generally kept in a file called COPYING or LICENSE. If you do not have a + copy of the license, write to the Free Software Foundation, 59 Temple Place, + Suite 330, Boston, MA 02111 USA. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + +******************************************************************************* +******************************************************************************/ + + + +#include +#include +#include +#include +#include + +#include +#include + + + +/* for dynamically connecting to the native fgets() */ +#if defined(RTLD_NEXT) +#define REAL_LIBC RTLD_NEXT +#else +#define REAL_LIBC ((void *) -1L) +#endif +typedef char * ( * fgets_t ) ( char * s, int n, FILE * stream ) ; + + + +/* private data */ +/* -- writeable data is stored in the shared library's data segment + -- every process that uses the shared library gets a private memory copy of + its entire data segment + -- static data in the shared library is not copied to the application + -- only read-only (i.e. 'const') data is stored in the shared library's + text segment +*/ +static char ** my_fgets_names = NULL ; +static int my_fgets_number_of_names = 0 ; +static int my_fgets_debug_flag = 0 ; + + + +/* invoked with _fgets_reset_ */ +static void +my_fgets_reset ( + void +) { + if ( my_fgets_names && (my_fgets_number_of_names > 0) ) { + int i ; + if ( my_fgets_debug_flag ) { + printf ( "libfgets: removing command list\n" ) ; + } + for ( i = 0 ; i < my_fgets_number_of_names ; i ++ ) { + if ( my_fgets_names[i] ) free ( my_fgets_names[i] ) ; + } + free ( my_fgets_names ) ; + } + my_fgets_names = NULL ; + my_fgets_number_of_names = 0 ; +} + + + +/* invoked with _fgets_dump_ */ +static void +my_fgets_dump ( + void +) { + char * s ; + printf ( "\n" ) ; + s = getenv ( "FGETS_PROMPT" ) ; + printf ( "FGETS_PROMPT = %s\n", s ? s : "" ) ; + s = getenv ( "FGETS_COMMAND_FILE" ) ; + printf ( "FGETS_COMMAND_FILE = %s\n", s ? s : "" ) ; + printf ( "debug flag = %d\n", my_fgets_debug_flag ) ; + printf ( "#commands = %d\n", my_fgets_number_of_names ) ; + if ( my_fgets_debug_flag ) { + if ( my_fgets_names && (my_fgets_number_of_names > 0) ) { + int i ; + for ( i = 0 ; i < my_fgets_number_of_names ; i ++ ) { + printf ( "%s\n", my_fgets_names[i] ) ; + } + } + } + printf ( "\n" ) ; +} + + + +/* invoked with _fgets_debug_ */ +static void +my_fgets_debug_toggle ( + void +) { + my_fgets_debug_flag = my_fgets_debug_flag ? 0 : 1 ; + if ( my_fgets_debug_flag ) { + printf ( "libfgets: debug flag = %d\n", my_fgets_debug_flag ) ; + } +} + + + +/* read the command list if needed, return the i-th name */ +static char * +my_fgets_lookup ( + int index +) { + if ( (! my_fgets_names) || (! my_fgets_number_of_names) ) { + char * fname ; + FILE * fp ; + fgets_t _fgets ; + int i ; + char buf1[256], buf2[256] ; + fname = getenv ( "FGETS_COMMAND_FILE" ) ; + if ( ! fname ) { + if ( my_fgets_debug_flag ) { + printf ( "libfgets: empty or unset FGETS_COMMAND_FILE\n" ) ; + } + return NULL ; + } + fp = fopen ( fname, "r" ) ; + if ( ! fp ) { + if ( my_fgets_debug_flag ) { + printf ( "libfgets: cannot open '%s' for reading\n", fname ) ; + } + return NULL ; + } + _fgets = (fgets_t) dlsym ( REAL_LIBC, "fgets" ) ; + if ( ! _fgets ) { + fprintf ( stderr, + "libfgets: failed to dynamically link to native fgets()\n" + ) ; + return NULL ; + } + for ( i = 0 ; _fgets(buf1,255,fp) ; i ++ ) ; + if ( ! i ) { fclose(fp) ; return NULL ; } + my_fgets_names = (char**) calloc ( i, sizeof(char*) ) ; + rewind ( fp ) ; + i = 0 ; + while ( _fgets(buf1,255,fp) ) { + buf1[255] = 0 ; + if ( 1 == sscanf(buf1,"%s",buf2) ) { + my_fgets_names[i] = strdup(buf2) ; + i ++ ; + } + } + fclose ( fp ) ; + my_fgets_number_of_names = i ; + if ( my_fgets_debug_flag ) { + printf ( "libfgets: successfully read %d commands\n", i ) ; + } + } + if ( index < my_fgets_number_of_names ) { + return my_fgets_names[index] ; + } else { + return NULL ; + } +} + + + +/* generate a list of partial name matches for readline() */ +static char * +my_fgets_generator ( + const char * text, + int state +) +{ + static int list_index, len ; + char * name ; + if ( ! state ) { + list_index = 0 ; + len = strlen ( text ) ; + } + while ( ( name = my_fgets_lookup(list_index) ) ) { + list_index ++ ; + if ( ! strncmp ( name, text, len ) ) { + return ( strdup ( name ) ) ; + } + } + return ( NULL ) ; +} + + + +/* partial name completion callback for readline() */ +static char ** +my_fgets_completion ( + const char * text, + int start, + int end +) +{ + char ** matches ; + matches = NULL ; + if ( ! start ) { + matches = rl_completion_matches ( text, my_fgets_generator ) ; + } + return ( matches ) ; +} + + + +/* fgets() intercept */ +char * +fgets ( + char * s, + int n, + FILE * stream +) +{ + if ( ! s ) return NULL ; + if ( stream == stdin ) { + char * prompt ; + char * my_fgets_line ; + rl_already_prompted = 1 ; + rl_attempted_completion_function = my_fgets_completion ; + rl_catch_signals = 1 ; + rl_catch_sigwinch = 1 ; + rl_set_signals () ; + prompt = getenv ( "FGETS_PROMPT" ) ; + for ( + my_fgets_line = 0 ; ! my_fgets_line ; my_fgets_line=readline(prompt) + ) ; + if ( ! strncmp(my_fgets_line, "_fgets_reset_", 13) ) { + my_fgets_reset () ; + free ( my_fgets_line ) ; + strcpy ( s, "\n" ) ; + return ( s ) ; + } + if ( ! strncmp(my_fgets_line, "_fgets_dump_", 12) ) { + my_fgets_dump () ; + free ( my_fgets_line ) ; + strcpy ( s, "\n" ) ; + return ( s ) ; + } + if ( ! strncmp(my_fgets_line, "_fgets_debug_", 13) ) { + my_fgets_debug_toggle () ; + free ( my_fgets_line ) ; + strcpy ( s, "\n" ) ; + return ( s ) ; + } + (void) strncpy ( s, my_fgets_line, n-1 ) ; + (void) strcat ( s, "\n" ) ; + if ( *my_fgets_line ) add_history ( my_fgets_line ) ; + free ( my_fgets_line ) ; + return ( s ) ; + } else { + static fgets_t _fgets ; + _fgets = (fgets_t) dlsym ( REAL_LIBC, "fgets" ) ; + if ( ! _fgets ) { + fprintf ( stderr, + "libfgets: failed to dynamically link to native fgets()\n" + ) ; + strcpy ( s, "\n" ) ; + return ( s ) ; + } + return ( + _fgets ( s, n, stream ) + ) ; + } +}
rl-fgets.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlversion.c =================================================================== --- rlversion.c (nonexistent) +++ rlversion.c (revision 33) @@ -0,0 +1,49 @@ +/* + * rlversion -- print out readline's version number + */ + +/* Copyright (C) 1987-2002 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include +#include "posixstat.h" + +#ifdef HAVE_STDLIB_H +# include +#else +extern void exit(); +#endif + +#ifdef READLINE_LIBRARY +# include "readline.h" +#else +# include +#endif + +main() +{ + printf ("%s\n", rl_library_version ? rl_library_version : "unknown"); + exit (0); +}
rlversion.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: readlinebuf.h =================================================================== --- readlinebuf.h (nonexistent) +++ readlinebuf.h (revision 33) @@ -0,0 +1,139 @@ +/******************************************************************************* + * $Revision: 1.2 $ + * $Date: 2001/09/11 06:19:36 $ + * $Author: vyzo $ + * + * Contents: A streambuf which uses the GNU readline library for line I/O + * (c) 2001 by Dimitris Vyzovitis [vyzo@media.mit.edu] + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ******************************************************************************/ + +#ifndef _READLINEBUF_H_ +#define _READLINEBUF_H_ + +#include +#include +#include +#include +#include + +#include +#include + +#if (defined __GNUC__) && (__GNUC__ < 3) +#include +#else +#include +using std::streamsize; +using std::streambuf; +#endif + +class readlinebuf : public streambuf { +public: +#if (defined __GNUC__) && (__GNUC__ < 3) + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; +#endif + static const int_type eof = EOF; // this is -1 + static const int_type not_eof = 0; + +private: + const char* prompt_; + bool history_; + char* line_; + int low_; + int high_; + +protected: + + virtual int_type showmanyc() const { return high_ - low_; } + + virtual streamsize xsgetn( char_type* buf, streamsize n ) { + int rd = n > (high_ - low_)? (high_ - low_) : n; + memcpy( buf, line_, rd ); + low_ += rd; + + if ( rd < n ) { + low_ = high_ = 0; + free( line_ ); // free( NULL ) is a noop + line_ = readline( prompt_ ); + if ( line_ ) { + high_ = strlen( line_ ); + if ( history_ && high_ ) add_history( line_ ); + rd += xsgetn( buf + rd, n - rd ); + } + } + + return rd; + } + + virtual int_type underflow() { + if ( high_ == low_ ) { + low_ = high_ = 0; + free( line_ ); // free( NULL ) is a noop + line_ = readline( prompt_ ); + if ( line_ ) { + high_ = strlen( line_ ); + if ( history_ && high_ ) add_history( line_ ); + } + } + + if ( low_ < high_ ) return line_[low_]; + else return eof; + } + + virtual int_type uflow() { + int_type c = underflow(); + if ( c != eof ) ++low_; + return c; + } + + virtual int_type pbackfail( int_type c = eof ) { + if ( low_ > 0 ) --low_; + else if ( c != eof ) { + if ( high_ > 0 ) { + char* nl = (char*)realloc( line_, high_ + 1 ); + if ( nl ) { + line_ = (char*)memcpy( nl + 1, line_, high_ ); + high_ += 1; + line_[0] = char( c ); + } else return eof; + } else { + assert( !line_ ); + line_ = (char*)malloc( sizeof( char ) ); + *line_ = char( c ); + high_ = 1; + } + } else return eof; + + return not_eof; + } + +public: + readlinebuf( const char* prompt = NULL, bool history = true ) + : prompt_( prompt ), history_( history ), + line_( NULL ), low_( 0 ), high_( 0 ) { + setbuf( 0, 0 ); + } + + +}; + +#endif
readlinebuf.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlcat.c =================================================================== --- rlcat.c (nonexistent) +++ rlcat.c (revision 33) @@ -0,0 +1,180 @@ +/* + * rlcat - cat(1) using readline + * + * usage: rlcat + */ + +/* Copyright (C) 1987-2002 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include "posixstat.h" + +#include +#include +#include +#include + +#ifdef HAVE_STDLIB_H +# include +#else +extern void exit(); +#endif + +#ifndef errno +extern int errno; +#endif + +#if defined (READLINE_LIBRARY) +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern int optind; +extern char *optarg; + +static int stdcat(); + +static char *progname; +static int vflag; + +static void +usage() +{ + fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *temp; + int opt, Vflag, Nflag; + + progname = strrchr(argv[0], '/'); + if (progname == 0) + progname = argv[0]; + else + progname++; + + vflag = Vflag = Nflag = 0; + while ((opt = getopt(argc, argv, "vEVN")) != EOF) + { + switch (opt) + { + case 'v': + vflag = 1; + break; + case 'V': + Vflag = 1; + break; + case 'E': + Vflag = 0; + break; + case 'N': + Nflag = 1; + break; + default: + usage (); + exit (2); + } + } + + argc -= optind; + argv += optind; + + if (isatty(0) == 0 || argc || Nflag) + return stdcat(argc, argv); + + rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs"); + while (temp = readline ("")) + { + if (*temp) + add_history (temp); + printf ("%s\n", temp); + } + + return (ferror (stdout)); +} + +static int +fcopy(fp) + FILE *fp; +{ + int c; + char *x; + + while ((c = getc(fp)) != EOF) + { + if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0) + { + x = rl_untranslate_keyseq (c); + if (fputs (x, stdout) != 0) + return 1; + } + else if (putchar (c) == EOF) + return 1; + } + return (ferror (stdout)); +} + +int +stdcat (argc, argv) + int argc; + char **argv; +{ + int i, fd, r; + char *s; + FILE *fp; + + if (argc == 0) + return (fcopy(stdin)); + + for (i = 0, r = 1; i < argc; i++) + { + if (*argv[i] == '-' && argv[i][1] == 0) + fp = stdin; + else + { + fp = fopen (argv[i], "r"); + if (fp == 0) + { + fprintf (stderr, "%s: %s: cannot open: %s\n", progname, argv[i], strerror(errno)); + continue; + } + } + r = fcopy (fp); + if (fp != stdin) + fclose(fp); + } + return r; +}
rlcat.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: manexamp.c =================================================================== --- manexamp.c (nonexistent) +++ manexamp.c (revision 33) @@ -0,0 +1,112 @@ +/* manexamp.c -- The examples which appear in the documentation are here. */ + +/* Copyright (C) 1987-2002 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#include +#include + +/* **************************************************************** */ +/* */ +/* How to Emulate gets () */ +/* */ +/* **************************************************************** */ + +/* A static variable for holding the line. */ +static char *line_read = (char *)NULL; + +/* Read a string, and return a pointer to it. Returns NULL on EOF. */ +char * +rl_gets () +{ + /* If the buffer has already been allocated, return the memory + to the free pool. */ + if (line_read) + { + free (line_read); + line_read = (char *)NULL; + } + + /* Get a line from the user. */ + line_read = readline (""); + + /* If the line has any text in it, save it on the history. */ + if (line_read && *line_read) + add_history (line_read); + + return (line_read); +} + +/* **************************************************************** */ +/* */ +/* Writing a Function to be Called by Readline. */ +/* */ +/* **************************************************************** */ + +/* Invert the case of the COUNT following characters. */ +invert_case_line (count, key) + int count, key; +{ + register int start, end; + + start = rl_point; + + if (count < 0) + { + direction = -1; + count = -count; + } + else + direction = 1; + + /* Find the end of the range to modify. */ + end = start + (count * direction); + + /* Force it to be within range. */ + if (end > rl_end) + end = rl_end; + else if (end < 0) + end = -1; + + if (start > end) + { + int temp = start; + start = end; + end = temp; + } + + if (start == end) + return; + + /* Tell readline that we are modifying the line, so save the undo + information. */ + rl_modifying (start, end); + + for (; start != end; start += direction) + { + if (_rl_uppercase_p (rl_line_buffer[start])) + rl_line_buffer[start] = _rl_to_lower (rl_line_buffer[start]); + else if (_rl_lowercase_p (rl_line_buffer[start])) + rl_line_buffer[start] = _rl_to_upper (rl_line_buffer[start]); + } + + /* Move point to on top of the last character changed. */ + rl_point = end - direction; +}
manexamp.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlfe/screen.h =================================================================== --- rlfe/screen.h (nonexistent) +++ rlfe/screen.h (revision 33) @@ -0,0 +1,2 @@ +/* Dummy header to avoid modifying pty.c */ +#include "os.h"
rlfe/screen.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlfe/configure.in =================================================================== --- rlfe/configure.in (nonexistent) +++ rlfe/configure.in (revision 33) @@ -0,0 +1,438 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(rlfe.c) +AC_CONFIG_HEADER(config.h) +VERSION=0.4 +AC_SUBST(VERSION) + +dnl +dnl Define some useful macros +dnl +AC_DEFUN(AC_PROGRAM_SOURCE, +[AC_REQUIRE([AC_PROG_CPP])AC_PROVIDE([$0])cat > conftest.c <&5 | sed -e '1,/_CUT_HERE_/d' -e 's/ //g' > conftest.out" +. ./conftest.out +rm -f conftest* +])dnl +dnl +define(AC_NOTE, +[echo "$1" 1>&AC_FD_MSG +])dnl + +old_CFLAGS="$CFLAGS" +AC_PROG_CC +AC_PROG_CPP +AC_PROG_GCC_TRADITIONAL +AC_ISC_POSIX + +AC_TRY_RUN(main(){exit(0);},,[ +if test $CC != cc ; then +AC_NOTE(Your $CC failed - restarting with CC=cc) +AC_NOTE() +CC=cc +export CC +exec $0 $configure_args +fi +]) + +AC_TRY_RUN(main(){exit(0);},, +exec 5>&2 +eval $ac_link +AC_NOTE(CC=$CC; CFLAGS=$CFLAGS; LIBS=$LIBS;) +AC_NOTE($ac_compile) +AC_MSG_ERROR(Can't run the compiler - sorry)) + +AC_TRY_RUN([ +main() +{ + int __something_strange_(); + __something_strange_(0); +} +],AC_MSG_ERROR(Your compiler does not set the exit status - sorry)) + +AC_PROG_AWK + +if test -f etc/toolcheck; then +AC_CHECKING(for buggy tools) +sh etc/toolcheck 1>&AC_FD_MSG +fi + +dnl +dnl **** special unix variants **** +dnl + +AC_CHECKING(for System V) +AC_TRY_COMPILE( +[#include +#include +#include ], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV)) + +AC_CHECKING(for Solaris 2.x) +AC_EGREP_CPP(yes, +[#if defined(SVR4) && defined(sun) + yes +#endif +], LIBS="$LIBS -lsocket -lnsl -lkstat") + +dnl +dnl **** select() **** +dnl + +AC_CHECKING(select) +AC_TRY_LINK(,[select(0, 0, 0, 0, 0);],, +LIBS="$LIBS -lnet -lnsl" +AC_CHECKING(select with $LIBS) +AC_TRY_LINK(,[select(0, 0, 0, 0, 0);],, +AC_MSG_ERROR(!!! no select - no screen)) +) +dnl +dnl **** check the select implementation **** +dnl + +AC_CHECKING(select return value) +AC_TRY_RUN([ +#include +#include +#include + +char *nam = "/tmp/conftest$$"; + +#ifdef NAMEDPIPE + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif +#ifndef S_IFIFO +#define S_IFIFO 0010000 +#endif + + +main() +{ +#ifdef FD_SET + fd_set f; +#else + int f; +#endif + +#ifdef __FreeBSD__ +/* From Andrew A. Chernov (ache@astral.msk.su): + * opening RDWR fifo fails in BSD 4.4, but select return values are + * right. + */ + exit(0); +#endif + (void)alarm(5); +#ifdef POSIX + if (mkfifo(nam, 0777)) +#else + if (mknod(nam, S_IFIFO|0777, 0)) +#endif + exit(1); + close(0); + if (open(nam, O_RDWR | O_NONBLOCK)) + exit(1); + if (write(0, "TEST", 4) == -1) + exit(1); + +#else + +#include +#include +#include + +main() +{ + int s1, s2, l; + struct sockaddr_un a; +#ifdef FD_SET + fd_set f; +#else + int f; +#endif + + (void)alarm(5); + if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + exit(1); + a.sun_family = AF_UNIX; + strcpy(a.sun_path, nam); + (void) unlink(nam); + if (bind(s1, (struct sockaddr *) &a, strlen(nam)+2) == -1) + exit(1); + if (listen(s1, 2)) + exit(1); + if (fork() == 0) + { + if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + kill(getppid(), 3); + (void)connect(s2, (struct sockaddr *)&a, strlen(nam) + 2); + if (write(s2, "HELLO", 5) == -1) + kill(getppid(), 3); + exit(0); + } + l = sizeof(a); + close(0); + if (accept(s1, (struct sockaddr *)&a, &l)) + exit(1); +#endif + + +#ifdef FD_SET + FD_SET(0, &f); +#else + f = 1; +#endif + if (select(1, &f, 0, 0, 0) == -1) + exit(1); + if (select(1, &f, &f, 0, 0) != 2) + exit(1); + exit(0); +} +],AC_NOTE(- select is ok), +AC_NOTE(- select can't count) AC_DEFINE(SELECT_BROKEN)) + +dnl +dnl **** termcap or terminfo **** +dnl +AC_CHECKING(for tgetent) +AC_TRY_LINK(,tgetent((char *)0, (char *)0);,, +olibs="$LIBS" +LIBS="-lcurses $olibs" +AC_CHECKING(libcurses) +AC_TRY_LINK(,[ +#ifdef __hpux +__sorry_hpux_libcurses_is_totally_broken_in_10_10(); +#else +tgetent((char *)0, (char *)0); +#endif +],, +LIBS="-ltermcap $olibs" +AC_CHECKING(libtermcap) +AC_TRY_LINK(,tgetent((char *)0, (char *)0);,, +LIBS="-ltermlib $olibs" +AC_CHECKING(libtermlib) +AC_TRY_LINK(,tgetent((char *)0, (char *)0);,, +LIBS="-lncurses $olibs" +AC_CHECKING(libncurses) +AC_TRY_LINK(,tgetent((char *)0, (char *)0);,, +AC_MSG_ERROR(!!! no tgetent - no screen)))))) + +AC_TRY_RUN([ +main() +{ + exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1); +}], AC_NOTE(- you use the termcap database), +AC_NOTE(- you use the terminfo database) AC_DEFINE(TERMINFO)) +AC_CHECKING(ospeed) +AC_TRY_LINK(extern short ospeed;,ospeed=5;,,AC_DEFINE(NEED_OSPEED)) + +dnl +dnl **** PTY specific things **** +dnl +AC_CHECKING(for /dev/ptc) +if test -r /dev/ptc; then +AC_DEFINE(HAVE_DEV_PTC) +fi + +AC_CHECKING(for SVR4 ptys) +sysvr4ptys= +if test -c /dev/ptmx ; then +AC_TRY_LINK([],[ptsname(0);grantpt(0);unlockpt(0);],[AC_DEFINE(HAVE_SVR4_PTYS) +sysvr4ptys=1]) +fi + +AC_CHECK_FUNCS(getpt) + +dnl check for openpty() +if test -z "$sysvr4ptys"; then +AC_CHECK_FUNCS(openpty,, +[AC_CHECK_LIB(util,openpty, [AC_DEFINE(HAVE_OPENPTY)] [LIBS="$LIBS -lutil"])]) +fi + +AC_CHECKING(for ptyranges) +if test -d /dev/ptym ; then +pdir='/dev/ptym' +else +pdir='/dev' +fi +dnl SCO uses ptyp%d +AC_EGREP_CPP(yes, +[#ifdef M_UNIX + yes; +#endif +], ptys=`echo /dev/ptyp??`, ptys=`echo $pdir/pty??`) +dnl if test -c /dev/ptyp19; then +dnl ptys=`echo /dev/ptyp??` +dnl else +dnl ptys=`echo $pdir/pty??` +dnl fi +if test "$ptys" != "$pdir/pty??" ; then +p0=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\).$/\1/g' | sort -u | tr -d '\012'` +p1=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\)$/\1/g' | sort -u | tr -d '\012'` +AC_DEFINE_UNQUOTED(PTYRANGE0,"$p0") +AC_DEFINE_UNQUOTED(PTYRANGE1,"$p1") +fi + +dnl **** pty mode/group handling **** +dnl +dnl support provided by Luke Mewburn , 931222 +AC_ARG_WITH(pty-mode, [ --with-pty-mode=mode default mode for ptys], [ ptymode="${withval}" ]) +AC_ARG_WITH(pty-group, [ --with-pty-group=group default group for ptys], [ ptygrp="${withval}" ]) +test -n "$ptymode" || ptymode=0620 +if test -n "$ptygrp" ; then +AC_DEFINE_UNQUOTED(PTYMODE, $ptymode) +AC_DEFINE_UNQUOTED(PTYGROUP,$ptygrp) +else + +AC_CHECKING(default tty permissions/group) +rm -f conftest_grp +AC_TRY_RUN([ +#include +#include +#include +main() +{ + struct stat sb; + char *x,*ttyname(); + int om, m; + FILE *fp; + + if (!(x = ttyname(0))) exit(1); + if (stat(x, &sb)) exit(1); + om = sb.st_mode; + if (om & 002) exit(0); + m = system("mesg y"); + if (m == -1 || m == 127) exit(1); + if (stat(x, &sb)) exit(1); + m = sb.st_mode; + if (chmod(x, om)) exit(1); + if (m & 002) exit(0); + if (sb.st_gid == getgid()) exit(1); + if (!(fp=fopen("conftest_grp", "w"))) + exit(1); + fprintf(fp, "%d\n", sb.st_gid); + fclose(fp); + exit(0); +} +],[ + if test -f conftest_grp; then + ptygrp=`cat conftest_grp` + AC_NOTE([- pty mode: $ptymode, group: $ptygrp]) + AC_DEFINE_UNQUOTED(PTYMODE, $ptymode) + AC_DEFINE_UNQUOTED(PTYGROUP,$ptygrp) + else + AC_NOTE(- ptys are world accessable) + fi +],[ + WRITEPATH='' + XTERMPATH='' + AC_PATH_PROG(WRITEPATH, write) + AC_PATH_PROG(XTERMPATH, xterm) + found= + if test -n "$WRITEPATH$XTERMPATH"; then + findfollow= + lsfollow= + found=`find $WRITEPATH $XTERMPATH -follow -print 2>/dev/null` + if test -n "$found"; then + findfollow=-follow + lsfollow=L + fi + if test -n "$XTERMPATH"; then + ptygrpn=`ls -l$lsfollow $XTERMPATH | sed -n -e 1p | $AWK '{print $4}'` + if test tty != "$ptygrpn"; then + XTERMPATH= + fi + fi + fi + if test -n "$WRITEPATH$XTERMPATH"; then + found=`find $WRITEPATH $XTERMPATH $findfollow -perm -2000 -print` + if test -n "$found"; then + ptygrp=`ls -ln$lsfollow $found | sed -n -e 1p | $AWK '{print $4}'` + AC_NOTE([- pty mode: $ptymode, group: $ptygrp]) + AC_DEFINE_UNQUOTED(PTYMODE, $ptymode) + AC_DEFINE_UNQUOTED(PTYGROUP,$ptygrp) + else + AC_NOTE(- ptys are world accessable) + fi + else + AC_NOTE(- can't determine - assume ptys are world accessable) + fi + ] +) +rm -f conftest_grp +fi + +dnl +dnl **** signal handling **** +dnl +if test -n "$posix" ; then + +dnl POSIX has reliable signals with void return type. +AC_NOTE(assuming posix signal definition) +AC_DEFINE(SIGVOID) + +else + +AC_CHECKING(return type of signal handlers) +AC_TRY_COMPILE( +[#include +#include +#ifdef signal +#undef signal +#endif +extern void (*signal ()) ();], [int i;], AC_DEFINE(SIGVOID)) +AC_CHECKING(sigset) +AC_TRY_LINK([ +#include +#include +],[ +#ifdef SIGVOID +sigset(0, (void (*)())0); +#else +sigset(0, (int (*)())0); +#endif +], AC_DEFINE(USESIGSET)) +AC_CHECKING(signal implementation) +AC_TRY_RUN([ +#include +#include + +#ifndef SIGCLD +#define SIGCLD SIGCHLD +#endif +#ifdef USESIGSET +#define signal sigset +#endif + +int got; + +#ifdef SIGVOID +void +#endif +hand() +{ + got++; +} + +main() +{ + /* on hpux we use sigvec to get bsd signals */ +#ifdef __hpux + (void)signal(SIGCLD, hand); + kill(getpid(), SIGCLD); + kill(getpid(), SIGCLD); + if (got < 2) + exit(1); +#endif + exit(0); +} +],,AC_DEFINE(SYSVSIGS)) + +fi + +AC_OUTPUT(Makefile)
rlfe/configure.in Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlfe/ChangeLog =================================================================== --- rlfe/ChangeLog (nonexistent) +++ rlfe/ChangeLog (revision 33) @@ -0,0 +1,37 @@ +2004-11-04 Per Bothner + + * pty.c: Import from screen-4.0.2. + * configure.in, Makefile.in, config.h.in: Set up autoconf handling, + copying a bunk of stuff over from screen. + * rlfe.c: Use OpenPTY from pty.c instead of get_master_pty. + +2004-11-03 Per Bothner + + * rlfe.c: Get input emphasis (boldening) more robust. + + * rlfe.c: Various cleanups on comments and names. + +2003-11-07 Wolfgang Taeuber + + * Specify a history file and the size of the history file with command + * line options; use EDITOR/VISUAL to set vi/emacs preference. + +1999-09-03 Chet Ramey + + * fep.c: Memmove is not universally available. This patch assumes + that an autoconf test has been performed, and that memcpy is + available without checking. + + * fep.c: VDISCARD is not universally available, even when termios is. + + * fep.c: If a system doesn't have TIOCSCTTY, the first `open' + performed after setsid allocates a controlling terminal. The + original code would leave the child process running on the slave pty + without a controlling tty if TIOCSCTTY was not available. + + * fep.c: Most versions of SVR4, including solaris, don't allow + terminal ioctl calls on the master side of the pty. + +1999-08-28 Per Bothner + + * fep.c: Initial release.
rlfe/ChangeLog Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlfe/os.h =================================================================== --- rlfe/os.h (nonexistent) +++ rlfe/os.h (revision 33) @@ -0,0 +1,530 @@ +/* Copyright (c) 1993-2002 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + * $Id$ FAU + */ + +#include +#include + +#include + +/* In strict ANSI mode, HP-UX machines define __hpux but not hpux */ +#if defined(__hpux) && !defined(hpux) +# define hpux +#endif + +#if defined(__bsdi__) || defined(__386BSD__) || defined(_CX_UX) || defined(hpux) || defined(_IBMR2) || defined(linux) +# include +#endif /* __bsdi__ || __386BSD__ || _CX_UX || hpux || _IBMR2 || linux */ + +#ifdef ISC +# ifdef ENAMETOOLONG +# undef ENAMETOOLONG +# endif +# ifdef ENOTEMPTY +# undef ENOTEMPTY +# endif +# include +# include +#endif + +#ifdef sun +# define getpgrp __getpgrp +# define exit __exit +#endif +#ifdef POSIX +# include +# if defined(__STDC__) +# include +# endif /* __STDC__ */ +#endif /* POSIX */ +#ifdef sun +# undef getpgrp +# undef exit +#endif /* sun */ + +#ifndef linux /* all done in */ +extern int errno; +#endif /* linux */ +#ifndef HAVE_STRERROR +/* No macros, please */ +#undef strerror +#endif + +#if !defined(SYSV) && !defined(linux) +# ifdef NEWSOS +# define strlen ___strlen___ +# include +# undef strlen +# else /* NEWSOS */ +# include +# endif /* NEWSOS */ +#else /* SYSV */ +# if defined(SVR4) || defined(NEWSOS) +# define strlen ___strlen___ +# include +# undef strlen +# if !defined(NEWSOS) && !defined(__hpux) + extern size_t strlen(const char *); +# endif +# else /* SVR4 */ +# include +# endif /* SVR4 */ +#endif /* SYSV */ + +#ifdef USEVARARGS +# if defined(__STDC__) +# include +# define VA_LIST(var) va_list var; +# define VA_DOTS ... +# define VA_DECL +# define VA_START(ap, fmt) va_start(ap, fmt) +# define VA_ARGS(ap) ap +# define VA_END(ap) va_end(ap) +# else +# include +# define VA_LIST(var) va_list var; +# define VA_DOTS va_alist +# define VA_DECL va_dcl +# define VA_START(ap, fmt) va_start(ap) +# define VA_ARGS(ap) ap +# define VA_END(ap) va_end(ap) +# endif +#else +# define VA_LIST(var) +# define VA_DOTS p1, p2, p3, p4, p5, p6 +# define VA_DECL unsigned long VA_DOTS; +# define VA_START(ap, fmt) +# define VA_ARGS(ap) VA_DOTS +# define VA_END(ap) +# undef vsnprintf +# define vsnprintf xsnprintf +#endif + +#if !defined(sun) && !defined(B43) && !defined(ISC) && !defined(pyr) && !defined(_CX_UX) +# include +#endif +#include + +#ifdef M_UNIX /* SCO */ +# include +# include +# define ftruncate(fd, s) chsize(fd, s) +#endif + +#ifdef SYSV +# define index strchr +# define rindex strrchr +# define bzero(poi,len) memset(poi,0,len) +# define bcmp memcmp +# define killpg(pgrp,sig) kill( -(pgrp), sig) +#endif + +#ifndef HAVE_GETCWD +# define getcwd(b,l) getwd(b) +#endif + +#ifndef USEBCOPY +# ifdef USEMEMMOVE +# define bcopy(s,d,len) memmove(d,s,len) +# else +# ifdef USEMEMCPY +# define bcopy(s,d,len) memcpy(d,s,len) +# else +# define NEED_OWN_BCOPY +# define bcopy xbcopy +# endif +# endif +#endif + +#ifdef hpux +# define setreuid(ruid, euid) setresuid(ruid, euid, -1) +# define setregid(rgid, egid) setresgid(rgid, egid, -1) +#endif + +#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) +# define USE_SETEUID +#endif + +#if !defined(HAVE__EXIT) && !defined(_exit) +#define _exit(x) exit(x) +#endif + +#ifndef HAVE_UTIMES +# define utimes utime +#endif + +#ifdef BUILTIN_TELNET +# include +# include +#endif + +#if defined(USE_LOCALE) && (!defined(HAVE_SETLOCALE) || !defined(HAVE_STRFTIME)) +# undef USE_LOCALE +#endif + +/***************************************************************** + * terminal handling + */ + +#ifdef POSIX +# include +# ifdef hpux +# include +# endif /* hpux */ +# ifdef NCCS +# define MAXCC NCCS +# else +# define MAXCC 256 +# endif +#else /* POSIX */ +# ifdef TERMIO +# include +# ifdef NCC +# define MAXCC NCC +# else +# define MAXCC 256 +# endif +# ifdef CYTERMIO +# include +# endif +# else /* TERMIO */ +# include +# endif /* TERMIO */ +#endif /* POSIX */ + +#ifndef VDISABLE +# ifdef _POSIX_VDISABLE +# define VDISABLE _POSIX_VDISABLE +# else +# define VDISABLE 0377 +# endif /* _POSIX_VDISABLE */ +#endif /* !VDISABLE */ + + +/* on sgi, regardless of the stream head's read mode (RNORM/RMSGN/RMSGD) + * TIOCPKT mode causes data loss if our buffer is too small (IOSIZE) + * to hold the whole packet at first read(). + * (Marc Boucher) + * + * matthew green: + * TIOCPKT is broken on dgux 5.4.1 generic AViiON mc88100 + * + * Joe Traister: On AIX4, programs like irc won't work if screen + * uses TIOCPKT (select fails to return on pty read). + */ +#if defined(sgi) || defined(DGUX) || defined(_IBMR2) +# undef TIOCPKT +#endif + +/* linux ncurses is broken, we have to use our own tputs */ +#if defined(linux) && defined(TERMINFO) +# define tputs xtputs +#endif + +/* Alexandre Oliva: SVR4 style ptys don't work with osf */ +#ifdef __osf__ +# undef HAVE_SVR4_PTYS +#endif + +/***************************************************************** + * utmp handling + */ + +#ifdef GETUTENT + typedef char *slot_t; +#else + typedef int slot_t; +#endif + +#if defined(UTMPOK) || defined(BUGGYGETLOGIN) +# if defined(SVR4) && !defined(DGUX) && !defined(__hpux) && !defined(linux) +# include +# define UTMPFILE UTMPX_FILE +# define utmp utmpx +# define getutent getutxent +# define getutid getutxid +# define getutline getutxline +# define pututline pututxline +# define setutent setutxent +# define endutent endutxent +# define ut_time ut_xtime +# else /* SVR4 */ +# include +# endif /* SVR4 */ +# ifdef apollo + /* + * We don't have GETUTENT, so we dig into utmp ourselves. + * But we save the permanent filedescriptor and + * open utmp just when we need to. + * This code supports an unsorted utmp. jw. + */ +# define UTNOKEEP +# endif /* apollo */ + +# ifndef UTMPFILE +# ifdef UTMP_FILE +# define UTMPFILE UTMP_FILE +# else +# ifdef _PATH_UTMP +# define UTMPFILE _PATH_UTMP +# else +# define UTMPFILE "/etc/utmp" +# endif /* _PATH_UTMP */ +# endif +# endif + +#endif /* UTMPOK || BUGGYGETLOGIN */ + +#if !defined(UTMPOK) && defined(USRLIMIT) +# undef USRLIMIT +#endif + +#ifdef LOGOUTOK +# ifndef LOGINDEFAULT +# define LOGINDEFAULT 0 +# endif +#else +# ifdef LOGINDEFAULT +# undef LOGINDEFAULT +# endif +# define LOGINDEFAULT 1 +#endif + + +/***************************************************************** + * file stuff + */ + +#ifndef F_OK +#define F_OK 0 +#endif +#ifndef X_OK +#define X_OK 1 +#endif +#ifndef W_OK +#define W_OK 2 +#endif +#ifndef R_OK +#define R_OK 4 +#endif + +#ifndef S_IFIFO +#define S_IFIFO 0010000 +#endif +#ifndef S_IREAD +#define S_IREAD 0000400 +#endif +#ifndef S_IWRITE +#define S_IWRITE 0000200 +#endif +#ifndef S_IEXEC +#define S_IEXEC 0000100 +#endif + +#if defined(S_IFIFO) && defined(S_IFMT) && !defined(S_ISFIFO) +#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#endif +#if defined(S_IFSOCK) && defined(S_IFMT) && !defined(S_ISSOCK) +#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#endif +#if defined(S_IFCHR) && defined(S_IFMT) && !defined(S_ISCHR) +#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#endif +#if defined(S_IFDIR) && defined(S_IFMT) && !defined(S_ISDIR) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif +#if defined(S_IFLNK) && defined(S_IFMT) && !defined(S_ISLNK) +#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#endif + +/* + * SunOS 4.1.3: `man 2V open' has only one line that mentions O_NOBLOCK: + * + * O_NONBLOCK Same as O_NDELAY above. + * + * on the very same SunOS 4.1.3, I traced the open system call and found + * that an open("/dev/ttyy08", O_RDWR|O_NONBLOCK|O_NOCTTY) was blocked, + * whereas open("/dev/ttyy08", O_RDWR|O_NDELAY |O_NOCTTY) went through. + * + * For this simple reason I now favour O_NDELAY. jw. 4.5.95 + */ +#if defined(sun) && !defined(SVR4) +# undef O_NONBLOCK +#endif + +#if !defined(O_NONBLOCK) && defined(O_NDELAY) +# define O_NONBLOCK O_NDELAY +#endif + +#if !defined(FNBLOCK) && defined(FNONBLOCK) +# define FNBLOCK FNONBLOCK +#endif +#if !defined(FNBLOCK) && defined(FNDELAY) +# define FNBLOCK FNDELAY +#endif +#if !defined(FNBLOCK) && defined(O_NONBLOCK) +# define FNBLOCK O_NONBLOCK +#endif + +#ifndef POSIX +#undef mkfifo +#define mkfifo(n,m) mknod(n,S_IFIFO|(m),0) +#endif + +#if !defined(HAVE_LSTAT) && !defined(lstat) +# define lstat stat +#endif + +/***************************************************************** + * signal handling + */ + +#ifdef SIGVOID +# define SIGRETURN +# define sigret_t void +#else +# define SIGRETURN return 0; +# define sigret_t int +#endif + +/* Geeeee, reverse it? */ +#if defined(SVR4) || (defined(SYSV) && defined(ISC)) || defined(_AIX) || defined(linux) || defined(ultrix) || defined(__386BSD__) || defined(__bsdi__) || defined(POSIX) || defined(NeXT) +# define SIGHASARG +#endif + +#ifdef SIGHASARG +# define SIGPROTOARG (int) +# define SIGDEFARG (sigsig) int sigsig; +# define SIGARG 0 +#else +# define SIGPROTOARG (void) +# define SIGDEFARG () +# define SIGARG +#endif + +#ifndef SIGCHLD +#define SIGCHLD SIGCLD +#endif + +#if defined(POSIX) || defined(hpux) +# define signal xsignal +#else +# ifdef USESIGSET +# define signal sigset +# endif /* USESIGSET */ +#endif + +/* used in screen.c and attacher.c */ +#ifndef NSIG /* kbeal needs these w/o SYSV */ +# define NSIG 32 +#endif /* !NSIG */ + + +/***************************************************************** + * Wait stuff + */ + +#if (!defined(sysV68) && !defined(M_XENIX)) || defined(NeXT) || defined(M_UNIX) +# include +#endif + +#ifndef WTERMSIG +# ifndef BSDWAIT /* if wait is NOT a union: */ +# define WTERMSIG(status) (status & 0177) +# else +# define WTERMSIG(status) status.w_T.w_Termsig +# endif +#endif + +#ifndef WSTOPSIG +# ifndef BSDWAIT /* if wait is NOT a union: */ +# define WSTOPSIG(status) ((status >> 8) & 0377) +# else +# define WSTOPSIG(status) status.w_S.w_Stopsig +# endif +#endif + +/* NET-2 uses WCOREDUMP */ +#if defined(WCOREDUMP) && !defined(WIFCORESIG) +# define WIFCORESIG(status) WCOREDUMP(status) +#endif + +#ifndef WIFCORESIG +# ifndef BSDWAIT /* if wait is NOT a union: */ +# define WIFCORESIG(status) (status & 0200) +# else +# define WIFCORESIG(status) status.w_T.w_Coredump +# endif +#endif + +#ifndef WEXITSTATUS +# ifndef BSDWAIT /* if wait is NOT a union: */ +# define WEXITSTATUS(status) ((status >> 8) & 0377) +# else +# define WEXITSTATUS(status) status.w_T.w_Retcode +# endif +#endif + + +/***************************************************************** + * select stuff + */ + +#if defined(M_XENIX) || defined(M_UNIX) || defined(_SEQUENT_) +#include /* for timeval + FD... */ +#endif + +/* + * SunOS 3.5 - Tom Schmidt - Micron Semiconductor, Inc - 27-Jul-93 + * tschmidt@vax.micron.com + */ +#ifndef FD_SET +# ifndef SUNOS3 +typedef struct fd_set { int fds_bits[1]; } fd_set; +# endif +# define FD_ZERO(fd) ((fd)->fds_bits[0] = 0) +# define FD_SET(b, fd) ((fd)->fds_bits[0] |= 1 << (b)) +# define FD_ISSET(b, fd) ((fd)->fds_bits[0] & 1 << (b)) +# define FD_SETSIZE 32 +#endif + + +/***************************************************************** + * user defineable stuff + */ + +#ifndef TERMCAP_BUFSIZE +# define TERMCAP_BUFSIZE 2048 +#endif + +#ifndef MAXPATHLEN +# define MAXPATHLEN 1024 +#endif + +/* + * you may try to vary this value. Use low values if your (VMS) system + * tends to choke when pasting. Use high values if you want to test + * how many characters your pty's can buffer. + */ +#define IOSIZE 4096 +
rlfe/os.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlfe/rlfe.c =================================================================== --- rlfe/rlfe.c (nonexistent) +++ rlfe/rlfe.c (revision 33) @@ -0,0 +1,780 @@ +/* A front-end using readline to "cook" input lines. + * + * Copyright (C) 2004, 1999 Per Bothner + * + * This front-end program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * Some code from Johnson & Troan: "Linux Application Development" + * (Addison-Wesley, 1998) was used directly or for inspiration. + * + * 2003-11-07 Wolfgang Taeuber + * Specify a history file and the size of the history file with command + * line options; use EDITOR/VISUAL to set vi/emacs preference. + */ + +/* PROBLEMS/TODO: + * + * Only tested under GNU/Linux and Mac OS 10.x; needs to be ported. + * + * Switching between line-editing-mode vs raw-char-mode depending on + * what tcgetattr returns is inherently not robust, plus it doesn't + * work when ssh/telnetting in. A better solution is possible if the + * tty system can send in-line escape sequences indicating the current + * mode, echo'd input, etc. That would also allow a user preference + * to set different colors for prompt, input, stdout, and stderr. + * + * When running mc -c under the Linux console, mc does not recognize + * mouse clicks, which mc does when not running under rlfe. + * + * Pasting selected text containing tabs is like hitting the tab character, + * which invokes readline completion. We don't want this. I don't know + * if this is fixable without integrating rlfe into a terminal emulator. + * + * Echo suppression is a kludge, but can only be avoided with better kernel + * support: We need a tty mode to disable "real" echoing, while still + * letting the inferior think its tty driver to doing echoing. + * Stevens's book claims SCR$ and BSD4.3+ have TIOCREMOTE. + * + * The latest readline may have some hooks we can use to avoid having + * to back up the prompt. (See HAVE_ALREADY_PROMPTED.) + * + * Desirable readline feature: When in cooked no-echo mode (e.g. password), + * echo characters are they are types with '*', but remove them when done. + * + * Asynchronous output while we're editing an input line should be + * inserted in the output view *before* the input line, so that the + * lines being edited (with the prompt) float at the end of the input. + * + * A "page mode" option to emulate more/less behavior: At each page of + * output, pause for a user command. This required parsing the output + * to keep track of line lengths. It also requires remembering the + * output, if we want an option to scroll back, which suggests that + * this should be integrated with a terminal emulator like xterm. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +#ifndef COMMAND +#define COMMAND "/bin/bash" +#endif +#ifndef COMMAND_ARGS +#define COMMAND_ARGS COMMAND +#endif + +#ifndef ALT_COMMAND +#define ALT_COMMAND "/bin/sh" +#endif +#ifndef ALT_COMMAND_ARGS +#define ALT_COMMAND_ARGS ALT_COMMAND +#endif + +#ifndef HAVE_MEMMOVE +# if __GNUC__ > 1 +# define memmove(d, s, n) __builtin_memcpy(d, s, n) +# else +# define memmove(d, s, n) memcpy(d, s, n) +# endif +#else +# define memmove(d, s, n) memcpy(d, s, n) +#endif + +#define APPLICATION_NAME "rlfe" + +static int in_from_inferior_fd; +static int out_to_inferior_fd; +static void set_edit_mode (); +static void usage_exit (); +static char *hist_file = 0; +static int hist_size = 0; + +/* Unfortunately, we cannot safely display echo from the inferior process. + The reason is that the echo bit in the pty is "owned" by the inferior, + and if we try to turn it off, we could confuse the inferior. + Thus, when echoing, we get echo twice: First readline echoes while + we're actually editing. Then we send the line to the inferior, and the + terminal driver send back an extra echo. + The work-around is to remember the input lines, and when we see that + line come back, we supress the output. + A better solution (supposedly available on SVR4) would be a smarter + terminal driver, with more flags ... */ +#define ECHO_SUPPRESS_MAX 1024 +char echo_suppress_buffer[ECHO_SUPPRESS_MAX]; +int echo_suppress_start = 0; +int echo_suppress_limit = 0; + +/*#define DEBUG*/ + +#ifdef DEBUG +FILE *logfile = NULL; +#define DPRINT0(FMT) (fprintf(logfile, FMT), fflush(logfile)) +#define DPRINT1(FMT, V1) (fprintf(logfile, FMT, V1), fflush(logfile)) +#define DPRINT2(FMT, V1, V2) (fprintf(logfile, FMT, V1, V2), fflush(logfile)) +#else +#define DPRINT0(FMT) ((void) 0) /* Do nothing */ +#define DPRINT1(FMT, V1) ((void) 0) /* Do nothing */ +#define DPRINT2(FMT, V1, V2) ((void) 0) /* Do nothing */ +#endif + +struct termios orig_term; + +/* Pid of child process. */ +static pid_t child = -1; + +static void +sig_child (int signo) +{ + int status; + wait (&status); + if (hist_file != 0) + { + write_history (hist_file); + if (hist_size) + history_truncate_file (hist_file, hist_size); + } + DPRINT0 ("(Child process died.)\n"); + tcsetattr(STDIN_FILENO, TCSANOW, &orig_term); + exit (0); +} + +volatile int propagate_sigwinch = 0; + +/* sigwinch_handler + * propagate window size changes from input file descriptor to + * master side of pty. + */ +void sigwinch_handler(int signal) { + propagate_sigwinch = 1; +} + + +/* get_slave_pty() returns an integer file descriptor. + * If it returns < 0, an error has occurred. + * Otherwise, it has returned the slave file descriptor. + */ + +int get_slave_pty(char *name) { + struct group *gptr; + gid_t gid; + int slave = -1; + + /* chown/chmod the corresponding pty, if possible. + * This will only work if the process has root permissions. + * Alternatively, write and exec a small setuid program that + * does just this. + */ + if ((gptr = getgrnam("tty")) != 0) { + gid = gptr->gr_gid; + } else { + /* if the tty group does not exist, don't change the + * group on the slave pty, only the owner + */ + gid = -1; + } + + /* Note that we do not check for errors here. If this is code + * where these actions are critical, check for errors! + */ + chown(name, getuid(), gid); + /* This code only makes the slave read/writeable for the user. + * If this is for an interactive shell that will want to + * receive "write" and "wall" messages, OR S_IWGRP into the + * second argument below. + */ + chmod(name, S_IRUSR|S_IWUSR); + + /* open the corresponding slave pty */ + slave = open(name, O_RDWR); + return (slave); +} + +/* Certain special characters, such as ctrl/C, we want to pass directly + to the inferior, rather than letting readline handle them. */ + +static char special_chars[20]; +static int special_chars_count; + +static void +add_special_char(int ch) +{ + if (ch != 0) + special_chars[special_chars_count++] = ch; +} + +static int eof_char; + +static int +is_special_char(int ch) +{ + int i; +#if 0 + if (ch == eof_char && rl_point == rl_end) + return 1; +#endif + for (i = special_chars_count; --i >= 0; ) + if (special_chars[i] == ch) + return 1; + return 0; +} + +static char buf[1024]; +/* buf[0 .. buf_count-1] is the what has been emitted on the current line. + It is used as the readline prompt. */ +static int buf_count = 0; + +int do_emphasize_input = 1; +int current_emphasize_input; + +char *start_input_mode = "\033[1m"; +char *end_input_mode = "\033[0m"; + +int num_keys = 0; + +static void maybe_emphasize_input (int on) +{ + if (on == current_emphasize_input + || (on && ! do_emphasize_input)) + return; + fprintf (rl_outstream, on ? start_input_mode : end_input_mode); + fflush (rl_outstream); + current_emphasize_input = on; +} + +static void +null_prep_terminal (int meta) +{ +} + +static void +null_deprep_terminal () +{ + maybe_emphasize_input (0); +} + +static int +pre_input_change_mode (void) +{ + return 0; +} + +char pending_special_char; + +static void +line_handler (char *line) +{ + if (line == NULL) + { + char buf[1]; + DPRINT0("saw eof!\n"); + buf[0] = '\004'; /* ctrl/d */ + write (out_to_inferior_fd, buf, 1); + } + else + { + static char enter[] = "\r"; + /* Send line to inferior: */ + int length = strlen (line); + if (length > ECHO_SUPPRESS_MAX-2) + { + echo_suppress_start = 0; + echo_suppress_limit = 0; + } + else + { + if (echo_suppress_limit + length > ECHO_SUPPRESS_MAX - 2) + { + if (echo_suppress_limit - echo_suppress_start + length + <= ECHO_SUPPRESS_MAX - 2) + { + memmove (echo_suppress_buffer, + echo_suppress_buffer + echo_suppress_start, + echo_suppress_limit - echo_suppress_start); + echo_suppress_limit -= echo_suppress_start; + echo_suppress_start = 0; + } + else + { + echo_suppress_limit = 0; + } + echo_suppress_start = 0; + } + memcpy (echo_suppress_buffer + echo_suppress_limit, + line, length); + echo_suppress_limit += length; + echo_suppress_buffer[echo_suppress_limit++] = '\r'; + echo_suppress_buffer[echo_suppress_limit++] = '\n'; + } + write (out_to_inferior_fd, line, length); + if (pending_special_char == 0) + { + write (out_to_inferior_fd, enter, sizeof(enter)-1); + if (*line) + add_history (line); + } + free (line); + } + rl_callback_handler_remove (); + buf_count = 0; + num_keys = 0; + if (pending_special_char != 0) + { + write (out_to_inferior_fd, &pending_special_char, 1); + pending_special_char = 0; + } +} + +/* Value of rl_getc_function. + Use this because readline should read from stdin, not rl_instream, + points to the pty (so readline has monitor its terminal modes). */ + +int +my_rl_getc (FILE *dummy) +{ + int ch = rl_getc (stdin); + if (is_special_char (ch)) + { + pending_special_char = ch; + return '\r'; + } + return ch; +} + +int +main(int argc, char** argv) +{ + char *path; + int i; + int master; + char *name; + int in_from_tty_fd; + struct sigaction act; + struct winsize ws; + struct termios t; + int maxfd; + fd_set in_set; + static char empty_string[1] = ""; + char *prompt = empty_string; + int ioctl_err = 0; + int arg_base = 1; + +#ifdef DEBUG + logfile = fopen("/tmp/rlfe.log", "w"); +#endif + + while (arg_base= argc ) + usage_exit(); + switch(argv[arg_base][1]) + { + case 'h': + arg_base++; + hist_file = argv[arg_base]; + break; + case 's': + arg_base++; + hist_size = atoi(argv[arg_base]); + if (hist_size<0) + usage_exit(); + break; + default: + usage_exit(); + } + arg_base++; + } + if (hist_file) + read_history (hist_file); + + set_edit_mode (); + + rl_readline_name = APPLICATION_NAME; + + if ((master = OpenPTY (&name)) < 0) + { + perror("ptypair: could not open master pty"); + exit(1); + } + + DPRINT1("pty name: '%s'\n", name); + + /* set up SIGWINCH handler */ + act.sa_handler = sigwinch_handler; + sigemptyset(&(act.sa_mask)); + act.sa_flags = 0; + if (sigaction(SIGWINCH, &act, NULL) < 0) + { + perror("ptypair: could not handle SIGWINCH "); + exit(1); + } + + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0) + { + perror("ptypair: could not get window size"); + exit(1); + } + + if ((child = fork()) < 0) + { + perror("cannot fork"); + exit(1); + } + + if (child == 0) + { + int slave; /* file descriptor for slave pty */ + + /* We are in the child process */ + close(master); + +#ifdef TIOCSCTTY + if ((slave = get_slave_pty(name)) < 0) + { + perror("ptypair: could not open slave pty"); + exit(1); + } +#endif + + /* We need to make this process a session group leader, because + * it is on a new PTY, and things like job control simply will + * not work correctly unless there is a session group leader + * and process group leader (which a session group leader + * automatically is). This also disassociates us from our old + * controlling tty. + */ + if (setsid() < 0) + { + perror("could not set session leader"); + } + + /* Tie us to our new controlling tty. */ +#ifdef TIOCSCTTY + if (ioctl(slave, TIOCSCTTY, NULL)) + { + perror("could not set new controlling tty"); + } +#else + if ((slave = get_slave_pty(name)) < 0) + { + perror("ptypair: could not open slave pty"); + exit(1); + } +#endif + + /* make slave pty be standard in, out, and error */ + dup2(slave, STDIN_FILENO); + dup2(slave, STDOUT_FILENO); + dup2(slave, STDERR_FILENO); + + /* at this point the slave pty should be standard input */ + if (slave > 2) + { + close(slave); + } + + /* Try to restore window size; failure isn't critical */ + if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &ws) < 0) + { + perror("could not restore window size"); + } + + /* now start the shell */ + { + static char* command_args[] = { COMMAND_ARGS, NULL }; + static char* alt_command_args[] = { ALT_COMMAND_ARGS, NULL }; + if (argc <= 1) + { + execvp (COMMAND, command_args); + execvp (ALT_COMMAND, alt_command_args); + } + else + execvp (argv[arg_base], &argv[arg_base]); + } + + /* should never be reached */ + exit(1); + } + + /* parent */ + signal (SIGCHLD, sig_child); + + /* Note that we only set termios settings for standard input; + * the master side of a pty is NOT a tty. + */ + tcgetattr(STDIN_FILENO, &orig_term); + + t = orig_term; + eof_char = t.c_cc[VEOF]; + /* add_special_char(t.c_cc[VEOF]);*/ + add_special_char(t.c_cc[VINTR]); + add_special_char(t.c_cc[VQUIT]); + add_special_char(t.c_cc[VSUSP]); +#if defined (VDISCARD) + add_special_char(t.c_cc[VDISCARD]); +#endif + + t.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \ + ECHOK | ECHOKE | ECHONL | ECHOPRT ); + t.c_iflag &= ~ICRNL; + t.c_iflag |= IGNBRK; + t.c_cc[VMIN] = 1; + t.c_cc[VTIME] = 0; + tcsetattr(STDIN_FILENO, TCSANOW, &t); + in_from_inferior_fd = master; + out_to_inferior_fd = master; + rl_instream = fdopen (master, "r"); + rl_getc_function = my_rl_getc; + + rl_prep_term_function = null_prep_terminal; + rl_deprep_term_function = null_deprep_terminal; + rl_pre_input_hook = pre_input_change_mode; + rl_callback_handler_install (prompt, line_handler); + + in_from_tty_fd = STDIN_FILENO; + FD_ZERO (&in_set); + maxfd = in_from_inferior_fd > in_from_tty_fd ? in_from_inferior_fd + : in_from_tty_fd; + for (;;) + { + int num; + FD_SET (in_from_inferior_fd, &in_set); + FD_SET (in_from_tty_fd, &in_set); + + num = select(maxfd+1, &in_set, NULL, NULL, NULL); + + if (propagate_sigwinch) + { + struct winsize ws; + if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) >= 0) + { + ioctl (master, TIOCSWINSZ, &ws); + } + propagate_sigwinch = 0; + continue; + } + + if (num <= 0) + { + perror ("select"); + exit (-1); + } + if (FD_ISSET (in_from_tty_fd, &in_set)) + { + extern int readline_echoing_p; + struct termios term_master; + int do_canon = 1; + int do_icrnl = 1; + int ioctl_ret; + + DPRINT1("[tty avail num_keys:%d]\n", num_keys); + + /* If we can't get tty modes for the master side of the pty, we + can't handle non-canonical-mode programs. Always assume the + master is in canonical echo mode if we can't tell. */ + ioctl_ret = tcgetattr(master, &term_master); + + if (ioctl_ret >= 0) + { + do_canon = (term_master.c_lflag & ICANON) != 0; + do_icrnl = (term_master.c_lflag & ICRNL) != 0; + readline_echoing_p = (term_master.c_lflag & ECHO) != 0; + DPRINT1 ("echo,canon,crnl:%03d\n", + 100 * readline_echoing_p + + 10 * do_canon + + 1 * do_icrnl); + } + else + { + if (ioctl_err == 0) + DPRINT1("tcgetattr on master fd failed: errno = %d\n", errno); + ioctl_err = 1; + } + + if (do_canon == 0 && num_keys == 0) + { + char ch[10]; + int count = read (STDIN_FILENO, ch, sizeof(ch)); + DPRINT1("[read %d chars from stdin: ", count); + DPRINT2(" \"%.*s\"]\n", count, ch); + if (do_icrnl) + { + int i = count; + while (--i >= 0) + { + if (ch[i] == '\r') + ch[i] = '\n'; + } + } + maybe_emphasize_input (1); + write (out_to_inferior_fd, ch, count); + } + else + { + if (num_keys == 0) + { + int i; + /* Re-install callback handler for new prompt. */ + if (prompt != empty_string) + free (prompt); + if (prompt == NULL) + { + DPRINT0("New empty prompt\n"); + prompt = empty_string; + } + else + { + if (do_emphasize_input && buf_count > 0) + { + prompt = malloc (buf_count + strlen (end_input_mode) + + strlen (start_input_mode) + 5); + sprintf (prompt, "\001%s\002%.*s\001%s\002", + end_input_mode, + buf_count, buf, + start_input_mode); + } + else + { + prompt = malloc (buf_count + 1); + memcpy (prompt, buf, buf_count); + prompt[buf_count] = '\0'; + } + DPRINT1("New prompt '%s'\n", prompt); +#if 0 /* ifdef HAVE_RL_ALREADY_PROMPTED */ + /* Doesn't quite work when do_emphasize_input is 1. */ + rl_already_prompted = buf_count > 0; +#else + if (buf_count > 0) + write (1, "\r", 1); +#endif + } + + rl_callback_handler_install (prompt, line_handler); + } + num_keys++; + maybe_emphasize_input (1); + rl_callback_read_char (); + } + } + else /* output from inferior. */ + { + int i; + int count; + int old_count; + if (buf_count > (sizeof(buf) >> 2)) + buf_count = 0; + count = read (in_from_inferior_fd, buf+buf_count, + sizeof(buf) - buf_count); + DPRINT2("read %d from inferior, buf_count=%d", count, buf_count); + DPRINT2(": \"%.*s\"", count, buf+buf_count); + maybe_emphasize_input (0); + if (count <= 0) + { + DPRINT0 ("(Connection closed by foreign host.)\n"); + tcsetattr(STDIN_FILENO, TCSANOW, &orig_term); + exit (0); + } + old_count = buf_count; + + /* Look for any pending echo that we need to suppress. */ + while (echo_suppress_start < echo_suppress_limit + && count > 0 + && buf[buf_count] == echo_suppress_buffer[echo_suppress_start]) + { + count--; + buf_count++; + echo_suppress_start++; + } + DPRINT1("suppressed %d characters of echo.\n", buf_count-old_count); + + /* Write to the terminal anything that was not suppressed. */ + if (count > 0) + write (1, buf + buf_count, count); + + /* Finally, look for a prompt candidate. + * When we get around to going input (from the keyboard), + * we will consider the prompt to be anything since the last + * line terminator. So we need to save that text in the + * initial part of buf. However, anything before the + * most recent end-of-line is not interesting. */ + buf_count += count; +#if 1 + for (i = buf_count; --i >= old_count; ) +#else + for (i = buf_count - 1; i-- >= buf_count - count; ) +#endif + { + if (buf[i] == '\n' || buf[i] == '\r') + { + i++; + memmove (buf, buf+i, buf_count - i); + buf_count -= i; + break; + } + } + DPRINT2("-> i: %d, buf_count: %d\n", i, buf_count); + } + } +} + +static void set_edit_mode () +{ + int vi = 0; + char *shellopts; + + shellopts = getenv ("SHELLOPTS"); + while (shellopts != 0) + { + if (strncmp ("vi", shellopts, 2) == 0) + { + vi = 1; + break; + } + shellopts = index (shellopts + 1, ':'); + } + + if (!vi) + { + if (getenv ("EDITOR") != 0) + vi |= strcmp (getenv ("EDITOR"), "vi") == 0; + } + + if (vi) + rl_variable_bind ("editing-mode", "vi"); + else + rl_variable_bind ("editing-mode", "emacs"); +} + + +static void usage_exit () +{ + fprintf (stderr, "Usage: rlfe [-h histfile] [-s size] cmd [arg1] [arg2] ...\n\n"); + exit (1); +}
rlfe/rlfe.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlfe/extern.h =================================================================== --- rlfe/extern.h (nonexistent) +++ rlfe/extern.h (revision 33) @@ -0,0 +1,33 @@ +/* Copyright (c) 1993-2002 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + * $Id$ FAU + */ + +#if !defined(__GNUC__) || __GNUC__ < 2 +#undef __attribute__ +#define __attribute__(x) +#endif + +/* pty.c */ +extern int OpenPTY __P((char **)); +extern void InitPTY __P((int)); +
rlfe/extern.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlfe/README =================================================================== --- rlfe/README (nonexistent) +++ rlfe/README (revision 33) @@ -0,0 +1,78 @@ +rlfe (ReadLine Front-End) is a "universal wrapper" around readline. +You specify an interactive program to run (typically a shell), and +readline is used to edit input lines. + +There are other such front-ends; what distinguishes this one is that +it monitors the state of the inferior pty, and if the inferior program +switches its terminal to raw mode, then rlfe passes your characters +through directly. This basically means you can run your entire +session (including bash and terminal-mode emacs) under rlfe. + +FEATURES + +* Can use all readline commands (and history) in commands that +read input lines in "canonical mode" - even 'cat'! + +* Automatically switches between "readline-editing mode" and "raw mode" +depending on the terminal mode. If the inferior program invokes +readline itself, it will do its own line editing. (The inferior +readline will not know about rlfe, and it will have its own history.) +You can even run programs like 'emavs -nw' and 'vi' under rlfe. +The goal is you could leave rlfe always on without even knowing +about it. (We're not quite there, but it works tolerably well.) + +* The input line (after any prompt) is changed to bold-face. + +INSTALL + +The usual: ./configure && make && make install + +Note so far rlfe has only been tested on GNU Linux (Fedora Core 2) +and Mac OS X (10.3). + +This assumes readline header files and libraries are in the default +places. If not, you can create a link named readline pointing to the +readline sources. To link with libreadline.a and libhistory.a +you can copy or link them, or add LDFLAGS='-/path/to/readline' to +the make command-line. + +USAGE + +Just run it. That by default runs bash. You can run some other +command by giving it as command-line arguments. + +There are a few tweaks: -h allows you to name the history file, +and -s allows you to specify its size. It default to "emacs" mode, +but if the the environment variable EDITOR is set to "vi" that +mode is chosen. + +ISSUES + +* The mode switching depends on the terminal mode set by the inferior +program. Thus ssh/telnet/screen-type programs will typically be in +raw mode, so rlfe won't be much use, even if remote programs run in +canonical mode. The work-around is to run rlfe on the remote end. + +* Echo supression and prompt recognition are somewhat fragile. +(A protocol so that the o/s tty code can reliably communicate its +state to rlfe could solve this problem, and the previous one.) + +* See the intro to rlfe.c for more notes. + +* Assumes a VT100-compatible terminal, though that could be generalized +if anybody cares. + +* Requires ncurses. + +* It would be useful to integrate rlfe's logic in a terminal emulator. +That would make it easier to reposition the edit position with a mouse, +integrate cut-and-paste with the system clipboard, and more robustly +handle escape sequence and multi-byte characters more robustly. + +AUTHOR + +Per Bothner + +LICENSE + +GPL.
rlfe/README Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlfe/pty.c =================================================================== --- rlfe/pty.c (nonexistent) +++ rlfe/pty.c (revision 33) @@ -0,0 +1,387 @@ +/* Copyright (c) 1993-2002 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + */ + +#include +#include +#include +#include + +#include "config.h" +#include "screen.h" + +#ifndef sun +# include +#endif + +/* for solaris 2.1, Unixware (SVR4.2) and possibly others */ +#ifdef HAVE_SVR4_PTYS +# include +#endif + +#if defined(sun) && defined(LOCKPTY) && !defined(TIOCEXCL) +# include +#endif + +#ifdef ISC +# include +# include +# include +#endif + +#ifdef sgi +# include +#endif /* sgi */ + +#include "extern.h" + +/* + * if no PTYRANGE[01] is in the config file, we pick a default + */ +#ifndef PTYRANGE0 +# define PTYRANGE0 "qpr" +#endif +#ifndef PTYRANGE1 +# define PTYRANGE1 "0123456789abcdef" +#endif + +/* SVR4 pseudo ttys don't seem to work with SCO-5 */ +#ifdef M_UNIX +# undef HAVE_SVR4_PTYS +#endif + +extern int eff_uid; + +/* used for opening a new pty-pair: */ +static char PtyName[32], TtyName[32]; + +#if !(defined(sequent) || defined(_SEQUENT_) || defined(HAVE_SVR4_PTYS)) +# ifdef hpux +static char PtyProto[] = "/dev/ptym/ptyXY"; +static char TtyProto[] = "/dev/pty/ttyXY"; +# else +# ifdef M_UNIX +static char PtyProto[] = "/dev/ptypXY"; +static char TtyProto[] = "/dev/ttypXY"; +# else +static char PtyProto[] = "/dev/ptyXY"; +static char TtyProto[] = "/dev/ttyXY"; +# endif +# endif /* hpux */ +#endif + +static void initmaster __P((int)); + +#if defined(sun) +/* sun's utmp_update program opens the salve side, thus corrupting + */ +int pty_preopen = 1; +#else +int pty_preopen = 0; +#endif + +/* + * Open all ptys with O_NOCTTY, just to be on the safe side + * (RISCos mips breaks otherwise) + */ +#ifndef O_NOCTTY +# define O_NOCTTY 0 +#endif + +/***************************************************************/ + +static void +initmaster(f) +int f; +{ +#ifdef POSIX + tcflush(f, TCIOFLUSH); +#else +# ifdef TIOCFLUSH + (void) ioctl(f, TIOCFLUSH, (char *) 0); +# endif +#endif +#ifdef LOCKPTY + (void) ioctl(f, TIOCEXCL, (char *) 0); +#endif +} + +void +InitPTY(f) +int f; +{ + if (f < 0) + return; +#if defined(I_PUSH) && defined(HAVE_SVR4_PTYS) && !defined(sgi) && !defined(linux) && !defined(__osf__) && !defined(M_UNIX) + if (ioctl(f, I_PUSH, "ptem")) + Panic(errno, "InitPTY: cannot I_PUSH ptem"); + if (ioctl(f, I_PUSH, "ldterm")) + Panic(errno, "InitPTY: cannot I_PUSH ldterm"); +# ifdef sun + if (ioctl(f, I_PUSH, "ttcompat")) + Panic(errno, "InitPTY: cannot I_PUSH ttcompat"); +# endif +#endif +} + +/***************************************************************/ + +#if defined(OSX) && !defined(PTY_DONE) +#define PTY_DONE +int +OpenPTY(ttyn) +char **ttyn; +{ + register int f; + if ((f = open_controlling_pty(TtyName)) < 0) + return -1; + initmaster(f); + *ttyn = TtyName; + return f; +} +#endif + +/***************************************************************/ + +#if (defined(sequent) || defined(_SEQUENT_)) && !defined(PTY_DONE) +#define PTY_DONE +int +OpenPTY(ttyn) +char **ttyn; +{ + char *m, *s; + register int f; + + if ((f = getpseudotty(&s, &m)) < 0) + return -1; +#ifdef _SEQUENT_ + fvhangup(s); +#endif + strncpy(PtyName, m, sizeof(PtyName)); + strncpy(TtyName, s, sizeof(TtyName)); + initmaster(f); + *ttyn = TtyName; + return f; +} +#endif + +/***************************************************************/ + +#if defined(__sgi) && !defined(PTY_DONE) +#define PTY_DONE +int +OpenPTY(ttyn) +char **ttyn; +{ + int f; + char *name, *_getpty(); + sigret_t (*sigcld)__P(SIGPROTOARG); + + /* + * SIGCHLD set to SIG_DFL for _getpty() because it may fork() and + * exec() /usr/adm/mkpts + */ + sigcld = signal(SIGCHLD, SIG_DFL); + name = _getpty(&f, O_RDWR | O_NONBLOCK, 0600, 0); + signal(SIGCHLD, sigcld); + + if (name == 0) + return -1; + initmaster(f); + *ttyn = name; + return f; +} +#endif + +/***************************************************************/ + +#if defined(MIPS) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE) +#define PTY_DONE +int +OpenPTY(ttyn) +char **ttyn; +{ + register int f; + struct stat buf; + + strcpy(PtyName, "/dev/ptc"); + if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) + return -1; + if (fstat(f, &buf) < 0) + { + close(f); + return -1; + } + sprintf(TtyName, "/dev/ttyq%d", minor(buf.st_rdev)); + initmaster(f); + *ttyn = TtyName; + return f; +} +#endif + +/***************************************************************/ + +#if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) +#define PTY_DONE +int +OpenPTY(ttyn) +char **ttyn; +{ + register int f; + char *m, *ptsname(); + int unlockpt __P((int)), grantpt __P((int)); +#if defined(HAVE_GETPT) && defined(linux) + int getpt __P((void)); +#endif + sigret_t (*sigcld)__P(SIGPROTOARG); + + strcpy(PtyName, "/dev/ptmx"); +#if defined(HAVE_GETPT) && defined(linux) + if ((f = getpt()) == -1) +#else + if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1) +#endif + return -1; + + /* + * SIGCHLD set to SIG_DFL for grantpt() because it fork()s and + * exec()s pt_chmod + */ + sigcld = signal(SIGCHLD, SIG_DFL); + if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f)) + { + signal(SIGCHLD, sigcld); + close(f); + return -1; + } + signal(SIGCHLD, sigcld); + strncpy(TtyName, m, sizeof(TtyName)); + initmaster(f); + *ttyn = TtyName; + return f; +} +#endif + +/***************************************************************/ + +#if defined(_AIX) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE) +#define PTY_DONE + +int +OpenPTY(ttyn) +char **ttyn; +{ + register int f; + + /* a dumb looking loop replaced by mycrofts code: */ + strcpy (PtyName, "/dev/ptc"); + if ((f = open (PtyName, O_RDWR | O_NOCTTY)) < 0) + return -1; + strncpy(TtyName, ttyname(f), sizeof(TtyName)); + if (eff_uid && access(TtyName, R_OK | W_OK)) + { + close(f); + return -1; + } + initmaster(f); +# ifdef _IBMR2 + pty_preopen = 1; +# endif + *ttyn = TtyName; + return f; +} +#endif + +/***************************************************************/ + +#if defined(HAVE_OPENPTY) && !defined(PTY_DONE) +#define PTY_DONE +int +OpenPTY(ttyn) +char **ttyn; +{ + int f, s; + if (openpty(&f, &s, TtyName, NULL, NULL) != 0) + return -1; + close(s); + initmaster(f); + pty_preopen = 1; + *ttyn = TtyName; + return f; +} +#endif + +/***************************************************************/ + +#ifndef PTY_DONE +int +OpenPTY(ttyn) +char **ttyn; +{ + register char *p, *q, *l, *d; + register int f; + + debug("OpenPTY: Using BSD style ptys.\n"); + strcpy(PtyName, PtyProto); + strcpy(TtyName, TtyProto); + for (p = PtyName; *p != 'X'; p++) + ; + for (q = TtyName; *q != 'X'; q++) + ; + for (l = PTYRANGE0; (*p = *l) != '\0'; l++) + { + for (d = PTYRANGE1; (p[1] = *d) != '\0'; d++) + { + debug1("OpenPTY tries '%s'\n", PtyName); + if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1) + continue; + q[0] = *l; + q[1] = *d; + if (eff_uid && access(TtyName, R_OK | W_OK)) + { + close(f); + continue; + } +#if defined(sun) && defined(TIOCGPGRP) && !defined(SUNOS3) + /* Hack to ensure that the slave side of the pty is + * unused. May not work in anything other than SunOS4.1 + */ + { + int pgrp; + + /* tcgetpgrp does not work (uses TIOCGETPGRP)! */ + if (ioctl(f, TIOCGPGRP, (char *)&pgrp) != -1 || errno != EIO) + { + close(f); + continue; + } + } +#endif + initmaster(f); + *ttyn = TtyName; + return f; + } + } + return -1; +} +#endif +
rlfe/pty.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: excallback.c =================================================================== --- excallback.c (nonexistent) +++ excallback.c (revision 33) @@ -0,0 +1,188 @@ +/* +From: Jeff Solomon +Date: Fri, 9 Apr 1999 10:13:27 -0700 (PDT) +To: chet@po.cwru.edu +Subject: new readline example +Message-ID: <14094.12094.527305.199695@mrclean.Stanford.EDU> + +Chet, + +I've been using readline 4.0. Specifically, I've been using the perl +version Term::ReadLine::Gnu. It works great. + +Anyway, I've been playing around the alternate interface and I wanted +to contribute a little C program, callback.c, to you that you could +use as an example of the alternate interface in the /examples +directory of the readline distribution. + +My example shows how, using the alternate interface, you can +interactively change the prompt (which is very nice imo). Also, I +point out that you must roll your own terminal setting when using the +alternate interface because readline depreps (using your parlance) the +terminal while in the user callback. I try to demostrate what I mean +with an example. I've included the program below. + +To compile, I just put the program in the examples directory and made +the appropriate changes to the EXECUTABLES and OBJECTS line and added +an additional target 'callback'. + +I compiled on my Sun Solaris2.6 box using Sun's cc. + +Let me know what you think. + +Jeff +*/ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include /* xxx - should make this more general */ + +#ifdef READLINE_LIBRARY +# include "readline.h" +#else +# include +#endif + +/* This little examples demonstrates the alternate interface to using readline. + * In the alternate interface, the user maintains control over program flow and + * only calls readline when STDIN is readable. Using the alternate interface, + * you can do anything else while still using readline (like talking to a + * network or another program) without blocking. + * + * Specifically, this program highlights two importants features of the + * alternate interface. The first is the ability to interactively change the + * prompt, which can't be done using the regular interface since rl_prompt is + * read-only. + * + * The second feature really highlights a subtle point when using the alternate + * interface. That is, readline will not alter the terminal when inside your + * callback handler. So let's so, your callback executes a user command that + * takes a non-trivial amount of time to complete (seconds). While your + * executing the command, the user continues to type keystrokes and expects them + * to be re-echoed on the new prompt when it returns. Unfortunately, the default + * terminal configuration doesn't do this. After the prompt returns, the user + * must hit one additional keystroke and then will see all of his previous + * keystrokes. To illustrate this, compile and run this program. Type "sleep" at + * the prompt and then type "bar" before the prompt returns (you have 3 + * seconds). Notice how "bar" is re-echoed on the prompt after the prompt + * returns? This is what you expect to happen. Now comment out the 4 lines below + * the line that says COMMENT LINE BELOW. Recompile and rerun the program and do + * the same thing. When the prompt returns, you should not see "bar". Now type + * "f", see how "barf" magically appears? This behavior is un-expected and not + * desired. + */ + +void process_line(char *line); +int change_prompt(void); +char *get_prompt(void); + +int prompt = 1; +char prompt_buf[40], line_buf[256]; +tcflag_t old_lflag; +cc_t old_vtime; +struct termios term; + +int +main() +{ + fd_set fds; + + /* Adjust the terminal slightly before the handler is installed. Disable + * canonical mode processing and set the input character time flag to be + * non-blocking. + */ + if( tcgetattr(STDIN_FILENO, &term) < 0 ) { + perror("tcgetattr"); + exit(1); + } + old_lflag = term.c_lflag; + old_vtime = term.c_cc[VTIME]; + term.c_lflag &= ~ICANON; + term.c_cc[VTIME] = 1; + /* COMMENT LINE BELOW - see above */ + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + + rl_add_defun("change-prompt", change_prompt, CTRL('t')); + rl_callback_handler_install(get_prompt(), process_line); + + while(1) { + FD_ZERO(&fds); + FD_SET(fileno(stdin), &fds); + + if( select(FD_SETSIZE, &fds, NULL, NULL, NULL) < 0) { + perror("select"); + exit(1); + } + + if( FD_ISSET(fileno(stdin), &fds) ) { + rl_callback_read_char(); + } + } +} + +void +process_line(char *line) +{ + if( line == NULL ) { + fprintf(stderr, "\n", line); + + /* reset the old terminal setting before exiting */ + term.c_lflag = old_lflag; + term.c_cc[VTIME] = old_vtime; + if( tcsetattr(STDIN_FILENO, TCSANOW, &term) < 0 ) { + perror("tcsetattr"); + exit(1); + } + exit(0); + } + + if( strcmp(line, "sleep") == 0 ) { + sleep(3); + } else { + fprintf(stderr, "|%s|\n", line); + } + + free (line); +} + +int +change_prompt(void) +{ + /* toggle the prompt variable */ + prompt = !prompt; + + /* save away the current contents of the line */ + strcpy(line_buf, rl_line_buffer); + + /* install a new handler which will change the prompt and erase the current line */ + rl_callback_handler_install(get_prompt(), process_line); + + /* insert the old text on the new line */ + rl_insert_text(line_buf); + + /* redraw the current line - this is an undocumented function. It invokes the + * redraw-current-line command. + */ + rl_refresh_line(0, 0); +} + +char * +get_prompt(void) +{ + /* The prompts can even be different lengths! */ + sprintf(prompt_buf, "%s", + prompt ? "Hit ctrl-t to toggle prompt> " : "Pretty cool huh?> "); + return prompt_buf; +}
excallback.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rlptytest.c =================================================================== --- rlptytest.c (nonexistent) +++ rlptytest.c (revision 33) @@ -0,0 +1,337 @@ +/* + * + * Another test harness for the readline callback interface. + * + * Author: Bob Rossi + */ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include +#include +#include + +#include +#include + +#include + +#if 0 /* LINUX */ +#include +#else +#include +#endif + +#ifdef READLINE_LIBRARY +# include "readline.h" +#else +# include +#endif + +/** + * Master/Slave PTY used to keep readline off of stdin/stdout. + */ +static int masterfd = -1; +static int slavefd; + +void +sigint (s) + int s; +{ + tty_reset (STDIN_FILENO); + close (masterfd); + close (slavefd); + printf ("\n"); + exit (0); +} + +static int +user_input() +{ + int size; + const int MAX = 1024; + char *buf = (char *)malloc(MAX+1); + + size = read (STDIN_FILENO, buf, MAX); + if (size == -1) + return -1; + + size = write (masterfd, buf, size); + if (size == -1) + return -1; + + return 0; +} + +static int +readline_input() +{ + const int MAX = 1024; + char *buf = (char *)malloc(MAX+1); + int size; + + size = read (masterfd, buf, MAX); + if (size == -1) + { + free( buf ); + buf = NULL; + return -1; + } + + buf[size] = 0; + + /* Display output from readline */ + if ( size > 0 ) + fprintf(stderr, "%s", buf); + + free( buf ); + buf = NULL; + return 0; +} + +static void +rlctx_send_user_command(char *line) +{ + /* This happens when rl_callback_read_char gets EOF */ + if ( line == NULL ) + return; + + if (strcmp (line, "exit") == 0) { + tty_reset (STDIN_FILENO); + close (masterfd); + close (slavefd); + printf ("\n"); + exit (0); + } + + /* Don't add the enter command */ + if ( line && *line != '\0' ) + add_history(line); +} + +static void +custom_deprep_term_function () +{ +} + +static int +init_readline (int inputfd, int outputfd) +{ + FILE *inputFILE, *outputFILE; + + inputFILE = fdopen (inputfd, "r"); + if (!inputFILE) + return -1; + + outputFILE = fdopen (outputfd, "w"); + if (!outputFILE) + return -1; + + rl_instream = inputFILE; + rl_outstream = outputFILE; + + /* Tell readline what the prompt is if it needs to put it back */ + rl_callback_handler_install("(rltest): ", rlctx_send_user_command); + + /* Set the terminal type to dumb so the output of readline can be + * understood by tgdb */ + if ( rl_reset_terminal("dumb") == -1 ) + return -1; + + /* For some reason, readline can not deprep the terminal. + * However, it doesn't matter because no other application is working on + * the terminal besides readline */ + rl_deprep_term_function = custom_deprep_term_function; + + using_history(); + read_history(".history"); + + return 0; +} + +static int +main_loop(void) +{ + fd_set rset; + int max; + + max = (masterfd > STDIN_FILENO) ? masterfd : STDIN_FILENO; + max = (max > slavefd) ? max : slavefd; + + for (;;) + { + /* Reset the fd_set, and watch for input from GDB or stdin */ + FD_ZERO(&rset); + + FD_SET(STDIN_FILENO, &rset); + FD_SET(slavefd, &rset); + FD_SET(masterfd, &rset); + + /* Wait for input */ + if (select(max + 1, &rset, NULL, NULL, NULL) == -1) + { + if (errno == EINTR) + continue; + else + return -1; + } + + /* Input received through the pty: Handle it + * Wrote to masterfd, slave fd has that input, alert readline to read it. + */ + if (FD_ISSET(slavefd, &rset)) + rl_callback_read_char(); + + /* Input received through the pty. + * Readline read from slavefd, and it wrote to the masterfd. + */ + if (FD_ISSET(masterfd, &rset)) + if ( readline_input() == -1 ) + return -1; + + /* Input received: Handle it, write to masterfd (input to readline) */ + if (FD_ISSET(STDIN_FILENO, &rset)) + if ( user_input() == -1 ) + return -1; + } + + return 0; +} + +/* The terminal attributes before calling tty_cbreak */ +static struct termios save_termios; +static struct winsize size; +static enum { RESET, TCBREAK } ttystate = RESET; + +/* tty_cbreak: Sets terminal to cbreak mode. Also known as noncanonical mode. + * 1. Signal handling is still turned on, so the user can still type those. + * 2. echo is off + * 3. Read in one char at a time. + * + * fd - The file descriptor of the terminal + * + * Returns: 0 on sucess, -1 on error + */ +int tty_cbreak(int fd){ + struct termios buf; + int ttysavefd = -1; + + if(tcgetattr(fd, &save_termios) < 0) + return -1; + + buf = save_termios; + buf.c_lflag &= ~(ECHO | ICANON); + buf.c_iflag &= ~(ICRNL | INLCR); + buf.c_cc[VMIN] = 1; + buf.c_cc[VTIME] = 0; + +#if defined (VLNEXT) && defined (_POSIX_VDISABLE) + buf.c_cc[VLNEXT] = _POSIX_VDISABLE; +#endif + +#if defined (VDSUSP) && defined (_POSIX_VDISABLE) + buf.c_cc[VDSUSP] = _POSIX_VDISABLE; +#endif + + /* enable flow control; only stty start char can restart output */ +#if 0 + buf.c_iflag |= (IXON|IXOFF); +#ifdef IXANY + buf.c_iflag &= ~IXANY; +#endif +#endif + + /* disable flow control; let ^S and ^Q through to pty */ + buf.c_iflag &= ~(IXON|IXOFF); +#ifdef IXANY + buf.c_iflag &= ~IXANY; +#endif + + if(tcsetattr(fd, TCSAFLUSH, &buf) < 0) + return -1; + + ttystate = TCBREAK; + ttysavefd = fd; + + /* set size */ + if(ioctl(fd, TIOCGWINSZ, (char *)&size) < 0) + return -1; + +#ifdef DEBUG + err_msg("%d rows and %d cols\n", size.ws_row, size.ws_col); +#endif + + return (0); +} + +int +tty_off_xon_xoff (int fd) +{ + struct termios buf; + int ttysavefd = -1; + + if(tcgetattr(fd, &buf) < 0) + return -1; + + buf.c_iflag &= ~(IXON|IXOFF); + + if(tcsetattr(fd, TCSAFLUSH, &buf) < 0) + return -1; + + return 0; +} + +/* tty_reset: Sets the terminal attributes back to their previous state. + * PRE: tty_cbreak must have already been called. + * + * fd - The file descrioptor of the terminal to reset. + * + * Returns: 0 on success, -1 on error + */ +int tty_reset(int fd) +{ + if(ttystate != TCBREAK) + return (0); + + if(tcsetattr(fd, TCSAFLUSH, &save_termios) < 0) + return (-1); + + ttystate = RESET; + + return 0; +} + +int +main() +{ + int val; + val = openpty (&masterfd, &slavefd, NULL, NULL, NULL); + if (val == -1) + return -1; + + val = tty_off_xon_xoff (masterfd); + if (val == -1) + return -1; + + val = init_readline (slavefd, slavefd); + if (val == -1) + return -1; + + val = tty_cbreak (STDIN_FILENO); + if (val == -1) + return -1; + + signal (SIGINT, sigint); + + val = main_loop (); + + tty_reset (STDIN_FILENO); + + if (val == -1) + return -1; + + return 0; +}
rlptytest.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: fileman.c =================================================================== --- fileman.c (nonexistent) +++ fileman.c (revision 33) @@ -0,0 +1,485 @@ +/* Copyright (C) 1987-2002 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +/* fileman.c -- A tiny application which demonstrates how to use the + GNU Readline library. This application interactively allows users + to manipulate files and their modes. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#ifdef HAVE_SYS_FILE_H +# include +#endif +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#include +#include +#include + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern char *xmalloc (); + +/* The names of functions that actually do the manipulation. */ +int com_list PARAMS((char *)); +int com_view PARAMS((char *)); +int com_rename PARAMS((char *)); +int com_stat PARAMS((char *)); +int com_pwd PARAMS((char *)); +int com_delete PARAMS((char *)); +int com_help PARAMS((char *)); +int com_cd PARAMS((char *)); +int com_quit PARAMS((char *)); + +/* A structure which contains information on the commands this program + can understand. */ + +typedef struct { + char *name; /* User printable name of the function. */ + rl_icpfunc_t *func; /* Function to call to do the job. */ + char *doc; /* Documentation for this function. */ +} COMMAND; + +COMMAND commands[] = { + { "cd", com_cd, "Change to directory DIR" }, + { "delete", com_delete, "Delete FILE" }, + { "help", com_help, "Display this text" }, + { "?", com_help, "Synonym for `help'" }, + { "list", com_list, "List files in DIR" }, + { "ls", com_list, "Synonym for `list'" }, + { "pwd", com_pwd, "Print the current working directory" }, + { "quit", com_quit, "Quit using Fileman" }, + { "rename", com_rename, "Rename FILE to NEWNAME" }, + { "stat", com_stat, "Print out statistics on FILE" }, + { "view", com_view, "View the contents of FILE" }, + { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } +}; + +/* Forward declarations. */ +char *stripwhite (); +COMMAND *find_command (); + +/* The name of this program, as taken from argv[0]. */ +char *progname; + +/* When non-zero, this global means the user is done using this program. */ +int done; + +char * +dupstr (s) + char *s; +{ + char *r; + + r = xmalloc (strlen (s) + 1); + strcpy (r, s); + return (r); +} + +main (argc, argv) + int argc; + char **argv; +{ + char *line, *s; + + progname = argv[0]; + + initialize_readline (); /* Bind our completer. */ + + /* Loop reading and executing lines until the user quits. */ + for ( ; done == 0; ) + { + line = readline ("FileMan: "); + + if (!line) + break; + + /* Remove leading and trailing whitespace from the line. + Then, if there is anything left, add it to the history list + and execute it. */ + s = stripwhite (line); + + if (*s) + { + add_history (s); + execute_line (s); + } + + free (line); + } + exit (0); +} + +/* Execute a command line. */ +int +execute_line (line) + char *line; +{ + register int i; + COMMAND *command; + char *word; + + /* Isolate the command word. */ + i = 0; + while (line[i] && whitespace (line[i])) + i++; + word = line + i; + + while (line[i] && !whitespace (line[i])) + i++; + + if (line[i]) + line[i++] = '\0'; + + command = find_command (word); + + if (!command) + { + fprintf (stderr, "%s: No such command for FileMan.\n", word); + return (-1); + } + + /* Get argument to command, if any. */ + while (whitespace (line[i])) + i++; + + word = line + i; + + /* Call the function. */ + return ((*(command->func)) (word)); +} + +/* Look up NAME as the name of a command, and return a pointer to that + command. Return a NULL pointer if NAME isn't a command name. */ +COMMAND * +find_command (name) + char *name; +{ + register int i; + + for (i = 0; commands[i].name; i++) + if (strcmp (name, commands[i].name) == 0) + return (&commands[i]); + + return ((COMMAND *)NULL); +} + +/* Strip whitespace from the start and end of STRING. Return a pointer + into STRING. */ +char * +stripwhite (string) + char *string; +{ + register char *s, *t; + + for (s = string; whitespace (*s); s++) + ; + + if (*s == 0) + return (s); + + t = s + strlen (s) - 1; + while (t > s && whitespace (*t)) + t--; + *++t = '\0'; + + return s; +} + +/* **************************************************************** */ +/* */ +/* Interface to Readline Completion */ +/* */ +/* **************************************************************** */ + +char *command_generator PARAMS((const char *, int)); +char **fileman_completion PARAMS((const char *, int, int)); + +/* Tell the GNU Readline library how to complete. We want to try to complete + on command names if this is the first word in the line, or on filenames + if not. */ +initialize_readline () +{ + /* Allow conditional parsing of the ~/.inputrc file. */ + rl_readline_name = "FileMan"; + + /* Tell the completer that we want a crack first. */ + rl_attempted_completion_function = fileman_completion; +} + +/* Attempt to complete on the contents of TEXT. START and END bound the + region of rl_line_buffer that contains the word to complete. TEXT is + the word to complete. We can use the entire contents of rl_line_buffer + in case we want to do some simple parsing. Return the array of matches, + or NULL if there aren't any. */ +char ** +fileman_completion (text, start, end) + const char *text; + int start, end; +{ + char **matches; + + matches = (char **)NULL; + + /* If this word is at the start of the line, then it is a command + to complete. Otherwise it is the name of a file in the current + directory. */ + if (start == 0) + matches = rl_completion_matches (text, command_generator); + + return (matches); +} + +/* Generator function for command completion. STATE lets us know whether + to start from scratch; without any state (i.e. STATE == 0), then we + start at the top of the list. */ +char * +command_generator (text, state) + const char *text; + int state; +{ + static int list_index, len; + char *name; + + /* If this is a new word to complete, initialize now. This includes + saving the length of TEXT for efficiency, and initializing the index + variable to 0. */ + if (!state) + { + list_index = 0; + len = strlen (text); + } + + /* Return the next name which partially matches from the command list. */ + while (name = commands[list_index].name) + { + list_index++; + + if (strncmp (name, text, len) == 0) + return (dupstr(name)); + } + + /* If no names matched, then return NULL. */ + return ((char *)NULL); +} + +/* **************************************************************** */ +/* */ +/* FileMan Commands */ +/* */ +/* **************************************************************** */ + +/* String to pass to system (). This is for the LIST, VIEW and RENAME + commands. */ +static char syscom[1024]; + +/* List the file(s) named in arg. */ +com_list (arg) + char *arg; +{ + if (!arg) + arg = ""; + + sprintf (syscom, "ls -FClg %s", arg); + return (system (syscom)); +} + +com_view (arg) + char *arg; +{ + if (!valid_argument ("view", arg)) + return 1; + +#if defined (__MSDOS__) + /* more.com doesn't grok slashes in pathnames */ + sprintf (syscom, "less %s", arg); +#else + sprintf (syscom, "more %s", arg); +#endif + return (system (syscom)); +} + +com_rename (arg) + char *arg; +{ + too_dangerous ("rename"); + return (1); +} + +com_stat (arg) + char *arg; +{ + struct stat finfo; + + if (!valid_argument ("stat", arg)) + return (1); + + if (stat (arg, &finfo) == -1) + { + perror (arg); + return (1); + } + + printf ("Statistics for `%s':\n", arg); + + printf ("%s has %d link%s, and is %d byte%s in length.\n", + arg, + finfo.st_nlink, + (finfo.st_nlink == 1) ? "" : "s", + finfo.st_size, + (finfo.st_size == 1) ? "" : "s"); + printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime)); + printf (" Last access at: %s", ctime (&finfo.st_atime)); + printf (" Last modified at: %s", ctime (&finfo.st_mtime)); + return (0); +} + +com_delete (arg) + char *arg; +{ + too_dangerous ("delete"); + return (1); +} + +/* Print out help for ARG, or for all of the commands if ARG is + not present. */ +com_help (arg) + char *arg; +{ + register int i; + int printed = 0; + + for (i = 0; commands[i].name; i++) + { + if (!*arg || (strcmp (arg, commands[i].name) == 0)) + { + printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); + printed++; + } + } + + if (!printed) + { + printf ("No commands match `%s'. Possibilties are:\n", arg); + + for (i = 0; commands[i].name; i++) + { + /* Print in six columns. */ + if (printed == 6) + { + printed = 0; + printf ("\n"); + } + + printf ("%s\t", commands[i].name); + printed++; + } + + if (printed) + printf ("\n"); + } + return (0); +} + +/* Change to the directory ARG. */ +com_cd (arg) + char *arg; +{ + if (chdir (arg) == -1) + { + perror (arg); + return 1; + } + + com_pwd (""); + return (0); +} + +/* Print out the current working directory. */ +com_pwd (ignore) + char *ignore; +{ + char dir[1024], *s; + + s = getcwd (dir, sizeof(dir) - 1); + if (s == 0) + { + printf ("Error getting pwd: %s\n", dir); + return 1; + } + + printf ("Current directory is %s\n", dir); + return 0; +} + +/* The user wishes to quit using this program. Just set DONE non-zero. */ +com_quit (arg) + char *arg; +{ + done = 1; + return (0); +} + +/* Function which tells you that you can't do this. */ +too_dangerous (caller) + char *caller; +{ + fprintf (stderr, + "%s: Too dangerous for me to distribute. Write it yourself.\n", + caller); +} + +/* Return non-zero if ARG is a valid argument for CALLER, else print + an error message and return zero. */ +int +valid_argument (caller, arg) + char *caller, *arg; +{ + if (!arg || !*arg) + { + fprintf (stderr, "%s: Argument required.\n", caller); + return (0); + } + + return (1); +}
fileman.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rl.c =================================================================== --- rl.c (nonexistent) +++ rl.c (revision 33) @@ -0,0 +1,158 @@ +/* + * rl - command-line interface to read a line from the standard input + * (or another fd) using readline. + * + * usage: rl [-p prompt] [-u unit] [-d default] [-n nchars] + */ + +/* Copyright (C) 1987-2002 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#include +#include + +#ifdef HAVE_STDLIB_H +# include +#else +extern void exit(); +#endif + +#if defined (READLINE_LIBRARY) +# include "posixstat.h" +# include "readline.h" +# include "history.h" +#else +# include +# include +# include +#endif + +extern int optind; +extern char *optarg; + +#if !defined (strchr) && !defined (__STDC__) +extern char *strrchr(); +#endif + +static char *progname; +static char *deftext; + +static int +set_deftext () +{ + if (deftext) + { + rl_insert_text (deftext); + deftext = (char *)NULL; + rl_startup_hook = (rl_hook_func_t *)NULL; + } + return 0; +} + +static void +usage() +{ + fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n", + progname, progname); +} + +int +main (argc, argv) + int argc; + char **argv; +{ + char *temp, *prompt; + struct stat sb; + int opt, fd, nch; + FILE *ifp; + + progname = strrchr(argv[0], '/'); + if (progname == 0) + progname = argv[0]; + else + progname++; + + /* defaults */ + prompt = "readline$ "; + fd = nch = 0; + deftext = (char *)0; + + while ((opt = getopt(argc, argv, "p:u:d:n:")) != EOF) + { + switch (opt) + { + case 'p': + prompt = optarg; + break; + case 'u': + fd = atoi(optarg); + if (fd < 0) + { + fprintf (stderr, "%s: bad file descriptor `%s'\n", progname, optarg); + exit (2); + } + break; + case 'd': + deftext = optarg; + break; + case 'n': + nch = atoi(optarg); + if (nch < 0) + { + fprintf (stderr, "%s: bad value for -n: `%s'\n", progname, optarg); + exit (2); + } + break; + default: + usage (); + exit (2); + } + } + + if (fd != 0) + { + if (fstat (fd, &sb) < 0) + { + fprintf (stderr, "%s: %d: bad file descriptor\n", progname, fd); + exit (1); + } + ifp = fdopen (fd, "r"); + rl_instream = ifp; + } + + if (deftext && *deftext) + rl_startup_hook = set_deftext; + + if (nch > 0) + rl_num_chars_to_read = nch; + + temp = readline (prompt); + + /* Test for EOF. */ + if (temp == 0) + exit (1); + + printf ("%s\n", temp); + exit (0); +}
rl.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property Index: rltest.c =================================================================== --- rltest.c (nonexistent) +++ rltest.c (revision 33) @@ -0,0 +1,93 @@ +/* **************************************************************** */ +/* */ +/* Testing Readline */ +/* */ +/* **************************************************************** */ + +/* Copyright (C) 1987-2002 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library, a library for + reading lines of text with interactive input and history editing. + + The GNU Readline Library is free software; you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2, or + (at your option) any later version. + + The GNU Readline Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The GNU General Public License is often shipped with GNU software, and + is generally kept in a file called COPYING or LICENSE. If you do not + have a copy of the license, write to the Free Software Foundation, + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if defined (HAVE_CONFIG_H) +#include +#endif + +#include +#include + +#ifdef HAVE_STDLIB_H +# include +#else +extern void exit(); +#endif + +#ifdef READLINE_LIBRARY +# include "readline.h" +# include "history.h" +#else +# include +# include +#endif + +extern HIST_ENTRY **history_list (); + +main () +{ + char *temp, *prompt; + int done; + + temp = (char *)NULL; + prompt = "readline$ "; + done = 0; + + while (!done) + { + temp = readline (prompt); + + /* Test for EOF. */ + if (!temp) + exit (1); + + /* If there is anything on the line, print it and remember it. */ + if (*temp) + { + fprintf (stderr, "%s\r\n", temp); + add_history (temp); + } + + /* Check for `command' that we handle. */ + if (strcmp (temp, "quit") == 0) + done = 1; + + if (strcmp (temp, "list") == 0) + { + HIST_ENTRY **list; + register int i; + + list = history_list (); + if (list) + { + for (i = 0; list[i]; i++) + fprintf (stderr, "%d: %s\r\n", i, list[i]->line); + } + } + free (temp); + } + exit (0); +}
rltest.c Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Id \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.