Giter VIP home page Giter VIP logo

editline's Introduction

Editline

License Badge Travis Status Coverity Status

Table of Contents

Introduction

This is a small line editing library. It can be linked into almost any program to provide command line editing and history functions. It is call compatible with the FSF readline library, but at a fraction of the size, and as a result fewer features. It is also distributed under a much more liberal License.

The small size (<30k), lack of dependencies (ncurses not needed!), and the free license should make this library interesting to many embedded developers.

Editline has several optional build-time features that can be enabled by supplying different options to the GNU configure script. See the output from configure --help for details. Some useful hints on how to use the library is available in the examples/ directory.

Editline is maintained collaboratively at GitHub.

Note: Windows is not a supported target for editline.

Example

Below is a very brief example to illustrate how one can use Editline to create a simple CLI, Ctrl-D exits the program. A slightly more advanced example is Jush, https://github.com/troglobit/jush/, a small and very simplistic UNIX shell. The Editline sources also include an examples/ sub-directory.

  1. Build and install the library, preferably using a release tarball The configure script defaults to a /usr/local prefix.

     tar xf editline-1.15.3.tar.xz
     cd editline-1.15.3/
     ./configure --prefix=/usr
     make all
     sudo make install
    
  2. Place the below source code in a separate project directory, e.g. ~/src/example.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <editline.h>

    int main(void)
    {
        char *p;

        while ((p = readline("CLI> ")) != NULL) {
            puts(p);
            free(p);
        }

        return 0;
    }
  1. Compile the example:

     cd ~/src/
     make LDLIBS=-leditline example
    

Here I use make and rely on its implicit (built-in) rules to handle all the compiler magic, but you may want to create your own Makefile for the project. In particular if you don't change the default prefix (above), because then you need to specify the search path for the include file(s) and the library manually.

A simple ~/src/Makefile could look like this:

CFLAGS    = -I/usr/local/include
LDFLAGS   = -L/usr/local/lib
LDLIBS    = -leditline
EXEC      = example
OBJS      = example.o

all: $(EXEC)

$(EXEC): $(OBJS)

clean:
        $(RM) $(OBJS) $(EXEC)

distclean: clean
        $(RM) *.o *~ *.bak

Then simply type make from your ~/src/ directory. You can also use pkg-config for your ~/src/Makefile, replace the following lines:

CFLAGS    = $(shell pkg-config --cflags libeditline)
LDFLAGS   = $(shell pkg-config --libs-only-L libeditline)
LDLIBS    = $(shell pkg-config --libs-only-l libeditline)

Then simply type make, like above.

However, most .rpm based distributions pkg-config doesn't search in /usr/local anymore, so you need to call make like this:

PKG_CONFIG_LIBDIR=/usr/local/lib/pkgconfig make

Debian/Ubuntu based systems do not have this problem.

API

Here is the libeditline interfaces. It has a small compatibility layer to FSF readline, which may not be entirely up-to-date.

    /* Editline specific global variables. */
    int         el_no_echo;   /* Do not echo input characters */
    int         el_no_hist;   /* Disable auto-save of and access to history,
                               * e.g. for password prompts or wizards */
    int         el_hist_size; /* Size of history scrollback buffer, default: 15 */
    
    /* Editline specific functions. */
    char *      el_find_word     (void);
    void        el_print_columns (int ac, char **av);
    el_status_t el_ring_bell     (void);
    el_status_t el_del_char      (void);
    
    /* Callback function for key binding */
    typedef el_status_t el_keymap_func_t(void);
    
    /* Bind key to a callback, use CTL('f') to change Ctrl-F, for example */
    el_status_t el_bind_key            (int key, el_keymap_func_t function);
    el_status_t el_bind_key_in_metamap (int key, el_keymap_func_t function);
    
    /* For compatibility with FSF readline. */
    int         rl_point;
    int         rl_mark;
    int         rl_end;
    int         rl_inhibit_complete;
    char       *rl_line_buffer;
    const char *rl_readline_name;
    
    void (*rl_deprep_term_function)(void);
    void rl_deprep_terminal (void);
    void rl_reset_terminal  (const char *terminal_name);

    void rl_initialize   (void);
    void rl_uninitialize (void);                         /* Free all internal memory */

    void rl_save_prompt    (void);
    void rl_restore_prompt (void);
    void rl_set_prompt     (const char *prompt);
    
    void rl_clear_message         (void);
    void rl_forced_update_display (void);

    /* Main function to use, saves history by default */
    char *readline    (const char *prompt);

    /* Use to save a read line to history, when el_no_hist is set */
    void add_history  (const char *line);
    
    /* Load and save editline history from/to a file. */
    int read_history  (const char *filename);
    int write_history (const char *filename);
    
    /* Magic completion API, see examples/cli.c for more info */
    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);
    
    /* Alternate interface to plain readline(), for event loops */
    void rl_callback_handler_install (const char *prompt, rl_vcpfunc_t *lhandler);
    void rl_callback_read_char       (void);
    void rl_callback_handler_remove  (void);

