Add fmt.
A very simple implementation of fmt, good enough for my daily use of !!fmt in vi to reflow checkin comments like this.
This commit is contained in:
parent
17bcad9d44
commit
4335501bf3
21
tests/fmt.test
Executable file
21
tests/fmt.test
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
[ -f testing.sh ] && . testing.sh
|
||||||
|
|
||||||
|
echo "hello world " > en.txt
|
||||||
|
echo "this is some text " >> en.txt
|
||||||
|
# https://en.wikipedia.org/wiki/Aegukga
|
||||||
|
echo "동해물과 백두산이 마르고 닳도록" > kr.txt
|
||||||
|
echo "하나님이 보우하사 우리나라 만세." >> kr.txt
|
||||||
|
|
||||||
|
#testing "name" "command" "result" "infile" "stdin"
|
||||||
|
|
||||||
|
testing "join" "fmt en.txt" "hello world this is some text\n" "" ""
|
||||||
|
testing "split" "fmt -w 10 en.txt" "hello\nworld\nthis is\nsome text\n" "" ""
|
||||||
|
testing "no room" "echo 'hello world' | fmt -w 1" "hello\nworld\n" "" ""
|
||||||
|
testing "blank line" "echo -e 'first paragraph of text\n\nand another' | fmt -w 10" "first\nparagraph\nof text\n\nand\nanother\n" "" ""
|
||||||
|
testing "ws-only line" "echo -e 'hello\n \nworld' | fmt -w 10" "hello\n\nworld\n" "" ""
|
||||||
|
testing "leading space" "echo ' hello world' | fmt -w 5" " hello\n world\n" "" ""
|
||||||
|
testing "utf8" "fmt -w 10 kr.txt" "동해물과\n백두산이\n마르고\n닳도록\n하나님이\n보우하사\n우리나라\n만세.\n" "" ""
|
||||||
|
|
||||||
|
rm en.txt kr.txt
|
78
toys/pending/fmt.c
Normal file
78
toys/pending/fmt.c
Normal file
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user