1 Commits

Author SHA1 Message Date
Joachim Nilsson
19f1943f6f Initial, and very poor, UTF-8 support. 2010-07-30 02:14:35 +02:00
19 changed files with 367 additions and 1077 deletions

View File

@@ -1,19 +0,0 @@
## $Revision: 1.2 $
##
## OS-9 makefile for editline library.
##
.SUFFIXES:
RFILES = editline.r complete.r sysos9.r
%.r: %.c
cc68 -r -Dstrchr=index -Dstrrchr=rindex -DNEED_STRDUP -DSYS_OS9 $*.c
testit: testit.r editline.lib
cc68 -f=testit testit.r -l=editline.lib
$(RFILES): $(RFILES:%.r=%.c)
editline.lib: $(RFILES)
cat $(RFILES) >$@

3
TODO
View File

@@ -1,8 +1,7 @@
TODO
* Port "fileman" example from BSD libedit, http://www.thrysoee.dk/editline/
* Instead of supporting multiline input, try the Emacs approach, line scrolling.
* Add support for rl_bind_key(), currently only en editline specific el_bind_key() exists.
* Add support for rl_bind_key(), currently one needs to "hack" the Map[]
* Add support for inhibiting completion: rl_inhibit_completion
* Make "char *rl_prompt" globally visible.
* Add support for rl_set_prompt().

View File

@@ -18,7 +18,7 @@
/* Define to enable SIGSTOP (Ctrl-Z) key. */
#undef CONFIG_SIGSTOP
/* Define to skip duplicate lines in the scrollback history. */
/* Don't save command if same as last one. */
#undef CONFIG_UNIQUE_HISTORY
/* Define to use the termcap library for terminal size. */
@@ -112,6 +112,12 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Enable static keyword, hides internal methods. */
#undef HIDE
/* Number of lines in history. */
#undef HIST_SIZE
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK

112
configure vendored
View File