Build & Install

Editline was originally designed for older UNIX systems and Plan 9. The current maintainer works exclusively on GNU/Linux systems, so it may use GCC and GNU Make specific extensions here and there. This is not on purpose and patches or pull requests to correct this are most welcome!

  1. Call ./autogen.sh if you build from git
  2. Configure editline with default features: ./configure
  3. Build the library and examples: make all
  4. Install using make install

The $DESTDIR environment variable is honored at install. For more options, see ./configure --help

Remember to run ldconfig after install to update the linker cache. If you've installed to a non-standard location (--prefix) you may also have to update your /etc/ld.so.conf, or use pkg-confg to build your application (above).

NOTE: RedHat/Fedora/CentOS and other .rpm-based distributions do not consider /usr/local as standard path anymore. So make sure to ./configure --prefix=/usr, otherwise the build system use the GNU default, which is /usr/local. The Debian based distributions, like Ubuntu, do not have this problem.

Origin & References

This line editing library was created by Rich Salz and Simmule Turner and in 1992. It is distributed with a “C News-like” license, similar to the BSD license. Rich's current version is however under the Apache license. For details on the licensing terms of this version of the software, see License.

This version of the editline library was forked from the Minix 2 source tree and is not related to the similarily named NetBSD version that Jess Thrysøe disitributes to the world outside *BSD. The libraries have much in common, but the latter is heavily refactored and also relies on libtermcap (usually supplied by ncurses), whereas this library only uses termios from the standard C library.

Patches and bug fixes from the following forks, based on the original comp.sources.unix posting, have been merged:

The version numbering scheme today follows that of the Debian version, details available in the ChangeLog.md. The current maintainer was unaware of the Debian version for quite some time, so a different name and versioning scheme was used. In June 2009 this was changed to line up alongside Debian, with the intent is to eventually merge the efforts.

Outstanding issues are listed in the TODO.md file.

editline's People

Contributors

abitmore avatar al20878 avatar c0deh4cker avatar cfischer1967 avatar cogutvalera avatar dtzwill avatar dvolynets avatar jakubpawlo avatar jmjatlanta avatar lnl7 avatar mattiaswal avatar mlundh avatar nobody5050 avatar oxalica avatar rcombs avatar rofl0r avatar tejing1 avatar the-king-of-toasters avatar tobygoodwin avatar trofi avatar troglobit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

editline's Issues

README: slightly incorrect statement about netbsd libedit dependencies

( refering to the sentence "The libraries have much in common, but the latter is heavily refactored and also relies on ncurses, whereas this library only uses termios from the standard C library." in README)

at least the libedit version used in sabotage linux, worked fine when linked against stallmann's original termcap library (before i changed the package to use netbsd's curses[0] instead): sabotage-linux/sabotage@9b3107c

[0] https://github.com/sabotage-linux/netbsd-curses

How to bind Ctrl + W to delete word backwards?

I am using the mysql client from which comes with editLine in my distribution:

$ mysql --version
mysql  Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using  EditLine wrapper

I would not mind if it was a in-place replacment behaving similar to readline. Yet certain emac-like keybindings from readline, I am very much used to, don't work anymore, breaking my habitual workflow.

