Commit Graph

961 Commits

Author SHA1 Message Date
Denys Vlasenko
786ca197ad awk: make builtin definitions more understandable, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-02 17:32:08 +02:00
Denys Vlasenko
640212ae0e awk: do not special-case "delete"
Rework of the previous fix:
Can use operation attributes to disable arg evaluation instead of special-casing.

function                                             old     new   delta
.rodata                                           104032  104036      +4
evaluate                                            3223    3215      -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 4/-8)               Total: -4 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-02 15:21:36 +02:00
Denys Vlasenko
ef5463cf16 awk: shuffle globals for smaller offsets
function                                             old     new   delta
awk_main                                             832     829      -3
evaluate                                            3229    3223      -6
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-9)               Total: -9 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-02 14:53:52 +02:00
Denys Vlasenko
966cafcc77 awk: use "static" tmpvars in main and exit
function                                             old     new   delta
awk_exit                                             103      93     -10
awk_main                                             850     832     -18
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-28)             Total: -28 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-02 14:33:13 +02:00
Denys Vlasenko
1193c68fa7 awk: when parsing length(), simplify eating of LPAREN
function                                             old     new   delta
parse_expr                                           945     948      +3

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-02 14:29:01 +02:00
Denys Vlasenko
40573556f2 awk: shuffle functions to reduce forward declarations, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-02 14:27:40 +02:00
Denys Vlasenko
8b4c429025 awk: use static tmpvars instead of nvalloc(1)ed ones
ptest() was using this idea already.

As far as I can see, this is safe. Ttestsuite passes.

One downside is that a temporary from e.g. printf invocation
won't be freed until the next printf call.

function                                             old     new   delta
awk_printf                                           481     468     -13
as_regex                                             137     111     -26
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-39)             Total: -39 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-01 17:50:26 +02:00
Denys Vlasenko
1573487e21 awk: rename temp variables, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-07-01 16:17:33 +02:00
Denys Vlasenko
d7354df169 awk: evaluate all, even superfluous function args
function                                             old     new   delta
evaluate                                            3128    3135      +7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-30 12:52:51 +02:00
Denys Vlasenko
ca9278ee58 awk: rewrite "print" logic a bit to make it clearer
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-30 12:42:39 +02:00
Denys Vlasenko
d150710169 awk: allow empty fuinctions with no arguments, disallow function redefinitions
function                                             old     new   delta
.rodata                                           103681  103700     +19
parse_program                                        303     307      +4
evaluate                                            3145    3141      -4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 23/-4)              Total: 19 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-30 12:23:51 +02:00
Denys Vlasenko
86fc2872b3 awk: replace incorrect use of union in undefined function check (no code changes)
...which reveals that it's buggy: it thinks "func f(){}" is an undefined function!

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-30 12:12:20 +02:00
Denys Vlasenko
6cf6f1eaee awk: remove custom pool allocator for temporary awk variables
It seems to be designed to reduce overhead of malloc's auxiliary data,
by allocating at least 64 variables as a block.
With "struct var" being about 20-32 bytes long (32/64 bits),
malloc overhead for one temporary indeed is high, ~33% more memory used
than needed.

function                                             old     new   delta
evaluate                                            3137    3145      +8
modprobe_main                                        798     803      +5
exec_builtin                                        1414    1419      +5
awk_printf                                           476     481      +5
as_regex                                             132     137      +5
EMSG_INTERNAL_ERROR                                   15       -     -15
nvfree                                               169     116     -53
nvalloc                                              145       -    -145
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 5/1 up/down: 28/-213)          Total: -185 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-30 08:01:29 +02:00
Denys Vlasenko
3aff3b9cb8 awk: assorted optimizations
hash_find(): do not caclculate hash twice. Do not divide - can use
cheap multiply-by-8 shift.

nextword(): do not repeatedly increment in-memory value, do it in register,
then store final result.

hashwalk_init(): do not strlen() twice.

