mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-01 12:19:28 +00:00
Add the -b option (break at byte position, not column number) and the -s
option (try to break at word bounaries) for SUSv3 conformance. Partially based on the NetBSD version, with the following changes: - style(9) - break on <blank>s, not spaces, per POSIX (and GNU) - when looking for last space on line, search backwards instead of forwards; less comparisons needed this way. - use LINE_MAX macro instead of a magic number and a comment saying it is LINE_MAX. PR: 36245 Reviewed by: mike Obtained from: NetBSD (partially)
This commit is contained in:
parent
6139043b1f
commit
13e06695bf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=94978
@ -32,7 +32,7 @@
|
||||
.\" @(#)fold.1 8.1 (Berkeley) 6/6/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 6, 1993
|
||||
.Dd April 17, 2002
|
||||
.Dt FOLD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -40,6 +40,7 @@
|
||||
.Nd "fold long lines for finite width output device"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl bs
|
||||
.Op Fl w Ar width
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
@ -50,6 +51,14 @@ breaking the lines to have a maximum of 80 characters.
|
||||
.Pp
|
||||
The following option is available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl b
|
||||
Count
|
||||
.Ar width
|
||||
in bytes rather than column positions.
|
||||
.It Fl s
|
||||
Fold line after the last blank character within the first
|
||||
.Ar width
|
||||
column positions (or bytes).
|
||||
.It Fl w Ar width
|
||||
Specify a line width to use instead of the default 80 characters.
|
||||
.Ar Width
|
||||
@ -61,5 +70,10 @@ before using
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr expand 1
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility conforms to
|
||||
.St -p1003.1-2001 .
|
||||
.Sh BUGS
|
||||
If underlining is present it may be messed up by folding.
|
||||
|
@ -49,16 +49,23 @@ static char sccsid[] = "@(#)fold.c 8.1 (Berkeley) 6/6/93";
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define DEFLINEWIDTH 80
|
||||
|
||||
void fold(int);
|
||||
static int newpos(int, int);
|
||||
static void usage(void);
|
||||
|
||||
int bflag; /* Count bytes, not columns */
|
||||
int sflag; /* Split on word boundaries */
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
@ -69,8 +76,14 @@ main(argc, argv)
|
||||
char *p;
|
||||
|
||||
width = -1;
|
||||
while ((ch = getopt(argc, argv, "0123456789w:")) != -1)
|
||||
while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1)
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
bflag = 1;
|
||||
break;
|
||||
case 's':
|
||||
sflag = 1;
|
||||
break;
|
||||
case 'w':
|
||||
if ((width = atoi(optarg)) <= 0) {
|
||||
errx(1, "illegal width value");
|
||||
@ -107,57 +120,98 @@ main(argc, argv)
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: fold [-w width] [file ...]\n");
|
||||
(void)fprintf(stderr, "usage: fold [-bs] [-w width] [file ...]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fold the contents of standard input to fit within WIDTH columns (or bytes)
|
||||
* and write to standard output.
|
||||
*
|
||||
* If sflag is set, split the line at the last space character on the line.
|
||||
* This flag necessitates storing the line in a buffer until the current
|
||||
* column > width, or a newline or EOF is read.
|
||||
*
|
||||
* The buffer can grow larger than WIDTH due to backspaces and carriage
|
||||
* returns embedded in the input stream.
|
||||
*/
|
||||
void
|
||||
fold(width)
|
||||
register int width;
|
||||
{
|
||||
register int ch, col, new;
|
||||
static char *buf;
|
||||
static int buf_max;
|
||||
int ch, col, i, indx, space;
|
||||
|
||||
for (col = 0;;) {
|
||||
switch (ch = getchar()) {
|
||||
case EOF:
|
||||
return;
|
||||
case '\b':
|
||||
new = col ? col - 1 : 0;
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
new = 0;
|
||||
break;
|
||||
case '\t':
|
||||
new = (col + 8) & ~7;
|
||||
break;
|
||||
default:
|
||||
new = col + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (new > width) {
|
||||
col = indx = 0;
|
||||
while ((ch = getchar()) != EOF) {
|
||||
if (ch == '\n') {
|
||||
if (indx != 0)
|
||||
fwrite(buf, 1, indx, stdout);
|
||||
putchar('\n');
|
||||
col = 0;
|
||||
col = indx = 0;
|
||||
continue;
|
||||
}
|
||||
putchar(ch);
|
||||
if ((col = newpos(col, ch)) > width) {
|
||||
if (sflag) {
|
||||
i = indx;
|
||||
while (--i >= 0 && !isblank(buf[i]))
|
||||
;
|
||||
space = i;
|
||||
}
|
||||
if (sflag && space != -1) {
|
||||
space++;
|
||||
fwrite(buf, 1, space, stdout);
|
||||
memmove(buf, buf + space, indx - space);
|
||||
indx -= space;
|
||||
col = 0;
|
||||
for (i = 0; i < indx; i++)
|
||||
col = newpos(col, buf[i]);
|
||||
} else {
|
||||
fwrite(buf, 1, indx, stdout);
|
||||
col = indx = 0;
|
||||
}
|
||||
putchar('\n');
|
||||
col = newpos(col, ch);
|
||||
}
|
||||
if (indx + 1 > buf_max) {
|
||||
buf_max += LINE_MAX;
|
||||
if ((buf = realloc(buf, buf_max)) == NULL)
|
||||
err(1, "realloc()");
|
||||
}
|
||||
buf[indx++] = ch;
|
||||
}
|
||||
|
||||
if (indx != 0)
|
||||
fwrite(buf, 1, indx, stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the current column position for a character.
|
||||
*/
|
||||
static int
|
||||
newpos(col, ch)
|
||||
int col, ch;
|
||||
{
|
||||
|
||||
if (bflag)
|
||||
++col;
|
||||
else
|
||||
switch (ch) {
|
||||
case '\b':
|
||||
if (col > 0)
|
||||
--col;
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
col = 0;
|
||||
break;
|
||||
case '\t':
|
||||
col += 8;
|
||||
col &= ~7;
|
||||
col = (col + 8) & ~7;
|
||||
break;
|
||||
default:
|
||||
++col;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (col);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user