OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /or1k/tags/VER_5_3/gdb-5.3/readline/examples
    from Rev 1182 to Rev 1765
    Reverse comparison

Rev 1182 → Rev 1765

/ChangeLog.gdb
0,0 → 1,10
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.
 
/Makefile.in
0,0 → 1,85
#
# This is the Makefile for the readline examples subdirectory.
#
# Copyright (C) 1994 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.
 
SHELL = @MAKE_SHELL@
RM = rm -f
 
srcdir = @srcdir@
VPATH = .:@srcdir@
top_srcdir = @top_srcdir@
BUILD_DIR = .
 
DEFS = @DEFS@
CC = @CC@
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@ -DREADLINE_LIBRARY
CPPFLAGS = @CPPFLAGS@
 
INCLUDES = -I$(srcdir) -I$(top_srcdir) -I..
 
CCFLAGS = $(DEFS) $(LOCAL_CFLAGS) $(CPPFLAGS) $(INCLUDES) $(CFLAGS)
LDFLAGS = -g -L..
 
READLINE_LIB = ../libreadline.a
HISTORY_LIB = ../libhistory.a
 
TERMCAP_LIB = @TERMCAP_LIB@
 
.c.o:
${RM} $@
$(CC) $(CCFLAGS) -c $<
 
EXECUTABLES = fileman rltest rl rlversion
OBJECTS = fileman.o rltest.o rl.o rlversion.o
 
all: $(EXECUTABLES)
 
rl: rl.o
$(CC) $(LDFLAGS) -o $@ rl.o -lreadline $(TERMCAP_LIB)
 
fileman: fileman.o
$(CC) $(LDFLAGS) -o $@ fileman.o -lreadline $(TERMCAP_LIB)
 
rltest: rltest.o
$(CC) $(LDFLAGS) -o $@ rltest.o -lreadline $(TERMCAP_LIB)
 
rlversion: rlversion.o $(READLINE_LIB)
$(CC) $(LDFLAGS) -o $@ rlversion.o -lreadline $(TERMCAP_LIB)
 
clean mostlyclean:
$(RM) $(OBJECTS)
$(RM) $(EXECUTABLES) *.exe
 
distclean maintainer-clean: clean
$(RM) Makefile
 
fileman.o: fileman.c
rltest.o: rltest.c
rl.o: rl.c
rlversion.o: rlversion.c
 
# Stuff for Per Bothner's `rlfe' program
rlfe: rlfe.o $(READLINE_LIB) $(HISTORY_LIB)
$(CC) $(LDFLAGS) -o $@ rlfe.o -lreadline -lhistory ${TERMCAP_LIB}
 
rlfe.o: rlfe.c
 
rlfe.o: $(top_srcdir)/readline.h
rlfe.o: $(top_srcdir)/history.h
/histexamp.c
0,0 → 1,82
main ()
{
char line[1024], *t;
int len, done = 0;
 
line[0] = 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;
 
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
printf ("%d: %s\n", i + history_base, 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");
}
}
}
}
/Inputrc
0,0 → 1,65
# 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.
#
 
# 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
/rlversion.c
0,0 → 1,23
/*
* rlversion -- print out readline's version number
*/
 
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
 
#include <stdio.h>
#include <sys/types.h>
#include "posixstat.h"
 
#ifdef READLINE_LIBRARY
# include "readline.h"
#else
# include <readline/readline.h>
#endif
 
main()
{
printf ("%s\n", rl_library_version ? rl_library_version : "unknown");
exit (0);
}
/manexamp.c
0,0 → 1,94
/* manexamp.c -- The examples which appear in the documentation are here. */
 
#include <stdio.h>
#include <readline/readline.h>
 
 
/* **************************************************************** */
/* */
* 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 (uppercase_p (rl_line_buffer[start]))
rl_line_buffer[start] = to_lower (rl_line_buffer[start]);
else if (lowercase_p (rl_line_buffer[start]))
rl_line_buffer[start] = to_upper (rl_line_buffer[start]);
}
 
/* Move point to on top of the last character changed. */
rl_point = end - direction;
}
 
/rlfe.c
0,0 → 1,685
/* A front-end using readline to "cook" input lines for Kawa.
*
* Copyright (C) 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.
*/
 
/* PROBLEMS/TODO:
*
* Only tested under Linux; needs to be ported.
*
* When running mc -c under the Linux console, mc does not recognize
* mouse clicks, which mc does when not running under fep.
*
* 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 fep 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.
*
* Desirable readline feature: When in cooked no-echo mode (e.g. password),
* echo characters are they are types with '*', but remove them when done.
*
* A synchronous 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.
*/
 
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
 
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
#include <grp.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
 
#ifdef READLINE_LIBRARY
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
 
#ifndef COMMAND
#define COMMAND "/bin/sh"
#endif
#ifndef COMMAND_ARGS
#define COMMAND_ARGS 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 "Fep"
 
static int in_from_inferior_fd;
static int out_to_inferior_fd;
 