function                                             old     new   delta
hash_search3                                           -      49     +49
hash_find                                            259     281     +22
nextword                                              19      16      -3
evaluate                                            3141    3137      -4
hash_search                                           54      28     -26
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/3 up/down: 71/-33)             Total: 38 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 19:07:36 +02:00
Denys Vlasenko
b3c91a127f awk: free unused parsing structures after parse is done
function                                             old     new   delta
hash_clear                                             -      90     +90
awk_main                                             827     849     +22
clear_array                                           90       -     -90
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/0 up/down: 112/-90)            Total: 22 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 19:06:59 +02:00
Denys Vlasenko
21fbee2e87 awk: document which hashes are used at what state (parse/execute)
We can free them after they are no longer needed.
(Currently, being a NOEXEC applet is much larger waste of memory
for the case of long-running awk script).

function                                             old     new   delta
awk_main                                             831     827      -4

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 14:33:04 +02:00
Denys Vlasenko
6872c193a9 awk: fix parsing of expressions such as "v (a)"
function                                             old     new   delta
next_token                                           812     825     +13

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 12:16:36 +02:00
Denys Vlasenko
686287b5da awk: deindent a block, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 03:47:46 +02:00
Denys Vlasenko
216d3d8ad9 awk: code shrink
function                                             old     new   delta
parse_expr                                           948     945      -3
chain_expr                                            65      62      -3
chain_group                                          655     649      -6
parse_program                                        310     303      -7
rollback_token                                        10       -     -10
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 0/4 up/down: 0/-29)             Total: -29 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 03:44:56 +02:00
Denys Vlasenko
4f27503a1e awk: get rid of "move name one char back" trick in next_token()
function                                             old     new   delta
next_token                                           791     812     +21
awk_main                                             886     831     -55
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 21/-55)            Total: -34 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 03:27:07 +02:00
Denys Vlasenko
f414fb4411 awk: when parsing TC_FUNCTION token, eat its opening '('
...like we do for array references.

function                                             old     new   delta
parse_expr                                           938     948     +10
next_token                                           788     791      +3
parse_program                                        313     310      -3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 13/-3)              Total: 10 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 03:02:21 +02:00
Denys Vlasenko
cb6061a4e9 awk: g_buf[] does not need a separate allocation
function                                             old     new   delta
exec_builtin                                        1400    1414     +14
evaluate                                            3132    3141      +9
getvar_s                                             121     125      +4
awk_main                                             902     886     -16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 27/-16)             Total: 11 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 02:43:02 +02:00
Denys Vlasenko
926420795b awk: simplify parsing of function declaration
function                                             old     new   delta
parse_program                                        328     313     -15

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 02:37:10 +02:00
Denys Vlasenko
9782cb7774 awk: rename TC_SEQSTART/END to L/RPAREN, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 01:50:47 +02:00
Denys Vlasenko
a493441ca5 awk: deindent code block, no code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 01:30:49 +02:00
Denys Vlasenko
adcd9a6f34 awk: use TS_foo for combined token classes. No code changes
Confusion with "simple" classes was the cause of a bug fixed by previous commit

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 01:23:37 +02:00
Denys Vlasenko
832cb4fcb9 awk: make ltclass ("last token class") local to next_token()
function                                             old     new   delta
next_token                                           784     790      +6
next_input_file                                      219     216      -3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 6/-3)                Total: 3 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 01:09:08 +02:00
Denys Vlasenko
af0172369e awk: remove redundant check
function                                             old     new   delta
next_token                                           785     784      -1
parse_program                                        337     328      -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-10)             Total: -10 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-29 01:03:42 +02:00
Ron Yorston
5dbbd0a6f5 vi: stored search pattern applies to ':s'
The same stored search pattern applies to both search ('/') and
search/replace (':s') operations.

A search/replace operation with an empty "find" string (':s//abc/')
should use the last stored search pattern, if available, and issue an
error message if there is none.

If the "find" string is not empty it should replace the stored search
pattern.

function                                             old     new   delta
colon                                               3952    4024     +72
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 72/0)               Total: 72 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-27 13:36:49 +02:00
Denys Vlasenko
78645d8371 awk: move locals deeper into scopes where they are used, no logic changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-25 19:41:05 +02:00
Denys Vlasenko
8c5da0323b awk: more efficient -f FILE, document what "some trick in next_token" is
function                                             old     new   delta
awk_main                                             890     898      +8

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-25 19:38:27 +02:00
S Harris
5c89e5a04e vi: fix read outside of text buffer during insert
Signed-off-by: S Harris <S.E.Harris@kent.ac.uk>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-23 19:15:07 +02:00
Ron Yorston
51358757c7 vi: fix backward search with GNU regex
With FEATURE_VI_REGEX_SEARCH enabled backward searches don't work.
This is problematic on distros that enable regexes, such as Tiny
Core Linux and Fedora.

