NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Re: lib/48957 libedit/readline.c prompt bug
The following reply was made to PR lib/48957; it has been noted by GNATS.
From: "Simon J. Gerraty" <sjg%juniper.net@localhost>
To: Christos Zoulas <christos%zoulas.com@localhost>
Cc: <sjg%juniper.net@localhost>, <gnats-bugs%NetBSD.org@localhost>
Subject: Re: Re: lib/48957 libedit/readline.c prompt bug
Date: Thu, 7 Dec 2017 18:03:30 -0800
Christos Zoulas <christos%zoulas.com@localhost> wrote:
> The caller is supposed to deal with input inside rl_linefunc according
> to this:
>
> https://
Sorry stupid IT filter renders the url useless ;-)
> ...since the prompt gets printed before the read_char returns.
>
> Do you have code that reproduces the different behavior between readline
> and libedit? Because my example does not do it.
Using straight readline isn't a problem, its code using the callback
dance.
Below is a simple test app, that captures the essence of what Python's
readline extension does (started from cpp output from that ;-)
When linked with real readline Python behaves ok.
With libedit/readline it looks like:
Python 2.7.8 (default, Dec 6 2017, 13:52:53)
[GCC 4.2.1 Compatible Juniper Clang 3.7.1
(git%psd-tools-git01.juniper.net@localhost:tool on junos
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hi'
>>> hi
print 'there'
>>> there
^D
which is broken.
I added the original copyright back to keep our lawyers happy ;-)
/*
* This test case is derrived from pre-processed output of
* python's readline extension - expecting to use gnu readline
* so we keep the original copyright...
* I have removed all the Py* and anything else that wasn't necessary
* to reproduce the prompt bug (prompt being issued before
* call_readline returns)
* with libedit/readline as currently in NetBSD and FreeBSD we see:
*
* >>> print 'hi'
* >>> hi
* print 'there'
* >>> there
*
* rather than:
*
* >>> print 'hi'
* hi
* >>> print 'there'
* there
* >>>
*/
/* This module makes GNU readline available to Python. It has ideas
* contributed by Lee Busby, LLNL, and William Magro, Cornell Theory
* Center. The completer interface was inspired by Lele Gaifax. More
* recently, it was largely rewritten by Guido van Rossum.
*/
#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <edit/readline/readline.h>
#include <edit/readline/history.h>
static char *completer_word_break_characters;
static int _history_length = -1;
static void
setup_readline(void)
{
using_history();
rl_readline_name = "python";
rl_bind_key('\t', rl_insert);
rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap);
rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap);
completer_word_break_characters =
rl_completer_word_break_characters =
strdup(" \t\n`~!@#$%^&*()-=+[{]}\\|;:'\",<>/?");
rl_initialize();
}
static char *completed_input_string;
static void
rlhandler(char *text)
{
completed_input_string = text;
rl_callback_handler_remove();
}
static char *
readline_until_enter_or_signal(char *prompt, int *signal)
{
char * not_done_reading = "";
fd_set selectset;
*signal = 0;
rl_callback_handler_install (prompt, rlhandler);
FD_ZERO(&selectset);
completed_input_string = not_done_reading;
while (completed_input_string == not_done_reading) {
int has_input = 0;
while (!has_input)
{ struct timeval timeout = {0, 100000};
FD_SET(0, &selectset);
has_input = select(2, &selectset, NULL, NULL, &timeout);
}
if(has_input > 0) {
rl_callback_read_char();
}
}
return completed_input_string;
}
static char *
call_readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
{
static int once;
size_t n;
char *p, *q;
int signal;
HIST_ENTRY *he;
if (sys_stdin != rl_instream || sys_stdout != rl_outstream) {
rl_instream = sys_stdin;
rl_outstream = sys_stdout;
rl_prep_terminal (1);
}
p = readline_until_enter_or_signal(prompt, &signal);
if (signal) {
return ((void *)0);
}
if (p == ((void *)0)) {
return p;
}
n = strlen(p);
return p;
}
int
main(int argc, char *argv[])
{
char *cp;
setup_readline();
while ((cp = call_readline(stdin, stdout, ">>> "))) {
printf("read: '%s'\n", cp);
}
return 0;
}
Home |
Main Index |
Thread Index |
Old Index