I am very much used to delete the last word by Ctrl + W. Yet via editline, it deletes to the beginning of the line instead just one word back.

I tried adding .editrc with the content:

bind ^W backward-delete-word

Yet it doesn't work.

How can I bind keys to my liking, and how can I get Ctrl + W to delete one word backwards?

No file name configure.

I normally don't still things from github, and I'm sorry if the answer is too obvious. But after cloning, and cd-ing into the editline folder on Fedora I tried the first step. After doing a find for this file in other folders, still nothing.

Request for \1 and \2 (RL_PROMPT_START_IGNORE, RL_PROMPT_END_IGNORE) support

Editline currently uses a "one byte per column" heuristic, and one way that breaks down is when it encounters colored prompts. The way readline (and libedit) handles this issue is by having the program tell it what parts of the prompt don't count into the width calculation: \1 (RL_PROMPT_START_IGNORE) starts the width-ignore area and \2 (RL_PROMPT_END_IGNORE) ends it.

See https://github.com/cdesjardins/libedit/search?q=RL_PROMPT_START_IGNORE for how it works in NetBSD libedit.

Does not compile cleanly

I tried to build this library with GCC 11 on Cygwin just now, and it does not compile cleanly:

In file included from editline.c:23:
editline.c: In function 'do_case':
editline.c:497:29: warning: array subscript has type 'char' [-Wchar-subscripts]
  497 |                 if (islower(*p))
      |                             ^~
