Importing usr.bin/fold

Replaces commands/fold. No Minix-specific changes needed.

Change-Id: Iefa9a082f900bb8c3a9f2f9f827ccbbd97c935f5
This commit is contained in:
Thomas Cort 2013-10-29 09:24:41 -04:00
parent b828b0feb7
commit b5a2a7adea
10 changed files with 351 additions and 112 deletions

View File

@ -9,7 +9,7 @@ SUBDIR= add_route arp ash at backup btrace \
dd decomp16 DESCRIBE devmand devsize df dhcpd \
dhrystone diff diskctl dumpcore \
eject factor fbdctl \
find fix fold format fortune fsck.mfs \
find fix format fortune fsck.mfs \
gcore gcov-pull getty grep hexdump host \
hostaddr id ifconfig ifdef \
intr ipcrm ipcs irdpd isoread last \

View File

@ -1,4 +0,0 @@
PROG= fold
MAN=
.include <bsd.prog.mk>

View File

@ -1,70 +0,0 @@
/* fold - folds long lines Author: Terrence W. Holm */
/* Usage: fold [ -width ] [ file ... ] */
#include <stdlib.h>
#include <stdio.h>
#define TAB 8
#define DEFAULT_WIDTH 80
int column = 0; /* Current column, retained between files */
int main(int argc, char **argv);
void Fold(FILE *f, int width);
int main(argc, argv)
int argc;
char *argv[];
{
int width = DEFAULT_WIDTH;
int i;
FILE *f;
if (argc > 1 && argv[1][0] == '-') {
if ((width = atoi(&argv[1][1])) <= 0) {
fprintf(stderr, "Bad number for fold\n");
exit(1);
}
--argc;
++argv;
}
if (argc == 1)
Fold(stdin, width);
else {
for (i = 1; i < argc; ++i) {
if ((f = fopen(argv[i], "r")) == NULL) {
perror(argv[i]);
exit(1);
}
Fold(f, width);
fclose(f);
}
}
return(0);
}
void Fold(f, width)
FILE *f;
int width;
{
int c;
while ((c = getc(f)) != EOF) {
if (c == '\t')
column = (column / TAB + 1) * TAB;
else if (c == '\b')
column = column > 0 ? column - 1 : 0;
else if (c == '\n' || c == '\r')
column = 0;
else
++column;
if (column > width) {
putchar('\n');
column = c == '\t' ? TAB : 1;
}
putchar(c);
}
}

View File

@ -5,7 +5,7 @@ MAN= ash.1 at.1 \
df.1 dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
dumpcore.1 eject.1 \
factor.1 \
flexdoc.1 fold.1 format.1 fortune.1 \
flexdoc.1 format.1 fortune.1 \
fsck.mfs.1 host.1 hostaddr.1 ifdef.1 \
isodir.1 isoinfo.1 isoread.1 \
last.1 loadfont.1 loadkeys.1 logger.1 \

View File

@ -1,35 +0,0 @@
.TH FOLD 1
.SH NAME
fold \- fold long lines
.SH SYNOPSIS
\fBfold\fR [\fB\-\fIn\fR]\fR [\fIfile\fR] ...\fR
.br
.de FL
.TP
\\fB\\$1\\fR
\\$2
..
.de EX
.TP 20
\\fB\\$1\\fR
# \\$2
..
.SH OPTIONS
.TP 5
.B \-\fIn\fR
# How long should the output lines be
.SH EXAMPLES
.TP 20
.B fold \-60
# Fold \fIstdin\fR to 60 characters
.TP 20
.B fold file
# Fold \fIfile\fP to 80 characters
.SH DESCRIPTION
.PP
\fIFold\fR takes copies its input from the named file (or \fIstdin\fR,
if none is specified) to standard output.
However, lines longer than the given maximum (default 80) are broken
into multiple lines of the maximum length by inserting new line characters.
.SH "SEE ALSO"
.BR width (1).

View File

@ -163,6 +163,7 @@
2012/10/17 12:00:00,usr.bin/expand
2013/10/17 12:00:00,usr.bin/env
2013/05/31 12:00:00,usr.bin/finger
2012/10/17 12:00:00,usr.bin/fold
2013/03/22 12:00:00,usr.bin/from
2012/10/17 12:00:00,usr.bin/fsplit
2013/04/05 12:00:00,usr.bin/ftp

View File

@ -10,7 +10,7 @@ SUBDIR= asa \
col column comm csplit ctags cut \
dirname du \
env expand \
finger from \
finger fold from \
fsplit ftp genassym getopt \
head indent infocmp join \
ldd leave \

6
usr.bin/fold/Makefile Normal file
View File

@ -0,0 +1,6 @@
# @(#)Makefile 8.1 (Berkeley) 6/6/93
# $NetBSD: Makefile,v 1.3 1995/09/01 01:42:41 jtc Exp $
PROG= fold
.include <bsd.prog.mk>

93
usr.bin/fold/fold.1 Normal file
View File

