Version 2. Same change but rebased after Ron's improvements. Fixes bug
where if you open a read only file, you can't save it as a different
filename.
function old new delta
colon 3160 3162 +2
Signed-off-by: Alison Winters <alisonatwork@outlook.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Commit 4bdc914ff (build system: fix compiler warnings) added a
test on the return value of fgets() in split-include.c.
During bisection it's possible to go back to a state where a
configuration value didn't exist. This results in an empty
include file corresponding to the missing feature. If a
subsequent bisection returns to a state where the feature exists
split-include treats the empty file as an error and the build
fails.
Add a call to ferror() to distinguish between fgets() failing
due to an error and due to there being no data to read.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The behaviour introduced by commit 31c765081d ("watchdog: stop
watchdog first on startup") causes warnings in the kernel log when the
nowayout feature is enabled:
[ 16.212184] watchdog: watchdog0: nowayout prevents watchdog being stopped!
[ 16.212196] watchdog: watchdog0: watchdog did not stop!
The latter may also appear by itself in case the watchdog is of the
type that cannot be stopped once started (e.g. the common
always-running gpio_wdt kind).
These warnings can be somewhat ominous and distracting, so allow
configuring whether to use this open-write-close-open sequence rather
than just open. Also saves a bit of .text when disabled:
function old new delta
shutdown_on_signal 31 58 +27
watchdog_main 339 306 -33
shutdown_watchdog 34 - -34
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/1 up/down: 27/-67) Total: -40 bytes
Make it default n:
- It's a workaround for one specific type of watchdog (and
that seems to be a defect in the kernel driver)
- Even when not enabled in busybox config, it can easily be
implemented outside busybox
- Code size
- Commit 31c765081d should be considered a regression for all the
boards that now end up with KERN_CRIT warnings in dmesg.
- The author of that commit said "This use case is evidently rare, so
if it is indeed causing problems for other people I'd OK then I
understand whatever needs to be done." in the v1 thread.
Cc: Matt Spinler <mspinler@linux.vnet.ibm.com>
Cc: deweloper@wp.pl
Cc: tito <farmatito@tiscali.it>
Signed-off-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This patch changes the functions used to update timestamps in touch.
Before, utimes() and lutimes() were used, which had certain
disadvantages.
They are unable to handle nanosecond timestamps, and implementations of
certain features like -a and -m require running stat() in a loop.
Almost all implementations of utimes() and lutimes() are wrappers for
utimensat(), this is the case for glibc, ulibc and musl libc.
function old new delta
__futimens_time64 - 24 +24
__lutimes_time64 80 - -80
touch_main 539 456 -83
------------------------------------------------------------------------------
(add/remove: 2/2 grow/shrink: 0/1 up/down: 24/-163) Total: -139 bytes
Signed-off-by: urmum-69 <urmum69@snopyta.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Long options handling (getopt32 vs getopt32long) is done in libbb.h, no need to
care here of the same logic. This cleans the code a bit.
Also, --no-create was grouped as a SUSv3 option, where as the short -c was not.
Even if it is part of SUS, leave it out as was the short option.
v2: Fix for disabled ENABLE_LONG_OPTS. getopt32long does not like
IF_FEATURE_xxx() style conditionals... :/
Signed-off-by: Xabier Oneca <xoneca@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When using a file's times as reference, use both atime and mtime for the files
to be modified.
Signed-off-by: Xabier Oneca <xoneca@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Add missing -a and -m options to be fully SUSv3 compliant.
function old new delta
touch_main 415 510 +95
packed_usage 33824 33865 +41
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 136/0) Total: 136 bytes
v2: Ignore -a/-m if not ENABLE_FEATURE_TOUCH_SUSV3.
Signed-off-by: Xabier Oneca <xoneca@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Fix tab completion for the path when equal sign (=) is used. For
example: dd if=/dev/ze<tab>
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Traditional vi is mostly silent about the results of yank, delete,
change, undo or substitution commands. Vim reports some details
about undo and substitution. BusyBox vi is positively verbose in
comparison.
Make some improvements to BusyBox vi:
- Add vim-like reporting of changes caused by substitutions, of
the form '64 substitutions on 53 lines'. This replaces a fairly
useless report of the result of the last change made.
- Ensure that the report about put operations correctly reflects the
newly introduced repetition count.
- Commit 25d2592640 tried to limit status updates for delete and
yank operations by detecting whether the register had changed.
This didn't always work because the previously allocated memory
could be reused for the new register contents. Fix this by
delaying freeing the old register until after the new one has
been allocated.
- Add a configuration option to control verbose status reporting.
This is on by default. Turning it off make BusyBox vi as taciturn
as traditional vi and saves 435 bytes.
function old new delta
colon 3212 3292 +80
yank_status - 74 +74
static.text_yank 99 86 -13
string_insert 130 76 -54
do_cmd 4842 4776 -66
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/3 up/down: 154/-133) Total: 21 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When a search for a character within a line fails issue a warning.
function old new delta
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0) Total: 0 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Make the ':s/find/replace/g' command behave more like vi:
- the final delimiter is optional if no flag is specified;
- the cursor is moved to the first visible character of the last
line where a substitution was made;
- a warning is displayed if no substitution was made.
function old new delta
colon 3156 3212 +56
.rodata 105133 105142 +9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 65/0) Total: 65 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Make the put commands 'p' and 'P' behave more like vi:
- allow a repetition count to be specified;
- when the text being inserted doesn't include a newline the cursor
should be positioned at the end of the inserted text.
function old new delta
do_cmd 4765 4842 +77
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 77/0) Total: 77 bytes
v2: Don't break build when FEATURE_VI_UNDO is disabled.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The '.' command repeats the last text change. When it has a
repetition count replay the change the number of times requested.
Update the stored count if it changes. For example,
3dw deletes 3 words
. deletes another 3 words
2. deletes 2 words and changes the stored count
. deletes 2 words
function old new delta
do_cmd 4746 4781 +35
.rodata 105133 105138 +5
edit_file 887 849 -38
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 40/-38) Total: 2 bytes
v2: Change implementation to include repetition count in string.
Otherwise repeating 'r' doesn't work properly.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Make the 'r' command behave more like vi:
- abort the command if ESC is entered after the 'r';
- allow a repeat count to be entered before the 'r';
- if the repeat count exceeds the space available on the line don't
change any characters and issue an alert.
function old new delta
do_cmd 4679 4746 +67
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 67/0) Total: 67 bytes
v2: Don't break build when FEATURE_VI_UNDO is disabled.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The left shift operator ('<') didn't support undo at all; right
shift ('>') required changes to be undone separately for each line.
Allow both types of shift to be undone as a single operation.
Also, neither traditional vi nor vim yank the lines being shifted by
the '<' and '>' commands, so remove that call to yank_delete();
When a repetition count was specified for the '~', 'x', 'X' or 's'
commands the changes had to be undone one character at a time.
Allow undo as a single operation (though the delete and change
parts of the 's' command still have to be undone separately).
function old new delta
undo_push_insert 37 40 +3
do_cmd 4695 4663 -32
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 3/-32) Total: -29 bytes
v2: Don't break build when FEATURE_VI_UNDO is disabled. Don't reset
'undo_del' too early in '~' handling code. Code shrink '~'.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
An example in my vi book presents different ways to fix the spelling
of the last word in a line:
... anyweigh.
With the cursor on the 'e' the command 'cway' should do the job.
Since commit 776b56d77, though, 'cw' incorrectly includes the full
stop in the range if we're on the last line of the file.
(Prior to commit 776b56d77 BusyBox vi got 'cw' right in this case but
'cW' wrong: it *didn't* delete the full stop.)
Reinstate some of the bloat removed by the earlier commit to fix this.
Also, commit 7b4c2276a (vi: fix word operations across line boundaries)
incorrectly ignores whitespace after a single character word. Adjust
the condition to avoid this.
function old new delta
find_range 707 737 +30
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 30/0) Total: 30 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Rewrite find_range(), pushing quite a bit of code from do_cmd()
down into it.
- The commands 'y', 'd', 'c', '<' and '>' can be given twice to
specify a whole-line range. BusyBox vi actually accepted any
second character from that group, e.g. 'dc' or '<y', with the
latter being accepted even if yank was disabled. Require the
two characters to match.
- '<' and '>' commands followed by ESC incorrectly issued an alert.
- Allow search commands and a marker (specified as "y'a", for example)
to define a range for those operators that support it.
function old new delta
find_range 518 707 +189
.rodata 105119 105133 +14
get_motion_char 68 - -68
do_cmd 4860 4695 -165
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/1 up/down: 203/-233) Total: -30 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Changes to search commands ('/', '?', 'n' and 'N'):
- Rewrite to be smaller and (possibly) clearer.
- Issue a warning when a repeat search is requested without a
previous search having been made.
Vim and BusyBox vi support a repetition count for searches though
the original vi doesn't. If the count exceeds the number of
occurrences of the search string the search may loop through the
file multiple times.
function old new delta
.rodata 105135 105119 -16
do_cmd 4898 4860 -38
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-54) Total: -54 bytes
Signed-off-by; Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Since commit 70ee23399 (vi: code shrink) the ':set' command is
unable to process multiple options on a line. Fix this by
temporarily null-terminating each option.
Change the default setting for all options to off to match vim.
Actually, 'flash' isn't an option in vim, only traditional vi,
where it's on by default. In vim the corresponding option is
'visualbell' which defaults to off. POSIX doesn't have either
of these.
Allow the abbreviation 'ts' for the 'tabstop' option.
Issue an error message if:
- an option is not implemented
- an option that takes a value has no '=' or has a 'no' prefix
- a boolean option has a '='
function old new delta
colon 2944 3003 +59
.rodata 103171 103189 +18
vi_main 274 270 -4
setops 73 - -73
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/1 up/down: 77/-77) Total: 0 bytes
v2: Try harder to detect invalid options. Thanks to Peter D for pointing
this out.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Since commit 25d259264 (vi: make buffer handling more vi-like)
find_range() can return early when an invalid movement is
specified.
The call to find_range() in the code that handles shift commands
('<' and '>') doesn't check for this condition. Previously this
only resulted in the current line being shifted but it can now
result in a segfault.
Check for an invalid movement and notify the user without taking
any further action.
function old new delta
do_cmd 4890 4898 +8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 8/0) Total: 8 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
- In the '+' and '-' commands the call to dot_skip_over_ws() is
only needed for the final line processed so it can be moved out
of the while loop.
- Marking sync_cursor() NOINLINE doesn't seem to offer the same
advantages it did in 2009 (commit adf922ec2).
function old new delta
refresh 694 974 +280
do_cmd 4900 4887 -13
sync_cursor 336 - -336
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/1 up/down: 280/-349) Total: -69 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Movement by paragraph doesn't always involve whole lines. If the
cursor is positioned in the middle of a line deleting to either end
of the paragraph will result in one partial line and zero or more
full lines.
Adjust the end of ranges delimited by paragraph movement to more
closely match what vi does.
function old new delta
find_range 467 518 +51
at_eof - 49 +49
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 100/0) Total: 100 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When moving by paragraph ('{' and '}'):
- Treat multiple empty lines as a single paragraph separator.
- When no paragraph separator is found move to the start or end of
the file depending on the direction of motion.
function old new delta
do_cmd 4821 4900 +79
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 79/0) Total: 79 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The paragraph motion commands '{' and '}' should accept a count.
function old new delta
do_cmd 5054 5071 +17
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 17/0) Total: 17 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The motion that determines the range of a change, delete, yank
or shift operation can have its own count. Thus the commands
'5dd' and 'd5d' are equivalent: both delete 5 lines.
When the command itself also has a count the two values are
multiplied. Thus the command '2d3w' deletes 6 words and '2D3G'
deletes from the current line to line 6.
(When dealing with structured data it might make sense to think in
units of 3 words so '2d3w' is deleting 2 such units. It doesn't
seem quite as sensible to express 'delete from current line to line 6'
as '2D3G' but vi permits it.)
function old new delta
get_motion_char - 68 +68
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/0 up/down: 68/0) Total: 68 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Add 'F', 'T' and '|' as commands that can be used to specify a
range for change/delete/yank operations.
function old new delta
.rodata 105129 105135 +6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 6/0) Total: 6 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
- Use a common routine to handle all commands to search for a
character in a line.
- When searching for the nth occurrence of a character don't move
the cursor if fewer than n occurrences are present.
- Add support for the 'T' command, search backwards for character
after next occurrence of given character.
function old new delta
do_cmd 4861 4805 -56
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-56) Total: -56 bytes
v2: Add parentheses to avoid searches continuing past end of line.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When the 'j'/'k' commands or up/down arrow keys are used to move
the cursor vertically 'vi' remembers the original cursor column
and positions the cursor there if possible. Also, if the '$'
command has been used to position the cursor at the end of a line
vertical movements keep the cursor at the end of the line.
Make BusyBox 'vi' do the same.
function old new delta
refresh 674 694 +20
do_cmd 4853 4861 +8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 28/0) Total: 28 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The 'G' command with no target (meaning 'go to last line') should
position the cursor on the first visible character of the line, as
it already does in other cases.
The 'M' command should position the cursor on the first visible
character (as 'H' and 'L' already do).
function old new delta
do_cmd 4842 4853 +11
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 11/0) Total: 11 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
If the name of the file being written doesn't match the current
filename and the output file already exists vi should issue a
warning and not overwrite the file.
Because the test only compares the file names it's somewhat over-
protective. If the current file name is 'my_text' and the user tries
to save to './my_text' they'll be prevented from doing so.
function old new delta
colon 3092 3151 +59
.rodata 105118 105146 +28
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 87/0) Total: 87 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Vi places text affected by change/delete/yank operations into a
buffer. The contents of such buffers can be restored with the put
commands, 'p' or 'P'. These behave differently depending on whether
the buffer contains whole lines or partial lines. For whole lines
the text is copied into the file on the line before (P) or after
(p) the current line. For partial lines the text is copied before
or after the current cursor position.
Whether an operation results in whole or partial lines depends on
the command used.
BusyBox vi treats any buffer with a newline as though it contained
whole lines. This is incorrect. Deleting multiple words across
a line boundary results in a buffer with a newline but not having
whole lines.
Rework how buffers are handled to behave more like vi.
function old new delta
static.text_yank 79 99 +20
colon 3092 3097 +5
edit_file 885 887 +2
yank_delete 127 112 -15
.rodata 105139 105101 -38
find_range 514 467 -47
do_cmd 5088 4842 -246
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/4 up/down: 27/-346) Total: -319 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
I was puzzled by code in find_range() which handles forward word
movement. It included a test to see if we're at the start of a
word. Since these are forward word movements surely we'd expect to
be at the start of a word? In fact, the test was intended to fix a
problem with changes to the last word in a file, as discussed in the
thread starting here:
http://lists.busybox.net/pipermail/busybox/2004-January/044552.html
The code can be simplified by testing directly for end of file instead
of indirectly for not being at the start of a word. Since trailing
whitespace is now handled in do_cmd() the code to back up off a newline
is no longer required.
function old new delta
find_range 619 514 -105
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-105) Total: -105 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Commit 4b49422a0 (vi: fix changes to word at end of line. Closes
11796) fixed a problem where an operation on a word at the end of
a line followed by a line starting with whitespace incorrectly
joined the lines. However it also broke the case where operating
on multiple words across a line boundary *should* join the lines.
Fix this by detecting when trailing whitepace in a word operation
includes a newline. Whitespace beyond the newline is excluded
from consideration.
function old new delta
do_cmd 5083 5088 +5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 5/0) Total: 5 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>