When calling GNU re_search() with a negative range parameter
(indicating a backward search) the start offset must be set to
the end of the area being searched.

The return value of re_search() is the offset of the matched pattern
from the start of the area being searched.  For a successful search
(positive return value) char_search() can return the pointer to
the start of the area plus the offset.

FEATURE_VI_REGEX_SEARCH isn't enabled by default but when it is:

function                                             old     new   delta
char_search                                          256     247      -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-9)               Total: -9 bytes

Signed-off-by: Andrey Dobrovolsky <andrey.dobrovolsky.odessa@gmail.com>
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-21 15:37:28 +02:00
Denys Vlasenko
ac4786ba00 qwk: make code clearer, no actual code changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-20 22:52:29 +02:00
Denys Vlasenko
fd217c1cbf awk: after preinc/dec, only allow variable, field ref, array ref, or another preinc/dec
Accepting nonsense like "--4", and even "-- -4" is confusing.

function                                             old     new   delta
parse_expr                                           917     938     +21

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-18 16:35:27 +02:00
Ron Yorston
038d400709 vi: reject change command when motion fails
If the motion command used to define the range of a change, yank or
delete fails the whole command should be rejected.  BusyBox vi already
handled failed searches in these circumstances.  Add some more cases:

- non-existent mark: d'x

- movement beyond end of file: c99999+ or 99999<<

This is implemented using a global variable which is set when a command
error is detected.  Unlike the case of motion within a line it's
insufficient to check that the motion command doesn't move the cursor:
this fails to process 'LyL' correctly, for example, as the second 'L'
doesn't move the cursor.

function                                             old     new   delta
indicate_error                                        75      82      +7
find_range                                           686     692      +6
do_cmd                                              4851    4852      +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 14/0)               Total: 14 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-16 23:53:03 +02:00
Ron Yorston
ac04eb3657 vi: up/down motion beyond end of file should fail
In traditional vi and vim line motion commands ('+'/'-'/'j'/'k')
fail if the movement would exceed the bounds of the file.  BusyBox vi
allowed such commands to succeed, leaving the cursor on the first or
last character of the file.

Make BusyBox vi work like vi/vim.

For the 'G'/'H'/'L' commands traditional vi treats an out of bounds
result as an error, vim doesn't.  BusyBox vi behaves like vim, both
before and after this patch.

function                                             old     new   delta
do_cmd                                              4785    4851     +66
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 66/0)               Total: 66 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-16 23:53:03 +02:00
Ron Yorston
f1d21b7434 vi: keep autoindent if line isn't empty
When ESC is entered to leave insert mode any autoindent should only
be removed if there's no content beyond the indent.  This may be the
case if a line has been split by entering insert mode and then
entering a CR.

Add a check to ensure there's only a newline after the indent.

function                                             old     new   delta
char_insert                                          912     929     +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>
2021-06-16 23:53:03 +02:00
Denys Vlasenko
a885ce1af0 awk: fix use-after-free in "$BIGNUM1 $BIGGERNUM2" concat op
Second reference to a field reallocs/moves Fields[] array, but first ref
still tries to use the element where it was before move.

function                                             old     new   delta
fsrealloc                                             94     106     +12

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-16 09:21:40 +02:00
Ron Yorston
52c4b7ac3b vi: initialise tabstop once not for each file
The default tabstop value should be set during early start up,
not reset for each new file.

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-14 20:58:17 +02:00
Ron Yorston
f7ed0e8ae0 vi: ':r' should insert text after current line
When no line number is specified ':read' should place the inserted
text after the current line, not before.

This used to be correct but was broken when commit 0c42a6b07
(vi: fix empty line range regression) revealed a bug in commit
7a8ceb4eb (vi: changes to line addresses for colon commands).

