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:
Elliott Hughes 2017-12-23 23:44:04 -08:00 committed by Rob Landley
parent 17bcad9d44
commit 4335501bf3
2 changed files with 99 additions and 0 deletions

21
tests/fmt.test Executable file
View 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
View 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);
}