blob: 618642a2b1585fb42825df8a145f897f3e3806a1 [file] [log] [blame]
/* 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);
}