summaryrefslogtreecommitdiff
Diffstat
-rw-r--r--AUTHORS4
-rw-r--r--Config.in338
-rw-r--r--Makefile51
-rw-r--r--Makefile.custom8
-rw-r--r--Makefile.flags30
-rw-r--r--Makefile.help4
-rw-r--r--README2
-rw-r--r--TODO2
-rw-r--r--android/librpc/libintl.h0
-rw-r--r--applets/Kbuild.src18
-rw-r--r--applets/applet_tables.c135
-rwxr-xr-xapplets/install.sh26
-rwxr-xr-xapplets/usage_compressed9
-rw-r--r--applets/usage_pod.c2
-rw-r--r--archival/Config.src4
-rw-r--r--archival/Kbuild.src2
-rw-r--r--archival/ar.c16
-rw-r--r--archival/bbunzip.c165
-rw-r--r--archival/bzip2.c2
-rw-r--r--archival/cpio.c58
-rw-r--r--archival/dpkg.c21
-rw-r--r--archival/dpkg_deb.c96
-rw-r--r--archival/gzip.c139
-rw-r--r--archival/libarchive/Kbuild.src17
-rw-r--r--archival/libarchive/bz/compress.c1
-rw-r--r--archival/libarchive/common.c9
-rw-r--r--archival/libarchive/data_extract_all.c118
-rw-r--r--archival/libarchive/data_extract_to_command.c5
-rw-r--r--archival/libarchive/decompress_bunzip2.c13
-rw-r--r--archival/libarchive/decompress_gunzip.c82
-rw-r--r--archival/libarchive/decompress_uncompress.c13
-rw-r--r--archival/libarchive/decompress_unlzma.c35
-rw-r--r--archival/libarchive/decompress_unxz.c8
-rw-r--r--archival/libarchive/filter_accept_list_reassign.c10
-rw-r--r--archival/libarchive/get_header_cpio.c9
-rw-r--r--archival/libarchive/get_header_tar.c122
-rw-r--r--archival/libarchive/get_header_tar_bz2.c2
-rw-r--r--archival/libarchive/get_header_tar_gz.c2
-rw-r--r--archival/libarchive/get_header_tar_lzma.c2
-rw-r--r--archival/libarchive/get_header_tar_xz.c21
-rw-r--r--archival/libarchive/init_handle.c4
-rw-r--r--archival/libarchive/lzo1x_9x.c1
-rw-r--r--archival/libarchive/open_transformer.c230
-rw-r--r--archival/libarchive/unpack_ar_archive.c2
-rw-r--r--archival/libarchive/unsafe_prefix.c36
-rw-r--r--archival/libarchive/unxz/xz_dec_lzma2.c3
-rw-r--r--archival/libarchive/unxz/xz_dec_stream.c2
-rw-r--r--archival/lzop.c55
-rw-r--r--archival/rpm.c5
-rw-r--r--archival/tar.c248
-rw-r--r--archival/unzip.c191
-rw-r--r--busybox-full.config484
-rw-r--r--busybox-full.sources22
-rw-r--r--busybox-minimal.sources4
-rw-r--r--configs/TEST_nommu_defconfig4
-rw-r--r--configs/TEST_noprintf_defconfig4
-rw-r--r--configs/TEST_rh9_defconfig4
-rw-r--r--configs/android2_defconfig5
-rw-r--r--configs/android_502_defconfig1140
-rw-r--r--configs/android_defconfig5
-rw-r--r--configs/android_ndk_defconfig188
-rw-r--r--configs/cygwin_defconfig5
-rw-r--r--configs/freebsd_defconfig4
-rw-r--r--console-tools/Config.src166
-rw-r--r--console-tools/Kbuild.src16
-rw-r--r--console-tools/chvt.c11
-rw-r--r--console-tools/clear.c9
-rw-r--r--console-tools/deallocvt.c10
-rw-r--r--console-tools/dumpkmap.c14
-rw-r--r--console-tools/fgconsole.c10
-rw-r--r--console-tools/kbd_mode.c10
-rw-r--r--console-tools/loadfont.c57
-rw-r--r--console-tools/loadkmap.c18
-rw-r--r--console-tools/openvt.c11
-rw-r--r--console-tools/reset.c13
-rw-r--r--console-tools/resize.c27
-rw-r--r--console-tools/setconsole.c18
-rw-r--r--console-tools/setkeycodes.c11
-rw-r--r--console-tools/setlogcons.c14
-rw-r--r--console-tools/showkey.c11
-rw-r--r--coreutils/Config.src746
-rw-r--r--coreutils/Kbuild.src86
-rw-r--r--coreutils/basename.c15
-rw-r--r--coreutils/cal.c18
-rw-r--r--coreutils/cat.c16
-rw-r--r--coreutils/catv.c32
-rw-r--r--coreutils/chgrp.c9
-rw-r--r--coreutils/chmod.c13
-rw-r--r--coreutils/chown.c27
-rw-r--r--coreutils/chroot.c10
-rw-r--r--coreutils/cksum.c13
-rw-r--r--coreutils/comm.c10
-rw-r--r--coreutils/cp.c53
-rw-r--r--coreutils/cut.c10
-rw-r--r--coreutils/date.c18
-rw-r--r--coreutils/dd.c232
-rw-r--r--coreutils/df.c104
-rw-r--r--coreutils/dirname.c10
-rw-r--r--coreutils/dos2unix.c52
-rw-r--r--coreutils/du.c74
-rw-r--r--coreutils/echo.c26
-rw-r--r--coreutils/env.c29
-rw-r--r--coreutils/expand.c31
-rw-r--r--coreutils/expr.c34
-rw-r--r--coreutils/false.c17
-rw-r--r--coreutils/fold.c9
-rw-r--r--coreutils/fsync.c9
-rw-r--r--coreutils/head.c19
-rw-r--r--coreutils/hostid.c5
-rw-r--r--coreutils/id.c11
-rw-r--r--coreutils/install.c72
-rw-r--r--coreutils/length.c.disabled31
-rw-r--r--coreutils/libcoreutils/getopt_mk_fifo_nod.c4
-rw-r--r--coreutils/ln.c10
-rw-r--r--coreutils/logname.c16
-rw-r--r--coreutils/ls.c107
-rw-r--r--coreutils/md5_sha1_sum.c145
-rw-r--r--coreutils/mkdir.c36
-rw-r--r--coreutils/mkfifo.c10
-rw-r--r--coreutils/mknod.c10
-rw-r--r--coreutils/mv.c29
-rw-r--r--coreutils/nice.c9
-rw-r--r--coreutils/nohup.c9
-rw-r--r--coreutils/od.c9
-rw-r--r--coreutils/od_bloaty.c249
-rw-r--r--coreutils/printenv.c9
-rw-r--r--coreutils/printf.c23
-rw-r--r--coreutils/pwd.c11
-rw-r--r--coreutils/readlink.c17
-rw-r--r--coreutils/realpath.c15
-rw-r--r--coreutils/rm.c19
-rw-r--r--coreutils/rmdir.c27
-rw-r--r--coreutils/seq.c9
-rw-r--r--coreutils/shuf.c153
-rw-r--r--coreutils/sleep.c44
-rw-r--r--coreutils/sort.c126
-rw-r--r--coreutils/split.c26
-rw-r--r--coreutils/stat.c91
-rw-r--r--coreutils/stty.c21
-rw-r--r--coreutils/sum.c16
-rw-r--r--coreutils/sync.c26
-rw-r--r--coreutils/tac.c14
-rw-r--r--coreutils/tail.c46
-rw-r--r--coreutils/tee.c21
-rw-r--r--coreutils/test.c116
-rw-r--r--coreutils/touch.c16
-rw-r--r--coreutils/tr.c30
-rw-r--r--coreutils/true.c17
-rw-r--r--coreutils/truncate.c87
-rw-r--r--coreutils/tty.c10
-rw-r--r--coreutils/uname.c39
-rw-r--r--coreutils/uniq.c14
-rw-r--r--coreutils/unlink.c33
-rw-r--r--coreutils/usleep.c9
-rw-r--r--coreutils/uudecode.c28
-rw-r--r--coreutils/uuencode.c9
-rw-r--r--coreutils/wc.c25
-rw-r--r--coreutils/who.c18
-rw-r--r--coreutils/whoami.c12
-rw-r--r--coreutils/yes.c17
-rw-r--r--debianutils/Config.src75
-rw-r--r--debianutils/Kbuild.src5
-rw-r--r--[-rwxr-xr-x]debianutils/mktemp.c10
-rw-r--r--debianutils/pipe_progress.c9
-rw-r--r--debianutils/run_parts.c45
-rw-r--r--debianutils/start_stop_daemon.c40
-rw-r--r--debianutils/which.c95
-rw-r--r--docs/busybox_footer.pod2
-rw-r--r--docs/cgi/env.html2
-rw-r--r--docs/ifupdown_design.txt2
-rw-r--r--docs/keep_data_small.txt14
-rw-r--r--docs/logging_and_backgrounding.txt2
-rw-r--r--docs/new-applet-HOWTO.txt104
-rw-r--r--docs/posix_conformance.txt1
-rw-r--r--docs/unit-tests.txt50
-rw-r--r--e2fsprogs/Config.src28
-rw-r--r--e2fsprogs/Kbuild.src6
-rw-r--r--e2fsprogs/chattr.c26
-rw-r--r--e2fsprogs/e2fs_lib.c4
-rw-r--r--e2fsprogs/fsck.c318
-rw-r--r--e2fsprogs/lsattr.c20
-rw-r--r--e2fsprogs/old_e2fsprogs/Config.src69
-rw-r--r--e2fsprogs/old_e2fsprogs/Kbuild.src18
-rw-r--r--e2fsprogs/old_e2fsprogs/README3
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/Kbuild.src26
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/blkid.h104
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/blkidP.h182
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/blkid_getsize.c179
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/cache.c125
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/dev.c213
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/devname.c367
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/devno.c222
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/list.c110
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/list.h73
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/probe.c726
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/probe.h374
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/read.c459
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/resolve.c139
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/save.c189
-rw-r--r--e2fsprogs/old_e2fsprogs/blkid/tag.c431
-rw-r--r--e2fsprogs/old_e2fsprogs/chattr.c220
-rw-r--r--e2fsprogs/old_e2fsprogs/e2fsbb.h43
-rw-r--r--e2fsprogs/old_e2fsprogs/e2fsck.c13516
-rw-r--r--e2fsprogs/old_e2fsprogs/e2fsck.h638
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/Kbuild.src18
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/e2p.h64
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/feature.c187
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/fgetsetflags.c70
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/fgetsetversion.c70
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/hashstr.c70
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/iod.c52
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/ls.c273
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/mntopts.c134
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/ostype.c72
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/parse_num.c65
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/pe.c32
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/pf.c74
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/ps.c27
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/uuid.c78
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/Kbuild.src26
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/alloc.c173
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/alloc_sb.c58
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/alloc_stats.c53
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c114
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/badblocks.c328
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bb_compat.c64
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c262
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bitmaps.c211
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bitops.c90
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bitops.h105
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/block.c437
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bmap.c261
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bmove.c155
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/brel.h86
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/brel_ma.c196
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/check_desc.c69
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/closefs.c380
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c72
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dblist.c260
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dblist_dir.c76
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c219
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c132
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dirhash.c234
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c95
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/e2image.h39
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/expanddir.c127
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2_err.h116
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h52
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2_fs.h569
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2_io.h112
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2_types.h2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2fs.h922
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h87
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2fs_inline.c365
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext_attr.c101
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/fileio.c377
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/finddev.c199
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/flushb.c83
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/freefs.c127
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/gen_bitmap.c49
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c156
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/getsectsize.c58
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/getsize.c291
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/icount.c467
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/imager.c377
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c69
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/initialize.c388
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/inline.c32
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/inode.c766
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c270
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/io_manager.c70
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/irel.h115
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/irel_ma.c367
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ismounted.c357
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h63
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/kernel-jbd.h235
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/kernel-list.h113
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/link.c135
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/lookup.c68
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c139
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c426
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/namei.c204
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/newdir.c72
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/openfs.c330
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c96
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c96
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c220
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c106
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c294
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/sparse.c79
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c234
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/test_io.c380
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/unix_io.c703
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/unlink.c99
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/valid_blk.c57
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/version.c51
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/write_bb_file.c35
-rw-r--r--e2fsprogs/old_e2fsprogs/fsck.c1375
-rw-r--r--e2fsprogs/old_e2fsprogs/fsck.h16
-rw-r--r--e2fsprogs/old_e2fsprogs/lsattr.c129
-rw-r--r--e2fsprogs/old_e2fsprogs/mke2fs.c1333
-rw-r--r--e2fsprogs/old_e2fsprogs/tune2fs.c710
-rw-r--r--e2fsprogs/old_e2fsprogs/util.c263
-rw-r--r--e2fsprogs/old_e2fsprogs/util.h22
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/Kbuild.src16
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/compare.c55
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/gen_uuid.c304
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/pack.c69
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/parse.c80
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/unpack.c63
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/unparse.c77
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/uuid.h103
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/uuidP.h60
-rw-r--r--e2fsprogs/old_e2fsprogs/uuid/uuid_time.c161
-rw-r--r--e2fsprogs/tune2fs.c45
-rw-r--r--editors/awk.c139
-rw-r--r--editors/diff.c19
-rw-r--r--editors/ed.c9
-rw-r--r--editors/patch.c45
-rw-r--r--editors/patch_toybox.c7
-rw-r--r--editors/sed.c179
-rw-r--r--editors/vi.c929
-rwxr-xr-xexamples/android-build2
-rw-r--r--examples/mdev.conf2
-rw-r--r--examples/mdev_fat.conf12
-rwxr-xr-xexamples/udhcp/sample.bound18
-rwxr-xr-xexamples/udhcp/sample.renew18
-rwxr-xr-xexamples/undeb74
-rwxr-xr-xexamples/unrpm65
-rw-r--r--examples/var_service/README233
-rw-r--r--examples/var_service/README_distro_proposal.txt291
-rw-r--r--examples/var_service/dhcp_if/README5
-rwxr-xr-xexamples/var_service/dhcp_if/convert2ntpconf2
-rwxr-xr-xexamples/var_service/dhcp_if/dhcp_handler13
-rwxr-xr-xexamples/var_service/dhcp_if/finish17
-rwxr-xr-xexamples/var_service/dhcp_if/log/run2
-rw-r--r--examples/var_service/dhcp_if_pinger/README5
-rwxr-xr-xexamples/var_service/dhcp_if_pinger/run44
-rw-r--r--examples/var_service/dhcpd_if/README5
-rwxr-xr-xexamples/var_service/dhcpd_if/log/run21
-rwxr-xr-xexamples/var_service/dhcpd_if/p_log4
-rwxr-xr-xexamples/var_service/dhcpd_if/run23
-rw-r--r--examples/var_service/dhcpd_if/udhcpc.conf28
-rwxr-xr-xexamples/var_service/dhcpd_if/w_dumpleases3
-rwxr-xr-xexamples/var_service/dhcpd_if/w_dumpleases_countdown3
-rwxr-xr-xexamples/var_service/dhcpd_if/w_log4
-rw-r--r--examples/var_service/ftpd/README5
-rwxr-xr-xexamples/var_service/ftpd/log/run2
-rw-r--r--examples/var_service/fw/README5
-rwxr-xr-xexamples/var_service/fw/run50
-rw-r--r--examples/var_service/getty_tty1/README5
-rw-r--r--examples/var_service/gpm/README5
-rw-r--r--examples/var_service/httpd/README5
-rwxr-xr-xexamples/var_service/httpd/log/run2
-rw-r--r--examples/var_service/ifplugd_if/README5
-rwxr-xr-xexamples/var_service/ifplugd_if/log/run2
-rwxr-xr-xexamples/var_service/ifplugd_if/run3
-rw-r--r--examples/var_service/inetd/README5
-rwxr-xr-xexamples/var_service/inetd/log/run2
-rw-r--r--examples/var_service/nmeter/README5
-rw-r--r--examples/var_service/ntpd/README5
-rwxr-xr-xexamples/var_service/ntpd/log/run2
-rwxr-xr-xexamples/var_service/ntpd/ntp.script21
-rwxr-xr-xexamples/var_service/ntpd/p_log_important4
-rwxr-xr-xexamples/var_service/ntpd/run2
-rw-r--r--examples/var_service/supplicant_if/README5
-rwxr-xr-xexamples/var_service/supplicant_if/log/run21
-rwxr-xr-xexamples/var_service/supplicant_if/p_log4
-rwxr-xr-xexamples/var_service/supplicant_if/run21
-rwxr-xr-xexamples/var_service/supplicant_if/w_log4
-rw-r--r--examples/var_service/supplicant_if/wpa_supplicant.conf28
-rw-r--r--examples/var_service/tftpd/README5
-rwxr-xr-xexamples/var_service/tftpd/log/run2
-rw-r--r--examples/var_service/zcip_if/README5
-rwxr-xr-xexamples/var_service/zcip_if/convert2ipconf24
-rwxr-xr-xexamples/var_service/zcip_if/finish13
-rwxr-xr-xexamples/var_service/zcip_if/log/run21
-rwxr-xr-xexamples/var_service/zcip_if/p_log4
-rwxr-xr-xexamples/var_service/zcip_if/run20
-rwxr-xr-xexamples/var_service/zcip_if/w_log4
-rwxr-xr-xexamples/var_service/zcip_if/zcip_handler47
-rw-r--r--findutils/find.c263
-rw-r--r--findutils/grep.c130
-rw-r--r--findutils/xargs.c190
-rwxr-xr-xinclude/applets.h.sh23
-rw-r--r--include/applets.src.h368
-rw-r--r--include/bb_archive.h61
-rw-r--r--include/busybox.h19
-rw-r--r--include/grp_.h65
-rw-r--r--include/libbb.h419
-rw-r--r--include/platform.h104
-rw-r--r--include/pwd_.h53
-rw-r--r--include/shadow_.h26
-rw-r--r--init/bootchartd.c7
-rw-r--r--init/halt.c50
-rw-r--r--init/init.c144
-rw-r--r--libbb/Config.src174
-rw-r--r--libbb/Kbuild.src16
-rw-r--r--libbb/appletlib.c327
-rw-r--r--libbb/auto_string.c23
-rw-r--r--libbb/bb_askpass.c11
-rw-r--r--libbb/bb_pwd.c48
-rw-r--r--libbb/bbunit.c65
-rw-r--r--libbb/change_identity.c23
-rw-r--r--libbb/common_bufsiz.c83
-rw-r--r--libbb/compare_string_array.c82
-rw-r--r--libbb/copy_file.c41
-rw-r--r--libbb/copyfd.c87
-rw-r--r--libbb/correct_password.c96
-rw-r--r--libbb/dump.c51
-rw-r--r--libbb/execable.c86
-rw-r--r--libbb/executable.c101
-rw-r--r--libbb/fflush_stdout_and_exit.c15
-rw-r--r--libbb/getopt32.c82
-rw-r--r--libbb/getpty.c2
-rw-r--r--libbb/hash_md5_sha.c386
-rw-r--r--libbb/human_readable.c20
-rw-r--r--libbb/in_ether.c1
-rw-r--r--libbb/inet_common.c84
-rw-r--r--libbb/info_msg.c62
-rw-r--r--libbb/inode_hash.c38
-rw-r--r--libbb/kernel_version.c8
-rw-r--r--libbb/lineedit.c256
-rw-r--r--libbb/logenv.c24
-rw-r--r--libbb/login.c40
-rw-r--r--libbb/loop.c29
-rw-r--r--libbb/make_directory.c19
-rw-r--r--libbb/match_fstype.c7
-rw-r--r--libbb/messages.c9
-rw-r--r--libbb/missing_syscalls.c7
-rw-r--r--libbb/mode_string.c4
-rw-r--r--libbb/obscure.c40
-rw-r--r--libbb/parse_config.c4
-rw-r--r--libbb/parse_mode.c16
-rw-r--r--libbb/platform.c37
-rw-r--r--libbb/printable_string.c10
-rw-r--r--libbb/procps.c28
-rw-r--r--libbb/progress.c20
-rw-r--r--libbb/pw_encrypt.c21
-rw-r--r--libbb/read_key.c12
-rw-r--r--libbb/read_printf.c8
-rw-r--r--libbb/remove_file.c8
-rw-r--r--libbb/replace.c45
-rw-r--r--libbb/rtc.c54
-rw-r--r--libbb/run_shell.c29
-rw-r--r--libbb/skip_whitespace.c2
-rw-r--r--libbb/speed_table.c84
-rw-r--r--libbb/strrstr.c19
-rw-r--r--libbb/sysconf.c30
-rw-r--r--libbb/systemd_support.c62
-rw-r--r--libbb/time.c1
-rw-r--r--libbb/u_signal_names.c2
-rw-r--r--libbb/ubi.c43
-rw-r--r--libbb/udp_io.c14
-rw-r--r--libbb/update_passwd.c60
-rw-r--r--libbb/utmp.c58
-rw-r--r--libbb/verror_msg.c34
-rw-r--r--libbb/vfork_daemon_rexec.c47
-rw-r--r--libbb/xatonum.c40
-rw-r--r--libbb/xconnect.c34
-rw-r--r--libbb/xfunc_die.c26
-rw-r--r--libbb/xfuncs.c76
-rw-r--r--libbb/xfuncs_printf.c39
-rw-r--r--libbb/xreadlink.c11
-rw-r--r--libpwdgrp/pwd_grp.c1277
-rw-r--r--libpwdgrp/pwd_grp_internal.c61
-rw-r--r--libpwdgrp/uidgid_get.c44
-rw-r--r--loginutils/Config.src237
-rw-r--r--loginutils/Kbuild.src12
-rw-r--r--loginutils/README2
-rw-r--r--loginutils/add-remove-shell.c17
-rw-r--r--loginutils/addgroup.c44
-rw-r--r--loginutils/adduser.c84
-rw-r--r--loginutils/chpasswd.c51
-rw-r--r--loginutils/cryptpw.c46
-rw-r--r--loginutils/deluser.c75
-rw-r--r--loginutils/getty.c60
-rw-r--r--loginutils/login.c111
-rw-r--r--loginutils/passwd.c26
-rw-r--r--loginutils/su.c65
-rw-r--r--loginutils/sulogin.c46
-rw-r--r--loginutils/vlock.c16
-rw-r--r--mailutils/Config.src43
-rw-r--r--mailutils/mail.c2
-rw-r--r--mailutils/makemime.c10
-rw-r--r--mailutils/popmaildir.c22
-rw-r--r--mailutils/reformime.c20
-rw-r--r--mailutils/sendmail.c138
-rwxr-xr-xmake_single_applets.sh73
-rw-r--r--miscutils/Config.src584
-rw-r--r--miscutils/Kbuild.src39
-rw-r--r--miscutils/adjtimex.c42
-rw-r--r--miscutils/bbconfig.c24
-rw-r--r--miscutils/beep.c28
-rw-r--r--miscutils/chat.c74
-rw-r--r--miscutils/chrt.c10
-rw-r--r--miscutils/conspy.c20
-rw-r--r--miscutils/crond.c346
-rw-r--r--miscutils/crontab.c14
-rw-r--r--miscutils/dc.c95
-rw-r--r--miscutils/devfsd.c91
-rw-r--r--miscutils/devmem.c10
-rw-r--r--miscutils/eject.c46
-rw-r--r--miscutils/fbsplash.c34
-rw-r--r--miscutils/flash_eraseall.c12
-rw-r--r--miscutils/flash_lock_unlock.c19
-rw-r--r--miscutils/flashcp.c12
-rw-r--r--miscutils/hdparm.c131
-rw-r--r--miscutils/i2c_tools.c1343
-rw-r--r--miscutils/inotifyd.c20
-rw-r--r--miscutils/ionice.c16
-rw-r--r--miscutils/last.c39
-rw-r--r--miscutils/last_fancy.c25
-rw-r--r--miscutils/less.c482
-rw-r--r--miscutils/makedevs.c44
-rw-r--r--miscutils/man.c213
-rw-r--r--miscutils/microcom.c18
-rw-r--r--miscutils/mountpoint.c9
-rw-r--r--miscutils/mt.c11
-rw-r--r--miscutils/nandwrite.c74
-rw-r--r--miscutils/raidautorun.c11
-rw-r--r--miscutils/readahead.c21
-rw-r--r--miscutils/runlevel.c25
-rw-r--r--miscutils/rx.c12
-rw-r--r--miscutils/setserial.c8
-rw-r--r--miscutils/setsid.c28
-rw-r--r--miscutils/strings.c42
-rw-r--r--miscutils/taskset.c127
-rw-r--r--miscutils/time.c12
-rw-r--r--miscutils/timeout.c13
-rw-r--r--miscutils/ttysize.c12
-rw-r--r--miscutils/ubi_tools.c68
-rw-r--r--miscutils/ubirename.c94
-rw-r--r--miscutils/volname.c9
-rw-r--r--miscutils/wall.c8
-rw-r--r--miscutils/watchdog.c15
-rw-r--r--modutils/Config.src93
-rw-r--r--modutils/Kbuild.src7
-rw-r--r--modutils/depmod.c136
-rw-r--r--modutils/insmod.c14
-rw-r--r--modutils/lsmod.c22
-rw-r--r--modutils/modinfo.c160
-rw-r--r--modutils/modprobe-small.c480
-rw-r--r--modutils/modprobe.c210
-rw-r--r--modutils/modutils-24.c4
-rw-r--r--modutils/modutils.c101
-rw-r--r--modutils/modutils.h30
-rw-r--r--modutils/rmmod.c24
-rw-r--r--networking/Config.src941
-rw-r--r--networking/Kbuild.src39
-rw-r--r--networking/arp.c21
-rw-r--r--networking/arping.c62
-rw-r--r--networking/brctl.c94
-rw-r--r--networking/dnsd.c11
-rw-r--r--networking/ether-wake.c10
-rw-r--r--networking/ftpd.c227
-rw-r--r--networking/ftpgetput.c35
-rw-r--r--networking/hostname.c26
-rw-r--r--networking/httpd.c238
-rw-r--r--networking/ifconfig.c51
-rw-r--r--networking/ifenslave.c19
-rw-r--r--networking/ifplugd.c61
-rw-r--r--networking/ifupdown.c239
-rw-r--r--networking/inetd.c85
-rw-r--r--networking/interface.c33
-rw-r--r--networking/ip.c192
-rw-r--r--networking/ipcalc.c28
-rw-r--r--networking/isrv.c4
-rw-r--r--networking/isrv.h26
-rw-r--r--networking/isrv_identd.c52
-rw-r--r--networking/libiproute/Kbuild.src11
-rw-r--r--networking/libiproute/ip_common.h2
-rw-r--r--networking/libiproute/ip_parse_common_args.c2
-rw-r--r--networking/libiproute/ipaddress.c74
-rw-r--r--networking/libiproute/iplink.c196
-rw-r--r--networking/libiproute/ipneigh.c357
-rw-r--r--networking/libiproute/iproute.c172
-rw-r--r--networking/libiproute/iprule.c61
-rw-r--r--networking/libiproute/iptunnel.c37
-rw-r--r--networking/libiproute/libnetlink.c87
-rw-r--r--networking/libiproute/ll_map.c39
-rw-r--r--networking/libiproute/ll_map.h2
-rw-r--r--networking/libiproute/ll_proto.c4
-rw-r--r--networking/libiproute/ll_types.c4
-rw-r--r--networking/libiproute/rt_names.c93
-rw-r--r--networking/libiproute/rt_names.h11
-rw-r--r--networking/libiproute/rtm_map.c6
-rw-r--r--networking/libiproute/rtm_map.h2
-rw-r--r--networking/libiproute/utils.c48
-rw-r--r--networking/libiproute/utils.h12
-rw-r--r--networking/nameif.c12
-rw-r--r--networking/nbd-client.c7
-rw-r--r--networking/nc.c14
-rw-r--r--networking/nc_bloaty.c8
-rw-r--r--networking/netstat.c34
-rw-r--r--networking/nslookup.c9
-rw-r--r--networking/ntpd.c593
-rw-r--r--networking/ntpd.diff24
-rw-r--r--networking/ntpd_simple.c1008
-rw-r--r--networking/ping.c110
-rw-r--r--networking/pscan.c9
-rw-r--r--networking/route.c64
-rw-r--r--networking/slattach.c22
-rwxr-xr-xnetworking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.822
-rwxr-xr-xnetworking/ssl_helper-wolfssl/00cfg-wolfssl-3.9.839
-rw-r--r--networking/ssl_helper-wolfssl/README27
-rw-r--r--networking/ssl_helper-wolfssl/ssl_helper.c480
-rwxr-xr-xnetworking/ssl_helper-wolfssl/ssl_helper.sh12
-rw-r--r--networking/ssl_helper/README16
-rw-r--r--networking/ssl_helper/ssl_helper.c406
-rwxr-xr-xnetworking/ssl_helper/ssl_helper.sh11
-rw-r--r--networking/tc.c59
-rw-r--r--networking/tcpudp.c102
-rw-r--r--networking/telnet.c46
-rw-r--r--networking/telnetd.IAC_test.sh87
-rw-r--r--networking/telnetd.c389
-rw-r--r--networking/telnetd.ctrlSQ.patch4
-rw-r--r--networking/tftp.c110
-rw-r--r--networking/traceroute.c287
-rw-r--r--networking/tunctl.c20
-rw-r--r--networking/udhcp/Config.src13
-rw-r--r--networking/udhcp/Kbuild.src4
-rw-r--r--networking/udhcp/arpping.c13
-rw-r--r--networking/udhcp/common.c40
-rw-r--r--networking/udhcp/common.h11
-rw-r--r--networking/udhcp/d6_dhcpc.c85
-rw-r--r--networking/udhcp/d6_packet.c12
-rw-r--r--networking/udhcp/d6_socket.c2
-rw-r--r--networking/udhcp/dhcpc.c298
-rw-r--r--networking/udhcp/dhcpd.c569
-rw-r--r--networking/udhcp/dhcpd.h35
-rw-r--r--networking/udhcp/dhcprelay.c8
-rw-r--r--networking/udhcp/domain_codec.c21
-rw-r--r--networking/udhcp/dumpleases.c31
-rw-r--r--networking/udhcp/files.c216
-rw-r--r--networking/udhcp/leases.c203
-rw-r--r--networking/udhcp/packet.c12
-rw-r--r--networking/udhcp/socket.c4
-rw-r--r--networking/udhcp/static_leases.c77
-rw-r--r--networking/vconfig.c11
-rw-r--r--networking/wget.c578
-rw-r--r--networking/whois.c147
-rw-r--r--networking/zcip.c536
-rw-r--r--printutils/Config.src18
-rw-r--r--printutils/Kbuild.src4
-rw-r--r--printutils/lpd.c19
-rw-r--r--printutils/lpr.c17
-rw-r--r--procps/Config.src140
-rw-r--r--procps/Kbuild.src17
-rw-r--r--procps/free.c94
-rw-r--r--procps/fuser.c15
-rw-r--r--procps/iostat.c9
-rw-r--r--procps/kill.c48
-rw-r--r--procps/mpstat.c18
-rw-r--r--procps/nmeter.c208
-rw-r--r--procps/pgrep.c24
-rw-r--r--procps/pidof.c29
-rw-r--r--procps/pmap.c4
-rw-r--r--procps/powertop.c16
-rw-r--r--procps/ps.c78
-rw-r--r--procps/pstree.c2
-rw-r--r--procps/pwdx.c4
-rw-r--r--procps/renice.c23
-rw-r--r--procps/sysctl.c12
-rw-r--r--procps/top.c268
-rw-r--r--procps/uptime.c15
-rw-r--r--procps/watch.c17
-rw-r--r--qemu_multiarch_testing/README63
-rwxr-xr-xqemu_multiarch_testing/extract_od_binary.sh6
-rwxr-xr-xqemu_multiarch_testing/hdc.dir/build50
-rwxr-xr-xqemu_multiarch_testing/hdc.dir/init9
-rwxr-xr-xqemu_multiarch_testing/make-hdc-img.sh30
-rwxr-xr-xqemu_multiarch_testing/parallel-build-hdc-img.sh40
-rw-r--r--runit/Config.src79
-rw-r--r--runit/Kbuild.src11
-rw-r--r--runit/chpst.c52
-rw-r--r--runit/runsv.c35
-rw-r--r--runit/runsvdir.c98
-rw-r--r--runit/sv.c141
-rw-r--r--runit/svlogd.c24
-rw-r--r--scripts/Makefile.build3
-rw-r--r--scripts/basic/docproc.c4
-rw-r--r--scripts/basic/fixdep.c2
-rwxr-xr-xscripts/gen_build_files.sh40
-rwxr-xr-xscripts/generate_BUFSIZ.sh137
-rw-r--r--scripts/kconfig/confdata.c3
-rwxr-xr-x[-rw-r--r--]scripts/kconfig/lxdialog/check-lxdialog.sh17
-rw-r--r--scripts/kconfig/util.c3
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped14
-rwxr-xr-xscripts/randomtest26
-rwxr-xr-xscripts/randomtest.loop1
-rwxr-xr-xscripts/trylink81
-rw-r--r--selinux/Config.src113
-rw-r--r--selinux/Kbuild.src12
-rw-r--r--selinux/chcon.c20
-rw-r--r--selinux/getenforce.c10
-rw-r--r--selinux/getsebool.c10
-rw-r--r--selinux/load_policy.c10
-rw-r--r--selinux/matchpathcon.c11
-rw-r--r--selinux/runcon.c27
-rw-r--r--selinux/selinuxenabled.c11
-rw-r--r--selinux/sestatus.c10
-rw-r--r--selinux/setenforce.c10
-rw-r--r--selinux/setfiles.c49
-rw-r--r--selinux/setsebool.c11
-rw-r--r--shell/Config.src45
-rw-r--r--shell/Kbuild.src2
-rw-r--r--shell/ash.c88
-rw-r--r--shell/ash_test/.gitignore7
-rw-r--r--shell/ash_test/ash-glob/glob1.right2
-rwxr-xr-xshell/ash_test/ash-glob/glob1.tests2
-rw-r--r--shell/ash_test/ash-glob/glob2.right18
-rwxr-xr-xshell/ash_test/ash-glob/glob2.tests27
-rw-r--r--shell/ash_test/ash-glob/glob3.right2
-rwxr-xr-xshell/ash_test/ash-glob/glob3.tests2
-rw-r--r--shell/ash_test/ash-glob/glob_and_assign.right6
-rwxr-xr-xshell/ash_test/ash-glob/glob_and_assign.tests10
-rw-r--r--shell/ash_test/ash-glob/glob_dir.right19
-rwxr-xr-xshell/ash_test/ash-glob/glob_dir.tests25
-rw-r--r--shell/ash_test/ash-glob/glob_redir.right2
-rwxr-xr-xshell/ash_test/ash-glob/glob_redir.tests9
-rw-r--r--shell/ash_test/ash-heredoc/heredoc1.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc1.tests3
-rw-r--r--shell/ash_test/ash-heredoc/heredoc2.right2
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc2.tests7
-rw-r--r--shell/ash_test/ash-heredoc/heredoc3.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc3.tests9
-rw-r--r--shell/ash_test/ash-heredoc/heredoc4.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc4.tests3
-rw-r--r--shell/ash_test/ash-heredoc/heredoc5.right (copied from shell/hush_test/hush-misc/heredoc2.right)0
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc5.tests (copied from shell/hush_test/hush-misc/heredoc2.tests)0
-rw-r--r--shell/ash_test/ash-heredoc/heredoc6.right2
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc6.tests4
-rw-r--r--shell/ash_test/ash-heredoc/heredoc7.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc7.tests3
-rw-r--r--shell/ash_test/ash-heredoc/heredoc_huge.right (copied from shell/hush_test/hush-misc/heredoc_huge.right)0
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc_huge.tests (copied from shell/hush_test/hush-misc/heredoc_huge.tests)0
-rw-r--r--shell/ash_test/ash-misc/and-or.right18
-rwxr-xr-xshell/ash_test/ash-misc/and-or.tests34
-rw-r--r--shell/ash_test/ash-misc/assignment1.right9
-rwxr-xr-xshell/ash_test/ash-misc/assignment1.tests42
-rw-r--r--shell/ash_test/ash-misc/assignment3.right2
-rwxr-xr-xshell/ash_test/ash-misc/assignment3.tests5
-rw-r--r--shell/ash_test/ash-misc/assignment4.right1
-rwxr-xr-xshell/ash_test/ash-misc/assignment4.tests3
-rw-r--r--shell/ash_test/ash-misc/break1.right2
-rwxr-xr-xshell/ash_test/ash-misc/break1.tests2
-rw-r--r--shell/ash_test/ash-misc/break2.right3
-rwxr-xr-xshell/ash_test/ash-misc/break2.tests6
-rw-r--r--shell/ash_test/ash-misc/break3.right2
-rwxr-xr-xshell/ash_test/ash-misc/break3.tests2
-rw-r--r--shell/ash_test/ash-misc/break4.right6
-rwxr-xr-xshell/ash_test/ash-misc/break4.tests12
-rw-r--r--shell/ash_test/ash-misc/break5.right13
-rwxr-xr-xshell/ash_test/ash-misc/break5.tests4
-rw-r--r--shell/ash_test/ash-misc/builtin1.right2
-rwxr-xr-xshell/ash_test/ash-misc/builtin1.tests6
-rw-r--r--shell/ash_test/ash-misc/case1.right22
-rwxr-xr-xshell/ash_test/ash-misc/case1.tests40
-rw-r--r--shell/ash_test/ash-misc/colon.right2
-rwxr-xr-xshell/ash_test/ash-misc/colon.tests5
-rw-r--r--shell/ash_test/ash-misc/command.right1
-rwxr-xr-xshell/ash_test/ash-misc/command.tests1
-rw-r--r--shell/ash_test/ash-misc/command2.right2
-rwxr-xr-xshell/ash_test/ash-misc/command2.tests6
-rw-r--r--shell/ash_test/ash-misc/compound.right14
-rwxr-xr-xshell/ash_test/ash-misc/compound.tests21
-rw-r--r--shell/ash_test/ash-misc/continue1.right8
-rwxr-xr-xshell/ash_test/ash-misc/continue1.tests4
-rw-r--r--shell/ash_test/ash-misc/continue2.right1
-rwxr-xr-xshell/ash_test/ash-misc/continue2.tests3
-rw-r--r--shell/ash_test/ash-misc/continue3.right2
-rwxr-xr-xshell/ash_test/ash-misc/continue3.tests3
-rwxr-xr-x[-rw-r--r--]shell/ash_test/ash-misc/echo_write_error.tests0
-rw-r--r--shell/ash_test/ash-misc/empty_for.right1
-rwxr-xr-xshell/ash_test/ash-misc/empty_for.tests3
-rw-r--r--shell/ash_test/ash-misc/empty_for2.right4
-rwxr-xr-xshell/ash_test/ash-misc/empty_for2.tests6
-rw-r--r--shell/ash_test/ash-misc/errexit1.right (copied from shell/msh_test/msh-execution/many_continues.right)0
-rwxr-xr-xshell/ash_test/ash-misc/errexit1.tests5
-rw-r--r--shell/ash_test/ash-misc/eval1.right1
-rwxr-xr-xshell/ash_test/ash-misc/eval1.tests4
-rw-r--r--shell/ash_test/ash-misc/eval2.right3
-rwxr-xr-xshell/ash_test/ash-misc/eval2.tests4
-rw-r--r--shell/ash_test/ash-misc/exec.right2
-rwxr-xr-xshell/ash_test/ash-misc/exec.tests3
-rw-r--r--shell/ash_test/ash-misc/exit1.right1
-rwxr-xr-xshell/ash_test/ash-misc/exit1.tests4
-rw-r--r--shell/ash_test/ash-misc/exitcode1.right2
-rwxr-xr-xshell/ash_test/ash-misc/exitcode1.tests2
-rw-r--r--shell/ash_test/ash-misc/exitcode2.right4
-rwxr-xr-xshell/ash_test/ash-misc/exitcode2.tests12
-rw-r--r--shell/ash_test/ash-misc/exitcode_EACCES.right2
-rwxr-xr-xshell/ash_test/ash-misc/exitcode_EACCES.tests (copied from shell/msh_test/msh-execution/exitcode_EACCES.tests)0
-rw-r--r--shell/ash_test/ash-misc/exitcode_ENOENT.right2
-rwxr-xr-xshell/ash_test/ash-misc/exitcode_ENOENT.tests (copied from shell/msh_test/msh-execution/exitcode_ENOENT.tests)0
-rw-r--r--shell/ash_test/ash-misc/for.right (renamed from shell/msh_test/msh-parsing/argv0.right)0
-rwxr-xr-xshell/ash_test/ash-misc/for.tests5
-rw-r--r--shell/ash_test/ash-misc/for_with_bslashes.right8
-rwxr-xr-xshell/ash_test/ash-misc/for_with_bslashes.tests10
-rw-r--r--shell/ash_test/ash-misc/for_with_keywords.right4
-rwxr-xr-xshell/ash_test/ash-misc/for_with_keywords.tests2
-rw-r--r--shell/ash_test/ash-misc/func1.right6
-rwxr-xr-xshell/ash_test/ash-misc/func1.tests16
-rw-r--r--shell/ash_test/ash-misc/func2.right5
-rwxr-xr-xshell/ash_test/ash-misc/func2.tests9
-rw-r--r--shell/ash_test/ash-misc/func3.right4
-rwxr-xr-xshell/ash_test/ash-misc/func3.tests8
-rw-r--r--shell/ash_test/ash-misc/func4.right2
-rwxr-xr-xshell/ash_test/ash-misc/func4.tests7
-rw-r--r--shell/ash_test/ash-misc/func5.right6
-rwxr-xr-xshell/ash_test/ash-misc/func5.tests13
-rw-r--r--shell/ash_test/ash-misc/func6.right2
-rwxr-xr-xshell/ash_test/ash-misc/func6.tests11
-rw-r--r--shell/ash_test/ash-misc/func_args1.right5
-rwxr-xr-xshell/ash_test/ash-misc/func_args1.tests8
-rw-r--r--shell/ash_test/ash-misc/func_bash1.right12
-rwxr-xr-xshell/ash_test/ash-misc/func_bash1.tests28
-rw-r--r--shell/ash_test/ash-misc/func_local1.right3
-rwxr-xr-xshell/ash_test/ash-misc/func_local1.tests5
-rw-r--r--shell/ash_test/ash-misc/func_local2.right14
-rwxr-xr-xshell/ash_test/ash-misc/func_local2.tests7
-rw-r--r--shell/ash_test/ash-misc/group_in_braces.right5
-rwxr-xr-xshell/ash_test/ash-misc/group_in_braces.tests11
-rw-r--r--shell/ash_test/ash-misc/if_false_exitcode.right1
-rwxr-xr-xshell/ash_test/ash-misc/if_false_exitcode.tests2
-rw-r--r--shell/ash_test/ash-misc/local1.right4
-rwxr-xr-xshell/ash_test/ash-misc/local1.tests11
-rw-r--r--shell/ash_test/ash-misc/local2.right1
-rwxr-xr-xshell/ash_test/ash-misc/local2.tests1
-rw-r--r--shell/ash_test/ash-misc/nommu1.right7
-rwxr-xr-xshell/ash_test/ash-misc/nommu1.tests12
-rw-r--r--shell/ash_test/ash-misc/nommu2.right5
-rwxr-xr-xshell/ash_test/ash-misc/nommu2.tests5
-rw-r--r--shell/ash_test/ash-misc/nommu3.right2
-rwxr-xr-xshell/ash_test/ash-misc/nommu3.tests15
-rw-r--r--shell/ash_test/ash-misc/opts1.right2
-rwxr-xr-xshell/ash_test/ash-misc/opts1.tests5
-rw-r--r--shell/ash_test/ash-misc/pid.right1
-rwxr-xr-xshell/ash_test/ash-misc/pid.tests1
-rw-r--r--shell/ash_test/ash-misc/pipefail.right40
-rwxr-xr-xshell/ash_test/ash-misc/pipefail.tests45
-rw-r--r--shell/ash_test/ash-misc/read.right (renamed from shell/msh_test/msh-bugs/read.right)0
-rwxr-xr-xshell/ash_test/ash-misc/read.tests (renamed from shell/msh_test/msh-bugs/read.tests)0
-rw-r--r--shell/ash_test/ash-misc/return1.right1
-rwxr-xr-xshell/ash_test/ash-misc/return1.tests4
-rw-r--r--shell/ash_test/ash-misc/shift.right (renamed from shell/msh_test/msh-bugs/shift.right)0
-rwxr-xr-xshell/ash_test/ash-misc/shift.tests (renamed from shell/msh_test/msh-bugs/shift.tests)0
-rw-r--r--shell/ash_test/ash-misc/sigint1.right1
-rwxr-xr-xshell/ash_test/ash-misc/sigint1.tests41
-rw-r--r--shell/ash_test/ash-misc/source3.right2
-rwxr-xr-xshell/ash_test/ash-misc/source3.tests6
-rw-r--r--shell/ash_test/ash-misc/source5.right4
-rwxr-xr-xshell/ash_test/ash-misc/source5.tests8
-rw-r--r--shell/ash_test/ash-misc/tickquote1.right1
-rwxr-xr-xshell/ash_test/ash-misc/tickquote1.tests1
-rw-r--r--shell/ash_test/ash-misc/unicode1.right3
-rwxr-xr-xshell/ash_test/ash-misc/unicode1.tests13
-rw-r--r--shell/ash_test/ash-misc/until1.right3
-rwxr-xr-xshell/ash_test/ash-misc/until1.tests11
-rw-r--r--shell/ash_test/ash-misc/wait4.right1
-rwxr-xr-xshell/ash_test/ash-misc/wait4.tests2
-rw-r--r--shell/ash_test/ash-misc/wait5.right2
-rwxr-xr-xshell/ash_test/ash-misc/wait5.tests5
-rw-r--r--shell/ash_test/ash-misc/while1.right1
-rwxr-xr-xshell/ash_test/ash-misc/while1.tests2
-rw-r--r--shell/ash_test/ash-misc/while2.right2
-rwxr-xr-xshell/ash_test/ash-misc/while2.tests2
-rw-r--r--shell/ash_test/ash-misc/while4.right1
-rwxr-xr-xshell/ash_test/ash-misc/while4.tests6
-rw-r--r--shell/ash_test/ash-misc/while_in_subshell.right1
-rwxr-xr-xshell/ash_test/ash-misc/while_in_subshell.tests2
-rwxr-xr-xshell/ash_test/ash-quoting/dollar_repl_slash_bash1.tests2
-rw-r--r--shell/ash_test/ash-quoting/dollar_squote_bash1.right1
-rwxr-xr-xshell/ash_test/ash-quoting/dollar_squote_bash1.tests1
-rw-r--r--shell/ash_test/ash-quoting/dollar_squote_bash2.right6
-rwxr-xr-xshell/ash_test/ash-quoting/dollar_squote_bash2.tests10
-rwxr-xr-xshell/ash_test/ash-read/read_r.tests6
-rw-r--r--shell/ash_test/ash-redir/redir1.right (copied from shell/hush_test/hush-misc/redir1.right)0
-rwxr-xr-xshell/ash_test/ash-redir/redir1.tests (copied from shell/hush_test/hush-misc/redir1.tests)0
-rwxr-xr-xshell/ash_test/ash-redir/redir7.tests6
-rwxr-xr-xshell/ash_test/ash-redir/redir8.tests8
-rw-r--r--shell/ash_test/ash-redir/redir_escapednum.right (copied from shell/hush_test/hush-misc/redir2.right)0
-rwxr-xr-xshell/ash_test/ash-redir/redir_escapednum.tests (copied from shell/hush_test/hush-misc/redir2.tests)0
-rw-r--r--shell/ash_test/ash-redir/redir_expand.right (copied from shell/hush_test/hush-misc/redir4.right)0
-rwxr-xr-xshell/ash_test/ash-redir/redir_expand.tests (copied from shell/hush_test/hush-misc/redir4.tests)0
-rw-r--r--shell/ash_test/ash-redir/redir_leak.right6
-rwxr-xr-xshell/ash_test/ash-redir/redir_leak.tests10
-rw-r--r--shell/ash_test/ash-redir/redir_multi.right (copied from shell/hush_test/hush-misc/redir6.right)0
-rwxr-xr-xshell/ash_test/ash-redir/redir_multi.tests (copied from shell/hush_test/hush-misc/redir6.tests)0
-rw-r--r--shell/ash_test/ash-redir/redir_script.right1
-rwxr-xr-xshell/ash_test/ash-redir/redir_script.tests29
-rw-r--r--shell/ash_test/ash-redir/redir_space.right (copied from shell/hush_test/hush-parsing/redir_space.right)0
-rwxr-xr-xshell/ash_test/ash-redir/redir_space.tests (copied from shell/hush_test/hush-parsing/redir_space.tests)0
-rw-r--r--shell/ash_test/ash-signals/continue_and_trap1.right1
-rwxr-xr-xshell/ash_test/ash-signals/continue_and_trap1.tests7
-rw-r--r--shell/ash_test/ash-signals/return_in_trap1.right4
-rwxr-xr-xshell/ash_test/ash-signals/return_in_trap1.tests18
-rw-r--r--shell/ash_test/ash-signals/save-ret.right (copied from shell/hush_test/hush-trap/save-ret.right)0
-rwxr-xr-xshell/ash_test/ash-signals/save-ret.tests (copied from shell/hush_test/hush-trap/save-ret.tests)0
-rwxr-xr-xshell/ash_test/ash-signals/signal1.tests2
-rw-r--r--shell/ash_test/ash-signals/sigquit_exec.right2
-rwxr-xr-xshell/ash_test/ash-signals/sigquit_exec.tests4
-rw-r--r--shell/ash_test/ash-vars/empty.right3
-rwxr-xr-xshell/ash_test/ash-vars/empty.tests5
-rw-r--r--shell/ash_test/ash-vars/glob_and_vars.right1
-rwxr-xr-xshell/ash_test/ash-vars/glob_and_vars.tests2
-rw-r--r--shell/ash_test/ash-vars/param_expand_len.right12
-rwxr-xr-xshell/ash_test/ash-vars/param_expand_len.tests24
-rw-r--r--shell/ash_test/ash-vars/param_glob.right4
-rwxr-xr-xshell/ash_test/ash-vars/param_glob.tests9
-rw-r--r--shell/ash_test/ash-vars/param_subshell.right7
-rwxr-xr-xshell/ash_test/ash-vars/param_subshell.tests15
-rw-r--r--shell/ash_test/ash-vars/readonly1.right2
-rwxr-xr-xshell/ash_test/ash-vars/readonly1.tests7
-rw-r--r--shell/ash_test/ash-vars/star.right (renamed from shell/msh_test/msh-vars/star.right)0
-rwxr-xr-xshell/ash_test/ash-vars/star.tests (renamed from shell/msh_test/msh-vars/star.tests)0
-rw-r--r--shell/ash_test/ash-vars/var-do-not-collapse-arithmetic-expansion-at-parse-time.right2
-rwxr-xr-xshell/ash_test/ash-vars/var-do-not-collapse-arithmetic-expansion-at-parse-time.tests3
-rw-r--r--shell/ash_test/ash-vars/var-do-not-expand-tilde-in-parameter-expansion-in-quotes.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-do-not-expand-tilde-in-parameter-expansion-in-quotes.tests2
-rw-r--r--shell/ash_test/ash-vars/var-do-not-quote-backslashes-in-parameter-expansions-outside-quotes.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-do-not-quote-backslashes-in-parameter-expansions-outside-quotes.tests3
-rw-r--r--shell/ash_test/ash-vars/var-expand-tilde-in-parameter-expansion.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-expand-tilde-in-parameter-expansion.tests2
-rw-r--r--shell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-1.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-1.tests2
-rw-r--r--shell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-2.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-2.tests2
-rw-r--r--shell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-3.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-3.tests2
-rw-r--r--shell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-4.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-4.tests2
-rw-r--r--shell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-5.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-pattern-replacement-in-parameter-expansion-5.tests2
-rw-r--r--shell/ash_test/ash-vars/var-runtime-quote-detection.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-runtime-quote-detection.tests1
-rw-r--r--shell/ash_test/ash-vars/var-utf8-length.right1
-rwxr-xr-xshell/ash_test/ash-vars/var-utf8-length.tests2
-rw-r--r--shell/ash_test/ash-vars/var1.right10
-rwxr-xr-xshell/ash_test/ash-vars/var1.tests19
-rw-r--r--shell/ash_test/ash-vars/var2.right3
-rwxr-xr-xshell/ash_test/ash-vars/var2.tests5
-rw-r--r--shell/ash_test/ash-vars/var3.right5
-rwxr-xr-xshell/ash_test/ash-vars/var3.tests1
-rw-r--r--shell/ash_test/ash-vars/var4.right1
-rwxr-xr-xshell/ash_test/ash-vars/var4.tests1
-rw-r--r--shell/ash_test/ash-vars/var5.right6
-rwxr-xr-xshell/ash_test/ash-vars/var5.tests14
-rw-r--r--shell/ash_test/ash-vars/var_bash1a.right6
-rwxr-xr-xshell/ash_test/ash-vars/var_bash1a.tests11
-rw-r--r--shell/ash_test/ash-vars/var_bash4.right25
-rwxr-xr-xshell/ash_test/ash-vars/var_bash4.tests52
-rw-r--r--shell/ash_test/ash-vars/var_bash5.right13
-rwxr-xr-xshell/ash_test/ash-vars/var_bash5.tests24
-rw-r--r--shell/ash_test/ash-vars/var_expand_in_assign.right (renamed from shell/msh_test/msh-bugs/var_expand_in_assign.right)0
-rwxr-xr-xshell/ash_test/ash-vars/var_expand_in_assign.tests (renamed from shell/msh_test/msh-bugs/var_expand_in_assign.tests)0
-rw-r--r--shell/ash_test/ash-vars/var_expand_in_redir.right (renamed from shell/msh_test/msh-bugs/var_expand_in_redir.right)0
-rwxr-xr-xshell/ash_test/ash-vars/var_expand_in_redir.tests (renamed from shell/msh_test/msh-bugs/var_expand_in_redir.tests)0
-rw-r--r--shell/ash_test/ash-vars/var_expand_on_ifs.right9
-rwxr-xr-xshell/ash_test/ash-vars/var_expand_on_ifs.tests11
-rw-r--r--shell/ash_test/ash-vars/var_in_pipes.right6
-rwxr-xr-xshell/ash_test/ash-vars/var_in_pipes.tests7
-rw-r--r--shell/ash_test/ash-vars/var_leaks.right (copied from shell/msh_test/msh-execution/many_continues.right)0
-rwxr-xr-xshell/ash_test/ash-vars/var_leaks.tests14
-rw-r--r--shell/ash_test/ash-vars/var_posix1.right30
-rwxr-xr-xshell/ash_test/ash-vars/var_posix1.tests37
-rw-r--r--shell/ash_test/ash-vars/var_serial.right5
-rwxr-xr-xshell/ash_test/ash-vars/var_serial.tests22
-rw-r--r--shell/ash_test/ash-vars/var_subst_in_for.right (renamed from shell/msh_test/msh-vars/var_subst_in_for.right)0
-rwxr-xr-xshell/ash_test/ash-vars/var_subst_in_for.tests40
-rw-r--r--shell/ash_test/ash-vars/var_unbackslash.right11
-rwxr-xr-xshell/ash_test/ash-vars/var_unbackslash.tests23
-rw-r--r--shell/ash_test/ash-vars/var_unbackslash1.right7
-rwxr-xr-xshell/ash_test/ash-vars/var_unbackslash1.tests35
-rw-r--r--shell/ash_test/ash-vars/var_wordsplit_ifs1.right41
-rwxr-xr-xshell/ash_test/ash-vars/var_wordsplit_ifs1.tests42
-rw-r--r--shell/ash_test/ash-vars/var_wordsplit_ifs2.right3
-rwxr-xr-xshell/ash_test/ash-vars/var_wordsplit_ifs2.tests13
-rw-r--r--shell/ash_test/ash-vars/var_wordsplit_ifs3.right12
-rwxr-xr-xshell/ash_test/ash-vars/var_wordsplit_ifs3.tests5
-rw-r--r--shell/ash_test/printenv.c1
-rwxr-xr-xshell/ash_test/run-all6
-rw-r--r--shell/hush.c2076
-rwxr-xr-xshell/hush_test/hush-glob/bash_brace1.tests2
-rw-r--r--shell/hush_test/hush-glob/glob3.right2
-rwxr-xr-xshell/hush_test/hush-glob/glob3.tests2
-rw-r--r--shell/hush_test/hush-glob/glob_dir.right19
-rwxr-xr-xshell/hush_test/hush-glob/glob_dir.tests25
-rw-r--r--shell/hush_test/hush-heredoc/heredoc1.right (renamed from shell/hush_test/hush-misc/heredoc1.right)0
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc1.tests (renamed from shell/hush_test/hush-misc/heredoc1.tests)0
-rw-r--r--shell/hush_test/hush-heredoc/heredoc2.right2
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc2.tests7
-rw-r--r--shell/hush_test/hush-heredoc/heredoc3.right (renamed from shell/hush_test/hush-misc/heredoc3.right)0
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc3.tests (renamed from shell/hush_test/hush-misc/heredoc3.tests)0
-rw-r--r--shell/hush_test/hush-heredoc/heredoc4.right1
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc4.tests3
-rw-r--r--shell/hush_test/hush-heredoc/heredoc5.right (renamed from shell/hush_test/hush-misc/heredoc2.right)0
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc5.tests (renamed from shell/hush_test/hush-misc/heredoc2.tests)0
-rw-r--r--shell/hush_test/hush-heredoc/heredoc6.right2
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc6.tests4
-rw-r--r--shell/hush_test/hush-heredoc/heredoc7.right1
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc7.tests3
-rw-r--r--shell/hush_test/hush-heredoc/heredoc_backslash1.right (renamed from shell/hush_test/hush-misc/heredoc_backslash1.right)0
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc_backslash1.tests (renamed from shell/hush_test/hush-misc/heredoc_backslash1.tests)0
-rw-r--r--shell/hush_test/hush-heredoc/heredoc_huge.right (renamed from shell/hush_test/hush-misc/heredoc_huge.right)0
-rwxr-xr-xshell/hush_test/hush-heredoc/heredoc_huge.tests (renamed from shell/hush_test/hush-misc/heredoc_huge.tests)0
-rw-r--r--shell/hush_test/hush-invert/invert.right10
-rwxr-xr-xshell/hush_test/hush-invert/invert.tests19
-rw-r--r--shell/hush_test/hush-misc/assignment2.right2
-rw-r--r--shell/hush_test/hush-misc/assignment2.rigth2
-rwxr-xr-xshell/hush_test/hush-misc/assignment2.tests1
-rw-r--r--shell/hush_test/hush-misc/eval1.right1
-rwxr-xr-xshell/hush_test/hush-misc/eval1.tests4
-rw-r--r--shell/hush_test/hush-misc/eval2.right3
-rwxr-xr-xshell/hush_test/hush-misc/eval2.tests4
-rw-r--r--shell/hush_test/hush-misc/exitcode1.right2
-rwxr-xr-xshell/hush_test/hush-misc/exitcode1.tests2
-rw-r--r--shell/hush_test/hush-misc/exitcode2.right4
-rwxr-xr-xshell/hush_test/hush-misc/exitcode2.tests12
-rw-r--r--shell/hush_test/hush-misc/exitcode_EACCES.right2
-rwxr-xr-xshell/hush_test/hush-misc/exitcode_EACCES.tests (renamed from shell/msh_test/msh-execution/exitcode_EACCES.tests)0
-rw-r--r--shell/hush_test/hush-misc/exitcode_ENOENT.right2
-rwxr-xr-xshell/hush_test/hush-misc/exitcode_ENOENT.tests (renamed from shell/msh_test/msh-execution/exitcode_ENOENT.tests)0
-rw-r--r--shell/hush_test/hush-misc/for.right (copied from shell/msh_test/msh-execution/many_continues.right)0
-rwxr-xr-xshell/hush_test/hush-misc/for.tests5
-rw-r--r--shell/hush_test/hush-misc/func6.right2
-rwxr-xr-xshell/hush_test/hush-misc/func6.tests11
-rwxr-xr-xshell/hush_test/hush-misc/func_args1.tests2
-rw-r--r--shell/hush_test/hush-misc/group_in_braces.right5
-rwxr-xr-xshell/hush_test/hush-misc/group_in_braces.tests11
-rw-r--r--shell/hush_test/hush-misc/last_amp.right2
-rwxr-xr-xshell/hush_test/hush-misc/last_amp.tests8
-rw-r--r--shell/hush_test/hush-misc/local1.right4
-rwxr-xr-xshell/hush_test/hush-misc/local1.tests11
-rw-r--r--shell/hush_test/hush-misc/nommu3.right2
-rwxr-xr-xshell/hush_test/hush-misc/nommu3.tests15
-rw-r--r--shell/hush_test/hush-misc/nulltick1.right3
-rwxr-xr-xshell/hush_test/hush-misc/nulltick1.tests3
-rw-r--r--shell/hush_test/hush-misc/source1.right7
-rwxr-xr-xshell/hush_test/hush-misc/source1.tests15
-rw-r--r--shell/hush_test/hush-misc/source2.right5
-rwxr-xr-xshell/hush_test/hush-misc/source2.tests11
-rw-r--r--shell/hush_test/hush-misc/source3.right2
-rwxr-xr-xshell/hush_test/hush-misc/source3.tests6
-rw-r--r--shell/hush_test/hush-misc/source4.right5
-rwxr-xr-xshell/hush_test/hush-misc/source4.tests10
-rw-r--r--shell/hush_test/hush-misc/source5.right4
-rwxr-xr-xshell/hush_test/hush-misc/source5.tests8
-rw-r--r--shell/hush_test/hush-misc/unicode1.right3
-rwxr-xr-xshell/hush_test/hush-misc/unicode1.tests13
-rw-r--r--shell/hush_test/hush-misc/wait1.right2
-rwxr-xr-xshell/hush_test/hush-misc/wait1.tests3
-rw-r--r--shell/hush_test/hush-misc/wait2.right2
-rwxr-xr-xshell/hush_test/hush-misc/wait2.tests4
-rw-r--r--shell/hush_test/hush-misc/wait3.right2
-rwxr-xr-xshell/hush_test/hush-misc/wait3.tests3
-rw-r--r--shell/hush_test/hush-misc/wait4.right1
-rwxr-xr-xshell/hush_test/hush-misc/wait4.tests2
-rw-r--r--shell/hush_test/hush-misc/wait5.right2
-rwxr-xr-xshell/hush_test/hush-misc/wait5.tests5
-rw-r--r--shell/hush_test/hush-quoting/dollar_repl_slash_bash1.right10
-rwxr-xr-xshell/hush_test/hush-quoting/dollar_repl_slash_bash1.tests21
-rwxr-xr-xshell/hush_test/hush-read/read_r.tests6
-rw-r--r--shell/hush_test/hush-redir/redir1.right (renamed from shell/hush_test/hush-misc/redir1.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir1.tests (renamed from shell/hush_test/hush-misc/redir1.tests)0
-rw-r--r--shell/hush_test/hush-redir/redir2.right (copied from shell/msh_test/msh-execution/many_continues.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir2.tests5
-rw-r--r--shell/hush_test/hush-redir/redir3.right (renamed from shell/hush_test/hush-misc/redir3.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir3.tests (renamed from shell/hush_test/hush-misc/redir3.tests)0
-rw-r--r--shell/hush_test/hush-redir/redir4.right (renamed from shell/msh_test/msh-execution/many_continues.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir4.tests72
-rw-r--r--shell/hush_test/hush-redir/redir5.right (renamed from shell/hush_test/hush-misc/redir5.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir5.tests (renamed from shell/hush_test/hush-misc/redir5.tests)0
-rw-r--r--shell/hush_test/hush-redir/redir6.right2
-rwxr-xr-xshell/hush_test/hush-redir/redir6.tests3
-rw-r--r--shell/hush_test/hush-redir/redir7.right3
-rwxr-xr-xshell/hush_test/hush-redir/redir7.tests12
-rw-r--r--shell/hush_test/hush-redir/redir8.right3
-rwxr-xr-xshell/hush_test/hush-redir/redir8.tests15
-rw-r--r--shell/hush_test/hush-redir/redir9.right2
-rwxr-xr-xshell/hush_test/hush-redir/redir9.tests4
-rw-r--r--shell/hush_test/hush-redir/redirA.right2
-rwxr-xr-xshell/hush_test/hush-redir/redirA.tests11
-rw-r--r--shell/hush_test/hush-redir/redir_escapednum.right (copied from shell/hush_test/hush-misc/redir2.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir_escapednum.tests (renamed from shell/hush_test/hush-misc/redir2.tests)0
-rw-r--r--shell/hush_test/hush-redir/redir_expand.right (renamed from shell/hush_test/hush-misc/redir4.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir_expand.tests (renamed from shell/hush_test/hush-misc/redir4.tests)0
-rw-r--r--shell/hush_test/hush-redir/redir_leak.right6
-rwxr-xr-xshell/hush_test/hush-redir/redir_leak.tests10
-rw-r--r--shell/hush_test/hush-redir/redir_multi.right (renamed from shell/hush_test/hush-misc/redir6.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir_multi.tests (renamed from shell/hush_test/hush-misc/redir6.tests)0
-rw-r--r--shell/hush_test/hush-redir/redir_script.right1
-rwxr-xr-xshell/hush_test/hush-redir/redir_script.tests29
-rw-r--r--shell/hush_test/hush-redir/redir_space.right (renamed from shell/hush_test/hush-parsing/redir_space.right)0
-rwxr-xr-xshell/hush_test/hush-redir/redir_space.tests (renamed from shell/hush_test/hush-parsing/redir_space.tests)0
-rw-r--r--shell/hush_test/hush-signals/catch.right (renamed from shell/hush_test/hush-trap/catch.right)0
-rwxr-xr-xshell/hush_test/hush-signals/catch.tests (renamed from shell/hush_test/hush-trap/catch.tests)0
-rw-r--r--shell/hush_test/hush-signals/continue_and_trap1.right1
-rwxr-xr-xshell/hush_test/hush-signals/continue_and_trap1.tests7
-rw-r--r--shell/hush_test/hush-signals/exit.right (renamed from shell/hush_test/hush-trap/exit.right)0
-rwxr-xr-xshell/hush_test/hush-signals/exit.tests (renamed from shell/hush_test/hush-trap/exit.tests)0
-rw-r--r--shell/hush_test/hush-signals/reap1.right (renamed from shell/hush_test/hush-misc/redir2.right)0
-rwxr-xr-xshell/hush_test/hush-signals/reap1.tests14
-rw-r--r--shell/hush_test/hush-signals/return_in_trap1.right4
-rwxr-xr-xshell/hush_test/hush-signals/return_in_trap1.tests18
-rw-r--r--shell/hush_test/hush-signals/save-ret.right (renamed from shell/hush_test/hush-trap/save-ret.right)0
-rwxr-xr-xshell/hush_test/hush-signals/save-ret.tests (renamed from shell/hush_test/hush-trap/save-ret.tests)0
-rw-r--r--shell/hush_test/hush-signals/savetrap.right (renamed from shell/hush_test/hush-trap/savetrap.right)0
-rwxr-xr-xshell/hush_test/hush-signals/savetrap.tests (renamed from shell/hush_test/hush-trap/savetrap.tests)0
-rw-r--r--shell/hush_test/hush-signals/sigint1.right1
-rwxr-xr-xshell/hush_test/hush-signals/sigint1.tests41
-rw-r--r--shell/hush_test/hush-signals/signal2.right3
-rwxr-xr-xshell/hush_test/hush-signals/signal2.tests18
-rw-r--r--shell/hush_test/hush-signals/signal3.right4
-rwxr-xr-xshell/hush_test/hush-signals/signal3.tests17
-rw-r--r--shell/hush_test/hush-signals/signal5.right12
-rwxr-xr-xshell/hush_test/hush-signals/signal5.tests14
-rw-r--r--shell/hush_test/hush-signals/signal6.right2
-rwxr-xr-xshell/hush_test/hush-signals/signal6.tests2
-rw-r--r--shell/hush_test/hush-signals/signal7.right (renamed from shell/hush_test/hush-trap/signal7.right)0
-rwxr-xr-xshell/hush_test/hush-signals/signal7.tests (renamed from shell/hush_test/hush-trap/signal7.tests)0
-rw-r--r--shell/hush_test/hush-signals/signal_read1.right (renamed from shell/hush_test/hush-trap/signal_read1.right)0
-rwxr-xr-xshell/hush_test/hush-signals/signal_read1.tests (renamed from shell/hush_test/hush-trap/signal_read1.tests)0
-rw-r--r--shell/hush_test/hush-signals/signal_read2.right (renamed from shell/hush_test/hush-trap/signal_read2.right)0
-rwxr-xr-xshell/hush_test/hush-signals/signal_read2.tests (renamed from shell/hush_test/hush-trap/signal_read2.tests)0
-rw-r--r--shell/hush_test/hush-signals/sigquit_exec.right2
-rwxr-xr-xshell/hush_test/hush-signals/sigquit_exec.tests4
-rw-r--r--shell/hush_test/hush-signals/subshell.right (renamed from shell/hush_test/hush-trap/subshell.right)0
-rwxr-xr-xshell/hush_test/hush-signals/subshell.tests (renamed from shell/hush_test/hush-trap/subshell.tests)0
-rw-r--r--shell/hush_test/hush-signals/usage.right (renamed from shell/hush_test/hush-trap/usage.right)0
-rwxr-xr-xshell/hush_test/hush-signals/usage.tests (renamed from shell/hush_test/hush-trap/usage.tests)0
-rw-r--r--shell/hush_test/hush-standalone/noexec_gets_no_env.right4
-rwxr-xr-xshell/hush_test/hush-standalone/noexec_gets_no_env.tests5
-rw-r--r--shell/hush_test/hush-standalone/nofork_trashes_getopt.right1
-rwxr-xr-xshell/hush_test/hush-standalone/nofork_trashes_getopt.tests6
-rw-r--r--shell/hush_test/hush-standalone/var_standalone1.right1
-rwxr-xr-xshell/hush_test/hush-standalone/var_standalone1.tests2
-rw-r--r--shell/hush_test/hush-vars/param_expand_len.right3
-rwxr-xr-xshell/hush_test/hush-vars/param_expand_len.tests7
-rw-r--r--shell/hush_test/hush-vars/var-do-not-collapse-arithmetic-expansion-at-parse-time.right2
-rwxr-xr-xshell/hush_test/hush-vars/var-do-not-collapse-arithmetic-expansion-at-parse-time.tests3
-rw-r--r--shell/hush_test/hush-vars/var-do-not-expand-tilde-in-parameter-expansion-in-quotes.right1
-rwxr-xr-xshell/hush_test/hush-vars/var-do-not-expand-tilde-in-parameter-expansion-in-quotes.tests2
-rw-r--r--shell/hush_test/hush-vars/var-do-not-quote-backslashes-in-parameter-expansions-outside-quotes.right1
-rwxr-xr-xshell/hush_test/hush-vars/var-do-not-quote-backslashes-in-parameter-expansions-outside-quotes.tests3
-rw-r--r--shell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-1.right1
-rwxr-xr-xshell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-1.tests2
-rw-r--r--shell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-2.right1
-rwxr-xr-xshell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-2.tests2
-rw-r--r--shell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-3.right1
-rwxr-xr-xshell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-3.tests2
-rw-r--r--shell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-4.right1
-rwxr-xr-xshell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-4.tests2
-rw-r--r--shell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-5.right1
-rwxr-xr-xshell/hush_test/hush-vars/var-pattern-replacement-in-parameter-expansion-5.tests2
-rw-r--r--shell/hush_test/hush-vars/var-runtime-quote-detection.right1
-rwxr-xr-xshell/hush_test/hush-vars/var-runtime-quote-detection.tests1
-rw-r--r--shell/hush_test/hush-vars/var3.right7
-rwxr-xr-xshell/hush_test/hush-vars/var3.tests5
-rw-r--r--shell/hush_test/hush-vars/var4.right1
-rwxr-xr-xshell/hush_test/hush-vars/var4.tests1
-rw-r--r--shell/hush_test/hush-vars/var5.right6
-rwxr-xr-xshell/hush_test/hush-vars/var5.tests14
-rw-r--r--shell/hush_test/hush-vars/var6.right2
-rwxr-xr-xshell/hush_test/hush-vars/var6.tests4
-rw-r--r--shell/hush_test/hush-vars/var_unbackslash1.right7
-rwxr-xr-xshell/hush_test/hush-vars/var_unbackslash1.tests35
-rw-r--r--shell/hush_test/hush-vars/var_wordsplit_ifs1.right41
-rwxr-xr-xshell/hush_test/hush-vars/var_wordsplit_ifs1.tests42
-rw-r--r--shell/hush_test/hush-vars/var_wordsplit_ifs2.right3
-rwxr-xr-xshell/hush_test/hush-vars/var_wordsplit_ifs2.tests13
-rw-r--r--shell/hush_test/hush-vars/var_wordsplit_ifs3.right12
-rwxr-xr-xshell/hush_test/hush-vars/var_wordsplit_ifs3.tests5
-rwxr-xr-xshell/hush_test/run-all3
-rw-r--r--shell/math.c27
-rw-r--r--shell/math.h2
-rw-r--r--shell/msh_test/msh-bugs/noeol3.right1
-rwxr-xr-xshell/msh_test/msh-bugs/noeol3.tests2
-rw-r--r--shell/msh_test/msh-bugs/process_subst.right3
-rwxr-xr-xshell/msh_test/msh-bugs/process_subst.tests3
-rw-r--r--shell/msh_test/msh-bugs/starquoted.right8
-rwxr-xr-xshell/msh_test/msh-bugs/starquoted.tests8
-rw-r--r--shell/msh_test/msh-bugs/syntax_err.right2
-rwxr-xr-xshell/msh_test/msh-bugs/syntax_err.tests3
-rw-r--r--shell/msh_test/msh-execution/exitcode_EACCES.right2
-rw-r--r--shell/msh_test/msh-execution/exitcode_ENOENT.right2
-rwxr-xr-xshell/msh_test/msh-execution/many_continues.tests15
-rw-r--r--shell/msh_test/msh-execution/nested_break.right8
-rwxr-xr-xshell/msh_test/msh-execution/nested_break.tests17
-rw-r--r--shell/msh_test/msh-misc/tick.right2
-rwxr-xr-xshell/msh_test/msh-misc/tick.tests4
-rwxr-xr-xshell/msh_test/msh-parsing/argv0.tests4
-rw-r--r--shell/msh_test/msh-parsing/noeol.right1
-rwxr-xr-xshell/msh_test/msh-parsing/noeol.tests2
-rw-r--r--shell/msh_test/msh-parsing/noeol2.right1
-rwxr-xr-xshell/msh_test/msh-parsing/noeol2.tests7
-rw-r--r--shell/msh_test/msh-parsing/quote1.right1
-rwxr-xr-xshell/msh_test/msh-parsing/quote1.tests2
-rw-r--r--shell/msh_test/msh-parsing/quote2.right1
-rwxr-xr-xshell/msh_test/msh-parsing/quote2.tests2
-rw-r--r--shell/msh_test/msh-parsing/quote3.right3
-rwxr-xr-xshell/msh_test/msh-parsing/quote3.tests8
-rw-r--r--shell/msh_test/msh-parsing/quote4.right1
-rwxr-xr-xshell/msh_test/msh-parsing/quote4.tests2
-rw-r--r--shell/msh_test/msh-vars/var.right4
-rwxr-xr-xshell/msh_test/msh-vars/var.tests9
-rwxr-xr-xshell/msh_test/msh-vars/var_subst_in_for.tests40
-rwxr-xr-xshell/msh_test/run-all64
-rw-r--r--shell/random.c142
-rw-r--r--shell/random.h16
-rw-r--r--shell/shell_common.c6
-rw-r--r--shell/shell_common.h2
-rw-r--r--sysklogd/Config.src159
-rw-r--r--sysklogd/Kbuild.src4
-rw-r--r--sysklogd/klogd.c39
-rw-r--r--sysklogd/logger.c15
-rw-r--r--sysklogd/logread.c46
-rw-r--r--sysklogd/syslogd.c248
-rw-r--r--sysklogd/syslogd_and_logger.c1
-rwxr-xr-xtestsuite/ar.tests2
-rwxr-xr-xtestsuite/awk.tests24
-rwxr-xr-xtestsuite/busybox.tests16
-rwxr-xr-xtestsuite/bzcat.tests88
-rw-r--r--testsuite/bzcat/bzcat-does-not-remove-compressed-file (renamed from testsuite/bunzip2/bzcat-does-not-remove-compressed-file)0
-rwxr-xr-xtestsuite/cpio.tests27
-rwxr-xr-xtestsuite/dc.tests56
-rwxr-xr-xtestsuite/diff.tests23
-rw-r--r--testsuite/du/du-m-works2
-rwxr-xr-xtestsuite/find.tests76
-rwxr-xr-xtestsuite/grep.tests34
-rw-r--r--testsuite/gzip/gzip-compression-levels5
-rwxr-xr-xtestsuite/makedevs.tests2
-rwxr-xr-xtestsuite/md5sum.tests22
-rwxr-xr-xtestsuite/mdev.tests2
-rwxr-xr-xtestsuite/patch.tests45
-rw-r--r--testsuite/pwd/pwd-prints-working-directory5
-rwxr-xr-xtestsuite/readlink.tests11
-rwxr-xr-xtestsuite/sed.tests72
-rwxr-xr-xtestsuite/sha3sum.tests2
-rwxr-xr-xtestsuite/sort.tests55
-rwxr-xr-xtestsuite/tar.tests77
-rw-r--r--testsuite/tar.utf8.tar.bz23
-rwxr-xr-xtestsuite/test.tests20
-rwxr-xr-xtestsuite/unzip.tests24
-rw-r--r--testsuite/which/which-uses-default-path2
-rw-r--r--util-linux/Config.src644
-rw-r--r--util-linux/Kbuild.src37
-rw-r--r--util-linux/acpid.c36
-rw-r--r--util-linux/blkdiscard.c82
-rw-r--r--util-linux/blkid.c20
-rw-r--r--util-linux/blockdev.c9
-rw-r--r--util-linux/dmesg.c95
-rw-r--r--util-linux/fatattr.c105
-rw-r--r--util-linux/fbset.c63
-rw-r--r--util-linux/fdformat.c14
-rw-r--r--util-linux/fdisk.c351
-rw-r--r--util-linux/fdisk_gpt.c58
-rw-r--r--util-linux/fdisk_osf.c5
-rw-r--r--util-linux/fdisk_sgi.c29
-rw-r--r--util-linux/findfs.c16
-rw-r--r--util-linux/flock.c30
-rw-r--r--util-linux/freeramdisk.c30
-rw-r--r--util-linux/fsck_minix.c30
-rw-r--r--util-linux/fstrim.c27
-rw-r--r--util-linux/getopt.c31
-rw-r--r--util-linux/hexdump.c32
-rw-r--r--util-linux/hwclock.c50
-rw-r--r--util-linux/ipcrm.c13
-rw-r--r--util-linux/ipcs.c11
-rw-r--r--util-linux/losetup.c12
-rw-r--r--util-linux/lspci.c13
-rw-r--r--util-linux/lsusb.c13
-rw-r--r--util-linux/mdev.c141
-rw-r--r--util-linux/minix.h5
-rw-r--r--util-linux/mkfs_ext2.c33
-rw-r--r--util-linux/mkfs_minix.c34
-rw-r--r--util-linux/mkfs_reiser.c21
-rw-r--r--util-linux/mkfs_vfat.c23
-rw-r--r--util-linux/mkswap.c27
-rw-r--r--util-linux/more.c27
-rw-r--r--util-linux/mount.c187
-rw-r--r--util-linux/nsenter.c291
-rw-r--r--util-linux/pivot_root.c16
-rw-r--r--util-linux/rdate.c24
-rw-r--r--util-linux/rdev.c9
-rw-r--r--util-linux/readprofile.c20
-rw-r--r--util-linux/rev.c9
-rw-r--r--util-linux/rtcwake.c79
-rw-r--r--util-linux/script.c26
-rw-r--r--util-linux/scriptreplay.c10
-rw-r--r--util-linux/setarch.c79
-rw-r--r--util-linux/swaponoff.c311
-rw-r--r--util-linux/switch_root.c25
-rw-r--r--util-linux/uevent.c130
-rw-r--r--util-linux/umount.c43
-rw-r--r--util-linux/unshare.c379
-rw-r--r--util-linux/volume_id/bcache.c110
-rw-r--r--util-linux/volume_id/get_devname.c10
-rw-r--r--util-linux/volume_id/luks.c2
-rw-r--r--util-linux/volume_id/ubifs.c125
-rw-r--r--util-linux/volume_id/volume_id.c6
-rw-r--r--util-linux/volume_id/volume_id_internal.h4
1303 files changed, 32187 insertions, 57138 deletions
diff --git a/editors/vi.c b/editors/vi.c
index ccf53a9..432fba8 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -17,7 +17,6 @@
* it would be easier to change the mark when add/delete lines
* More intelligence in refresh()
* ":r !cmd" and "!cmd" to filter text through an external command
- * A true "undo" facility
* An "ex" line oriented mode- maybe using "cmdedit"
*/
@@ -136,6 +135,36 @@
//config: cursor position using "ESC [ 6 n" escape sequence, then read stdin.
//config:
//config: This is not clean but helps a lot on serial lines and such.
+//config:config FEATURE_VI_UNDO
+//config: bool "Support undo command 'u'"
+//config: default y
+//config: depends on VI
+//config: help
+//config: Support the 'u' command to undo insertion, deletion, and replacement
+//config: of text.
+//config:config FEATURE_VI_UNDO_QUEUE
+//config: bool "Enable undo operation queuing"
+//config: default y
+//config: depends on FEATURE_VI_UNDO
+//config: help
+//config: The vi undo functions can use an intermediate queue to greatly lower
+//config: malloc() calls and overhead. When the maximum size of this queue is
+//config: reached, the contents of the queue are committed to the undo stack.
+//config: This increases the size of the undo code and allows some undo
+//config: operations (especially un-typing/backspacing) to be far more useful.
+//config:config FEATURE_VI_UNDO_QUEUE_MAX
+//config: int "Maximum undo character queue size"
+//config: default 256
+//config: range 32 65536
+//config: depends on FEATURE_VI_UNDO_QUEUE
+//config: help
+//config: This option sets the number of bytes used at runtime for the queue.
+//config: Smaller values will create more undo objects and reduce the amount
+//config: of typed or backspaced characters that are grouped into one undo
+//config: operation; larger values increase the potential size of each undo
+//config: and will generally malloc() larger objects and less frequently.
+//config: Unless you want more (or less) frequent "undo points" while typing,
+//config: you should probably leave this unchanged.
//applet:IF_VI(APPLET(vi, BB_DIR_BIN, BB_SUID_DROP))
@@ -222,7 +251,7 @@ enum {
// cmds modifying text[]
// vda: removed "aAiIs" as they switch us into insert mode
// and remembering input for replay after them makes no sense
-static const char modifying_cmds[] = "cCdDJoOpPrRxX<>~";
+static const char modifying_cmds[] ALIGN1 = "cCdDJoOpPrRxX<>~";
#endif
enum {
@@ -277,8 +306,8 @@ struct globals {
smallint editing; // >0 while we are editing a file
// [code audit says "can be 0, 1 or 2 only"]
smallint cmd_mode; // 0=command 1=insert 2=replace
- int file_modified; // buffer contents changed (counter, not flag!)
- int last_file_modified; // = -1;
+ int modified_count; // buffer contents changed if !0
+ int last_modified_count; // = -1;
int save_argc; // how many file names on cmd line
int cmdcnt; // repetition count
int rows, columns; // the terminal screen is this size
@@ -347,6 +376,41 @@ struct globals {
char get_input_line__buf[MAX_INPUT_LEN]; /* former static */
char scr_out_buf[MAX_SCR_COLS + MAX_TABSTOP * 2];
+#if ENABLE_FEATURE_VI_UNDO
+// undo_push() operations
+#define UNDO_INS 0
+#define UNDO_DEL 1
+#define UNDO_INS_CHAIN 2
+#define UNDO_DEL_CHAIN 3
+// UNDO_*_QUEUED must be equal to UNDO_xxx ORed with UNDO_QUEUED_FLAG
+#define UNDO_QUEUED_FLAG 4
+#define UNDO_INS_QUEUED 4
+#define UNDO_DEL_QUEUED 5
+#define UNDO_USE_SPOS 32
+#define UNDO_EMPTY 64
+// Pass-through flags for functions that can be undone
+#define NO_UNDO 0
+#define ALLOW_UNDO 1
+#define ALLOW_UNDO_CHAIN 2
+# if ENABLE_FEATURE_VI_UNDO_QUEUE
+#define ALLOW_UNDO_QUEUED 3
+ char undo_queue_state;
+ int undo_q;
+ char *undo_queue_spos; // Start position of queued operation
+ char undo_queue[CONFIG_FEATURE_VI_UNDO_QUEUE_MAX];
+# else
+// If undo queuing disabled, don't invoke the missing queue logic
+#define ALLOW_UNDO_QUEUED 1
+# endif
+
+ struct undo_object {
+ struct undo_object *prev; // Linking back avoids list traversal (LIFO)
+ int start; // Offset where the data should be restored/deleted
+ int length; // total data size
+ uint8_t u_type; // 0=deleted, 1=inserted, 2=swapped
+ char undo_text[1]; // text that was deleted (if deletion)
+ } *undo_stack_tail;
+#endif /* ENABLE_FEATURE_VI_UNDO */
};
#define G (*ptr_to_globals)
#define text (G.text )
@@ -358,8 +422,8 @@ struct globals {
#define vi_setops (G.vi_setops )
#define editing (G.editing )
#define cmd_mode (G.cmd_mode )
-#define file_modified (G.file_modified )
-#define last_file_modified (G.last_file_modified )
+#define modified_count (G.modified_count )
+#define last_modified_count (G.last_modified_count)
#define save_argc (G.save_argc )
#define cmdcnt (G.cmdcnt )
#define rows (G.rows )
@@ -408,15 +472,24 @@ struct globals {
#define last_modifying_cmd (G.last_modifying_cmd )
#define get_input_line__buf (G.get_input_line__buf)
+#if ENABLE_FEATURE_VI_UNDO
+#define undo_stack_tail (G.undo_stack_tail )
+# if ENABLE_FEATURE_VI_UNDO_QUEUE
+#define undo_queue_state (G.undo_queue_state)
+#define undo_q (G.undo_q )
+#define undo_queue (G.undo_queue )
+#define undo_queue_spos (G.undo_queue_spos )
+# endif
+#endif
+
#define INIT_G() do { \
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
- last_file_modified = -1; \
+ last_modified_count = -1; \
/* "" but has space for 2 chars: */ \
IF_FEATURE_VI_SEARCH(last_search_pattern = xzalloc(2);) \
} while (0)
-static int init_text_buffer(char *); // init from file or create new
static void edit_file(char *); // edit one file
static void do_cmd(int); // execute a command
static int next_tabstop(int);
@@ -427,7 +500,7 @@ static char *prev_line(char *); // return pointer to prev line B-o-l
static char *next_line(char *); // return pointer to next line B-o-l
static char *end_screen(void); // get pointer to last char on screen
static int count_lines(char *, char *); // count line from start to stop
-static char *find_line(int); // find begining of line #li
+static char *find_line(int); // find beginning of line #li
static char *move_to_col(char *, int); // move "p" to column l
static void dot_left(void); // move dot left- dont leave line
static void dot_right(void); // move dot right- dont leave line
@@ -437,10 +510,12 @@ static void dot_next(void); // move dot to next line B-o-l
static void dot_prev(void); // move dot to prev line B-o-l
static void dot_scroll(int, int); // move the screen up or down
static void dot_skip_over_ws(void); // move dot pat WS
-static void dot_delete(void); // delete the char at 'dot'
static char *bound_dot(char *); // make sure text[0] <= P < "end"
static char *new_screen(int, int); // malloc virtual screen memory
-static char *char_insert(char *, char); // insert the char c at 'p'
+#if !ENABLE_FEATURE_VI_UNDO
+#define char_insert(a,b,c) char_insert(a,b)
+#endif
+static char *char_insert(char *, char, int); // insert the char c at 'p'
// might reallocate text[]! use p += stupid_insert(p, ...),
// and be careful to not use pointers into potentially freed text[]!
static uintptr_t stupid_insert(char *, char); // stupidly insert the char c at 'p'
@@ -448,11 +523,17 @@ static int find_range(char **, char **, char); // return pointers for an object
static int st_test(char *, int, int, char *); // helper for skip_thing()
static char *skip_thing(char *, int, int, int); // skip some object
static char *find_pair(char *, char); // find matching pair () [] {}
-static char *text_hole_delete(char *, char *); // at "p", delete a 'size' byte hole
+#if !ENABLE_FEATURE_VI_UNDO
+#define text_hole_delete(a,b,c) text_hole_delete(a,b)
+#endif
+static char *text_hole_delete(char *, char *, int); // at "p", delete a 'size' byte hole
// might reallocate text[]! use p += text_hole_make(p, ...),
// and be careful to not use pointers into potentially freed text[]!
static uintptr_t text_hole_make(char *, int); // at "p", make a 'size' byte hole
-static char *yank_delete(char *, char *, int, int); // yank text[] into register then delete
+#if !ENABLE_FEATURE_VI_UNDO
+#define yank_delete(a,b,c,d,e) yank_delete(a,b,c,d)
+#endif
+static char *yank_delete(char *, char *, int, int, int); // yank text[] into register then delete
static void show_help(void); // display some help info
static void rawmode(void); // set "raw" mode on tty
static void cookmode(void); // return to "cooked" mode on tty
@@ -460,10 +541,6 @@ static void cookmode(void); // return to "cooked" mode on tty
static int mysleep(int);
static int readit(void); // read (maybe cursor) key from stdin
static int get_one_char(void); // read 1 char from stdin
-static int file_size(const char *); // what is the byte size of "fn"
-#if !ENABLE_FEATURE_VI_READONLY
-#define file_insert(fn, p, update_ro_status) file_insert(fn, p)
-#endif
// file_insert might reallocate text[]!
static int file_insert(const char *, char *, int);
static int file_write(char *, char *, char *);
@@ -485,8 +562,7 @@ static void redraw(int); // force a full screen refresh
static char* format_line(char* /*, int*/);
static void refresh(int); // update the terminal from screen[]
-static void Indicate_Error(void); // use flash or beep to indicate error
-#define indicate_error(c) Indicate_Error()
+static void indicate_error(void); // use flash or beep to indicate error
static void Hit_Return(void);
#if ENABLE_FEATURE_VI_SEARCH
@@ -495,8 +571,8 @@ static char *char_search(char *, const char *, int, int); // search for pattern
#if ENABLE_FEATURE_VI_COLON
static char *get_one_address(char *, int *); // get colon addr, if present
static char *get_address(char *, int *, int *); // get two colon addrs, if present
-static void colon(char *); // execute the "colon" mode cmds
#endif
+static void colon(char *); // execute the "colon" mode cmds
#if ENABLE_FEATURE_VI_USE_SIGNALS
static void winch_sig(int); // catch window size changes
static void suspend_sig(int); // catch ctrl-Z
@@ -514,20 +590,36 @@ static void showmatching(char *); // show the matching pair () [] {}
#if ENABLE_FEATURE_VI_YANKMARK || (ENABLE_FEATURE_VI_COLON && ENABLE_FEATURE_VI_SEARCH) || ENABLE_FEATURE_VI_CRASHME
// might reallocate text[]! use p += string_insert(p, ...),
// and be careful to not use pointers into potentially freed text[]!
-static uintptr_t string_insert(char *, const char *); // insert the string at 'p'
+# if !ENABLE_FEATURE_VI_UNDO
+#define string_insert(a,b,c) string_insert(a,b)
+# endif
+static uintptr_t string_insert(char *, const char *, int); // insert the string at 'p'
#endif
#if ENABLE_FEATURE_VI_YANKMARK
static char *text_yank(char *, char *, int); // save copy of "p" into a register
static char what_reg(void); // what is letter of current YDreg
static void check_context(char); // remember context for '' command
#endif
+#if ENABLE_FEATURE_VI_UNDO
+static void flush_undo_data(void);
+static void undo_push(char *, unsigned int, unsigned char); // Push an operation on the undo stack
+static void undo_pop(void); // Undo the last operation
+# if ENABLE_FEATURE_VI_UNDO_QUEUE
+static void undo_queue_commit(void); // Flush any queued objects to the undo stack
+# else
+# define undo_queue_commit() ((void)0)
+# endif
+#else
+#define flush_undo_data() ((void)0)
+#define undo_queue_commit() ((void)0)
+#endif
+
#if ENABLE_FEATURE_VI_CRASHME
static void crash_dummy();
static void crash_test();
static int crashme = 0;
#endif
-
static void write1(const char *out)
{
fputs(out, stdout);
@@ -540,6 +632,14 @@ int vi_main(int argc, char **argv)
INIT_G();
+#if ENABLE_FEATURE_VI_UNDO
+ /* undo_stack_tail = NULL; - already is */
+#if ENABLE_FEATURE_VI_UNDO_QUEUE
+ undo_queue_state = UNDO_EMPTY;
+ /* undo_q = 0; - already is */
+#endif
+#endif
+
#if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME
my_pid = getpid();
#endif
@@ -618,30 +718,29 @@ int vi_main(int argc, char **argv)
static int init_text_buffer(char *fn)
{
int rc;
- int size = file_size(fn); // file size. -1 means does not exist.
+
+ flush_undo_data();
+ modified_count = 0;
+ last_modified_count = -1;
+#if ENABLE_FEATURE_VI_YANKMARK
+ /* init the marks */
+ memset(mark, 0, sizeof(mark));
+#endif
/* allocate/reallocate text buffer */
free(text);
- text_size = size + 10240;
+ text_size = 10240;
screenbegin = dot = end = text = xzalloc(text_size);
if (fn != current_filename) {
free(current_filename);
current_filename = xstrdup(fn);
}
- if (size < 0) {
- // file dont exist. Start empty buf with dummy line
- char_insert(text, '\n');
- rc = 0;
- } else {
- rc = file_insert(fn, text, 1);
+ rc = file_insert(fn, text, 1);
+ if (rc < 0) {
+ // file doesnt exist. Start empty buf with dummy line
+ char_insert(text, '\n', NO_UNDO);
}
- file_modified = 0;
- last_file_modified = -1;
-#if ENABLE_FEATURE_VI_YANKMARK
- /* init the marks. */
- memset(mark, 0, sizeof(mark));
-#endif
return rc;
}
@@ -758,7 +857,7 @@ static void edit_file(char *fn)
crash_dummy(); // generate a random command
} else {
crashme = 0;
- string_insert(text, "\n\n##### Ran out of text to work on. #####\n\n"); // insert the string
+ string_insert(text, "\n\n##### Ran out of text to work on. #####\n\n", NO_UNDO); // insert the string
dot = text;
refresh(FALSE);
}
@@ -911,13 +1010,71 @@ static void setops(const char *args, const char *opname, int flg_no,
}
#endif
+#endif /* FEATURE_VI_COLON */
+
// buf must be no longer than MAX_INPUT_LEN!
static void colon(char *buf)
{
+#if !ENABLE_FEATURE_VI_COLON
+ /* Simple ":cmd" handler with minimal set of commands */
+ char *p = buf;
+ int cnt;
+
+ if (*p == ':')
+ p++;
+ cnt = strlen(p);
+ if (cnt == 0)
+ return;
+ if (strncmp(p, "quit", cnt) == 0
+ || strncmp(p, "q!", cnt) == 0
+ ) {
+ if (modified_count && p[1] != '!') {
+ status_line_bold("No write since last change (:%s! overrides)", p);
+ } else {
+ editing = 0;
+ }
+ return;
+ }
+ if (strncmp(p, "write", cnt) == 0
+ || strncmp(p, "wq", cnt) == 0
+ || strncmp(p, "wn", cnt) == 0
+ || (p[0] == 'x' && !p[1])
+ ) {
+ cnt = file_write(current_filename, text, end - 1);
+ if (cnt < 0) {
+ if (cnt == -1)
+ status_line_bold("Write error: %s", strerror(errno));
+ } else {
+ modified_count = 0;
+ last_modified_count = -1;
+ status_line("'%s' %dL, %dC",
+ current_filename,
+ count_lines(text, end - 1), cnt
+ );
+ if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
+ || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
+ ) {
+ editing = 0;
+ }
+ }
+ return;
+ }
+ if (strncmp(p, "file", cnt) == 0) {
+ last_status_cksum = 0; // force status update
+ return;
+ }
+ if (sscanf(p, "%d", &cnt) > 0) {
+ dot = find_line(cnt);
+ dot_skip_over_ws();
+ return;
+ }
+ not_implemented(p);
+#else
+
char c, *orig_buf, *buf1, *q, *r;
char *fn, cmd[MAX_INPUT_LEN], args[MAX_INPUT_LEN];
- int i, l, li, ch, b, e;
- int useforce, forced = FALSE;
+ int i, l, li, b, e;
+ int useforce;
// :3154 // if (-e line 3154) goto it else stay put
// :4,33w! foo // write a portion of buffer to file "foo"
@@ -939,7 +1096,7 @@ static void colon(char *buf)
if (*buf == ':')
buf++; // move past the ':'
- li = ch = i = 0;
+ li = i = 0;
b = e = -1;
q = text; // assume 1,$ for the range
r = end - 1;
@@ -1017,11 +1174,13 @@ static void colon(char *buf)
q = begin_line(dot); // assume .,. for the range
r = end_line(dot);
}
- dot = yank_delete(q, r, 1, YANKDEL); // save, then delete lines
+ dot = yank_delete(q, r, 1, YANKDEL, ALLOW_UNDO); // save, then delete lines
dot_skip_over_ws();
} else if (strncmp(cmd, "edit", i) == 0) { // Edit a file
+ int size;
+
// don't edit, if the current file has been modified
- if (file_modified && !useforce) {
+ if (modified_count && !useforce) {
status_line_bold("No write since last change (:%s! overrides)", cmd);
goto ret;
}
@@ -1037,8 +1196,7 @@ static void colon(char *buf)
goto ret;
}
- if (init_text_buffer(fn) < 0)
- goto ret;
+ size = init_text_buffer(fn);
#if ENABLE_FEATURE_VI_YANKMARK
if (Ureg >= 0 && Ureg < 28) {
@@ -1054,12 +1212,14 @@ static void colon(char *buf)
li = count_lines(text, end - 1);
status_line("'%s'%s"
IF_FEATURE_VI_READONLY("%s")
- " %dL, %dC", current_filename,
- (file_size(fn) < 0 ? " [New file]" : ""),
+ " %dL, %dC",
+ current_filename,
+ (size < 0 ? " [New file]" : ""),
IF_FEATURE_VI_READONLY(
((readonly_mode) ? " [Readonly]" : ""),
)
- li, ch);
+ li, (int)(end - text)
+ );
} else if (strncmp(cmd, "file", i) == 0) { // what File is this
if (b != -1 || e != -1) {
status_line_bold("No address allowed on this command");
@@ -1124,7 +1284,7 @@ static void colon(char *buf)
goto ret;
}
// don't exit if the file been modified
- if (file_modified) {
+ if (modified_count) {
status_line_bold("No write since last change (:%s! overrides)", cmd);
goto ret;
}
@@ -1148,6 +1308,8 @@ static void colon(char *buf)
}
editing = 0;
} else if (strncmp(cmd, "read", i) == 0) { // read file into text[]
+ int size;
+
fn = args;
if (!fn[0]) {
status_line_bold("No filename given");
@@ -1157,30 +1319,35 @@ static void colon(char *buf)
q = begin_line(dot); // assume "dot"
}
// read after current line- unless user said ":0r foo"
- if (b != 0)
+ if (b != 0) {
q = next_line(q);
+ // read after last line
+ if (q == end-1)
+ ++q;
+ }
{ // dance around potentially-reallocated text[]
uintptr_t ofs = q - text;
- ch = file_insert(fn, q, 0);
+ size = file_insert(fn, q, 0);
q = text + ofs;
}
- if (ch < 0)
+ if (size < 0)
goto ret; // nothing was inserted
// how many lines in text[]?
- li = count_lines(q, q + ch - 1);
+ li = count_lines(q, q + size - 1);
status_line("'%s'"
IF_FEATURE_VI_READONLY("%s")
- " %dL, %dC", fn,
+ " %dL, %dC",
+ fn,
IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),)
- li, ch);
- if (ch > 0) {
+ li, size
+ );
+ if (size > 0) {
// if the insert is before "dot" then we need to update
if (q <= dot)
- dot += ch;
- /*file_modified++; - done by file_insert */
+ dot += size;
}
} else if (strncmp(cmd, "rewind", i) == 0) { // rewind cmd line args
- if (file_modified && !useforce) {
+ if (modified_count && !useforce) {
status_line_bold("No write since last change (:%s! overrides)", cmd);
} else {
// reset the filenames to edit
@@ -1237,6 +1404,9 @@ static void colon(char *buf)
char *F, *R, *flags;
size_t len_F, len_R;
int gflag; // global replace flag
+#if ENABLE_FEATURE_VI_UNDO
+ int dont_chain_first_item = ALLOW_UNDO;
+#endif
// F points to the "find" pattern
// R points to the "replace" pattern
@@ -1271,9 +1441,13 @@ static void colon(char *buf)
if (found) {
uintptr_t bias;
// we found the "find" pattern - delete it
- text_hole_delete(found, found + len_F - 1);
- // inset the "replace" patern
- bias = string_insert(found, R); // insert the string
+ // For undo support, the first item should not be chained
+ text_hole_delete(found, found + len_F - 1, dont_chain_first_item);
+#if ENABLE_FEATURE_VI_UNDO
+ dont_chain_first_item = ALLOW_UNDO_CHAIN;
+#endif
+ // insert the "replace" patern
+ bias = string_insert(found, R, ALLOW_UNDO_CHAIN);
found += bias;
ls += bias;
/*q += bias; - recalculated anyway */
@@ -1295,6 +1469,9 @@ static void colon(char *buf)
|| strncmp(cmd, "wn", i) == 0
|| (cmd[0] == 'x' && !cmd[1])
) {
+ int size;
+ //int forced = FALSE;
+
// is there a file name to write to?
if (args[0]) {
fn = args;
@@ -1307,34 +1484,33 @@ static void colon(char *buf)
#endif
// how many lines in text[]?
li = count_lines(q, r);
- ch = r - q + 1;
- // see if file exists- if not, its just a new file request
- if (useforce) {
+ size = r - q + 1;
+ //if (useforce) {
// if "fn" is not write-able, chmod u+w
// sprintf(syscmd, "chmod u+w %s", fn);
// system(syscmd);
- forced = TRUE;
- }
+ // forced = TRUE;
+ //}
l = file_write(fn, q, r);
- if (useforce && forced) {
+ //if (useforce && forced) {
// chmod u-w
// sprintf(syscmd, "chmod u-w %s", fn);
// system(syscmd);
- forced = FALSE;
- }
+ // forced = FALSE;
+ //}
if (l < 0) {
if (l == -1)
status_line_bold_errno(fn);
} else {
status_line("'%s' %dL, %dC", fn, li, l);
- if (q == text && r == end - 1 && l == ch) {
- file_modified = 0;
- last_file_modified = -1;
+ if (q == text && r == end - 1 && l == size) {
+ modified_count = 0;
+ last_modified_count = -1;
}
if ((cmd[0] == 'x' || cmd[1] == 'q' || cmd[1] == 'n'
|| cmd[0] == 'X' || cmd[1] == 'Q' || cmd[1] == 'N'
)
- && l == ch
+ && l == size
) {
editing = 0;
}
@@ -1361,9 +1537,8 @@ static void colon(char *buf)
colon_s_fail:
status_line(":s expression missing delimiters");
#endif
-}
-
#endif /* FEATURE_VI_COLON */
+}
static void Hit_Return(void)
{
@@ -1510,10 +1685,10 @@ static char *dollar_line(char *p) // return pointer to just before NL line
static char *prev_line(char *p) // return pointer first char prev line
{
- p = begin_line(p); // goto begining of cur line
+ p = begin_line(p); // goto beginning of cur line
if (p > text && p[-1] == '\n')
p--; // step to prev line
- p = begin_line(p); // goto begining of prev line
+ p = begin_line(p); // goto beginning of prev line
return p;
}
@@ -1561,7 +1736,7 @@ static int count_lines(char *start, char *stop)
return cnt;
}
-static char *find_line(int li) // find begining of line #li
+static char *find_line(int li) // find beginning of line #li
{
char *q;
@@ -1574,23 +1749,27 @@ static char *find_line(int li) // find begining of line #li
//----- Dot Movement Routines ----------------------------------
static void dot_left(void)
{
+ undo_queue_commit();
if (dot > text && dot[-1] != '\n')
dot--;
}
static void dot_right(void)
{
+ undo_queue_commit();
if (dot < end - 1 && *dot != '\n')
dot++;
}
static void dot_begin(void)
{
+ undo_queue_commit();
dot = begin_line(dot); // return pointer to first char cur line
}
static void dot_end(void)
{
+ undo_queue_commit();
dot = end_line(dot); // return pointer to last char cur line
}
@@ -1616,11 +1795,13 @@ static char *move_to_col(char *p, int l)
static void dot_next(void)
{
+ undo_queue_commit();
dot = next_line(dot);
}
static void dot_prev(void)
{
+ undo_queue_commit();
dot = prev_line(dot);
}
@@ -1628,6 +1809,7 @@ static void dot_scroll(int cnt, int dir)
{
char *q;
+ undo_queue_commit();
for (; cnt > 0; cnt--) {
if (dir < 0) {
// scroll Backwards
@@ -1655,20 +1837,15 @@ static void dot_skip_over_ws(void)
dot++;
}
-static void dot_delete(void) // delete the char at 'dot'
-{
- text_hole_delete(dot, dot);
-}
-
static char *bound_dot(char *p) // make sure text[0] <= P < "end"
{
if (p >= end && end > text) {
p = end - 1;
- indicate_error('1');
+ indicate_error();
}
if (p < text) {
p = text;
- indicate_error('2');
+ indicate_error();
}
return p;
}
@@ -1806,17 +1983,34 @@ static char *char_search(char *p, const char *pat, int dir, int range)
#endif /* FEATURE_VI_SEARCH */
-static char *char_insert(char *p, char c) // insert the char c at 'p'
+static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
{
if (c == 22) { // Is this an ctrl-V?
p += stupid_insert(p, '^'); // use ^ to indicate literal next
refresh(FALSE); // show the ^
c = get_one_char();
*p = c;
+#if ENABLE_FEATURE_VI_UNDO
+ switch (undo) {
+ case ALLOW_UNDO:
+ undo_push(p, 1, UNDO_INS);
+ break;
+ case ALLOW_UNDO_CHAIN:
+ undo_push(p, 1, UNDO_INS_CHAIN);
+ break;
+# if ENABLE_FEATURE_VI_UNDO_QUEUE
+ case ALLOW_UNDO_QUEUED:
+ undo_push(p, 1, UNDO_INS_QUEUED);
+ break;
+# endif
+ }
+#else
+ modified_count++;
+#endif /* ENABLE_FEATURE_VI_UNDO */
p++;
- file_modified++;
} else if (c == 27) { // Is this an ESC?
cmd_mode = 0;
+ undo_queue_commit();
cmdcnt = 0;
end_cmd_q(); // stop adding to q
last_status_cksum = 0; // force status update
@@ -1824,26 +2018,39 @@ static char *char_insert(char *p, char c) // insert the char c at 'p'
p--;
}
} else if (c == erase_char || c == 8 || c == 127) { // Is this a BS
- // 123456789
- if ((p[-1] != '\n') && (dot>text)) {
+ if (p > text) {
p--;
- p = text_hole_delete(p, p); // shrink buffer 1 char
+ p = text_hole_delete(p, p, ALLOW_UNDO_QUEUED); // shrink buffer 1 char
}
} else {
-#if ENABLE_FEATURE_VI_SETOPTS
// insert a char into text[]
- char *sp; // "save p"
-#endif
-
if (c == 13)
c = '\n'; // translate \r to \n
-#if ENABLE_FEATURE_VI_SETOPTS
- sp = p; // remember addr of insert
-#endif
+#if ENABLE_FEATURE_VI_UNDO
+# if ENABLE_FEATURE_VI_UNDO_QUEUE
+ if (c == '\n')
+ undo_queue_commit();
+# endif
+ switch (undo) {
+ case ALLOW_UNDO:
+ undo_push(p, 1, UNDO_INS);
+ break;
+ case ALLOW_UNDO_CHAIN:
+ undo_push(p, 1, UNDO_INS_CHAIN);
+ break;
+# if ENABLE_FEATURE_VI_UNDO_QUEUE
+ case ALLOW_UNDO_QUEUED:
+ undo_push(p, 1, UNDO_INS_QUEUED);
+ break;
+# endif
+ }
+#else
+ modified_count++;
+#endif /* ENABLE_FEATURE_VI_UNDO */
p += 1 + stupid_insert(p, c); // insert the char
#if ENABLE_FEATURE_VI_SETOPTS
- if (showmatch && strchr(")]}", *sp) != NULL) {
- showmatching(sp);
+ if (showmatch && strchr(")]}", c) != NULL) {
+ showmatching(p - 1);
}
if (autoindent && c == '\n') { // auto indent the new line
char *q;
@@ -1855,6 +2062,9 @@ static char *char_insert(char *p, char c) // insert the char c at 'p'
bias = text_hole_make(p, len);
p += bias;
q += bias;
+#if ENABLE_FEATURE_VI_UNDO
+ undo_push(p, len, UNDO_INS);
+#endif
memcpy(p, q, len);
p += len;
}
@@ -1872,7 +2082,6 @@ static uintptr_t stupid_insert(char *p, char c) // stupidly insert the char c at
bias = text_hole_make(p, 1);
p += bias;
*p = c;
- //file_modified++; - done by text_hole_make()
return bias;
}
@@ -2001,34 +2210,32 @@ static char *skip_thing(char *p, int linecnt, int dir, int type)
}
// find matching char of pair () [] {}
+// will crash if c is not one of these
static char *find_pair(char *p, const char c)
{
- char match, *q;
+ const char *braces = "()[]{}";
+ char match;
int dir, level;
- match = ')';
+ dir = strchr(braces, c) - braces;
+ dir ^= 1;
+ match = braces[dir];
+ dir = ((dir & 1) << 1) - 1; /* 1 for ([{, -1 for )\} */
+
+ // look for match, count levels of pairs (( ))
level = 1;
- dir = 1; // assume forward
- switch (c) {
- case '(': match = ')'; break;
- case '[': match = ']'; break;
- case '{': match = '}'; break;
- case ')': match = '('; dir = -1; break;
- case ']': match = '['; dir = -1; break;
- case '}': match = '{'; dir = -1; break;
- }
- for (q = p + dir; text <= q && q < end; q += dir) {
- // look for match, count levels of pairs (( ))
- if (*q == c)
+ for (;;) {
+ p += dir;
+ if (p < text || p >= end)
+ return NULL;
+ if (*p == c)
level++; // increase pair levels
- if (*q == match)
+ if (*p == match) {
level--; // reduce pair level
- if (level == 0)
- break; // found matching pair
+ if (level == 0)
+ return p; // found matching pair
+ }
}
- if (level != 0)
- q = NULL; // indicate no match
- return q;
}
#if ENABLE_FEATURE_VI_SETOPTS
@@ -2040,7 +2247,7 @@ static void showmatching(char *p)
// we found half of a pair
q = find_pair(p, *p); // get loc of matching char
if (q == NULL) {
- indicate_error('3'); // no matching char
+ indicate_error(); // no matching char
} else {
// "q" now points to matching pair
save_dot = dot; // remember where we are
@@ -2053,6 +2260,199 @@ static void showmatching(char *p)
}
#endif /* FEATURE_VI_SETOPTS */
+#if ENABLE_FEATURE_VI_UNDO
+static void flush_undo_data(void)
+{
+ struct undo_object *undo_entry;
+
+ while (undo_stack_tail) {
+ undo_entry = undo_stack_tail;
+ undo_stack_tail = undo_entry->prev;
+ free(undo_entry);
+ }
+}
+
+// Undo functions and hooks added by Jody Bruchon (jody@jodybruchon.com)
+static void undo_push(char *src, unsigned int length, uint8_t u_type) // Add to the undo stack
+{
+ struct undo_object *undo_entry;
+
+ // "u_type" values
+ // UNDO_INS: insertion, undo will remove from buffer
+ // UNDO_DEL: deleted text, undo will restore to buffer
+ // UNDO_{INS,DEL}_CHAIN: Same as above but also calls undo_pop() when complete
+ // The CHAIN operations are for handling multiple operations that the user
+ // performs with a single action, i.e. REPLACE mode or find-and-replace commands
+ // UNDO_{INS,DEL}_QUEUED: If queuing feature is enabled, allow use of the queue
+ // for the INS/DEL operation. The raw values should be equal to the values of
+ // UNDO_{INS,DEL} ORed with UNDO_QUEUED_FLAG
+
+#if ENABLE_FEATURE_VI_UNDO_QUEUE
+ // This undo queuing functionality groups multiple character typing or backspaces
+ // into a single large undo object. This greatly reduces calls to malloc() for
+ // single-character operations while typing and has the side benefit of letting
+ // an undo operation remove chunks of text rather than a single character.
+ switch (u_type) {
+ case UNDO_EMPTY: // Just in case this ever happens...
+ return;
+ case UNDO_DEL_QUEUED:
+ if (length != 1)
+ return; // Only queue single characters
+ switch (undo_queue_state) {
+ case UNDO_EMPTY:
+ undo_queue_state = UNDO_DEL;
+ case UNDO_DEL:
+ undo_queue_spos = src;
+ undo_q++;
+ undo_queue[CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q] = *src;
+ // If queue is full, dump it into an object
+ if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX)
+ undo_queue_commit();
+ return;
+ case UNDO_INS:
+ // Switch from storing inserted text to deleted text
+ undo_queue_commit();
+ undo_push(src, length, UNDO_DEL_QUEUED);
+ return;
+ }
+ break;
+ case UNDO_INS_QUEUED:
+ if (length != 1)
+ return;
+ switch (undo_queue_state) {
+ case UNDO_EMPTY:
+ undo_queue_state = UNDO_INS;
+ undo_queue_spos = src;
+ case UNDO_INS:
+ undo_q++; // Don't need to save any data for insertions
+ if (undo_q == CONFIG_FEATURE_VI_UNDO_QUEUE_MAX)
+ undo_queue_commit();
+ return;
+ case UNDO_DEL:
+ // Switch from storing deleted text to inserted text
+ undo_queue_commit();
+ undo_push(src, length, UNDO_INS_QUEUED);
+ return;
+ }
+ break;
+ }
+#else
+ // If undo queuing is disabled, ignore the queuing flag entirely
+ u_type = u_type & ~UNDO_QUEUED_FLAG;
+#endif
+
+ // Allocate a new undo object
+ if (u_type == UNDO_DEL || u_type == UNDO_DEL_CHAIN) {
+ // For UNDO_DEL objects, save deleted text
+ if ((src + length) == end)
+ length--;
+ // If this deletion empties text[], strip the newline. When the buffer becomes
+ // zero-length, a newline is added back, which requires this to compensate.
+ undo_entry = xzalloc(offsetof(struct undo_object, undo_text) + length);
+ memcpy(undo_entry->undo_text, src, length);
+ } else {
+ undo_entry = xzalloc(sizeof(*undo_entry));
+ }
+ undo_entry->length = length;
+#if ENABLE_FEATURE_VI_UNDO_QUEUE
+ if ((u_type & UNDO_USE_SPOS) != 0) {
+ undo_entry->start = undo_queue_spos - text; // use start position from queue
+ } else {
+ undo_entry->start = src - text; // use offset from start of text buffer
+ }
+ u_type = (u_type & ~UNDO_USE_SPOS);
+#else
+ undo_entry->start = src - text;
+#endif
+ undo_entry->u_type = u_type;
+
+ // Push it on undo stack
+ undo_entry->prev = undo_stack_tail;
+ undo_stack_tail = undo_entry;
+ modified_count++;
+}
+
+static void undo_pop(void) // Undo the last operation
+{
+ int repeat;
+ char *u_start, *u_end;
+ struct undo_object *undo_entry;
+
+ // Commit pending undo queue before popping (should be unnecessary)
+ undo_queue_commit();
+
+ undo_entry = undo_stack_tail;
+ // Check for an empty undo stack
+ if (!undo_entry) {
+ status_line("Already at oldest change");
+ return;
+ }
+
+ switch (undo_entry->u_type) {
+ case UNDO_DEL:
+ case UNDO_DEL_CHAIN:
+ // make hole and put in text that was deleted; deallocate text
+ u_start = text + undo_entry->start;
+ text_hole_make(u_start, undo_entry->length);
+ memcpy(u_start, undo_entry->undo_text, undo_entry->length);
+ status_line("Undo [%d] %s %d chars at position %d",
+ modified_count, "restored",
+ undo_entry->length, undo_entry->start
+ );
+ break;
+ case UNDO_INS:
+ case UNDO_INS_CHAIN:
+ // delete what was inserted
+ u_start = undo_entry->start + text;
+ u_end = u_start - 1 + undo_entry->length;
+ text_hole_delete(u_start, u_end, NO_UNDO);
+ status_line("Undo [%d] %s %d chars at position %d",
+ modified_count, "deleted",
+ undo_entry->length, undo_entry->start
+ );
+ break;
+ }
+ repeat = 0;
+ switch (undo_entry->u_type) {
+ // If this is the end of a chain, lower modification count and refresh display
+ case UNDO_DEL:
+ case UNDO_INS:
+ dot = (text + undo_entry->start);
+ refresh(FALSE);
+ break;
+ case UNDO_DEL_CHAIN:
+ case UNDO_INS_CHAIN:
+ repeat = 1;
+ break;
+ }
+ // Deallocate the undo object we just processed
+ undo_stack_tail = undo_entry->prev;
+ free(undo_entry);
+ modified_count--;
+ // For chained operations, continue popping all the way down the chain.
+ if (repeat) {
+ undo_pop(); // Follow the undo chain if one exists
+ }
+}
+
+#if ENABLE_FEATURE_VI_UNDO_QUEUE
+static void undo_queue_commit(void) // Flush any queued objects to the undo stack
+{
+ // Pushes the queue object onto the undo stack
+ if (undo_q > 0) {
+ // Deleted character undo events grow from the end
+ undo_push(undo_queue + CONFIG_FEATURE_VI_UNDO_QUEUE_MAX - undo_q,
+ undo_q,
+ (undo_queue_state | UNDO_USE_SPOS)
+ );
+ undo_queue_state = UNDO_EMPTY;
+ undo_q = 0;
+ }
+}
+#endif
+
+#endif /* ENABLE_FEATURE_VI_UNDO */
+
// open a hole in text[]
// might reallocate text[]! use p += text_hole_make(p, ...),
// and be careful to not use pointers into potentially freed text[]!
@@ -2084,12 +2484,12 @@ static uintptr_t text_hole_make(char *p, int size) // at "p", make a 'size' byte
}
memmove(p + size, p, end - size - p);
memset(p, ' ', size); // clear new hole
- file_modified++;
return bias;
}
// close a hole in text[]
-static char *text_hole_delete(char *p, char *q) // delete "p" through "q", inclusive
+// "undo" value indicates if this operation should be undo-able
+static char *text_hole_delete(char *p, char *q, int undo) // delete "p" through "q", inclusive
{
char *src, *dest;
int cnt, hole_size;
@@ -2104,10 +2504,29 @@ static char *text_hole_delete(char *p, char *q) // delete "p" through "q", inclu
}
hole_size = q - p + 1;
cnt = end - src;
+#if ENABLE_FEATURE_VI_UNDO
+ switch (undo) {
+ case NO_UNDO:
+ break;
+ case ALLOW_UNDO:
+ undo_push(p, hole_size, UNDO_DEL);
+ break;
+ case ALLOW_UNDO_CHAIN:
+ undo_push(p, hole_size, UNDO_DEL_CHAIN);
+ break;
+# if ENABLE_FEATURE_VI_UNDO_QUEUE
+ case ALLOW_UNDO_QUEUED:
+ undo_push(p, hole_size, UNDO_DEL_QUEUED);
+ break;
+# endif
+ }
+ modified_count--;
+#endif
if (src < text || src > end)
goto thd0;
if (dest < text || dest >= end)
goto thd0;
+ modified_count++;
if (src >= end)
goto thd_atend; // just delete the end of the buffer
memmove(dest, src, cnt);
@@ -2117,7 +2536,6 @@ static char *text_hole_delete(char *p, char *q) // delete "p" through "q", inclu
dest = end - 1; // make sure dest in below end-1
if (end <= text)
dest = end = text; // keep pointers valid
- file_modified++;
thd0:
return dest;
}
@@ -2125,7 +2543,7 @@ static char *text_hole_delete(char *p, char *q) // delete "p" through "q", inclu
// copy text into register, then delete text.
// if dist <= 0, do not include, or go past, a NewLine
//
-static char *yank_delete(char *start, char *stop, int dist, int yf)
+static char *yank_delete(char *start, char *stop, int dist, int yf, int undo)
{
char *p;
@@ -2154,7 +2572,7 @@ static char *yank_delete(char *start, char *stop, int dist, int yf)
text_yank(start, stop, YDreg);
#endif
if (yf == YANKDEL) {
- p = text_hole_delete(start, stop);
+ p = text_hole_delete(start, stop, undo);
} // delete lines
return p;
}
@@ -2220,12 +2638,22 @@ static void end_cmd_q(void)
|| ENABLE_FEATURE_VI_CRASHME
// might reallocate text[]! use p += string_insert(p, ...),
// and be careful to not use pointers into potentially freed text[]!
-static uintptr_t string_insert(char *p, const char *s) // insert the string at 'p'
+static uintptr_t string_insert(char *p, const char *s, int undo) // insert the string at 'p'
{
uintptr_t bias;
int i;
i = strlen(s);
+#if ENABLE_FEATURE_VI_UNDO
+ switch (undo) {
+ case ALLOW_UNDO:
+ undo_push(p, i, UNDO_INS);
+ break;
+ case ALLOW_UNDO_CHAIN:
+ undo_push(p, i, UNDO_INS_CHAIN);
+ break;
+ }
+#endif
bias = text_hole_make(p, i);
p += bias;
memcpy(p, s, i);
@@ -2296,9 +2724,8 @@ static char *swap_context(char *p) // goto new context for '' command make this
// only swap context if other context is valid
if (text <= mark[27] && mark[27] <= end - 1) {
tmp = mark[27];
- mark[27] = mark[26];
- mark[26] = tmp;
- p = mark[26]; // where we are going- previous context
+ mark[27] = p;
+ mark[26] = p = tmp;
context_start = prev_line(prev_line(prev_line(p)));
context_end = next_line(next_line(next_line(p)));
}
@@ -2378,6 +2805,9 @@ static int mysleep(int hund) // sleep for 'hund' 1/100 seconds or stdin ready
{
struct pollfd pfd[1];
+ if (hund != 0)
+ fflush_all();
+
pfd[0].fd = STDIN_FILENO;
pfd[0].events = POLLIN;
return safe_poll(pfd, 1, hund*10) > 0;
@@ -2474,62 +2904,50 @@ static char *get_input_line(const char *prompt)
#undef buf
}
-static int file_size(const char *fn) // what is the byte size of "fn"
-{
- struct stat st_buf;
- int cnt;
-
- cnt = -1;
- if (fn && stat(fn, &st_buf) == 0) // see if file exists
- cnt = (int) st_buf.st_size;
- return cnt;
-}
-
// might reallocate text[]!
-static int file_insert(const char *fn, char *p, int update_ro_status)
+static int file_insert(const char *fn, char *p, int initial)
{
int cnt = -1;
int fd, size;
struct stat statbuf;
+ if (p < text)
+ p = text;
+ if (p > end)
+ p = end;
+
+ fd = open(fn, O_RDONLY);
+ if (fd < 0) {
+ if (!initial)
+ status_line_bold_errno(fn);
+ return cnt;
+ }
+
/* Validate file */
- if (stat(fn, &statbuf) < 0) {
+ if (fstat(fd, &statbuf) < 0) {
status_line_bold_errno(fn);
- goto fi0;
+ goto fi;
}
if (!S_ISREG(statbuf.st_mode)) {
- // This is not a regular file
status_line_bold("'%s' is not a regular file", fn);
- goto fi0;
- }
- if (p < text || p > end) {
- status_line_bold("Trying to insert file outside of memory");
- goto fi0;
- }
-
- // read file to buffer
- fd = open(fn, O_RDONLY);
- if (fd < 0) {
- status_line_bold_errno(fn);
- goto fi0;
+ goto fi;
}
size = (statbuf.st_size < INT_MAX ? (int)statbuf.st_size : INT_MAX);
p += text_hole_make(p, size);
- cnt = safe_read(fd, p, size);
+ cnt = full_read(fd, p, size);
if (cnt < 0) {
status_line_bold_errno(fn);
- p = text_hole_delete(p, p + size - 1); // un-do buffer insert
+ p = text_hole_delete(p, p + size - 1, NO_UNDO); // un-do buffer insert
} else if (cnt < size) {
- // There was a partial read, shrink unused space text[]
- p = text_hole_delete(p + cnt, p + size - 1); // un-do buffer insert
+ // There was a partial read, shrink unused space
+ p = text_hole_delete(p + cnt, p + size - 1, NO_UNDO);
status_line_bold("can't read '%s'", fn);
}
- if (cnt >= size)
- file_modified++;
+ fi:
close(fd);
- fi0:
+
#if ENABLE_FEATURE_VI_READONLY
- if (update_ro_status
+ if (initial
&& ((access(fn, W_OK) < 0) ||
/* root will always have access()
* so we check fileperms too */
@@ -2562,7 +2980,7 @@ static int file_write(char *fn, char *first, char *last)
ftruncate(fd, charcnt);
if (charcnt == cnt) {
// good write
- //file_modified = FALSE;
+ //modified_count = FALSE;
} else {
charcnt = 0;
}
@@ -2635,7 +3053,7 @@ static void flash(int h)
redraw(TRUE);
}
-static void Indicate_Error(void)
+static void indicate_error(void)
{
#if ENABLE_FEATURE_VI_CRASHME
if (crashme > 0)
@@ -2784,7 +3202,7 @@ static int format_edit_status(void)
int cur, percent, ret, trunc_at;
- // file_modified is now a counter rather than a flag. this
+ // modified_count is now a counter rather than a flag. this
// helps reduce the amount of line counting we need to do.
// (this will cause a mis-reporting of modified status
// once every MAXINT editing operations.)
@@ -2794,11 +3212,12 @@ static int format_edit_status(void)
// we're on, then we shouldn't have to do this count_lines()
cur = count_lines(text, dot);
- // reduce counting -- the total lines can't have
- // changed if we haven't done any edits.
- if (file_modified != last_file_modified) {
+ // count_lines() is expensive.
+ // Call it only if something was changed since last time
+ // we were here:
+ if (modified_count != last_modified_count) {
tot = cur + count_lines(dot, end - 1) - 1;
- last_file_modified = file_modified;
+ last_modified_count = modified_count;
}
// current line percent
@@ -2825,7 +3244,7 @@ static int format_edit_status(void)
#if ENABLE_FEATURE_VI_READONLY
(readonly_mode ? " [Readonly]" : ""),
#endif
- (file_modified ? " [Modified]" : ""),
+ (modified_count ? " [Modified]" : ""),
cur, tot, percent);
if (ret >= 0 && ret < trunc_at)
@@ -2938,7 +3357,7 @@ static void refresh(int full_screen)
tp = t + 1;
}
- // see if there are any changes between vitual screen and out_buf
+ // see if there are any changes between virtual screen and out_buf
changed = FALSE; // assume no change
cs = 0;
ce = columns - 1;
@@ -2975,7 +3394,7 @@ static void refresh(int full_screen)
if (cs < 0) cs = 0;
if (ce > columns - 1) ce = columns - 1;
if (cs > ce) { cs = 0; ce = columns - 1; }
- // is there a change between vitual screen and out_buf
+ // is there a change between virtual screen and out_buf
if (changed) {
// copy changed part of buffer to virtual screen
memcpy(sp+cs, out_buf+cs, ce-cs+1);
@@ -3050,11 +3469,12 @@ static void do_cmd(int c)
if (*dot == '\n') {
// don't Replace past E-o-l
cmd_mode = 1; // convert to insert
+ undo_queue_commit();
} else {
if (1 <= c || Isprint(c)) {
if (c != 27)
- dot = yank_delete(dot, dot, 0, YANKDEL); // delete char
- dot = char_insert(dot, c); // insert new char
+ dot = yank_delete(dot, dot, 0, YANKDEL, ALLOW_UNDO); // delete char
+ dot = char_insert(dot, c, ALLOW_UNDO_CHAIN); // insert new char
}
goto dc1;
}
@@ -3064,7 +3484,7 @@ static void do_cmd(int c)
if (c == KEYCODE_INSERT) goto dc5;
// insert the char c at "dot"
if (1 <= c || Isprint(c)) {
- dot = char_insert(dot, c);
+ dot = char_insert(dot, c, ALLOW_UNDO_QUEUED);
}
goto dc1;
}
@@ -3110,7 +3530,6 @@ static void do_cmd(int c)
//case ']': // ]-
//case '_': // _-
//case '`': // `-
- //case 'u': // u- FIXME- there is no undo
//case 'v': // v-
default: // unrecognized command
buf[0] = c;
@@ -3177,8 +3596,9 @@ static void do_cmd(int c)
break;
case 27: // esc
if (cmd_mode == 0)
- indicate_error(c);
+ indicate_error();
cmd_mode = 0; // stop insrting
+ undo_queue_commit();
end_cmd_q();
last_status_cksum = 0; // force status update
break;
@@ -3195,12 +3615,13 @@ static void do_cmd(int c)
if ((unsigned)c1 <= 25) { // a-z?
YDreg = c1;
} else {
- indicate_error(c);
+ indicate_error();
}
break;
case '\'': // '- goto a specific mark
- c1 = (get_one_char() | 0x20) - 'a';
- if ((unsigned)c1 <= 25) { // a-z?
+ c1 = (get_one_char() | 0x20);
+ if ((unsigned)(c1 - 'a') <= 25) { // a-z?
+ c1 = (c1 - 'a');
// get the b-o-l
q = mark[c1];
if (text <= q && q < end) {
@@ -3213,7 +3634,7 @@ static void do_cmd(int c)
dot_begin(); // go to B-o-l
dot_skip_over_ws();
} else {
- indicate_error(c);
+ indicate_error();
}
break;
case 'm': // m- Mark a line
@@ -3226,7 +3647,7 @@ static void do_cmd(int c)
// remember the line
mark[c1] = dot;
} else {
- indicate_error(c);
+ indicate_error();
}
break;
case 'P': // P- Put register before
@@ -3253,20 +3674,25 @@ static void do_cmd(int c)
if (c == 'p')
dot_right(); // move to right, can move to NL
}
- string_insert(dot, p); // insert the string
+ string_insert(dot, p, ALLOW_UNDO); // insert the string
end_cmd_q(); // stop adding to q
break;
case 'U': // U- Undo; replace current line with original version
if (reg[Ureg] != NULL) {
p = begin_line(dot);
q = end_line(dot);
- p = text_hole_delete(p, q); // delete cur line
- p += string_insert(p, reg[Ureg]); // insert orig line
+ p = text_hole_delete(p, q, ALLOW_UNDO); // delete cur line
+ p += string_insert(p, reg[Ureg], ALLOW_UNDO_CHAIN); // insert orig line
dot = p;
dot_skip_over_ws();
}
break;
#endif /* FEATURE_VI_YANKMARK */
+#if ENABLE_FEATURE_VI_UNDO
+ case 'u': // u- undo last operation
+ undo_pop();
+ break;
+#endif
case '$': // $- goto end of line
case KEYCODE_END: // Cursor Key End
for (;;) {
@@ -3282,7 +3708,7 @@ static void do_cmd(int c)
// we found half of a pair
p = find_pair(q, *q);
if (p == NULL) {
- indicate_error(c);
+ indicate_error();
} else {
dot = p;
}
@@ -3290,7 +3716,7 @@ static void do_cmd(int c)
}
}
if (*q == '\n')
- indicate_error(c);
+ indicate_error();
break;
case 'f': // f- forward to a user specified char
last_forward_char = get_one_char(); // get the search char
@@ -3419,7 +3845,7 @@ static void do_cmd(int c)
}
break;
#endif /* FEATURE_VI_SEARCH */
- case '0': // 0- goto begining of line
+ case '0': // 0- goto beginning of line
case '1': // 1-
case '2': // 2-
case '3': // 3-
@@ -3437,57 +3863,14 @@ static void do_cmd(int c)
break;
case ':': // :- the colon mode commands
p = get_input_line(":"); // get input line- use "status line"
-#if ENABLE_FEATURE_VI_COLON
colon(p); // execute the command
-#else
- if (*p == ':')
- p++; // move past the ':'
- cnt = strlen(p);
- if (cnt <= 0)
- break;
- if (strncmp(p, "quit", cnt) == 0
- || strncmp(p, "q!", cnt) == 0 // delete lines
- ) {
- if (file_modified && p[1] != '!') {
- status_line_bold("No write since last change (:%s! overrides)", p);
- } else {
- editing = 0;
- }
- } else if (strncmp(p, "write", cnt) == 0
- || strncmp(p, "wq", cnt) == 0
- || strncmp(p, "wn", cnt) == 0
- || (p[0] == 'x' && !p[1])
- ) {
- cnt = file_write(current_filename, text, end - 1);
- if (cnt < 0) {
- if (cnt == -1)
- status_line_bold("Write error: %s", strerror(errno));
- } else {
- file_modified = 0;
- last_file_modified = -1;
- status_line("'%s' %dL, %dC", current_filename, count_lines(text, end - 1), cnt);
- if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
- || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
- ) {
- editing = 0;
- }
- }
- } else if (strncmp(p, "file", cnt) == 0) {
- last_status_cksum = 0; // force status update
- } else if (sscanf(p, "%d", &j) > 0) {
- dot = find_line(j); // go to line # j
- dot_skip_over_ws();
- } else { // unrecognized cmd
- not_implemented(p);
- }
-#endif /* !FEATURE_VI_COLON */
break;
case '<': // <- Left shift something
case '>': // >- Right shift something
cnt = count_lines(text, dot); // remember what line we are on
c1 = get_one_char(); // get the type of thing to delete
find_range(&p, &q, c1);
- yank_delete(p, q, 1, YANKONLY); // save copy before change
+ yank_delete(p, q, 1, YANKONLY, NO_UNDO); // save copy before change
p = begin_line(p);
q = end_line(q);
i = count_lines(p, q); // # of lines we are shifting
@@ -3496,16 +3879,16 @@ static void do_cmd(int c)
// shift left- remove tab or 8 spaces
if (*p == '\t') {
// shrink buffer 1 char
- text_hole_delete(p, p);
+ text_hole_delete(p, p, NO_UNDO);
} else if (*p == ' ') {
// we should be calculating columns, not just SPACE
for (j = 0; *p == ' ' && j < tabstop; j++) {
- text_hole_delete(p, p);
+ text_hole_delete(p, p, NO_UNDO);
}
}
} else if (c == '>') {
// shift right -- add tab or 8 spaces
- char_insert(p, '\t');
+ char_insert(p, '\t', ALLOW_UNDO);
}
}
dot = find_line(cnt); // what line were we on
@@ -3540,7 +3923,7 @@ static void do_cmd(int c)
save_dot = dot;
dot = dollar_line(dot); // move to before NL
// copy text into a register and delete
- dot = yank_delete(save_dot, dot, 0, YANKDEL); // delete to e-o-l
+ dot = yank_delete(save_dot, dot, 0, YANKDEL, ALLOW_UNDO); // delete to e-o-l
if (c == 'C')
goto dc_i; // start inserting
#if ENABLE_FEATURE_VI_DOT_CMD
@@ -3552,7 +3935,9 @@ static void do_cmd(int c)
c1 = get_one_char();
if (c1 != 'g') {
buf[0] = 'g';
- buf[1] = c1; // TODO: if Unicode?
+ // c1 < 0 if the key was special. Try "g<up-arrow>"
+ // TODO: if Unicode?
+ buf[1] = (c1 >= 0 ? c1 : '*');
buf[2] = '\0';
not_implemented(buf);
break;
@@ -3585,15 +3970,22 @@ static void do_cmd(int c)
case KEYCODE_INSERT: // Cursor Key Insert
dc_i:
cmd_mode = 1; // start inserting
+ undo_queue_commit(); // commit queue when cmd_mode changes
break;
case 'J': // J- join current and next lines together
do {
dot_end(); // move to NL
if (dot < end - 1) { // make sure not last char in text[]
+#if ENABLE_FEATURE_VI_UNDO
+ undo_push(dot, 1, UNDO_DEL);
*dot++ = ' '; // replace NL with space
- file_modified++;
+ undo_push((dot - 1), 1, UNDO_INS_CHAIN);
+#else
+ *dot++ = ' ';
+ modified_count++;
+#endif
while (isblank(*dot)) { // delete leading WS
- dot_delete();
+ text_hole_delete(dot, dot, ALLOW_UNDO_CHAIN);
}
}
} while (--cmdcnt > 0);
@@ -3622,10 +4014,10 @@ static void do_cmd(int c)
dot_prev();
case 'o': // o- open a empty line below; Yes, I know it is in the middle of the "if (..."
dot_end();
- dot = char_insert(dot, '\n');
+ dot = char_insert(dot, '\n', ALLOW_UNDO);
} else {
dot_begin(); // 0
- dot = char_insert(dot, '\n'); // i\n ESC
+ dot = char_insert(dot, '\n', ALLOW_UNDO); // i\n ESC
dot_prev(); // -
}
goto dc_i;
@@ -3633,10 +4025,12 @@ static void do_cmd(int c)
case 'R': // R- continuous Replace char
dc5:
cmd_mode = 2;
+ undo_queue_commit();
break;
case KEYCODE_DELETE:
- c = 'x';
- // fall through
+ if (dot < end - 1)
+ dot = yank_delete(dot, dot, 1, YANKDEL, ALLOW_UNDO);
+ break;
case 'X': // X- delete char before dot
case 'x': // x- delete the current char
case 's': // s- substitute the current char
@@ -3647,7 +4041,7 @@ static void do_cmd(int c)
if (dot[dir] != '\n') {
if (c == 'X')
dot--; // delete prev char
- dot = yank_delete(dot, dot, 0, YANKDEL); // delete char
+ dot = yank_delete(dot, dot, 0, YANKDEL, ALLOW_UNDO); // delete char
}
} while (--cmdcnt > 0);
end_cmd_q(); // stop adding to q
@@ -3658,10 +4052,10 @@ static void do_cmd(int c)
// ZZ means to save file (if necessary), then exit
c1 = get_one_char();
if (c1 != 'Z') {
- indicate_error(c);
+ indicate_error();
break;
}
- if (file_modified) {
+ if (modified_count) {
if (ENABLE_FEATURE_VI_READONLY && readonly_mode) {
status_line_bold("'%s' is read only", current_filename);
break;
@@ -3718,6 +4112,7 @@ static void do_cmd(int c)
c1 = get_one_char(); // get the type of thing to delete
// determine range, and whether it spans lines
ml = find_range(&p, &q, c1);
+ place_cursor(0, 0);
if (c1 == 27) { // ESC- user changed mind and wants out
c = c1 = 27; // Escape- do nothing
} else if (strchr("wW", c1)) {
@@ -3729,23 +4124,23 @@ static void do_cmd(int c)
q--;
}
}
- dot = yank_delete(p, q, ml, yf); // delete word
+ dot = yank_delete(p, q, ml, yf, ALLOW_UNDO); // delete word
} else if (strchr("^0bBeEft%$ lh\b\177", c1)) {
// partial line copy text into a register and delete
- dot = yank_delete(p, q, ml, yf); // delete word
+ dot = yank_delete(p, q, ml, yf, ALLOW_UNDO); // delete word
} else if (strchr("cdykjHL+-{}\r\n", c1)) {
// whole line copy text into a register and delete
- dot = yank_delete(p, q, ml, yf); // delete lines
+ dot = yank_delete(p, q, ml, yf, ALLOW_UNDO); // delete lines
whole = 1;
} else {
// could not recognize object
c = c1 = 27; // error-
ml = 0;
- indicate_error(c);
+ indicate_error();
}
if (ml && whole) {
if (c == 'c') {
- dot = char_insert(dot, '\n');
+ dot = char_insert(dot, '\n', ALLOW_UNDO_CHAIN);
// on the last line of file don't move to prev line
if (whole && dot != (end-1)) {
dot_prev();
@@ -3791,8 +4186,14 @@ static void do_cmd(int c)
case 'r': // r- replace the current char with user input
c1 = get_one_char(); // get the replacement char
if (*dot != '\n') {
+#if ENABLE_FEATURE_VI_UNDO
+ undo_push(dot, 1, UNDO_DEL);
*dot = c1;
- file_modified++;
+ undo_push(dot, 1, UNDO_INS_CHAIN);
+#else
+ *dot = c1;
+ modified_count++;
+#endif
}
end_cmd_q(); // stop adding to q
break;
@@ -3832,13 +4233,25 @@ static void do_cmd(int c)
break;
case '~': // ~- flip the case of letters a-z -> A-Z
do {
+#if ENABLE_FEATURE_VI_UNDO
if (islower(*dot)) {
+ undo_push(dot, 1, UNDO_DEL);
*dot = toupper(*dot);
- file_modified++;
+ undo_push(dot, 1, UNDO_INS_CHAIN);
} else if (isupper(*dot)) {
+ undo_push(dot, 1, UNDO_DEL);
*dot = tolower(*dot);
- file_modified++;
+ undo_push(dot, 1, UNDO_INS_CHAIN);
}
+#else
+ if (islower(*dot)) {
+ *dot = toupper(*dot);
+ modified_count++;
+ } else if (isupper(*dot)) {
+ *dot = tolower(*dot);
+ modified_count++;
+ }
+#endif
dot_right();
} while (--cmdcnt > 0);
end_cmd_q(); // stop adding to q
@@ -3868,7 +4281,7 @@ static void do_cmd(int c)
dc1:
// if text[] just became empty, add back an empty line
if (end == text) {
- char_insert(text, '\n'); // start empty buf with dummy line
+ char_insert(text, '\n', NO_UNDO); // start empty buf with dummy line
dot = text;
}
// it is OK for dot to exactly equal to end, otherwise check dot validity