function                                             old     new   delta
colon                                               3960    3952      -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-8)               Total: -8 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-14 20:58:17 +02:00
Denys Vlasenko
e2b9215868 *: --help tweaks
function                                             old     new   delta
packed_usage                                       33589   33552     -37

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-14 20:47:20 +02:00
Denys Vlasenko
6b6826f0b8 *: --help tweaks
function                                             old     new   delta
.rodata                                           103190  103189      -1
packed_usage                                       33590   33566     -24
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-25)             Total: -25 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-13 01:08:48 +02:00
Ron Yorston
9659a8db1d vi: remove autoindent from otherwise empty lines
Lines that have no content apart from automatic indentation should
be treated as empty when the user hits return or ESC.

The implementation uses the global variable 'indentcol'.  Usually
this is zero.  It can also be -1 to indicate an 'O' (open above)
command, replacing the overloading of the tabstop option bit.

A value greater than zero indicates that the current line has
been autoindented to the given column (or that the autoindent has
been adjusted with ctrl-D).  Any other change to the line resets
'indentcol' to zero.

Replace strspn() with ident_len().  The latter handles the unlikely
case that it's called on the last line of a file which doesn't have
a terminating newline.

function                                             old     new   delta
char_insert                                          741     912    +171
indent_len                                             -      42     +42
do_cmd                                              4781    4785      +4
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 217/0)             Total: 217 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-02 06:29:34 +02:00
Ron Yorston
16e2fa9049 vi: make autoindent respect expandtab setting
Autoindent took a copy of the indent from a neighbouring line, which
may not have respected the expandtab setting.

Determine the target column and construct a suitable indent.  This
will consist entirely of spaces if expandtab is enabled or an
efficient combination of tabs and spaces otherwise.

function                                             old     new   delta
char_insert                                          719     741     +22
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 22/0)               Total: 22 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-02 06:16:36 +02:00
Ron Yorston
d95f89ec57 vi: make cursor positioning more vi compatible
Commit 24effc7a3 (vi: cursor positioning after whole-line 'y')
tried to save a few bytes by treating whole-line deletion the
same as whole-line yank.  If the deletion removed the last lines
of the file the cursor was left beyond the end of the file.
Revert the part of the commit related to whole-line deletion.

Position the cursor on the first non-whitespace character of the
line when whole lines are 'put'.

function                                             old     new   delta
do_cmd                                              4759    4781     +22
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 22/0)               Total: 22 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-06-02 06:16:36 +02:00
Ron Yorston
8e71f2aab8 vi: :wq/:x should warn if there are more files to edit
':wq' or ':x' should issue a warning if there are more files to edit,
unless they're followed by '!'.

function                                             old     new   delta
colon                                               3911    3960     +49
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 49/0)               Total: 49 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-05-04 14:51:48 +02:00
Ron Yorston
24effc7a3f vi: cursor positioning after whole-line 'y'
The 'y' command to yank text should leave the cursor at the start
of the range.  This mostly works correctly in BusyBox vi but not
for whole-line yanks with backward motion, e.g. '2yk' to yank two
lines backwards.  In this case the cursor is left at the end of the
range.

Fix this by returning the actual range from find_range().  Cursor
positioning following whole-line deletion is inconsistent between
vim and traditional vi.  For BusyBox vi chose the option that uses
least code without being exactly compatible with either.

Also, find_range() preserved the value of 'dot', the current cursor
position.  Since this isn't used by either caller of find_range()
we can save a few bytes by not bothering.

function                                             old     new   delta
do_cmd                                              4730    4759     +29
find_range                                           749     686     -63
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 29/-63)            Total: -34 bytes

Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-05-04 14:51:48 +02:00
Denys Vlasenko
74e1f321c1 vi: trivial code shrink
function                                             old     new   delta
get_input_line                                       178     176      -2

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2021-05-01 14:00:09 +02:00
Ron Yorston
0c42a6b072 vi: fix empty line range regression
Commit 7a8ceb4eb (vi: changes to line addresses for colon commands)
was supposed to address the issue:

  When the last address is empty it should refer to the current line.

This was intended to allow ranges of the form '1,' with an empty
last address.  It should have been expressed as:

  When the last address is empty *and the second last isn't* it
  should refer to the current line.

Otherwise a command like ':w' only writes the current line resulting
in serious loss of data.

function                                             old     new   delta
colon                                               3906    3911      +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>
2021-04-30 01:40:27 +02:00