aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
Diffstat (limited to 'toys')
-rw-r--r--toys/pending/fmt.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/toys/pending/fmt.c b/toys/pending/fmt.c
new file mode 100644
index 00000000..618642a2
--- /dev/null
+++ b/toys/pending/fmt.c
@@ -0,0 +1,78 @@
+/* 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 y
+ 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);
+}