/* 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) /* Do nothing */
#define DPRINT1(FMT, V1) /* Do nothing */
#define DPRINT2(FMT, V1, V2) /* 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);
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_master_pty() takes a double-indirect character pointer in which
* to put a slave name, and returns an integer file descriptor.
* If it returns < 0, an error has occurred.
* Otherwise, it has returned the master pty file descriptor, and fills
* in *name with the name of the corresponding slave pty.
* Once the slave pty has been opened, you are responsible to free *name.
*/
 
int get_master_pty(char **name) {
int i, j;
/* default to returning error */
int master = -1;
 
/* create a dummy name to fill in */
*name = strdup("/dev/ptyXX");
 
/* search for an unused pty */
for (i=0; i<16 && master <= 0; i++) {
for (j=0; j<16 && master <= 0; j++) {
(*name)[5] = 'p';
(*name)[8] = "pqrstuvwxyzPQRST"[i];
(*name)[9] = "0123456789abcdef"[j];
/* open the master pty */
if ((master = open(*name, O_RDWR)) < 0) {
if (errno == ENOENT) {
/* we are out of pty devices */
free (*name);
return (master);
}
}
else {
/* By substituting a letter, we change the master pty
* name into the slave pty name.
*/
(*name)[5] = 't';
if (access(*name, R_OK|W_OK) != 0)
{
close(master);
master = -1;
}
}
}
}
if ((master < 0) && (i == 16) && (j == 16)) {
/* must have tried every pty unsuccessfully */
free (*name);
return (master);
}
 
(*name)[5] = 't';
 
return (master);
}
 
/* 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 num_keys = 0;
 
static void
null_prep_terminal (int meta)
{
}
 
static void
null_deprep_terminal ()
{
}
 
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;
 
#ifdef DEBUG
logfile = fopen("LOG", "w");
#endif
 
rl_readline_name = APPLICATION_NAME;
if ((master = get_master_pty(&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);
}
free(name);
#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);
}
free(name);
#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 };
if (argc <= 1)
execvp(COMMAND, command_args);
else
execvp(argv[1], &argv[1]);
}
 
/* should never be reached */
exit(1);
}
 
/* parent */
signal (SIGCHLD, sig_child);
free(name);
 
/* 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
 
#if 0
t.c_lflag |= (ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \
ECHOK | ECHOKE | ECHONL | ECHOPRT );
#else
t.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOCTL | ECHOE | \
ECHOK | ECHOKE | ECHONL | ECHOPRT );
#endif
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_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 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)
{
DPRINT2 ("echo:%d, canon:%d\n",
(term_master.c_lflag & ECHO) != 0,
(term_master.c_lflag & ICANON) != 0);
do_canon = (term_master.c_lflag & ICANON) != 0;
readline_echoing_p = (term_master.c_lflag & ECHO) != 0;
}
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));
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);
prompt = malloc (buf_count + 1);
if (prompt == NULL)
prompt = empty_string;
else
{
memcpy (prompt, buf, buf_count);
prompt[buf_count] = '\0';
DPRINT1("New prompt '%s'\n", prompt);
#if 0 /* ifdef HAVE_RL_ALREADY_PROMPTED -- doesn't work */
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++;
rl_callback_read_char ();
}
}
else /* input 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);
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++;
}
 
/* 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);
}
}
}
/excallback.c
0,0 → 1,188
/*
From: Jeff Solomon <jsolomon@stanford.edu>
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 <config.h>
#endif
 
#include <stdio.h>
#include <sys/types.h>
 
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
 
#include <termios.h> /* xxx - should make this more general */
 
#ifdef READLINE_LIBRARY
# include "readline.h"
#else
# include <readline/readline.h>
#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;
}
/fileman.c
0,0 → 1,458
/* 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 <config.h>
#endif
 
#include <sys/types.h>
#ifdef HAVE_SYS_FILE_H
# include <sys/file.h>
#endif
#include <sys/stat.h>
 
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
 
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
 
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
 
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
 
#ifdef READLINE_LIBRARY
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
 
extern char *xmalloc ();
 
/* The names of functions that actually do the manipulation. */
int com_list (), com_view (), com_rename (), com_stat (), com_pwd ();
int com_delete (), com_help (), com_cd (), com_quit ();
 
/* A structure which contains information on the commands this program
can understand. */
 
typedef struct {
char *name; /* User printable name of the function. */
Function *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, (Function *)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 ();
char **fileman_completion ();
 
/* 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 = (CPPFunction *)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)
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 = 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)
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);
}
/rl.c
0,0 → 1,131
/*
* 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]
*/
 
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
 
#include <stdio.h>
#include <sys/types.h>
#include "posixstat.h"
 
#if defined (READLINE_LIBRARY)
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#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 = (Function *)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);
 
puts (temp);
exit (0);
}
/rltest.c
0,0 → 1,67
/* **************************************************************** */
/* */
/* Testing Readline */
/* */
/* **************************************************************** */
 
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
 
#include <stdio.h>
#include <sys/types.h>
 
#ifdef READLINE_LIBRARY
# include "readline.h"
# include "history.h"
#else
# include <readline/readline.h>
# include <readline/history.h>
#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);
}

powered by: WebSVN 2.1.0

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