aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2018-06-25 11:28:24 -0700
committerElliott Hughes <enh@google.com>2018-06-25 11:30:53 -0700
commit132f6309a68504261c3400b59f9eb282849fed16 (patch)
treec77f57abc3b7cd43f0b9fd1ac60d41ca0e01da9c
parentc1e1b62acf6df14b90dadebf94636621b0a0d09b (diff)
parent89d6d71cdaa31672a52032ba77b376093a4c8e9e (diff)
downloadtoybox-132f6309a68504261c3400b59f9eb282849fed16.tar.gz
Merge remote-tracking branch 'toybox/master' into HEADandroid-p-preview-4
Change-Id: I3c99e29d1f2246f8c0fd3572ac7e62d7576c3566
-rw-r--r--Android.bp2
-rw-r--r--generated/flags.h4
-rw-r--r--generated/globals.h16
-rw-r--r--generated/help.h12
-rw-r--r--generated/newtoys.h2
-rw-r--r--main.c2
-rwxr-xr-xscripts/install.sh2
-rwxr-xr-xtests/cut.test46
-rw-r--r--toys/other/fmt.c93
-rw-r--r--toys/pending/fmt.c78
-rwxr-xr-xwww/news.html88
11 files changed, 242 insertions, 103 deletions
diff --git a/Android.bp b/Android.bp
index bd849830..8ff205af 100644
--- a/Android.bp
+++ b/Android.bp
@@ -102,6 +102,7 @@ cc_defaults {
"toys/other/dos2unix.c",
"toys/other/fallocate.c",
"toys/other/flock.c",
+ "toys/other/fmt.c",
"toys/other/free.c",
"toys/other/freeramdisk.c",
"toys/other/fsfreeze.c",
@@ -151,7 +152,6 @@ cc_defaults {
"toys/pending/dd.c",
"toys/pending/diff.c",
"toys/pending/expr.c",
- "toys/pending/fmt.c",
"toys/pending/getfattr.c",
"toys/pending/gzip.c",
"toys/pending/lsof.c",
diff --git a/generated/flags.h b/generated/flags.h
index 8cacb9f6..108c631d 100644
--- a/generated/flags.h
+++ b/generated/flags.h
@@ -865,9 +865,9 @@
#undef FLAG_n
#endif
-// fmt w# w#
+// fmt w#<0=75 w#<0=75
#undef OPTSTR_fmt
-#define OPTSTR_fmt "w#"
+#define OPTSTR_fmt "w#<0=75"
#ifdef CLEANUP_fmt
#undef CLEANUP_fmt
#undef FOR_fmt
diff --git a/generated/globals.h b/generated/globals.h
index 0789b91b..830d52ce 100644
--- a/generated/globals.h
+++ b/generated/globals.h
@@ -252,6 +252,14 @@ struct fallocate_data {
long size;
};
+// toys/other/fmt.c
+
+struct fmt_data {
+ int width;
+
+ int level, pos;
+};
+
// toys/other/free.c
struct free_data {
@@ -609,12 +617,6 @@ struct fdisk_data {
long cylinders;
};
-// toys/pending/fmt.c
-
-struct fmt_data {
- int width;
-};
-
// toys/pending/fold.c
struct fold_data {
@@ -1445,6 +1447,7 @@ extern union global_union {
struct chrt_data chrt;
struct dos2unix_data dos2unix;
struct fallocate_data fallocate;
+ struct fmt_data fmt;
struct free_data free;
struct hexedit_data hexedit;
struct hwclock_data hwclock;
@@ -1482,7 +1485,6 @@ extern union global_union {
struct dumpleases_data dumpleases;
struct expr_data expr;
struct fdisk_data fdisk;
- struct fmt_data fmt;
struct fold_data fold;
struct fsck_data fsck;
struct getfattr_data getfattr;
diff --git a/generated/help.h b/generated/help.h
index 3637a545..ae7e4c5f 100644
--- a/generated/help.h
+++ b/generated/help.h
@@ -256,6 +256,8 @@
#define HELP_free "usage: free [-bkmgt]\n\nDisplay the total, free and used amount of physical memory and swap space.\n\n-bkmgt Output units (default is bytes)\n-h Human readable\n\n"
+#define HELP_fmt "usage: fmt [-w WIDTH] [FILE...]\n\nReformat input to wordwrap at a given line length, preserving existing\nindentation level, writing to stdout.\n\n-w WIDTH maximum characters per line (default 75)\n\n"
+
#define HELP_flock "usage: flock [-sxun] fd\n\nManage advisory file locks.\n\n-s Shared lock\n-x Exclusive lock (default)\n-u Unlock\n-n Non-blocking: fail rather than wait for the lock\n\n"
#define HELP_fallocate "usage: fallocate [-l size] [-o offset] file\n\nTell the filesystem to allocate space for a file.\n\n"
@@ -308,10 +310,10 @@
#define HELP_useradd "usage: useradd [-SDH] [-h DIR] [-s SHELL] [-G GRP] [-g NAME] [-u UID] USER [GROUP]\n\nCreate new user, or add USER to GROUP\n\n-D Don't assign a password\n-g NAME Real name\n-G GRP Add user to existing group\n-h DIR Home directory\n-H Don't create home directory\n-s SHELL Login shell\n-S Create a system user\n-u UID User id\n\n"
-#define HELP_traceroute "usage: traceroute [-46FUIldnvr] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]\n[-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE] [-z PAUSE_MSEC] HOST [BYTES]\n\ntraceroute6 [-dnrv] [-m MAXTTL] [-p PORT] [-q PROBES][-s SRC_IP] [-t TOS] [-w WAIT_SEC]\n [-i IFACE] HOST [BYTES]\n\nTrace the route to HOST\n\n-4,-6 Force IP or IPv6 name resolution\n-F Set the don't fragment bit (supports IPV4 only)\n-U Use UDP datagrams instead of ICMP ECHO (supports IPV4 only)\n-I Use ICMP ECHO instead of UDP datagrams (supports IPV4 only)\n-l Display the TTL value of the returned packet (supports IPV4 only)\n-d Set SO_DEBUG options to socket\n-n Print numeric addresses\n-v verbose\n-r Bypass routing tables, send directly to HOST\n-m Max time-to-live (max number of hops)(RANGE 1 to 255)\n-p Base UDP port number used in probes(default 33434)(RANGE 1 to 65535)\n-q Number of probes per TTL (default 3)(RANGE 1 to 255)\n-s IP address to use as the source address\n-t Type-of-service in probe packets (default 0)(RANGE 0 to 255)\n-w Time in seconds to wait for a response (default 3)(RANGE 0 to 86400)\n-g Loose source route gateway (8 max) (supports IPV4 only)\n-z Pause Time in milisec (default 0)(RANGE 0 to 86400) (supports IPV4 only)\n-f Start from the 1ST_TTL hop (instead from 1)(RANGE 1 to 255) (supports IPV4 only)\n-i Specify a network interface to operate with\n\n"
-
#define HELP_tr "usage: tr [-cds] SET1 [SET2]\n\nTranslate, squeeze, or delete characters from stdin, writing to stdout\n\n-c/-C Take complement of SET1\n-d Delete input characters coded SET1\n-s Squeeze multiple output characters of SET2 into one character\n\n"
+#define HELP_traceroute "usage: traceroute [-46FUIldnvr] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]\n[-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE] [-z PAUSE_MSEC] HOST [BYTES]\n\ntraceroute6 [-dnrv] [-m MAXTTL] [-p PORT] [-q PROBES][-s SRC_IP] [-t TOS] [-w WAIT_SEC]\n [-i IFACE] HOST [BYTES]\n\nTrace the route to HOST\n\n-4,-6 Force IP or IPv6 name resolution\n-F Set the don't fragment bit (supports IPV4 only)\n-U Use UDP datagrams instead of ICMP ECHO (supports IPV4 only)\n-I Use ICMP ECHO instead of UDP datagrams (supports IPV4 only)\n-l Display the TTL value of the returned packet (supports IPV4 only)\n-d Set SO_DEBUG options to socket\n-n Print numeric addresses\n-v verbose\n-r Bypass routing tables, send directly to HOST\n-m Max time-to-live (max number of hops)(RANGE 1 to 255)\n-p Base UDP port number used in probes(default 33434)(RANGE 1 to 65535)\n-q Number of probes per TTL (default 3)(RANGE 1 to 255)\n-s IP address to use as the source address\n-t Type-of-service in probe packets (default 0)(RANGE 0 to 255)\n-w Time in seconds to wait for a response (default 3)(RANGE 0 to 86400)\n-g Loose source route gateway (8 max) (supports IPV4 only)\n-z Pause Time in milisec (default 0)(RANGE 0 to 86400) (supports IPV4 only)\n-f Start from the 1ST_TTL hop (instead from 1)(RANGE 1 to 255) (supports IPV4 only)\n-i Specify a network interface to operate with\n\n"
+
#define HELP_tftpd "usage: tftpd [-cr] [-u USER] [DIR]\n\nTransfer file from/to tftp server.\n\n-r read only\n-c Allow file creation via upload\n-u run as USER\n-l Log to syslog (inetd mode requires this)\n\n"
#define HELP_tftp "usage: tftp [OPTIONS] HOST [PORT]\n\nTransfer file from/to tftp server.\n\n-l FILE Local FILE\n-r FILE Remote FILE\n-g Get file\n-p Put file\n-b SIZE Transfer blocks of SIZE octets(8 <= SIZE <= 65464)\n\n"
@@ -396,8 +398,6 @@
#define HELP_fold "usage: fold [-bsu] [-w WIDTH] [FILE...]\n\nFolds (wraps) or unfolds ascii text by adding or removing newlines.\nDefault line width is 80 columns for folding and infinite for unfolding.\n\n-b Fold based on bytes instead of columns\n-s Fold/unfold at whitespace boundaries if possible\n-u Unfold text (and refold if -w is given)\n-w Set lines to WIDTH columns or bytes\n\n"
-#define HELP_fmt "usage: fmt [-w WIDTH] [FILE...]\n\nReformat input to not exceed a maximum line length.\n\n-w WIDTH maximum characters per line (default 75)\n\n"
-
#define HELP_fdisk "usage: fdisk [-lu] [-C CYLINDERS] [-H HEADS] [-S SECTORS] [-b SECTSZ] DISK\n\nChange partition table\n\n-u Start and End are in sectors (instead of cylinders)\n-l Show partition table for each DISK, then exit\n-b size sector size (512, 1024, 2048 or 4096)\n-C CYLINDERS Set number of cylinders/heads/sectors\n-H HEADS\n-S SECTORS\n\n"
#define HELP_expr "usage: expr ARG1 OPERATOR ARG2...\n\nEvaluate expression and print result. For example, \"expr 1 + 2\".\n\nThe supported operators are (grouped from highest to lowest priority):\n\n ( ) : * / % + - != <= < >= > = & |\n\nEach constant and operator must be a separate command line argument.\nAll operators are infix, meaning they expect a constant (or expression\nthat resolves to a constant) on each side of the operator. Operators of\nthe same priority (within each group above) are evaluated left to right.\nParentheses may be used (as separate arguments) to elevate the priority\nof expressions.\n\nCalling expr from a command shell requires a lot of \\( or '*' escaping\nto avoid interpreting shell control characters.\n\nThe & and | operators are logical (not bitwise) and may operate on\nstrings (a blank string is \"false\"). Comparison operators may also\noperate on strings (alphabetical sort).\n\nConstants may be strings or integers. Comparison, logical, and regex\noperators may operate on strings (a blank string is \"false\"), other\noperators require integers.\n\n"
@@ -408,10 +408,10 @@
#define HELP_dhcpd "usage: dhcpd [-46fS] [-i IFACE] [-P N] [CONFFILE]\n\n -f Run in foreground\n -i Interface to use\n -S Log to syslog too\n -P N Use port N (default ipv4 67, ipv6 547)\n -4, -6 Run as a DHCPv4 or DHCPv6 server\n\n"
-#define HELP_dhcp6 "usage: dhcp6 [-fbnqvR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n\n Configure network dynamicaly using DHCP.\n\n -i Interface to use (default eth0)\n -p Create pidfile\n -s Run PROG at DHCP events\n -t Send up to N Solicit packets\n -T Pause between packets (default 3 seconds)\n -A Wait N seconds after failure (default 20)\n -f Run in foreground\n -b Background if lease is not obtained\n -n Exit if lease is not obtained\n -q Exit after obtaining lease\n -R Release IP on exit\n -S Log to syslog too\n -r Request this IP address\n -v Verbose\n\n Signals:\n USR1 Renew current lease\n USR2 Release current lease\n\n"
-
#define HELP_dhcp "usage: dhcp [-fbnqvoCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL] [-O OPT]\n\n Configure network dynamicaly using DHCP.\n\n -i Interface to use (default eth0)\n -p Create pidfile\n -s Run PROG at DHCP events (default /usr/share/dhcp/default.script)\n -B Request broadcast replies\n -t Send up to N discover packets\n -T Pause between packets (default 3 seconds)\n -A Wait N seconds after failure (default 20)\n -f Run in foreground\n -b Background if lease is not obtained\n -n Exit if lease is not obtained\n -q Exit after obtaining lease\n -R Release IP on exit\n -S Log to syslog too\n -a Use arping to validate offered address\n -O Request option OPT from server (cumulative)\n -o Don't request any options (unless -O is given)\n -r Request this IP address\n -x OPT:VAL Include option OPT in sent packets (cumulative)\n -F Ask server to update DNS mapping for NAME\n -H Send NAME as client hostname (default none)\n -V VENDOR Vendor identifier (default 'toybox VERSION')\n -C Don't send MAC as client identifier\n -v Verbose\n\n Signals:\n USR1 Renew current lease\n USR2 Release current lease\n\n\n"
+#define HELP_dhcp6 "usage: dhcp6 [-fbnqvR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n\n Configure network dynamicaly using DHCP.\n\n -i Interface to use (default eth0)\n -p Create pidfile\n -s Run PROG at DHCP events\n -t Send up to N Solicit packets\n -T Pause between packets (default 3 seconds)\n -A Wait N seconds after failure (default 20)\n -f Run in foreground\n -b Background if lease is not obtained\n -n Exit if lease is not obtained\n -q Exit after obtaining lease\n -R Release IP on exit\n -S Log to syslog too\n -r Request this IP address\n -v Verbose\n\n Signals:\n USR1 Renew current lease\n USR2 Release current lease\n\n"
+
#define HELP_dd "usage: dd [if=FILE] [of=FILE] [ibs=N] [obs=N] [bs=N] [count=N] [skip=N]\n [seek=N] [conv=notrunc|noerror|sync|fsync] [status=noxfer|none]\n\nOptions:\nif=FILE Read from FILE instead of stdin\nof=FILE Write to FILE instead of stdout\nbs=N Read and write N bytes at a time\nibs=N Read N bytes at a time\nobs=N Write N bytes at a time\ncount=N Copy only N input blocks\nskip=N Skip N input blocks\nseek=N Skip N output blocks\nconv=notrunc Don't truncate output file\nconv=noerror Continue after read errors\nconv=sync Pad blocks with zeros\nconv=fsync Physically write data out before finishing\nstatus=noxfer Don't show transfer rate\nstatus=none Don't show transfer rate or records in/out\n\nNumbers may be suffixed by c (*1), w (*2), b (*512), kD (*1000), k (*1024),\nMD (*1000*1000), M (*1024*1024), GD (*1000*1000*1000) or G (*1024*1024*1024).\n\n"
#define HELP_crontab "usage: crontab [-u user] FILE\n [-u user] [-e | -l | -r]\n [-c dir]\n\nFiles used to schedule the execution of programs.\n\n-c crontab dir\n-e edit user's crontab\n-l list user's crontab\n-r delete user's crontab\n-u user\nFILE Replace crontab by FILE ('-': stdin)\n\n"
diff --git a/generated/newtoys.h b/generated/newtoys.h
index f9851dfe..f0c57113 100644
--- a/generated/newtoys.h
+++ b/generated/newtoys.h
@@ -74,7 +74,7 @@ USE_FGREP(OLDTOY(fgrep, grep, TOYFLAG_BIN))
USE_FILE(NEWTOY(file, "<1hL[!hL]", TOYFLAG_USR|TOYFLAG_BIN))
USE_FIND(NEWTOY(find, "?^HL[-HL]", TOYFLAG_USR|TOYFLAG_BIN))
USE_FLOCK(NEWTOY(flock, "<1>1nsux[-sux]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_FMT(NEWTOY(fmt, "w#", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_FMT(NEWTOY(fmt, "w#<0=75", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
USE_FOLD(NEWTOY(fold, "bsuw#<1", TOYFLAG_USR|TOYFLAG_BIN))
USE_FREE(NEWTOY(free, "htgmkb[!htgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
USE_FREERAMDISK(NEWTOY(freeramdisk, "<1>1", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
diff --git a/main.c b/main.c
index 4eeb193f..a3477a60 100644
--- a/main.c
+++ b/main.c
@@ -9,7 +9,7 @@
#ifndef TOYBOX_VENDOR
#define TOYBOX_VENDOR ""
#endif
-#define TOYBOX_VERSION "0.7.6"TOYBOX_VENDOR
+#define TOYBOX_VERSION "0.7.7"TOYBOX_VENDOR
#endif
// Populate toy_list[].
diff --git a/scripts/install.sh b/scripts/install.sh
index 898bfada..b780ef4b 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -106,7 +106,7 @@ done
# The following are commands toybox should provide, but doesn't yet.
# For now symlink the host version. This list must go away by 1.0.
-PENDING="bunzip2 bzcat dd diff expr ftpd ftpget ftpput gunzip less ping route tar test tr vi wget zcat awk bzip2 fdisk gzip sh sha512sum unxz xzcat bc"
+PENDING="bunzip2 bzcat dd diff expr ftpd ftpget ftpput gunzip less route tar test tr vi wget zcat awk bzip2 fdisk gzip sh sha512sum unxz xzcat bc bison flex"
# "gcc" should go away for llvm, but some things still hardwire it
TOOLCHAIN="ar as nm cc make ld gcc objdump"
diff --git a/tests/cut.test b/tests/cut.test
index f84acea8..e5a23fc1 100755
--- a/tests/cut.test
+++ b/tests/cut.test
@@ -7,17 +7,51 @@
[ -f testing.sh ] && . testing.sh
#testing "name" "command" "result" "infile" "stdin"
-#set -x
# Creating test file for testing cut
echo "one:two:three:four:five:six:seven
-alpha:beta:gamma:delta:epsilon:zeta:eta:teta:iota:kappa:lambda:mu
+alpha:beta:gamma:delta:epsilon:zeta:eta:theta:iota:kappa:lambda:mu
the quick brown fox jumps over the lazy dog" >abc.txt
-testing "with -c (a-b)" "cut -c 4-10 abc.txt" ":two:th\nha:beta\n quick \n" "" ""
-testing "with -f (a-)" "cut -d ':' -f 5- abc.txt" "five:six:seven\nepsilon:zeta:eta:teta:iota:kappa:lambda:mu\nthe quick brown fox jumps over the lazy dog\n" "" ""
-
-testing "with -f (a)" "cut -d ' ' -f 3 abc.txt" "one:two:three:four:five:six:seven\nalpha:beta:gamma:delta:epsilon:zeta:eta:teta:iota:kappa:lambda:mu\nbrown\n" "" ""
+testing "-b a,a,a" "cut -b 3,3,3 abc.txt" "e\np\ne\n" "" ""
+testing "-b overlaps" "cut -b 1-3,2-5,7-9,9-10 abc.txt" \
+ "one:to:th\nalphabeta\nthe qick \n" "" ""
+testing "-b encapsulated" "cut -b 3-8,4-6 abc.txt" "e:two:\npha:be\ne quic\n" \
+ "" ""
+testing "-bO overlaps" \
+ "cut --output-delimiter ' ' -b 1-3,2-5,7-9,9-10 abc.txt" \
+ "one:t o:th\nalpha beta\nthe q ick \n" "" ""
+testing "high-low error" "cut -b 8-3 abc.txt 2>/dev/null || echo err" "err\n" \
+ "" ""
+
+testing "-c a-b" "cut -c 4-10 abc.txt" ":two:th\nha:beta\n quick \n" "" ""
+testing "-c a-" "cut -c 41- abc.txt" "\ntheta:iota:kappa:lambda:mu\ndog\n" "" ""
+testing "-c -b" "cut -c -39 abc.txt" \
+ "one:two:three:four:five:six:seven\nalpha:beta:gamma:delta:epsilon:zeta:eta\nthe quick brown fox jumps over the lazy\n" \
+ "" ""
+testing "-c a" "cut -c 40 abc.txt" "\n:\n \n" "" ""
+testing "-c a,b-c,d" "cut -c 3,5-7,10 abc.txt" "etwoh\npa:ba\nequi \n" "" ""
+SKIP_HOST=1 testing "-c japan.txt" 'cut -c 3-6,9-12 "$FILES/utf8/japan.txt"' \
+ "ガラスをられます\n" "" ""
+
+# substitute for awk
+SKIP_HOST=1 testcmd "-DF" "-DF 2,7,5" \
+ "said and your\nare\nis demand. supply\nforecast :\nyou you better,\n\nEm: Took hate\n" "" \
+"Bother, said Pooh. It's your husband, and he has a gun.
+Cheerios are donut seeds.
+Talk is cheap because supply exceeds demand.
+Weather forecast for tonight : dark.
+Apple: you can buy better, but you can't pay more.
+Subcalifragilisticexpialidocious.
+Auntie Em: Hate you, hate Kansas. Took the dog. Dorothy."
+
+testcmd "empty field" "-d ':' -f 1-3" "a::b\n" "" "a::b\n"
+testcmd "empty field 2" "-d ':' -f 3-5" "b::c\n" "" "a::b::c:d\n"
+
+testing "-f a-" "cut -d ':' -f 5- abc.txt" "five:six:seven\nepsilon:zeta:eta:theta:iota:kappa:lambda:mu\nthe quick brown fox jumps over the lazy dog\n" "" ""
+
+testing "show whole line with no delim" "cut -d ' ' -f 3 abc.txt" \
+ "one:two:three:four:five:six:seven\nalpha:beta:gamma:delta:epsilon:zeta:eta:theta:iota:kappa:lambda:mu\nbrown\n" "" ""
testing "with echo, -c (a-b)" "echo 'ref_categorie=test' | cut -c 1-15 " "ref_categorie=t\n" "" ""
testing "with echo, -c (a)" "echo 'ref_categorie=test' | cut -c 14" "=\n" "" ""
diff --git a/toys/other/fmt.c b/toys/other/fmt.c
new file mode 100644
index 00000000..764fe2b7
--- /dev/null
+++ b/toys/other/fmt.c
@@ -0,0 +1,93 @@
+/* fmt.c - Text formatter
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * No standard.
+ *
+ * Only counts space and tab for indent level (eats other low ascii chars,
+ * treats all UTF8 chars as non-whitespace), preserves indentation but squashes
+ * together runs of whitespace. No header/footer logic, no end-of-sentence
+ * double-space, preserves initial tab/space mix when indenting new lines.
+
+USE_FMT(NEWTOY(fmt, "w#<0=75", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
+
+config FMT
+ bool "fmt"
+ default y
+ help
+ usage: fmt [-w WIDTH] [FILE...]
+
+ Reformat input to wordwrap at a given line length, preserving existing
+ indentation level, writing to stdout.
+
+ -w WIDTH maximum characters per line (default 75)
+*/
+
+#define FOR_fmt
+#include "toys.h"
+
+GLOBALS(
+ int width;
+
+ int level, pos;
+)
+
+static void newline(void)
+{
+ if (TT.pos) xputc('\n');
+ TT.pos = 0;
+}
+
+// Process lines of input, with (0,0) flush between files
+static void fmt_line(char **pline, long len)
+{
+ char *line;
+ int idx, indent, count;
+
+ // Flush line on EOF
+ if (!pline) return newline();
+
+ // Measure indentation
+ for (line = *pline, idx = count = 0; isspace(line[idx]); idx++) {
+ if (line[idx]=='\t') count += 8-(count&7);
+ else if (line[idx]==' ') count++;
+ }
+ indent = idx;
+
+ // Blank lines (even with same indentation) flush line
+ if (idx==len) {
+ xputc('\n');
+ TT.level = 0;
+
+ return newline();
+ }
+
+ // Did indentation change?
+ if (count!=TT.level) newline();
+ TT.level = count;
+
+ // Loop through words
+ while (idx<len) {
+ char *word = line+idx;
+
+ // Measure this word (unicode width) and end
+ while (idx<len && !isspace(line[idx])) idx++;
+ line[idx++] = 0;
+ count = utf8len(word);
+ if (TT.pos+count+!!TT.pos>=TT.width) newline();
+
+ // When indenting a new line, preserve tab/space mixture of input
+ if (!TT.pos) {
+ TT.pos = TT.level;
+ if (indent) printf("%.*s", indent, line);
+ } else count++;
+ printf(" %s"+!(TT.pos!=TT.level), word);
+ TT.pos += count;
+ while (isspace(line[idx])) idx++;
+ }
+}
+
+void fmt_main(void)
+{
+ loopfiles_lines(toys.optargs, fmt_line);
+}
diff --git a/toys/pending/fmt.c b/toys/pending/fmt.c
deleted file mode 100644
index 4b001f3f..00000000
--- a/toys/pending/fmt.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* fmt.c - Text formatter
- *
- * Copyright 2017 The Android Open Source Project
- *
- * Deviations from original:
- * we treat all whitespace as equal (no tab expansion, no runs of spaces)
- * we don't try to recognize ends of sentences to double-space after ./?/!
-
-USE_FMT(NEWTOY(fmt, "w#", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
-
-config FMT
- bool "fmt"
- default n
- help
- usage: fmt [-w WIDTH] [FILE...]
-
- Reformat input to not exceed a maximum line length.
-
- -w WIDTH maximum characters per line (default 75)
-*/
-
-#define FOR_fmt
-#include "toys.h"
-
-GLOBALS(
- int width;
-)
-
-static void do_fmt(int fd, char *name)
-{
- FILE *fp = xfdopen(fd, "re");
- char *line = NULL;
- size_t allocated_length = 0;
- int cols = 0, is_first = 1, indent_end = 0, line_length;
-
- while ((line_length = getline(&line, &allocated_length, fp)) > 0) {
- int b = 0, e, w;
-
- while (b < line_length && isspace(line[b])) b++;
- if (b == line_length) {
- if (cols > 0) xputc('\n');
- xputc('\n');
- is_first = 1;
- cols = 0;
- continue;
- }
- if (is_first) indent_end = b;
-
- for (; b < line_length; b = e + 1) {
- while (isspace(line[b])) b++;
- for (e = b + 1; e < line_length && !isspace(line[e]);) e++;
- if (e >= line_length) break;
-
- line[e] = 0;
- w = utf8len(line + b);
-
- if (!is_first && (cols + (is_first?indent_end:1) + w) >= TT.width) {
- xputc('\n');
- is_first = 1;
- cols = 0;
- }
- xprintf("%.*s%.*s",is_first?indent_end:1,is_first?line:" ",(e-b),line+b);
- cols += (is_first?indent_end:1) + w;
- b = e + 1;
- is_first = 0;
- }
- }
- if (cols > 0) xputc('\n');
- fclose(fp);
-}
-
-void fmt_main(void)
-{
- if (TT.width < 0) error_exit("negative width: %d", TT.width);
- if (!TT.width) TT.width = 75;
-
- loopfiles(toys.optargs, do_fmt);
-}
diff --git a/www/news.html b/www/news.html
index 5e46cf31..38d6b6e3 100755
--- a/www/news.html
+++ b/www/news.html
@@ -8,6 +8,94 @@ a development environment. See the links on the left for details.</p>
<h2>News</h2>
+<a name="23-06-2018" /><a href="#23-06-2018"><hr><h2><b>June 23, 2018</b></h2></a>
+<blockquote><p>
+<p>There is a theory which states that if ever anyone discovers exactly what
+the Universe is for and why it is here, it will instantly disappear and be
+replaced by something even more bizarre and inexplicable. There is another
+theory which states that this has already happened.</p>
+<p> - The Hitchhiker's Guide to the Galaxy</p>
+</blockquote>
+
+<p><a href=downloads/toybox-0.7.7.tar.gz>Toybox 0.7.7</a>
+(<a href=https://github.com/landley/toybox/releases/tag/0.7.7>git commit</a>)
+is out.</p>
+
+<p><u>New commands</u>: Rob Landley added <b>getconf</b>, Elliott Hughes added
+<b>uuidgen</b>, and <b>ping</b> and <b>fmt</b> were promoted out of pending.</p>
+
+<p><u>New options</u>: The <b>cp</b> command added the --parents option,
+<b>readlink</b> now has -m to show where a missing path would be,
+<b>netstat</b> got some updates (better nommu support, it can use /etc/services
+names, more command line options are bounds checked),
+Ng Zhi An added --getra and --setra (get/set readahead) to <b>blockdev</b>,
+Elliott Hughes added <b>xxd</b> -o and made <b>top</b> -d understand fractional
+sections (because the Linux Test Project uses that), and
+Minghui Liu added <b>watch</b> -b.</p>
+
+<p><u>Bugfixes</u>: Several fixes to <b>vmstat</b>: Elliott Hughes made it work on a
+48-core machine
+and fixed a glitch with -n, Haroon Maqsood pointed out "vmstat 1 1" didn't
+stop and "vmstat -n" didn't print the first theader line.
+Minghui Liu fixed a bug where <b>cp</b> -p didn't preserve
+timestamps, and pointed out the b, c, and d suffixes on numbers weren't
+working. Ryan Pritchard pointed out that <b>du</b> -d0 should act like du -s.
+Filip Perich made an RFC2347 OACK compliance fix to <b>tftp</b> in pending.
+Zach van Rijn fixed a bug in <b>xxd</b> causing incorrect translation of
+uppercase characters.
+Elliott fixed several things in <b>top</b> (removed spurious '\r' characters from -b
+output, removed interactive flicker, made running processes bold), and
+pushed Rob to make <b>file</b> work better recognizing things on stdin
+("cat /bin/ls | file -" still won't work but "file - < /bin/ls" should).
+Rob fixed a bug in <b>netstat</b> on 64 bit big endian systems,
+and fixed <b>cut</b> -DF
+(a posix compliance fix broke its ability to act as a decent awk replacment
+because outputting all delimiterless lines isn't what you want there, -D
+now disables that too).</p>
+</u></p>
+
+<p><u>Documentation</u>: Rob added a buildroot section to the roadmap with the
+prequisites that needs to run, and reformatted more of the ps --help text
+to two columns.</p>
+
+<p><u>Library</u>:
+FLAGS_NODASH is now set in toys.optargs when an optstring starting
+with & has no dash in its first argument. (This lets "ps -ax" and "ps ax"
+behave differently.) Factored out xtestfile() into lib/.
+The comma-separated-list parsing infrastructure moved to lib/commas.c.
+Added mkpath() for the common case of mkpathat() and #defined MKPATHAT_*
+constants for the uncommon cases. Elliott added better error checking
+to xparsetime() and fixed a bug in names_to_pid() (used in <b>pidof</b>
+and <b>killall</b> and such).
+Rob inlined the old toys/e2fs.h into pending's mke2fs,
+and removed a rogue semicolon from the WOULD_EXIT() macro that screwed
+up if() statement levels. The do_lines() semantics changed adding a
+callback(0,0) at the end of each file.</p>
+
+<p><u>Tests</u>:
+The test_* commands under toys/example were all renamed demo_* so
+they don't share a namespace with running a standalone command
+through the test suite (ala "make test_sed"), then
+demo_human_readable became demo_number so it can also test atolx()
+suffixes. The readlink.test was getting confused by a
+behavior difference between toybox and ubuntu (Ubuntu's ln -sf wouldn't
+replace a symlink that pointed to itself, toybox's would), now there's
+an explicit rm so it works on ubuntu too. The test suite plumbing's
+error message for a test with the wrong number of arguments now
+correctly identifies which test it's complaining about, and it can now
+run a test on a command name beginning with "-" (none yet but it
+comes up in toysh).</p>
+
+<p><u>Building</u>: You can now override strip with $STRIP. The set of
+"make install_airlock" commands got tweaked for the 4.17 kernel (which
+needs bison and flex because the new kconfig plumbing doesn't have _shipped
+versions of those generated files like the old kconfig did), and for
+the new release (remove ping, toybox provides it now).
+$LDFLAGS now applies to library probing (the android NDK provides
+dynamic libraries without corresponding --static versions).
+Elliott took a CFG_TOYBOX_DEBUG check out of an error_exit() to make
+clang stop complaining about an error that should never happen.</p>
+
<a name="24-02-2018" /><a href="#24-02-2018"><hr><h2><b>February 24, 2018</b></h2></a>
<blockquote><p>
"Arthur," said Ford.<br />