@@ -748,6 +748,8 @@ am__EXEEXT_TRUE
LTLIBOBJS
TERMLIBS
AM_CFLAGS
CONFIG_DEFAULT_COMPLETE_FALSE
CONFIG_DEFAULT_COMPLETE_TRUE
LIBOBJS
CPP
OTOOL64
@@ -867,12 +869,13 @@ with_pic
enable_fast_install
with_gnu_ld
enable_libtool_lock
enable_unique_history
enable_default_complete
enable_arrow_keys
enable_sigstop
enable_terminal_bell
enable_termcap
enable_history
enable_unique_history
'
ac_precious_vars='build_alias
host_alias
@@ -1511,15 +1514,13 @@ Optional Features:
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
--disable-unique-history
Disable uniqify of scrollback. Default: duplicate
entries are ignored. Use this to save dupes.
--disable-default-complete
Disable default (filename) completion handler.
--disable-arrow-keys Disable ANSI arrow keys.
--enable-sigstop Enable SIGSTOP key.
--enable-terminal-bell Enable terminal bell on completion.
--enable-termcap Use termcap library to query terminal size.
--enable-default-complete Enable default completion handler.
--enable-arrow-keys Enable ANSI arrow keys.
--enable-sigstop Enable SIGSTOP key.
--enable-terminal-bell Enable terminal bell on completion.
--enable-termcap Use the termcap library for terminal size.
--enable-history=LINES Enable scrollback history, default off.
--enable-unique-history Uniqify scrollback history, i.e., don't save dupes.
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -4561,13 +4562,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:4564: $ac_compile\"" >&5)
(eval echo "\"\$as_me:4565: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
(eval echo "\"\$as_me:4567: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval echo "\"\$as_me:4568: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
(eval echo "\"\$as_me:4570: output\"" >&5)
(eval echo "\"\$as_me:4571: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -5773,7 +5774,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 5776 "configure"' > conftest.$ac_ext
echo '#line 5777 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -7303,11 +7304,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7306: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7307: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7310: \$? = $ac_status" >&5
echo "$as_me:7311: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7642,11 +7643,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7645: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7646: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7649: \$? = $ac_status" >&5
echo "$as_me:7650: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7747,11 +7748,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7750: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7751: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7754: \$? = $ac_status" >&5
echo "$as_me:7755: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -7802,11 +7803,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7805: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7806: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:7809: \$? = $ac_status" >&5
echo "$as_me:7810: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -10186,7 +10187,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 10189 "configure"
#line 10190 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10282,7 +10283,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
#line 10285 "configure"
#line 10286 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10907,6 +10908,9 @@ fi
$as_echo "#define SYS_UNIX 1" >>confdefs.h
$as_echo "#define HIDE 1" >>confdefs.h
ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
if test "x$ac_cv_type_size_t" = x""yes; then :
@@ -11126,32 +11130,26 @@ fi
done
# Check whether --enable-unique-history was given.
if test "${enable_unique_history+set}" = set; then :
enableval=$enable_unique_history;
else
$as_echo "#define CONFIG_UNIQUE_HISTORY 1" >>confdefs.h
# Check whether --enable-default-complete was given.
if test "${enable_default_complete+set}" = set; then :
enableval=$enable_default_complete; complete=true;
$as_echo "#define CONFIG_DEFAULT_COMPLETE /**/" >>confdefs.h
fi
# Check whether --enable-default-complete was given.
if test "${enable_default_complete+set}" = set; then :
enableval=$enable_default_complete;
if test x$complete = xtrue; then
CONFIG_DEFAULT_COMPLETE_TRUE=
CONFIG_DEFAULT_COMPLETE_FALSE='#'
else
$as_echo "#define CONFIG_DEFAULT_COMPLETE 1" >>confdefs.h
CONFIG_DEFAULT_COMPLETE_TRUE='#'
CONFIG_DEFAULT_COMPLETE_FALSE=
fi
# Check whether --enable-arrow-keys was given.
if test "${enable_arrow_keys+set}" = set; then :
enableval=$enable_arrow_keys;
else
$as_echo "#define CONFIG_ANSI_ARROWS 1" >>confdefs.h
$as_echo "#define CONFIG_ANSI_ARROWS /**/" >>confdefs.h
fi
@@ -11159,7 +11157,7 @@ fi
# Check whether --enable-sigstop was given.
if test "${enable_sigstop+set}" = set; then :
enableval=$enable_sigstop;
$as_echo "#define CONFIG_SIGSTOP 1" >>confdefs.h
$as_echo "#define CONFIG_SIGSTOP /**/" >>confdefs.h
fi
@@ -11167,7 +11165,7 @@ fi
# Check whether --enable-terminal-bell was given.
if test "${enable_terminal_bell+set}" = set; then :
enableval=$enable_terminal_bell;
$as_echo "#define CONFIG_ANNOYING_NOISE 1" >>confdefs.h
$as_echo "#define CONFIG_ANNOYING_NOISE /**/" >>confdefs.h
fi
@@ -11175,7 +11173,31 @@ fi
# Check whether --enable-termcap was given.
if test "${enable_termcap+set}" = set; then :
enableval=$enable_termcap;
$as_echo "#define CONFIG_USE_TERMCAP 1" >>confdefs.h
$as_echo "#define CONFIG_USE_TERMCAP /**/" >>confdefs.h
fi
# Default history size 1, i.e. disabled.
let HIST_SIZE=1
# Check whether --enable-history was given.
if test "${enable_history+set}" = set; then :
enableval=$enable_history; let HIST_SIZE=$enableval
fi
if test $HIST_SIZE -lt 1; then
let HIST_SIZE=1
fi
cat >>confdefs.h <<_ACEOF
#define HIST_SIZE $HIST_SIZE
_ACEOF
# Check whether --enable-unique-history was given.
if test "${enable_unique_history+set}" = set; then :
enableval=$enable_unique_history;
$as_echo "#define CONFIG_UNIQUE_HISTORY /**/" >>confdefs.h
fi
@@ -11512,6 +11534,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
as_fn_error "conditional \"am__fastdepCC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${CONFIG_DEFAULT_COMPLETE_TRUE}" && test -z "${CONFIG_DEFAULT_COMPLETE_FALSE}"; then
as_fn_error "conditional \"CONFIG_DEFAULT_COMPLETE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
: ${CONFIG_STATUS=./config.status}
ac_write_fail=0

View File

@@ -43,6 +43,7 @@ AC_HEADER_TIOCGWINSZ
# Overrides and types, should be a check.
AC_DEFINE([SYS_UNIX], [1], [Default to UNIX backend, should be detected.])
AC_DEFINE([HIDE], [1], [Enable static keyword, hides internal methods.])
AC_TYPE_SIZE_T
# Checks for library functions.
@@ -51,30 +52,40 @@ AC_PROG_GCC_TRADITIONAL
AC_FUNC_STAT
AC_CHECK_FUNCS([strchr strdup strrchr tcgetattr perror])
AC_ARG_ENABLE(unique-history,
[AS_HELP_STRING([--disable-unique-history],
[Disable uniqify of scrollback. Default: duplicate entries are ignored. Use this to save dupes.])],
, AC_DEFINE(CONFIG_UNIQUE_HISTORY, 1, [Define to skip duplicate lines in the scrollback history.]))
AC_ARG_ENABLE(default-complete,
[AS_HELP_STRING([--disable-default-complete], [Disable default (filename) completion handler.])],
, AC_DEFINE(CONFIG_DEFAULT_COMPLETE, 1, [Define to enable the default completion handler.]))
[ --enable-default-complete Enable default completion handler.],
complete=true; AC_DEFINE(CONFIG_DEFAULT_COMPLETE,, [Define to enable the default completion handler.]))
AM_CONDITIONAL([CONFIG_DEFAULT_COMPLETE], [test x$complete = xtrue])
AC_ARG_ENABLE(arrow-keys,
[AS_HELP_STRING([--disable-arrow-keys], [Disable ANSI arrow keys.])],
, AC_DEFINE(CONFIG_ANSI_ARROWS, 1, [Define to include ANSI arrow keys support.]))
[ --enable-arrow-keys Enable ANSI arrow keys.],
AC_DEFINE([CONFIG_ANSI_ARROWS],, [Define to include ANSI arrow keys support.]))
AC_ARG_ENABLE(sigstop,
[AS_HELP_STRING([--enable-sigstop], [Enable SIGSTOP key.])],
AC_DEFINE([CONFIG_SIGSTOP], 1, [Define to enable SIGSTOP (Ctrl-Z) key.]))
[ --enable-sigstop Enable SIGSTOP key.],
AC_DEFINE([CONFIG_SIGSTOP],, [Define to enable SIGSTOP (Ctrl-Z) key.]))
AC_ARG_ENABLE(terminal-bell,
[AS_HELP_STRING([--enable-terminal-bell], [Enable terminal bell on completion.])],
AC_DEFINE([CONFIG_ANNOYING_NOISE], 1, [Define to enable terminal bell on completion.]))
[ --enable-terminal-bell Enable terminal bell on completion.],
AC_DEFINE([CONFIG_ANNOYING_NOISE],, [Define to enable terminal bell on completion.]))
AC_ARG_ENABLE(termcap,
[AS_HELP_STRING([--enable-termcap], [Use termcap library to query terminal size.])],
AC_DEFINE([CONFIG_USE_TERMCAP], 1, [Define to use the termcap library for terminal size.]))
[ --enable-termcap Use the termcap library for terminal size.],
AC_DEFINE([CONFIG_USE_TERMCAP],, [Define to use the termcap library for terminal size.]))
# Default history size 1, i.e. disabled.
let HIST_SIZE=1
AC_ARG_ENABLE(history,
[ --enable-history=LINES Enable scrollback history, default off.],
let HIST_SIZE=$enableval)
if test $HIST_SIZE -lt 1; then
let HIST_SIZE=1
fi
AC_DEFINE_UNQUOTED(HIST_SIZE, $HIST_SIZE, [Number of lines in history.])
AC_ARG_ENABLE(unique-history,
[ --enable-unique-history Uniqify scrollback history, i.e., don't save dupes.],
AC_DEFINE([CONFIG_UNIQUE_HISTORY],, [Don't save command if same as last one.]))
# Restore gnu89 inline semantics on gcc 4.3 and newer
saved_cflags="$CFLAGS"

View File

@@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = foreign
noinst_PROGRAMS = testit cli fileman
noinst_PROGRAMS = testit cli
LDADD = $(top_builddir)/src/libeditline.la $(TERMLIBS)
AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include
AM_LDFLAGS = -static

View File

@@ -34,7 +34,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = testit$(EXEEXT) cli$(EXEEXT) fileman$(EXEEXT)
noinst_PROGRAMS = testit$(EXEEXT) cli$(EXEEXT)
subdir = examples
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -58,11 +58,6 @@ cli_DEPENDENCIES = $(top_builddir)/src/libeditline.la \
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
am__v_lt_0 = --silent
fileman_SOURCES = fileman.c
fileman_OBJECTS = fileman.$(OBJEXT)
fileman_LDADD = $(LDADD)
fileman_DEPENDENCIES = $(top_builddir)/src/libeditline.la \
$(am__DEPENDENCIES_1)
testit_SOURCES = testit.c
testit_OBJECTS = testit.$(OBJEXT)
testit_LDADD = $(LDADD)
@@ -94,8 +89,8 @@ am__v_CCLD_0 = @echo " CCLD " $@;
AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = cli.c fileman.c testit.c
DIST_SOURCES = cli.c fileman.c testit.c
SOURCES = cli.c testit.c
DIST_SOURCES = cli.c testit.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -215,7 +210,6 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
LDADD = $(top_builddir)/src/libeditline.la $(TERMLIBS)
AM_LDFLAGS = -static
all: all-am
.SUFFIXES:
@@ -262,9 +256,6 @@ clean-noinstPROGRAMS:
cli$(EXEEXT): $(cli_OBJECTS) $(cli_DEPENDENCIES)
@rm -f cli$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(cli_OBJECTS) $(cli_LDADD) $(LIBS)
fileman$(EXEEXT): $(fileman_OBJECTS) $(fileman_DEPENDENCIES)
@rm -f fileman$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(fileman_OBJECTS) $(fileman_LDADD) $(LIBS)
testit$(EXEEXT): $(testit_OBJECTS) $(testit_DEPENDENCIES)
@rm -f testit$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(testit_OBJECTS) $(testit_LDADD) $(LIBS)
@@ -276,7 +267,6 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cli.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileman.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testit.Po@am__quote@
.c.o:

View File

@@ -22,8 +22,6 @@
#include "editline.h"
#include <string.h>
#define HISTORY "/tmp/.cli-history"
static char *list[] = {
"foo ", "bar ", "bsd ", "cli ", "ls ", "cd ", "malloc ", "tee ", NULL
};
@@ -80,28 +78,6 @@ static int my_rl_list_possib(char *token, char ***av)
return total;
}
el_status_t list_possible(void)
{
char **av;
char *word;
int ac;
word = el_find_word();
ac = rl_list_possib(word, &av);
if (word)
free(word);
if (ac) {
el_print_columns(ac, av);
while (--ac >= 0)
free(av[ac]);
free(av);
return CSmove;
}
return el_ring_bell();
}
int main(int ac __attribute__ ((unused)), char *av[] __attribute__ ((unused)))
{
char *line;
@@ -110,15 +86,11 @@ int main(int ac __attribute__ ((unused)), char *av[] __attribute__ ((unused)))
/* Setup callbacks */
rl_set_complete_func(&my_rl_complete);
rl_set_list_possib_func(&my_rl_list_possib);
el_bind_key('?', list_possible);
read_history(HISTORY);
while ((line = readline(prompt)) != NULL) {
printf("\t\t\t|%s|\n", line);
free(line);
}
write_history(HISTORY);
return 0;
}

View File

@@ -1,499 +0,0 @@
/* 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.
NOTE: this was taken from the GNU Readline documentation and ported
to libedit. A commad to output the history list was added.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
/* GNU readline
#include <readline/readline.h>
#include <readline/history.h>
*/
/* NetBSD libedit
#include <editline/readline.h>
*/
#include <editline.h>
void * xmalloc (size_t size);
void too_dangerous (char *caller);
void initialize_readline ();
int execute_line (char *line);
int valid_argument (char *caller, char *arg);
typedef int rl_icpfunc_t (char *);
/* The names of functions that actually do the manipulation. */
int com_list (char *);
int com_view (char *);
int com_history (char *);
int com_rename(char *);
int com_stat(char *);
int com_pwd(char *);
int com_delete(char *);
int com_help(char *);
int com_cd(char *);
int com_quit(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" },
{ "history", com_history, "List editline history" },
{ (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 means the user is done using this program. */
int done;
char *
dupstr (char* s)
{
char *r;
r = xmalloc (strlen (s) + 1);
strcpy (r, s);
return (r);
}
int
main (int argc, char **argv)
{
char *line, *s;
progname = argv[0];
setlocale(LC_CTYPE, "");
initialize_readline(); /* Bind our completer. */
stifle_history(7);
/* 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) {
char* expansion;
int result;
result = history_expand(s, &expansion);
if (result < 0 || result == 2) {
fprintf(stderr, "%s\n", expansion);
} else {
add_history(expansion);
execute_line(expansion);
}
free(expansion);
}
free(line);
}
exit (0);
return 0;
}
/* Execute a command line. */
int
execute_line (char *line)
{
register int i;
COMMAND *command;
char *word;
/* Isolate the command word. */
i = 0;
while (line[i] && isspace (line[i]))
i++;
word = line + i;
while (line[i] && !isspace (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 (isspace (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 (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 (char *string)
{
register char *s, *t;
for (s = string; isspace (*s); s++)
;
if (*s == 0)
return (s);
t = s + strlen (s) - 1;
while (t > s && isspace (*t))
t--;
*++t = '\0';
return s;
}
/* **************************************************************** */
/* */
/* Interface to Readline Completion */
/* */
/* **************************************************************** */
char *command_generator(const char *, int);
char **fileman_completion(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. */
void
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. Returnthe array of matches, or NULL if there aren't any. */
char **
fileman_completion (const char* text, int start, int 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)
/* TODO */
matches = completion_matches (text, command_generator);
/* 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. */
int
com_list (char *arg)
{
if (!arg)
arg = "";
sprintf (syscom, "ls -FClg %s", arg);
return (system (syscom));
}
int
com_view (char *arg)
{
if (!valid_argument ("view", arg))
return 1;
sprintf (syscom, "more %s", arg);
return (system (syscom));
}
int
com_history(char* arg)
{
HIST_ENTRY *he;
/* rewind history */
while (next_history())
;
for (he = current_history(); he != NULL; he = previous_history()) {
//printf("%5d %s\n", *((int*)he->data) - 1, he->line);
printf("%s\n", he->line);
}
return 0;
}
int
com_rename (char *arg)
{
too_dangerous ("rename");
return (1);
}
int
com_stat (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 %ld link%s, and is %lld byte%s in length.\n", arg,
(long) finfo.st_nlink,
(finfo.st_nlink == 1) ? "" : "s",
(long long) 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);
}
int
com_delete (char *arg)
{
too_dangerous ("delete");
return (1);
}
/* Print out help for ARG, or for all of the commands if ARG is
not present. */
int
com_help (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. */
int
com_cd (char *arg)
{
if (chdir (arg) == -1)
{
perror (arg);
return 1;
}
com_pwd ("");
return (0);
}
/* Print out the current working directory. */
int
com_pwd (char* ignore)
{
char dir[1024], *s;
s = (char*)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. */
int
com_quit (char *arg)
{
done = 1;
return (0);
}
/* Function which tells you that you can't do this. */
void
too_dangerous (char *caller)
{
fprintf (stderr,
"%s: Too dangerous for me to distribute.\n",
caller);
fprintf (stderr, "Write it yourself.\n");
}
/* Return non-zero if ARG is a valid argument for CALLER,
else print an error message and return zero. */
int
valid_argument (char *caller, char *arg)
{
if (!arg || !*arg)
{
fprintf (stderr, "%s: Argument required.\n", caller);
return (0);
}
return (1);
}
void *
xmalloc (size_t size)
{
register void *value = (void*)malloc(size);
if (value == 0)
fprintf(stderr, "virtual memory exhausted");
return value;
}

View File

@@ -27,60 +27,31 @@ typedef enum {
} el_status_t;
/* Editline specific types, despite rl_ prefix. From Heimdal project. */
typedef char* rl_complete_func_t(char*, int*);
typedef int rl_list_possib_func_t(char*, char***);
typedef el_status_t el_keymap_func_t(void);
typedef int rl_hook_func_t(void);
typedef int rl_getc_func_t(void);
typedef void rl_voidfunc_t(void);
typedef void rl_vintfunc_t(int);
typedef char* (*rl_complete_func_t)(char*, int*);
typedef int (*rl_list_possib_func_t)(char*, char***);
typedef el_status_t (*el_keymap_func_t)(void);
/* Display 8-bit chars "as-is" or as `M-x'? Toggle with M-m. (Default:0 - "as-is") */
extern int rl_meta_chars;
/* Use these functions to set custom command/file completion, see cli.c for example usage. */
rl_complete_func_t rl_set_complete_func(rl_complete_func_t func);
rl_list_possib_func_t rl_set_list_possib_func(rl_list_possib_func_t func);
/* Editline specific functions. */
extern char * el_find_word(void);
extern void el_print_columns(int ac, char **av);
extern el_status_t el_ring_bell(void);
void el_bind_key_in_metamap(char c, el_keymap_func_t func);
extern void el_bind_key(int key, el_keymap_func_t function);
extern void el_bind_key_in_metamap(int key, el_keymap_func_t function);
extern char *rl_complete(char *token, int *match);
extern int rl_list_possib(char *token, char ***av);
/* For compatibility with GNU Readline. */
/* For compatibility with FSF readline. */
extern int rl_point;
extern int rl_mark;
extern int rl_end;
extern char *rl_line_buffer;
extern const char *rl_readline_name;
extern FILE *rl_instream; /* The stdio stream from which input is read. Defaults to stdin if NULL - Not supported yet! */
extern FILE *rl_outstream; /* The stdio stream to which output is flushed. Defaults to stdout if NULL - Not supported yet! */
extern int el_no_echo; /* e.g under emacs, don't echo except prompt */
extern int el_hist_size; /* size of history scrollback buffer, default: 15 */
extern int el_no_echo; /* e.g under emacs, don't echo except prompt */
extern void rl_reset_terminal(char *p);
extern void rl_initialize(void);
extern void rl_reset_terminal(const char *terminal_name);
extern void rl_prep_terminal(int meta_flag);
extern void rl_deprep_terminal(void);
extern int rl_getc(void);
extern char *readline(const char *prompt);
extern void add_history(const char *line);
extern int read_history(const char *filename);
extern int write_history(const char *filename);
extern rl_complete_func_t *rl_set_complete_func(rl_complete_func_t *func);
extern rl_list_possib_func_t *rl_set_list_possib_func(rl_list_possib_func_t *func);
extern char *(*rl_completion_entry_function)(const char *text, int state);
extern char *rl_filename_completion_function(const char *text, int state);
extern int rl_attempted_completion_over;
extern char **(*rl_attempted_completion_function)(const char *text, int start, int end);
extern void add_history(char *line); /* OBSOLETE: Made part of readline(). -- kjb */
#endif /* __EDITLINE_H__ */

View File

@@ -3,43 +3,54 @@
editline \- command-line editing library with history
.SH SYNOPSIS
.nf
.B "char *readline(char *prompt);"
.B "char *"
.B "readline(prompt)"
.B " char *prompt;"
.B "void"
.B "add_history(line)"
.B " char *line;"
.fi
.SH DESCRIPTION
.I Editline
is a library that provides an line-editing interface with history.
It is intended to be functionally equivalent with the
is a library that provides an line-editing interface with text recall.
It is intended to be compatible with the
.I readline
library provided by the Free Software Foundation, but much smaller.
The bulk of this manual page describes the user interface.
.PP
The
.I readline()
function displays the given
.I prompt
on stdout, waits for user input on stdin and then
returns a line of text with the trailing newline removed. The data is returned in a
buffer allocated with
.I readline
routine returns a line of text with the trailing newline removed.
The data is returned in a buffer allocated with
.IR malloc (3),
so the space should be released with
.IR free (3)
when the calling program is done with it.
Before accepting input from the user, the specified
.I prompt
is displayed on the terminal.
.PP
Each line returned is copied to the internal history list, unless it happens
to be equal to the previous line. This is configurable if you are building editline
from source.
to be equal to the previous line.
.SS "User Interface"
A program that uses this library provides a simple emacs-like editing interface to
its users. A line may be edited before it is sent to the calling program by typing
either control characters or escape sequences. A control character, shown as a caret
followed by a letter, is typed by holding down the ``control'' key while the letter
is typed. For example, ``^A'' is a control-A. An escape sequence is entered by
typing the ``escape'' key followed by one or more characters. The escape key is
abbreviated as ``ESC''. Note that unlike control keys, case matters in escape
sequences; ``ESC\ F'' is not the same as ``ESC\ f''.
A program that uses this library provides a simple emacs-like editing
interface to its users.
A line may be edited before it is sent to the calling program by typing either
control characters or escape sequences.
A control character, shown as a caret followed by a letter, is typed by
holding down the ``control'' key while the letter is typed.
For example, ``^A'' is a control-A.
An escape sequence is entered by typing the ``escape'' key followed by one or
more characters.
The escape key is abbreviated as ``ESC''.
Note that unlike control keys, case matters in escape sequences; ``ESC\ F''
is not the same as ``ESC\ f''.
.PP
An editing command may be typed anywhere on the line, not just at the beginning. In
addition, a return may also be typed anywhere on the line, not just at the end.
An editing command may be typed anywhere on the line, not just at the
beginning.
In addition, a return may also be typed anywhere on the line, not just at
the end.
.PP
Most editing commands may be given a repeat count,
.IR n ,
@@ -70,8 +81,8 @@ The following control characters are accepted:
^M Done with line (alternate return key)
^N Get next line from history [n]
^P Get previous line from history [n]
^R Search backward (forward if [n]) through history for
\& text; must start line if text begins with an uparrow
^R Search backward (forward if [n]) through history for text;
\& must start line if text begins with an uparrow
^T Transpose characters
^V Insert next character, even if it is an edit command
^W Wipe to the mark
@@ -98,8 +109,7 @@ ESC\ b Move backward a word [n]
ESC\ d Delete word under cursor [n]
ESC\ f Move forward a word [n]
ESC\ l Make word lowercase [n]
ESC\ m Toggle if 8bit chars display normally or with an
\& ``M\-'' prefix
ESC\ m Toggle if 8bit chars display normally or with ``M\-'' prefix
ESC\ u Make word uppercase [n]
ESC\ y Yank back last killed text
ESC\ v Show library version
@@ -154,41 +164,11 @@ for you:
.RE
The tab key is shown by ``[TAB]'' and the automatically-entered text
is shown in italics.
.SH "USAGE"
To include
.I readline()
in your program, simply call it as you do any other function. Just make sure to link
your program with libeditline.
.SS "Example"
The following brief example lets you enter a line and edit it, then displays it.
.nf
.B "#include <stdlib.h>"
.B ""
.B "extern char *readline(char *prompt);"
.B ""
.B "int main (void)"
.B "{"
.B " char *p;"
.B ""
.B " while ((p = readline(``CLI> '')) != NULL) {"
.B " printf(\"%s\n\", p);"
.B " free(p);"
.B " }"
.B ""
.B " return 0;"
.B "}"
.fi
.SH "BUGS AND LIMITATIONS"
Doesn't know how to handle multiple lines or unicode characters well. See the TODO
file in the distribution if you want to help out.
Doesn't know how to handle multiple lines.
.SH AUTHORS
The original editline library was created by Simmule R. Turner and Rich $alz. It is
now maintained in several forks: Heimdal, Festival speech tools, Mozilla, Google
Gadgets for Linux, and many other places. The original manual page was made by DaviD
W. Sanderson. This version was made by Joachim Nilsson <troglobit@gmail.com>.
Simmule R. Turner <uunet.uu.net!capitol!sysgo!simmy>
and Rich $alz <rsalz@osf.org>.
Original manual page by DaviD W. Sanderson <dws@ssec.wisc.edu>.
.\" $PchId: editline.3,v 1.3 1996/02/22 21:18:51 philip Exp $

View File

@@ -1,3 +1,7 @@
AUTOMAKE_OPTIONS = foreign
lib_LTLIBRARIES = libeditline.la
libeditline_la_SOURCES = editline.c editline.h complete.c sysunix.c unix.h
libeditline_la_SOURCES = editline.c editline.h sysunix.c unix.h
if CONFIG_DEFAULT_COMPLETE
# Built-in completion handler.
libeditline_la_SOURCES += complete.c
endif

View File

@@ -34,6 +34,8 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
# Built-in completion handler.
@CONFIG_DEFAULT_COMPLETE_TRUE@am__append_1 = complete.c
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -71,7 +73,10 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libeditline_la_LIBADD =
am_libeditline_la_OBJECTS = editline.lo complete.lo sysunix.lo
am__libeditline_la_SOURCES_DIST = editline.c editline.h sysunix.c \
unix.h complete.c
@CONFIG_DEFAULT_COMPLETE_TRUE@am__objects_1 = complete.lo
am_libeditline_la_OBJECTS = editline.lo sysunix.lo $(am__objects_1)
libeditline_la_OBJECTS = $(am_libeditline_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
@@ -103,7 +108,7 @@ AM_V_GEN = $(am__v_GEN_$(V))
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libeditline_la_SOURCES)
DIST_SOURCES = $(libeditline_la_SOURCES)
DIST_SOURCES = $(am__libeditline_la_SOURCES_DIST)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -223,7 +228,8 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
lib_LTLIBRARIES = libeditline.la
libeditline_la_SOURCES = editline.c editline.h complete.c sysunix.c unix.h
libeditline_la_SOURCES = editline.c editline.h sysunix.c unix.h \
$(am__append_1)
all: all-am
.SUFFIXES:

View File

@@ -140,12 +140,12 @@ static int SplitPath(char *path, char **dirpart, char **filepart)
return 0;
}
static rl_complete_func_t *el_complete_func = NULL;
static rl_complete_func_t el_complete_func = NULL;
/* For compatibility with the Heimdal project. */
rl_complete_func_t *rl_set_complete_func(rl_complete_func_t *func)
rl_complete_func_t rl_set_complete_func(rl_complete_func_t func)
{
rl_complete_func_t *old = el_complete_func;
rl_complete_func_t old = el_complete_func;
el_complete_func = func;
return old;
}
@@ -234,12 +234,12 @@ char *rl_complete(char *token, int *match)
#endif
}
static rl_list_possib_func_t *el_list_possib_func = NULL;
static rl_list_possib_func_t el_list_possib_func = NULL;
/* For compatibility with the Heimdal project. */
rl_list_possib_func_t *rl_set_list_possib_func(rl_list_possib_func_t *func)
rl_list_possib_func_t rl_set_list_possib_func(rl_list_possib_func_t func)
{
rl_list_possib_func_t *old = el_list_possib_func;
rl_list_possib_func_t old = el_list_possib_func;
el_list_possib_func = func;
return old;
}

View File

@@ -30,8 +30,6 @@
*/
#define SCREEN_COLS 80
#define SCREEN_ROWS 24
#define EL_STDIN 0
#define EL_STDOUT 1
#define NO_ARG (-1)
#define DEL 127
#define CTL(x) ((x) & 0x1F)
@@ -40,6 +38,9 @@
#define META(x) ((x) | 0x80)
#define ISMETA(x) ((x) & 0x80)
#define UNMETA(x) ((x) & 0x7F)
#ifndef HIST_SIZE /* Default to one line history, i.e. disabled. */
#define HIST_SIZE 1
#endif
#define SEPS "\"#$&'()*:;<=>?[\\]^`{|}~\n\t "
/*
@@ -63,14 +64,9 @@ typedef struct {
typedef struct {
int Size;
int Pos;
char **Lines;
char *Lines[HIST_SIZE];
} el_hist_t;
rl_getc_func_t *rl_getc_function = rl_getc;
rl_hook_func_t *rl_event_hook;
rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
/*
** Globals.
*/
@@ -83,34 +79,25 @@ int rl_quit;
int rl_susp;
#endif
int el_hist_size = 15;
static el_hist_t H = {
.Size = 0,
.Pos = 0,
.Lines = NULL,
};
static char NILSTR[] = "";
static const char *el_input = NILSTR;
static char *Yanked;
static char *Screen;
static char NEWLINE[]= CRLF;
static const char *el_term = "dumb";
static el_hist_t H;
static int Repeat;
static int old_point;
static int el_push_back;
static int el_pushed;
static int el_intr_pending;
static int el_infd = EL_STDIN;
static int el_outfd = EL_STDOUT;
static el_keymap_t Map[];
static el_keymap_t MetaMap[];
static size_t Length;
static size_t ScreenCount;
static size_t ScreenSize;
static char *backspace = "\b";
static int tty_cols = SCREEN_COLS;
static int tty_rows = SCREEN_ROWS;
static char *backspace;
static int tty_cols;
static int tty_rows;
int el_no_echo = 0; /* e.g., under Emacs */
int rl_point;
@@ -119,9 +106,7 @@ int rl_end;
int rl_meta_chars = 0; /* Display 8-bit chars as the actual char(0) or as `M-x'(1)? */
char *rl_line_buffer;
const char *rl_prompt;
const char *rl_readline_name; /* Set by calling program, for conditional parsing of ~/.inputrc - Not supported yet! */
FILE *rl_instream = NULL; /* The stdio stream from which input is read. Defaults to stdin if NULL */
FILE *rl_outstream = NULL; /* The stdio stream to which output is flushed. Defaults to stdout if NULL */
const char *rl_readline_name;/* Set by calling program, for conditional parsing of ~/.inputrc - Not supported yet! */
/* User definable callbacks. */
char **(*rl_attempted_completion_function)(const char *token, int start, int end);
@@ -150,6 +135,16 @@ static int is_alpha_num(unsigned char c)
return 0;
}
/* http://www.utf8-chartable.de/unicode-utf8-table.pl */
int isutf8(unsigned char c)
{
if (c >= 0xC2 && c <= 0xCF)
return 1;
return 0;
}
/*
** TTY input/output functions.
*/
@@ -160,7 +155,7 @@ static void tty_flush(void)
if (ScreenCount) {
if (!el_no_echo)
res = write(el_outfd, Screen, ScreenCount);
res = write(1, Screen, ScreenCount);
ScreenCount = 0;
}
}
@@ -182,7 +177,15 @@ static void tty_puts(const char *p)
static void tty_show(unsigned char c)
{
if (c == DEL) {
static int mode_compose = 0;
if (mode_compose) {
tty_put(c);
mode_compose = 0;
} else if (isutf8(c)) {
mode_compose = 1;
tty_put(c);
} else if (c == DEL) {
tty_put('^');
tty_put('?');
} else if (ISCTL(c)) {
@@ -209,20 +212,11 @@ static void tty_push(int c)
el_push_back = c;
}
int rl_getc(void)
{
int r;
char c;
do {
r = read(el_infd, &c, 1);
} while (r == -1 && errno == EINTR);
return r == 1 ? c : EOF;
}
static int tty_get(void)
{
char c;
int r;
tty_flush();
if (el_pushed) {
el_pushed = 0;
@@ -230,11 +224,15 @@ static int tty_get(void)
}
if (*el_input)
return *el_input++;
do
{
r = read(0, &c, 1);
} while (r == -1 && errno == EINTR);
return rl_getc_function();
return r == 1 ? c : EOF;
}
#define tty_back() tty_puts(backspace)
#define tty_back() (backspace ? tty_puts(backspace) : tty_put('\b'))
static void tty_backn(int n)
{
@@ -244,13 +242,21 @@ static void tty_backn(int n)
static void tty_info(void)
{
static int init;
static int init;
#ifdef CONFIG_USE_TERMCAP
char *term;
char buff[2048];
char *bp;
#endif
#ifdef TIOCGWINSZ
struct winsize W;
#endif
if (init) {
#ifdef TIOCGWINSZ
struct winsize W;
if (ioctl(el_outfd, TIOCGWINSZ, &W) >= 0 && W.ws_col > 0 && W.ws_row > 0) {
/* Perhaps we got resized. */
if (ioctl(0, TIOCGWINSZ, &W) >= 0
&& W.ws_col > 0 && W.ws_row > 0) {
tty_cols = (int)W.ws_col;
tty_rows = (int)W.ws_row;
}
@@ -261,28 +267,39 @@ static void tty_info(void)
/* Initialize to faulty values to trigger fallback if nothing else works. */
tty_cols = tty_rows = -1;
rl_reset_terminal(NULL);
#ifdef CONFIG_USE_TERMCAP
bp = buff;
if ((term = getenv("TERM")) == NULL)
term = "dumb";
if (-1 != tgetent(buff, term)) {
if ((backspace = tgetstr("le", &bp)) != NULL)
backspace = strdup(backspace);
else
backspace = "\b";
tty_cols = tgetnum("co");
tty_rows = tgetnum("li");
}
/* Make sure to check width & rows and fallback to TIOCGWINSZ if available. */
#endif
if (tty_cols <= 0 || tty_rows <= 0) {
#ifdef TIOCGWINSZ
if (-1 != ioctl(0, TIOCGWINSZ, &W)) {
tty_cols = (int)W.ws_col;
tty_rows = (int)W.ws_row;
return;
}
#endif
tty_cols = SCREEN_COLS;
tty_rows = SCREEN_ROWS;
}
}
/*
** Glue routines to rl_ttyset()
*/
void rl_prep_terminal(int meta_flag)
{
rl_meta_chars = !meta_flag;
rl_ttyset(0);
}
void rl_deprep_terminal(void)
{
rl_ttyset(1);
}
/*
** Print an array of words in columns.
*/
void el_print_columns(int ac, char **av)
static void columns(int ac, char **av)
{
char *p;
int i;
@@ -326,7 +343,9 @@ static void left(el_status_t Change)
{
if (rl_point) {
tty_back();
if (ISMETA(rl_line_buffer[rl_point - 1])) {
if (isutf8(rl_line_buffer[rl_point - 2])) {
rl_point--;
} else if (ISMETA(rl_line_buffer[rl_point - 1])) {
if (rl_meta_chars) {
tty_back();
tty_back();
@@ -343,11 +362,14 @@ static void right(el_status_t Change)
{
tty_show(rl_line_buffer[rl_point]);
if (isutf8(rl_line_buffer[rl_point]))
tty_show(rl_line_buffer[++rl_point]);
if (Change == CSmove)
rl_point++;
}
el_status_t el_ring_bell(void)
static el_status_t ring_bell(void)
{
tty_put('\07');
tty_flush();
@@ -365,7 +387,7 @@ static el_status_t do_macro(int c)
if ((el_input = (char *)getenv((char *)name)) == NULL) {
el_input = NILSTR;
return el_ring_bell();
return ring_bell();
}
return CSstay;
}
@@ -536,7 +558,7 @@ static const char *prev_hist(void)
static el_status_t do_insert_hist(const char *p)
{
if (p == NULL)
return el_ring_bell();
return ring_bell();
rl_point = 0;
reposition();
@@ -554,7 +576,7 @@ static el_status_t do_hist(const char *(*move)(void))
i = 0;
do {
if ((p = move()) == NULL)
return el_ring_bell();
return ring_bell();
} while (++i < Repeat);
return do_insert_hist(p);
}
@@ -641,7 +663,7 @@ static el_status_t h_search(void)
const char *p;
if (Searching)
return el_ring_bell();
return ring_bell();
Searching = 1;
clear_line();
@@ -661,7 +683,7 @@ static el_status_t h_search(void)
p = search_hist(p, move);
clear_line();
if (p == NULL) {
el_ring_bell();
ring_bell();
return redisplay();
}
return do_insert_hist(p);
@@ -703,7 +725,7 @@ static el_status_t delete_string(int count)
char *p;
if (count <= 0 || rl_end == rl_point)
return el_ring_bell();
return ring_bell();
if (count == 1 && rl_point == rl_end - 1) {
/* Optimize common case of delete at end of line. */
@@ -714,6 +736,9 @@ static el_status_t delete_string(int count)
if (ISCTL(*p)) {
i = 2;
tty_put(' ');
} else if (isutf8(*p)) {
i = 2;
tty_put(' ');
} else if (rl_meta_chars && ISMETA(*p)) {
i = 3;
tty_put(' ');
@@ -867,7 +892,7 @@ static el_status_t meta(void)
break;
}
return el_ring_bell();
return ring_bell();
}
#endif /* CONFIG_ANSI_ARROWS */
@@ -885,7 +910,21 @@ static el_status_t meta(void)
return kp->Function();
}
return el_ring_bell();
return ring_bell();
}
static el_status_t utf8(int c)
{
char buff[3];
if (!isutf8(c))
return CSeof;
buff[0] = c;
buff[1] = tty_get();
buff[2] = '\0';
return insert_string(buff);
}
static el_status_t emacs(int c)
@@ -896,6 +935,10 @@ static el_status_t emacs(int c)
/* Save point before interpreting input character 'c'. */
old_point = rl_point;
if (isutf8(c)) {
return utf8(c);
}
if (rl_meta_chars && ISMETA(c)) {
tty_push(UNMETA(c));
return meta();
@@ -916,7 +959,10 @@ static el_status_t emacs(int c)
static el_status_t tty_special(int c)
{
if (rl_meta_chars && ISMETA(c))
if (isutf8(c))
return CSdispatch;
if (rl_meta_chars && ISMETA(c))
return CSdispatch;
if (c == rl_erase || c == DEL)
@@ -1001,33 +1047,19 @@ static char *editinput(void)
return NULL;
}
static void hist_alloc(void)
{
if (!H.Lines)
H.Lines = calloc(el_hist_size, sizeof(char *));
}
static void hist_add(const char *p)
static void hist_add(char *p)
{
int i;
char *s;
#ifdef CONFIG_UNIQUE_HISTORY
if (H.Pos && strcmp(p, H.Lines[H.Pos - 1]) == 0)
if ((p = (char *)strdup((char *)p)) == NULL)
return;
#endif
if (H.Size && strcmp(p, H.Lines[H.Size - 1]) == 0)
return;
if ((s = strdup(p)) == NULL)
return;
if (H.Size < el_hist_size) {
H.Lines[H.Size++] = s;
if (H.Size < HIST_SIZE) {
H.Lines[H.Size++] = p;
} else {
free(H.Lines[0]);
for (i = 0; i < el_hist_size - 1; i++)
for (i = 0; i < HIST_SIZE - 1; i++)
H.Lines[i] = H.Lines[i + 1];
H.Lines[i] = s;
H.Lines[i] = p;
}
H.Pos = H.Size - 1;
}
@@ -1056,7 +1088,7 @@ static char *read_redirected(void)
p += oldpos; /* Continue where we left off... */
}
if (read(el_infd, p, 1) <= 0) {
if (read(0, p, 1) <= 0) {
/* Ignore "incomplete" lines at EOF, just like we do for a tty. */
free(line);
return NULL;
@@ -1071,67 +1103,19 @@ static char *read_redirected(void)
}
/* For compatibility with FSF readline. */
void rl_reset_terminal(const char *terminal_name)
void rl_reset_terminal(char *p __attribute__((__unused__)))
{
#ifdef CONFIG_USE_TERMCAP
char buff[2048];
char *bp;
#endif
#ifdef TIOCGWINSZ
struct winsize W;
#endif
if (terminal_name) {
el_term = terminal_name;
return;
}
if ((el_term = getenv("TERM")) == NULL)
el_term = "dumb";
#ifdef CONFIG_USE_TERMCAP
bp = buff;
if (-1 != tgetent(buff, el_term)) {
if ((backspace = tgetstr("le", &bp)) != NULL)
backspace = strdup(backspace);
tty_cols = tgetnum("co");
tty_rows = tgetnum("li");
}
/* Make sure to check width & rows and fallback to TIOCGWINSZ if available. */
#endif
if (tty_cols <= 0 || tty_rows <= 0) {
#ifdef TIOCGWINSZ
if (-1 != ioctl(el_outfd, TIOCGWINSZ, &W)) {
tty_cols = (int)W.ws_col;
tty_rows = (int)W.ws_row;
return;
}
#endif
tty_cols = SCREEN_COLS;
tty_rows = SCREEN_ROWS;
}
}
void rl_initialize(void)
{
if (!rl_prompt)
rl_prompt = "? ";
hist_alloc();
/* Setup I/O descriptors */
if (!rl_instream) el_infd = EL_STDIN;
else el_infd = fileno(rl_instream);
if (el_infd < 0) el_infd = EL_STDIN;
if (!rl_outstream) el_outfd = EL_STDOUT;
else el_outfd = fileno(rl_outstream);
if (el_outfd < 0) el_outfd = EL_STDOUT;
}
char *readline(const char *prompt)
{
char *line;
char *line;
/* Unless called by the user already. */
rl_initialize();
@@ -1149,7 +1133,7 @@ char *readline(const char *prompt)
}
tty_info();
rl_prep_term_function(!rl_meta_chars);
rl_ttyset(0);
hist_add(NILSTR);
ScreenSize = SCREEN_INC;
Screen = malloc(sizeof(char) * ScreenSize);
@@ -1174,13 +1158,18 @@ char *readline(const char *prompt)
tty_flush();
}
rl_deprep_term_function();
rl_ttyset(1);
free(Screen);
free(H.Lines[--H.Size]);
/* Always add history, if it's a sane line. */
if (line != NULL && *line != '\0')
if (line != NULL && *line != '\0'
#ifdef CONFIG_UNIQUE_HISTORY
&& !(H.Pos && strcmp(line, H.Lines[H.Pos - 1]) == 0)
#endif
&& !(H.Size && strcmp(line, H.Lines[H.Size - 1]) == 0)
) {
hist_add(line);
}
if (el_intr_pending > 0) {
int s = el_intr_pending;
@@ -1191,58 +1180,20 @@ char *readline(const char *prompt)
return line;
}
/* Even though readline() itself adds history automatically, the user can also add
* lines. This is for compat with GNU Readline. */
void add_history(const char *p)
void add_history(char *p __attribute__ ((unused)))
{
#ifdef obsolete /* Made part of readline(). -- kjb */
if (p == NULL || *p == '\0')
return;
hist_add(p);
}
int read_history(const char *filename)
{
FILE *fp;
char buf[SCREEN_INC];
hist_alloc();
fp = fopen(filename, "r");
if (fp) {
H.Size = 0;
while (H.Size < el_hist_size) {
if (!fgets(buf, SCREEN_INC, fp))
break;
buf[strlen(buf) - 1] = 0; /* Remove '\n' */
add_history(buf);
}
fclose(fp);
return 0;
}
return errno;
}
int write_history(const char *filename)
{
FILE *fp;
hist_alloc();
fp = fopen(filename, "w");
if (fp) {
int i = 0;
while (i < H.Size) {
fprintf(fp, "%s\n", H.Lines[i++]);
}
fclose(fp);
return 0;
}
return errno;
#ifdef CONFIG_UNIQUE_HISTORY
if (H.Pos && strcmp(p, (char *) H.Lines[H.Pos - 1]) == 0)
return;
#endif
if (H.Size && strcmp(p, (char *) H.Lines[H.Size - 1]) == 0)
return;
hist_add((char *)p);
#endif
}
@@ -1250,7 +1201,7 @@ int write_history(const char *filename)
** Move back to the beginning of the current word and return an
** allocated copy of it.
*/
char *el_find_word(void)
static char *find_word(void)
{
char *p, *q;
char *new;
@@ -1293,12 +1244,12 @@ static el_status_t c_possible(void)
char *word;
int ac;
word = el_find_word();
word = find_word();
ac = rl_list_possib(word, &av);
if (word)
free(word);
if (ac) {
el_print_columns(ac, av);
columns(ac, av);
while (--ac >= 0)
free(av[ac]);
free(av);
@@ -1306,7 +1257,7 @@ static el_status_t c_possible(void)
return CSmove;
}
return el_ring_bell();
return ring_bell();
}
static el_status_t c_complete(void)
@@ -1317,7 +1268,7 @@ static el_status_t c_complete(void)
int unique;
el_status_t s = 0;
word = el_find_word();
word = find_word();
p = (char *)rl_complete((char *)word, &unique);
if (word)
free(word);
@@ -1340,7 +1291,7 @@ static el_status_t c_complete(void)
s = insert_string(new);
#ifdef CONFIG_ANNOYING_NOISE
if (!unique)
el_ring_bell();
ring_bell();
#endif
}
free(new);
@@ -1399,7 +1350,7 @@ static el_status_t exchange(void)
int c;
if ((c = tty_get()) != CTL('X'))
return c == EOF ? CSeof : el_ring_bell();
return c == EOF ? CSeof : ring_bell();
if ((c = rl_mark) <= rl_end) {
rl_mark = rl_point;
@@ -1419,7 +1370,7 @@ static el_status_t yank(void)
static el_status_t copy_region(void)
{
if (rl_mark > rl_end)
return el_ring_bell();
return ring_bell();
if (rl_point > rl_mark)
save_yank(rl_mark, rl_point - rl_mark);
@@ -1545,14 +1496,14 @@ static el_status_t last_argument(void)
int ac;
if (H.Size == 1 || (p = (char *)H.Lines[H.Size - 2]) == NULL)
return el_ring_bell();
return ring_bell();
if ((p = strdup(p)) == NULL)
return CSstay;
ac = argify(p, &av);
if (Repeat != NO_ARG)
s = Repeat < ac ? insert_string(av[Repeat]) : el_ring_bell();
s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell();
else
s = ac ? insert_string(av[ac - 1]) : CSstay;
@@ -1563,14 +1514,14 @@ static el_status_t last_argument(void)
return s;
}
static el_keymap_t Map[64] = {
static el_keymap_t Map[33] = {
{ CTL('@'), mk_set },
{ CTL('A'), beg_line },
{ CTL('B'), bk_char },
{ CTL('D'), del_char },
{ CTL('E'), end_line },
{ CTL('F'), fd_char },
{ CTL('G'), el_ring_bell },
{ CTL('G'), ring_bell },
{ CTL('H'), bk_del_char },
{ CTL('I'), c_complete },
{ CTL('J'), accept_line },
@@ -1578,13 +1529,13 @@ static el_keymap_t Map[64] = {
{ CTL('L'), redisplay },
{ CTL('M'), accept_line },
{ CTL('N'), h_next },
{ CTL('O'), el_ring_bell },
{ CTL('O'), ring_bell },
{ CTL('P'), h_prev },
{ CTL('Q'), el_ring_bell },
{ CTL('Q'), ring_bell },
{ CTL('R'), h_search },
{ CTL('S'), el_ring_bell },
{ CTL('S'), ring_bell },
{ CTL('T'), transpose },
{ CTL('U'), el_ring_bell },
{ CTL('U'), ring_bell },
{ CTL('V'), quote },
{ CTL('W'), bk_kill_word },
{ CTL('X'), exchange },
@@ -1592,12 +1543,12 @@ static el_keymap_t Map[64] = {
#ifdef SYSTEM_IS_WIN32
{ CTL('Z'), end_of_input },
#else
{ CTL('Z'), el_ring_bell },
{ CTL('Z'), ring_bell },
#endif
{ CTL('['), meta },
{ CTL(']'), move_to_char },
{ CTL('^'), el_ring_bell },
{ CTL('_'), el_ring_bell },
{ CTL('^'), ring_bell },
{ CTL('_'), ring_bell },
{ 0, NULL }
};
@@ -1621,40 +1572,31 @@ static el_keymap_t MetaMap[64]= {
{ 0, NULL }
};
static void el_bind_key_in_map(int key, el_keymap_func_t function, el_keymap_t map[], size_t mapsz)
void el_bind_key_in_metamap(char c, el_keymap_func_t func)
{
size_t i;
/* Add given function to key map for META keys */
int i;
for (i = 0; Map[i].Function != NULL; i++)
for (i = 0; MetaMap[i].Key != 0; i++)
{
if (map[i].Key == key)
if (MetaMap[i].Key == c)
{
map[i].Function = function;
MetaMap[i].Function = func;
return;
}
}
/* A new key so have to add it to end */
if (i == mapsz)
if (i == 63)
{
fprintf(stderr,"editline: failed binding key 0x%x, keymap full.\n", key);
fprintf(stderr,"editline: MetaMap table full, requires increase\n");
return;
}
map[i].Key = key;
map[i].Function = function;
map[i + 1].Function = NULL; /* Terminate list */
}
void el_bind_key(int key, el_keymap_func_t function)
{
el_bind_key_in_map(key, function, Map, ARRAY_ELEMENTS(Map));
}
void el_bind_key_in_metamap(int key, el_keymap_func_t function)
{
el_bind_key_in_map(key, function, MetaMap, ARRAY_ELEMENTS(MetaMap));
MetaMap[i].Function = func;
MetaMap[i].Key = c;
MetaMap[i + 1].Function = 0; /* Zero the last location */
MetaMap[i + 1].Key = 0; /* Zero the last location */
}
/**

View File

@@ -53,11 +53,8 @@
# include <sys/ioctl.h>
#endif
#define MEM_INC 64
#define SCREEN_INC 256
/* http://stackoverflow.com/questions/1598773/is-there-a-standard-function-in-c-that-would-return-the-length-of-an-array/1598827#1598827 */
#define ARRAY_ELEMENTS(arr) ((sizeof(arr)/sizeof(0[arr])) / ((size_t)(!(sizeof(arr) % sizeof(0[arr])))))
#define MEM_INC 64
#define SCREEN_INC 256
/*
** Variables and routines internal to this package.

View File

@@ -1,25 +0,0 @@
/* Editline system header file for OS-9 (on 68k).
*
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz. All rights reserved.
*
* This software is not subject to any license of the American Telephone
* and Telegraph Company or of the Regents of the University of California.
*
* Permission is granted to anyone to use this software for any purpose on
* any computer system, and to alter it and redistribute it freely, subject
* to the following restrictions:
* 1. The authors are not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits must appear in the documentation.
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits must appear in the documentation.
* 4. This notice may not be removed or altered.
*/
#define CRLF "\r\l"
#include <dir.h>
typedef struct direct DIRENTRY;

View File

@@ -1,65 +0,0 @@
/* OS-9 (on 68k) system-dependant routines for editline library.
*
* Copyright (c) 1992, 1993 Simmule Turner and Rich Salz. All rights reserved.
*
* This software is not subject to any license of the American Telephone
* and Telegraph Company or of the Regents of the University of California.
*
* Permission is granted to anyone to use this software for any purpose on
* any computer system, and to alter it and redistribute it freely, subject
* to the following restrictions:
* 1. The authors are not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits must appear in the documentation.
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits must appear in the documentation.
* 4. This notice may not be removed or altered.
*/
#include "editline.h"
#include <sgstat.h>
#include <modes.h>
void rl_ttyset(int Reset)
{
static struct sgbuf old;
struct sgbuf new;
if (Reset == 0) {
_gs_opt(0, &old);
_gs_opt(0, &new);
new.sg_backsp = 0; new.sg_delete = 0; new.sg_echo = 0;
new.sg_alf = 0; new.sg_nulls = 0; new.sg_pause = 0;
new.sg_page = 0; new.sg_bspch = 0; new.sg_dlnch = 0;
new.sg_eorch = 0; new.sg_eofch = 0; new.sg_rlnch = 0;
new.sg_dulnch = 0; new.sg_psch = 0; new.sg_kbich = 0;
new.sg_kbach = 0; new.sg_bsech = 0; new.sg_bellch = 0;
new.sg_xon = 0; new.sg_xoff = 0; new.sg_tabcr = 0;
new.sg_tabsiz = 0;
_ss_opt(0, &new);
rl_erase = old.sg_bspch;
rl_kill = old.sg_dlnch;
rl_eof = old.sg_eofch;
rl_intr = old.sg_kbich;
rl_quit = -1;
}
else {
_ss_opt(0, &old);
}
}
void rl_add_slash(char *path, char *p)
{
strcat(p, access(path, S_IREAD | S_IFDIR) ? " " : "/");
}
/**
* Local Variables:
* version-control: t
* indent-tabs-mode: t
* c-file-style: "ellemtel"
* c-basic-offset: 4
* End:
*/

View File

@@ -43,11 +43,9 @@ void rl_ttyset(int Reset)
new = old;
new.c_lflag &= ~(ECHO | ICANON | ISIG);
new.c_iflag &= ~INPCK;
if (rl_meta_chars)
new.c_iflag |= ISTRIP;
else
new.c_iflag &= ~ISTRIP;
new.c_iflag &= ~(ISTRIP | INPCK); /* | PARENB */
// new.c_cflag &= ~(CSIZE);
// new.c_cflag |= (CS8 | CLOCAL);
new.c_cc[VMIN] = 1;
new.c_cc[VTIME] = 0;
if (-1 == tcsetattr(0, TCSADRAIN, &new))
@@ -80,12 +78,9 @@ void rl_ttyset(int Reset)
new = old;
new.c_lflag &= ~(ECHO | ICANON | ISIG);
new.c_iflag &= ~INPCK;
if (rl_meta_chars)
new.c_iflag |= ISTRIP;
else
new.c_iflag &= ~ISTRIP;
new.c_iflag &= ~(ISTRIP | INPCK); /* | PARENB */
// new.c_cflag &= ~(CSIZE);
// new.c_cflag |= (CS8 | CLOCAL);
new.c_cc[VMIN] = 1;
new.c_cc[VTIME] = 0;
if (-1 == ioctl(0, TCSETAW, &new))
@@ -130,10 +125,9 @@ void rl_ttyset(int Reset)
new_sgttyb = old_sgttyb;
new_sgttyb.sg_flags &= ~ECHO;
new_sgttyb.sg_flags |= RAW;
if (rl_meta_chars)
new_sgttyb.sg_flags &= ~PASS8;
else
new_sgttyb.sg_flags |= PASS8;
#ifdef PASS8
new_sgttyb.sg_flags |= PASS8;
#endif
if (-1 == ioctl(0, TIOCSETP, &new_sgttyb))
perror("Failed TIOCSETP");
new_tchars = old_tchars;