with the trailing newline, others don't so don't make any assumptions
about it when printing. Also print the correct event number (generated),
separate the event number from the event with a tab, and visually encode
the string (don't encode tabs and spaces though).
For example if you do
$mkdir -p /tmp/dir1/dir2
Then:
$ls /tmp/di <TAB> auto completes to
$ls /tmp/dir1/
Hitting <TAB> again auto completes to
$ls /tmp/dir1/dir2
Whereas it should auto complete to
$ls /tmp/dir1/dir2/
Essentially, in cases like above where you have to hit <TAB> twice to get
to the match and there is only one match (because only one file/sub-directory) then
auto complete doesn't work correctly. It doesn't append a trailing slash (in case
of directory) or a space (in case of a file) to the match name.
I have tested file name completion in sh(1) and symbol completion in gdb after
this change.
In libedit, the only way how H_ENTER can fail is memory exhaustion,
too, and of course it is handled gracefully, returning -1 from
history(). So of course, we will continue to handle it gracefully
in add_history() as well, but we are free to decide what to do with
the library state in this case because GNU just dies...
I think the most reasonable course of action is to simply not change
the library state in any way when add_history() fails due to memory
exhaustion, but just return.
If H_ENTER does not fail, we know that the history now contains at
least one entry, so there is no need any longer to check the H_GETSIZE
return value. And we can of course always set current_history_valid.
While testing these changes, i noticed three problems so closely
related that i'd like to fix them in the same diff.
1. libedit has the wrong prototype for add_history().
GNU readline-6.3 defines it as void add_history(const char *).
Of course, that is very stupid - no way to report problems to
the caller! But the whole point of a compatibility mode is
being compatible, so we should ultimately change this.
Of course, changing the prototype of a public symbol requires
a libedit major bump. I don't want to do that casually.
Rather, i will take a note and change the prototype the next
time we need a libedit major bump for more important reasons.
For now, let's just always return 0.
2. While *implicitely* pushing an old entry off the history
increments history_base in GNU readline, testing reveals that
*explicitly* deleting one does not. Again, this is not
documented, but it applies to both remove_history() and
stifle_history(). So delete history_base manipulation
from stifle_history(), which also allows to simplify the
code and delete two automatic variables.
3. GNU readline add_history(NULL) crashes with a segfault.
There is nothing wrong with having a public interface
behave that way. Many standard interfaces do, including
strlen(3). Such crashes can even be useful to catch
buggy application programs.
In libedit/readline.c rev. 1.104, Christos made add_history()
silently ignore this coding error, according to the commit
message to hide a bug in nslookup(1). That change was never
merged to OpenBSD. I strongly disagree with this change.
If nslookup(1) is still broken, that program needs to be
fixed instead. In any case, delete the bogus check; hiding
bugs is dangerous.
Reduce obfuscation of errno handling. There is only one purpose
non-local errno handling is needed for: Inside el_wgets(), several
functions call down indirectly to el_wgetc(), many of them via the
dispatch table. When el_wgetc() fails, it does properly report
failure, but then various cleanup is done which may clobber errno.
But when returning due to failure, el_wgets() wants to have errno
set to the reason of the original read failure, not to the reason
of some subsequent failure of some cleanup operation. So el_wgetc()
needs to save errno, and if it's non-zero, el_wgets() needs to
restore it on failure.
This core logic is currently obscured by the fact that el_errno
is set and inspected at some additional places where it isn't needed.
Besides, since el_wgetc() and and el_wgets() are both in read.c,
el_errno does not need to be in struct editline, it can and should
be local to read.c in struct el_read_t.
Let's look at what can be simplified.
1. keymacro_get() abuses el_errno instead of having a proper
error return code. Adding that error return code is easy
because node_trav() already detects the condition and an
adequate code is already defined. Returning it, testing
for it in read_getcmd(), and returning with error from there
removes the need to inspect el_errno from el_wgets() after
calling read_getcmd().
Note that resetting lastchar and cursor and clearing buffer[0]
is irrelevant. The code returns from el_wgets() right afterwards.
Outside el_wgets(), these variables are no longer relevant.
When el_wgets() is called the next time, it will call ch_reset()
anyway, resetting the two pointers. And as long as lastchar
points to the beginning of the buffer, the contents of the
buffer won't be used for anything.
2. read_getcmd() doesn't need to set el_errno again after el_wgetc()
failure since el_wgetc() already did so. While here, remove
the silly "if EOF or error" comments from the el_wgetc()
return value tests. It's a public interface documented in a
manual, so people working on the implementation can obviously
be expected to know how it works. It's a case of
count++; /* Increment count. */
3. In the two code paths of el_wgets() that lead up to "goto noedit",
there is no need to save the errno because nothing that might
change it happens before returning.
For clarity, since el_wgets() is the function restoring the errno,
also move initializing it to the same function.
Finally, note that restoring errno when the saved value is zero is
wrong. No library code is ever allowed to clear a previously set
value of errno. Only application programs are allowed to do that,
and even they usually don't need to do so, except when using certain
ill-designed interfaces like strtol(3).
I tested that the behaviour remains sane in the following cases,
all during execution of el_wgets(3) and with a signal handler
for USR1 installed without SA_RESTART.
* Enter some text and maybe move around a bit.
Then send a USR1 signal.
The signal gets processed, then read_char() resumes reading.
Send another USR1 signal.
Now el_wgets() sets errno=EINTR and returns -1.
* Press Ctrl-V to activate ed-quoted-insert.
Then send a USR1 signal.
The signal gets processed, then read_char() resumes reading.
Send another USR1 signal.
ed_quoted_insert() returns ed_end_of_file(), i.e. CC_EOF,
and el_wgets() returns 0.
* Press a key starting a keyboard macro.
Then send a USR1 signal.
The signal gets processed, then read_char() resumes reading.
Send another USR1 signal.
Now el_wgets() sets errno=EINTR and returns -1.
* Press : to enter builtin command mode.
Start typing a command.
Then send a USR1 signal.
The signal gets processed, then read_char() resumes reading.
Send another USR1 signal.
Now c_gets() returns -1, ed_command() beeps and returns CC_REFRESH,
and el_wgets() resumes operation as it should.
I also tested with "el_set(el, EL_EDITMODE, 0)", and it returns
the right value and sets errno correctly.
currently belonging to the chared module. The read module does so
from three of its functions, while no other module uses the macro
data, not even the chared module itself. That's quite logical
because macros are a feature of input handling, all of which is
done by the read module, and none by the chared module. So move
the data into the read modules's own opaque data structure, struct
el_read_t.
That simplifies internal interfaces in several respects: The
semi-public chared.h has one fewer struct, one fewer #define, and
one fewer member in struct el_chared_t; all three move to one single
C file, read.c, and are now module-local. And the internal interface
function ch_reset() needs one fewer argument, making the code of many
functions in various modules more readable.
The price is one additional internal interface function, read_end(),
10 lines long including comments, called publicly from exactly one
place: el_end() in el.c. That's hardly an increase in complexity
since most other modules already have their *_end() function, read.c
was the odd one out not having one.
From Ingo Schwarze
name, document the return values, expand the list of affected
functions, warn against using EL_GETCFN, and clarify some wording
and notation. (Ingo Schwarze)
Even though section "2.3.3 Information About the History List"
of the history(3) info(1) manual only says
-- Function: int where_history (void)
Returns the offset of the current history element.
which maybe isn't completely clear, a plausible implementation
is that the offset returned is the same offset that can be used
for history_set_pos(), i.e. that it is 0 for the oldest entry
and increases with time, and that's how the GNU implementation
behaves indeed.
The libedit implementation, on the other hand, returns 1 for the
newest entry and increases going back in time.
perspective of the dawn of time, so "next" means "newer" and "previous"
means "older". Libedit, by contrast, uses reverse chronology and
regards history from the perspective of the present, such that "next"
means "longer ago" and "previous" means "not so long ago".
The following patch fixes previous_history() and next_history()
as proposed by Bastian Maerkisch.
But there is a related problem demonstrated by Bastian's regression
tests that his patch did not fix: next_history() can advance not
only to the newest entry, but beyond it, which core libedit cannot
do. So that feature must be implemented locally in readline.c.
With that, the last of Bastians tests is fixed, test_movement_direction().
This patch also improves libedit documentation to more clearly state
what "previous" and "next" mean. GNU readline documentation is
just as unclear, but we can't easily fix that since libedit doesn't
include its own readline.3 manual.
(Ingo Schwarze)
implementation: libedit goes to the entry with the given number
stored in the HistEvent structure, while GNU subtracts history_base,
then advances that many entries from the oldest one. If entries were
removed in between, GNU advances further than libedit.
The call sequence H_CURR, H_DELDATA, H_CURR, H_NEXT_EVDATA looks
weird, as if part of that must somehow be redundant. But actually,
the user interface is so counter-intuitive that every single step
is really required.
- The first H_CURR is needed to be able to go back after an error.
- The H_DELDATA is needed to move the cursor. Even though it takes
a pointer to ev, that structure is not filled in when the call
succeeds. H_DELDATA only moves the cursor, it doesn't tell us
the new event number.
- Consequently, the second H_CURR is required to get ev.num filled
in. But it doesn't return the data because ev has no field for
that.
- So even though the cursor is already positioned correctly,
H_NEXT_EVDATA is needed as the final step merely to get the data.
(Ingo Schwarze)
- Put the data type el_rfunc_t into the public header <histedit.h>.
- Make el_read in struct editline an opaque pointer rather
than an embedded struct.
- Do not include "read.h" everywhere, but only in the two files
needing access to el_read, read.c and el.c.
- To functions that don't need more, pass the struct el_read_t *
rather than the full EditLine *.
- Of course, that means that read_init() can now fail from
memory exhaustion, but it's easy to clean up after that.
* Replace fcns.c by a shorter and simpler func.h
and include it only in the one file needing it, map.c.
* Combine help.h and help.c into a simplified help.h
and include it only in the one file needing it, map.c.
* Check the very simple, static files editline.c, historyn.c, and
tokenizern.c into CVS rather than needlessly generating them.
* So we no longer autogenerate any C files. :-)
* Shorten and simplify makelist by deleting the options -n, -e, -bc,
and -m; the latter was unused and useless in the first place.
* Move the declaration of el_func_t from fcns.h to the header
actually needing it, map.h. Since that header is already
included by el.h for unrelated reasons, that makes el_func_t
just as globally available as before.
* No longer include the simplified fcns.h into el.h,
include it directly into the *.c files needing it.
* Delete the stubs of the XK_EXE mechanism that was never implemented.
From a security, stability, and simplicity perspective, i would
consider implementing it a truly terrible idea, so let's better
get rid of it.
* Do not use the local variable "num" in el_wgets() alternately for
two completely different purposes. Only use it for the number
of characters read, as stated in the comment (or -1 as long as
that number is still unknown), not for the (more or less boolean)
return value of read_getcmd(). Actually, there is no need at
all to save the latter return value after testing it once.
* The function read_getcmd() has very unusual return values:
It returns -1 for success and 0 for EOF/error. Switch that around
to 0 for success and -1 for EOF/error to be less confusing, and
get rid of the OKCMD preprocessor macro.
* Get rid of one #ifdef section in el_wgets() by using
el->el_chared.c_macro directly at the only place
where it is used.
* Delete the unused MIN() macro.
- The file tokenizer.c no longer uses chartype.h,
so don't include the header.
- The dummy definitions of ct_{de,en}code_string() for the
NARROWCHAR case are only used in history.c, so move them there.
- Now the whole content of chartype.h is for the wide character
case only. So remove the NARROWCHAR ifdef and include the
header only in the wide character case.
- In chartype.h, move ct_encode_char() below the comment explaining it.
- No more need for underscores before ct_{de,en}code_string().
- Make the conversion buffer resize functions private.
They are only called from the decoding and encoding functions
inside chartype.c, and no need can possibly arise to call them
from anywhere else.