editline.c:499:32: warning: array subscript has type 'char' [-Wchar-subscripts]
  499 |             } else if (isupper(*p)) {
      |                                ^~
editline.c: In function 'argify':
editline.c:1878:28: warning: array subscript has type 'char' [-Wchar-subscripts]
 1878 |     for (c = line; isspace(*c); c++)
      |                            ^~
editline.c:1885:22: warning: array subscript has type 'char' [-Wchar-subscripts]
 1885 |         if (!isspace(*c)) {
      |                      ^~
  CC       libeditline_la-complete.lo
In file included from complete.c:23:
complete.c: In function 'rl_find_token':
complete.c:281:35: warning: array subscript has type 'char' [-Wchar-subscripts]
  281 |         if (isspace(rl_line_buffer[pos])) {
      |                     ~~~~~~~~~~~~~~^~~~~
complete.c:289:47: warning: array subscript has type 'char' [-Wchar-subscripts]
  289 |     while (pos >= 0 && !isspace(rl_line_buffer[pos])) {
      |                                 ~~~~~~~~~~~~~~^~~~~

A "char" subscript can actually be a big deal for characters with the 8th bit set (will get converted to a negative "int"), so the warnings do not look great.
Any chance you can fix these please (e.g. by adding explicit (unsigned char) casts where necessary)?
Thanks.

P.S. BTW the "Build & Install" instructions in README.md call for running configure but it is not provided in the source tree if cloned directly from github, and it looks like autogen.sh needs to be executed first in order to actually build configure -- but that step is missing entirely from the instructions.

missing functions to use editline as drop-in replacement for readline with gdb 7.6

gdb 7.6 seems to be the most elaborate readline user in sabotage linux, but it can be tricked, to link against libedit instead of readline, and i hoped as well against editline...

Here's a list of missing functions:

  • undefined reference to `history_base'
  • undefined reference to `history_expand'
  • undefined reference to `history_get'
  • undefined reference to `history_is_stifled'
  • undefined reference to `history_length'
  • undefined reference to `max_input_history'
  • undefined reference to `rl_add_defun'
  • undefined reference to `rl_already_prompted'
  • undefined reference to `rl_callback_handler_install'
  • undefined reference to `rl_callback_handler_remove'
  • undefined reference to `rl_callback_read_char'
  • undefined reference to `rl_completer_quote_characters'
  • undefined reference to `rl_completer_word_break_characters'
  • undefined reference to `rl_completion_entry_function'
  • undefined reference to `rl_completion_word_break_hook'
  • undefined reference to `rl_filename_completion_function'
  • undefined reference to `rl_get_previous_history'
  • undefined reference to `rl_get_screen_size'
  • undefined reference to `rl_newline'
  • undefined reference to `rl_pre_input_hook'
  • undefined reference to `rl_redisplay'
  • undefined reference to `rl_set_screen_size'
  • undefined reference to `rl_terminal_name'
  • undefined reference to `stifle_history'
  • undefined reference to `tilde_expand'
  • undefined reference to `unstifle_history'
  • undefined reference to `where_history'

Support for Latin-1?

Is it possible editline only supports UTF8?

As you may know, mysql now only supports editline and this causes problems with german umlaut characters on systems with LC_CTYPE=de_DE or de_DE.iso88591 instead of de_DE.utf8

fileman.c example. Error free(): double free detected in tcache 2

Error Description

So I'm using rl_attempted_completion_function to add my own keyword completion, but ever since that the filepath completion doesn't work as expected, it will crash with free(): double free detected in tcache 2. I thought it was my problem, so I tried the fileman.c given in the example, but it ended up the same.
Comment out the binding to rl_attempted_completion_function, then it will work normally. So I guess there's something wrong with executing that function.

How to trigger

If you input ./ <tab>, then it will crash, but if you quote the path it works, e.g "/usr <tab>, it will show /usr/lib.

Sysinfo

System: Lubuntu 20.04
GCC Version: 9.3.0

The process that uses editline does not respect CTRL+Z

When I press CTRL+Z to suspend the process that runs editline (I'm in Linux), it doesn't react. FYI, when using the readline library everything works as expected (i.e. the process would have been suspended and the prompt returns to the terminal). How can this be fixed? Thanks!

Completion functions returning strings containing tabs or spaces display incorrectly

In a project of mine, I wrote a completer function that does only return strdup("\t"); (to disable completion of filenames, which are meaningless for my project). However, this prints ^I instead of a tab as it should. When I try to return something like strdup("hello world"), it prints hello\ world instead. I assume that the issue is due to the very questionable implementation of CTL() and META(). It seems to me that the proper way of doing this is to use a type larger than a char, where the modifers are stored in higher bits. Of course this will require changing the public interface to libeditline, so maybe the current functions should be deprecated (but still remain), and new, proper functions should be added.

I just did some digging and found out that the string returned from my completer function is passed to insert_string(), which passes it to tty_string(), and then each character goes to tty_show(), which does use the ISCTL() and ISMETA() macros to incorrectly convert a tab into ^I. Also, it is line 1385 of editline.c which adds a newline before spaces. No idea why it does that though.

strdup implementation has off-by-one error

In src/sysunix.c there is this:

#ifndef HAVE_STRDUP
/* Return an allocated copy of a string. */
char *strdup(const char *p)
{
    char *new = malloc(sizeof(char) * strlen(p));

This forgets to malloc the terminating NUL for the string and causes undefined behavior for the subsequent strcpy.

This should be

malloc(strlen(p) + 1);

Note that multiplying by sizeof(char) is considered silly, since it is 1 by definition in the C Standard.

Usage with an external event loop

I am looking for a line editing library that I can use together with an event loop. That means no blocking readline function and no direct access to stdin.
Instead, I would call readline() with one or more the user pressed, readline should process these keys and return.
Is this possible with editline, or if not, could you give an estimate on how much work it would be to implement something like this?

Cannot find sgstat.h or modes.h.

This is not an issue with the compilation of the library, more of an issue with that I cannot find where these headers reside, I cannot find much information about them, but it compiles perfectly fine.

#include <sgstat.h>
#include <modes.h>

Prompt not displayed on non-interactive sessions, inconsistent with GNU readline

On editline-1.17.1:

co/nix » echo '1+1' | LD_PRELOAD=result/lib/libreadline.so nix repl --quiet | cat
nix-repl> 1+1
2


co/nix » echo '1+1' | nix repl --quiet | cat
Failed tcsetattr(TCSADRAIN): Inappropriate ioctl for device
Failed tcsetattr(TCSADRAIN): Inappropriate ioctl for device
2

Confirmed by inspection of the code: when !isatty(), prompts aren't printed.

rl_point is always zero

I try to use alternative API

/* For wcwidth() */
#define _XOPEN_SOURCE 700

#include <locale.h>
#include <ncurses.h>
#include <editline/readline.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>

int kurzor;

static int		readline_proxy;
static bool		readline_proxy_is_valid = false;
char   *string = NULL;

/*
 * Zkopiruje znak z proxy do readline
 */
static int
readline_getc(FILE  *dummy)
{
	readline_proxy_is_valid = false;
	return readline_proxy;
}

/*
 * Touto funkci readline predava vysledek editace
 */
static void
readline_callback(char *line)
{
	free(string);
	string = NULL;

	if (line)
		string = strdup(line);


}

/*
 * Chceme mit zobrazeni ve vlastni rezii
 */
static void
readline_redisplay()
{
	/* do nothing here */
}

/*
 * Vrati (zobrazovaci) sirku retezce.
 */
static size_t
strnwidth(const char *s, size_t n)
{
	mbstate_t shift_state;
	wchar_t wc;
	size_t wc_len;
	size_t width = 0;
	size_t ch_width;

	memset(&shift_state, '\0', sizeof shift_state);

	for (size_t i = 0; i < n; i += wc_len)
	{
		wc_len = mbrtowc(&wc, s + i, MB_CUR_MAX, &shift_state);
		if (!wc_len)
			return width;

		if ((wc_len == (size_t) -1) || (wc_len == (size_t) -2))
			return width + strnlen(s + i, n - i);

		if (iswcntrl(wc))
			width += 2;
		else if ((ch_width = wcwidth(wc)) > 0)
			width += ch_width;
    }

    return width;
}

int
main()
{
	int		c = 0;
	bool	alt = false;
	char   *prompt = ": ";

	setlocale(LC_ALL, "");

	initscr();
	cbreak();
	noecho();

	/* ENTER neni \n */
	nonl();

	/*
	 * readline vyzaduje neprekodovany vstup tj
	 * vypnuty keypad a cteni vice bajtovych
	 * znaku po bajtech (emuluje se binarni
	 * cteni ze souboru v aktualnim kodovani)
	 */
	keypad(stdscr, FALSE);

	/*
	 * Instalace hooku - pokud se pouzije rl_getc_function,
	 * tak by se mel VZDY pouzit i rl_input_available_hook.
	 */
	rl_getc_function = readline_getc;
	rl_redisplay_function = readline_redisplay;

	/*
	 * Nechceme obsluhu signalu v readline, a nechceme tab
	 * complete (neni nakonfigurovano, hrozi pady.
	 */
	rl_catch_signals = 0;
	rl_catch_sigwinch = 0;
	rl_inhibit_completion = 0;

	/* Zahajeni editace */
	rl_callback_handler_install(prompt, readline_callback);

	/* Vlozi vychozi (default) text */
	rl_insert_text("Editaci ukonci 2x stisk ESCAPE");

	while (1)
	{
		int		cursor_pos;

		clear();

		mvaddstr(10, 10, rl_prompt);
		addstr(rl_line_buffer);

		if (string)
		{
			mvaddstr(12, 6, "text: ");
			attron(A_REVERSE);
			addstr(string);
			attroff(A_REVERSE);
		}

		/* nastav kurzor */
		cursor_pos = strnwidth(rl_prompt, SIZE_MAX) +
					 strnwidth(rl_line_buffer, rl_point);
		move(10, 10 + cursor_pos);

		refresh();

		get_wch(&c);

		/* ignoruj tabelatory */
		if (c == '\t')
			continue;

		if (c == 27)
		{
			if (alt)
				break;
			else
				alt = true;
		}
		else
			alt = false;

		readline_proxy = c;
		readline_proxy_is_valid = true;

		/* posli echo readline, ze jsou nova data k precteni */
		rl_callback_read_char();
	}

	rl_callback_handler_remove();

	endwin();
}

I am able to build this example, but the variables rl_point and rl_end are always zero. Unfortunately editline doesn't decode cursor keys or other control keys.

Is this functionality supported? I try to use editline from ncurses application.

tested on FC34

Name         : editline
Version      : 1.17.1
Release      : 3.fc34
Architecture : x86_64
Size         : 28 k
Source       : editline-1.17.1-3.fc34.src.rpm
Repository   : fedora
Summary      : A small compatible replacement for readline
URL          : https://troglobit.com/projects/editline/
License      : HSRL
Description  : This is a line editing library for UNIX. It can be linked into almost
             : any program to provide command line editing and history. It is call
             : compatible with the FSF readline library, but is a fraction of the
             : size (and offers fewer features).

Request for UTF-8 support

Any idea if UTF support can be added to this lib?
Preferably without depending on locale stuff from glibc

How to call function 'el_bind_key'

Using the readline library, one can have this rl_bind_key('\t', rl_insert); which disables readline from displaying files that exist on the current working directory when the user presses TAB.

I am now trying to get ride of readline and use the editline library instead. I found out function el_bind_key (which looks like it's the replacement for function rl_bind_key) but not sure how the second parameter of this function should look like.

Basically, I want to disable editline displaying files that exist on the current working directory when the user presses TAB.

Feature request: able to gracefully end readline() from another thread

When readline() is running in a thread waiting for input from tty, terminal is prepped, the function blocks until got an "end" (e.g. EOL, EOF, SIGINT or etc) from tty. In case when another thread decided to no longer accept input from tty (e.g. timeout or got a signal from outside), we need a way to gracefully end readline() and restore terminal, rather than waiting for an end. We can't forcefully end the thread because terminal won't be restored.

Run with mpi

I use editline with mpi and have the loop in rank 0. Everything seems OK except the prompt message.

Does editline support context specific auto-complete?

Hi
I've just been looking at this library for use in a simple CLI application.
I see that there is some support for supplying custom auto-complete functions so that (for example) the application can auto-complete commands from a fixed set of command names.
When I try out the example cli application, I see that auto-complete searches the same list with each and every argument.
What I'd like to do is vary the auto-complete function depending on the arguments already entered by the user so that (for example) auto-completing the second argument in a command searches one list if the first argument is 'a', and a different list if the first argument is 'b'.
Is this possible out of the box with this library? Is there a way to obtain the arguments already entered so that auto-complete can be made more context specific?
Thanks

undocumented dependency on libtermcap

checking termcap.h usability... no                                              
checking termcap.h presence... no                                               
checking for termcap.h... no                                                    
checking for termio.h... no                                            
checking for termios.h... yes                                          
...
make[2]: Entering directory `/src/build/editline/editline-1.15.1/examples'
libtool: link: gcc -I../src -I../include -fdata-sections -ffunction-sections -Os ...
/bin/ld: cannot find -ltermcap                                                  

and with --disable-termcap:

 libtool: link: gcc -I../src -I../include -fdata-sections -ffunction-sections -Os
../src/.libs/libeditline.a(editline.o): In function `rl_reset_terminal':        
editline.c:(.text.rl_reset_terminal+0x57): undefined reference to `tgetent'     
editline.c:(.text.rl_reset_terminal+0x68): undefined reference to `tgetstr'     
editline.c:(.text.rl_reset_terminal+0x8d): undefined reference to `tgetnum'     
editline.c:(.text.rl_reset_terminal+0x9d): undefined reference to `tgetnum'     
collect2: error: ld returned 1 exit status                                 

Prompt not redisplayed after displaying completion possibilities

I have a simple application that uses editline v1.17.1, and returns 4 possible completions on the empty string.

The 4 completions are displayed correctly, however the prompt is not re-displayed, ending up with this:

Run cli:

(device) [email protected] /> 

Press tab once, you get 4 completions as expected, but no redisplay of the prompt:

(device) [email protected] /> 
services  system    exit      quit

Type 's' followed by tab, and you get 2 completions as expected, but no redisplay of prompt, and the 's' character appears twice:

(device) [email protected] /> 
services  system    exit      quit
s
services  system
ss

Type 'e' followed by tab, giving you the unique option 'services'. This is displayed, but the prompt is still missing, and we still have a stray s:

(device) [email protected] /> 
services  system    exit      quit
s
services  system
sservices 

Press 'enter' despite the corrupt prompt, and the line is returned correctly and the prompt redisplayed:

(device) [email protected] /> 
services  system    exit      quit
s
services  system
sservices 
(device) [email protected] /services> 

The prompt is "(device) %s@%s /%s> " and contains no special characters.

Is this a known issue?

Apple Terminal on Big Sur, cli running on CentOS8.

Address sanitizer reports error

Hi,
I am using editline in a project where I am also enabling address sanitizer. I get a buffer overrun error in completion.c:203. I am not quite sure what the correct way of fixing the issue is, but it seems as the memcpy is trying to read beyond the allocated memory in the av[0] array. Reducing the size of the copy (+1 instead of +2 on line 200) resolves that particular issue, but I can not guarantee that it will not break anything else.

Inclusion in a debian repository

Currently Debian distributes what it seems to be a very old version in comparison (1.12), based solely in the version numbering and release date, I believe is one of the original sources that was merged, based in the readme description. Is there any particular reason why is that? Given that the required build files for such package are already part of this repo (and they do work, recently tested in debian bullseye), is it just a matter of coordination with a debian maintainer? Or is there something else?.

Personally I have a particular interest in this package because is a dependency of Nix and the packaging effort of nix in debian would benefit itself by having a recent editline in the official repos, currently they have opted for trying to implement readline support in nix PR1/merged PR2/pending instead of packaging this library. At this time, Nix doesn't have the autocomplete functionality for the readline build option and it seems that the the Nix maintainers are even reconsidering the idea of allowing the extra option to support readline and stick only to editline.

Not sure if this is the best place to get more context. But I suppose it would be better to have this discussion in some place that can be publicly found for any future reference.

Thanks.

Segmentation violation

This shows up on macOS 10.13 (and maybe others).

editline/src/editline.c

Lines 178 to 182 in 534b389

Screen[ScreenCount] = c;
if (++ScreenCount > ScreenSize) {
ScreenSize += SCREEN_INC;
Screen = realloc(Screen, sizeof(char) * ScreenSize);
}

I believe the realloc should happen before the character is added to the array. Once I made that change, the SIGSEV went away.

Note: The array of items to display had 122 entries, longest 46 (3 columns).

Update: After taking another look, changing the > to a >= will do the trick.

Example Step 2 needs header file <stdio.h>

#include <stdlib.h>
#include <stdio.h> // This line should put before #include <editline.h>, or it will be failed to compile.
#include <editline.h>

int main(void)
{
    char *p;
    while ((p = readline("CLI> ")) != NULL) {
        puts(p);
        free(p);
    }

    return 0;
}

without #include <stdio.h>, the error message

$ g++ test.cc -I$HOME/mylib/include -L$HOME/mylib/lib -leditline

/mylib/include/editline.h:87:8: error: ‘FILE’ does not name a type
extern FILE       *rl_instream;  /* The stdio stream from which input is read. Defaults to stdin if NULL - Not supported yet! */
        ^~~~
In file included from test.cc:3:0:
mylib/include/editline.h:88:8: error: ‘FILE’ does not name a type
extern FILE       *rl_outstream; /* The stdio stream to which output is flushed. Defaults to stdout if NULL - Not supported yet! */

test.cc: In function ‘int main()’:
test.cc:10:9: error: ‘puts’ was not declared in this scope
         puts(p);
         ^~~~

Can you state in the source it's licensed under Apache-2.0?

It seems LICENSE is completely custom and similar to Zlib License.
README says:

  • This line editing library was created by Rich Salz and Simmule Turner and in 1992. It is distributed with a “C News-like” license, similar to the BSD license. Rich's current version is however under the Apache license. For details on the licensing terms of this version of the software, see License.
 Copyright 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.

But the text does not resemble Apache-1.0, Apache-1.1, Apache-2.0.

Please, can you state clearly it's licensed under Apache-2.0? Maybe update LICENSE file?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.