@ -0,0 +1,93 @@
.\" $NetBSD: fold.1,v 1.17 2012/05/12 15:17:15 wiz Exp $
.\"
.\" Copyright (c) 1980, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)fold.1 8.1 (Berkeley) 6/6/93
.\"
.Dd May 12, 2012
.Dt FOLD 1
.Os
.Sh NAME
.Nm fold
.Nd "fold long lines for finite width output device"
.Sh SYNOPSIS
.Nm
.Op Fl bs
.Op Fl w Ar width
.Op Ar
.Sh DESCRIPTION
.Nm
is a filter which folds the contents of the specified files,
or the standard input if no files are specified,
breaking the lines to have a maximum of 80 characters.
.Pp
The options are as follows:
.Bl -tag -width XwXwidthXX
.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).
If a blank character does not exist within the width, then
a longer line will still be split at the width.
.It Fl w Ar width
Specifies
.Ar width
to use as a line width, instead of the default 80 characters.
.El
.Sh ENVIRONMENT
.Bl -tag -width indent
.It Ev LC_CTYPE
.El
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
.Xr expand 1 ,
.Xr fmt 1
.Sh STANDARDS
The
.Nm
utility conforms to
.St -p1003.1-2008 .
.Sh HISTORY
The
.Nm
utility appeared in
.Bx 1 .
.Sh BUGS
If underlining is present it may be messed up by folding.
.Pp
.Ar Width
should be a multiple of 8 if tabs are present, or the tabs should
be expanded using
.Xr expand 1
before using
.Nm .

248
usr.bin/fold/fold.c Normal file
View File

@ -0,0 +1,248 @@
/* $NetBSD: fold.c,v 1.17 2011/09/04 20:24:59 joerg Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kevin Ruddy.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1990, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)fold.c 8.1 (Berkeley) 6/6/93";
#endif
__RCSID("$NetBSD: fold.c,v 1.17 2011/09/04 20:24:59 joerg Exp $");
#endif /* not lint */
#include <limits.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wchar.h>
#include <err.h>
#define DEFLINEWIDTH 80
static void fold(int);
static int new_column_position(int, wint_t);
__dead static void usage(void);
static int count_bytes = 0;
static int split_words = 0;
int
main(int argc, char **argv)
{
int ch;
int width;
char *p;
setlocale(LC_CTYPE, "");
setprogname(argv[0]);
width = -1;
while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1)
switch (ch) {
case 'b':
count_bytes = 1;
break;
case 's':
split_words = 1;
break;
case 'w':
if ((width = atoi(optarg)) <= 0)
errx(1, "illegal width value");
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (width == -1) {
p = argv[optind - 1];
if (p[0] == '-' && p[1] == ch && !p[2])
width = atoi(++p);
else
width = atoi(argv[optind] + 1);
}
break;
default:
usage();
}
argv += optind;
argc -= optind;
if (width == -1)
width = DEFLINEWIDTH;
if (!*argv)
fold(width);
else for (; *argv; ++argv)
if (!freopen(*argv, "r", stdin)) {
err (1, "%s", *argv);
/* NOTREACHED */
} else
fold(width);
exit(0);
}
/*
* Fold the contents of standard input to fit within WIDTH columns
* (or bytes) and write to standard output.
*
* If split_words 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.
*/
static void
fold(int width)
{
static wchar_t *buf = NULL;
wchar_t *nbuf;
static int buf_max = 0;
wint_t ch;
int col, indx, i;
col = indx = 0;
while ((ch = getwchar()) != WEOF) {
if (ch == L'\n') {
if (indx != 0) {
for (i = 0; i < indx; i++)
putwchar(buf[i]);
}
putwchar(L'\n');
col = indx = 0;
continue;
}
col = new_column_position (col, ch);
if (col > width) {
int last_space;
#ifdef __GNUC__
last_space = 0; /* XXX gcc */
#endif
if (split_words) {
for (i = 0, last_space = -1; i < indx; i++)
if (buf[i] == L' ')
last_space = i;
}
if (split_words && last_space != -1) {
for (i = 0; i < last_space; i++)
putwchar(buf[i]);
/* increase last_space here, so we skip trailing whitespace */
last_space++;
wmemmove (buf, buf+last_space, indx-last_space);
indx -= last_space;
col = 0;
for (i = 0; i < indx; i++) {
col = new_column_position (col, buf[i]);
}
} else {
for (i = 0; i < indx; i++)
putwchar(buf[i]);
col = indx = 0;
}
putwchar('\n');
/* calculate the column position for the next line. */
col = new_column_position (col, ch);
}
if (indx + 1 > buf_max) {
/* Allocate buffer in LINE_MAX increments */
if ((nbuf = realloc (buf, buf_max + 2048)) == NULL) {
err (1, "realloc");
/* NOTREACHED */
}
buf = nbuf;
buf_max += 2048;
}
buf[indx++] = ch;
}
if (indx != 0) {
for (i = 0; i < indx; i++)
putwchar(buf[i]);
}
}
/*
* calculate the column position
*/
static int
new_column_position (int col, wint_t ch)
{
int w;
if (!count_bytes) {
switch (ch) {
case L'\b':
if (col > 0)
--col;
break;
case L'\r':
col = 0;
break;
case L'\t':
col = (col + 8) & ~7;
break;
default:
w = wcwidth(ch);
if (w > 0)
col += w;
break;
}
} else {
char dummy[MB_LEN_MAX];
/* XXX: we assume stateless encoding */
col += wcrtomb(dummy, ch, NULL);
}
return col;
}
static void
usage(void)
{
(void)fprintf(stderr,
"usage: %s [-bs] [-w width] [file ...]\n", getprogname());
exit(1);
}