This commit is contained in:
Connor Lane Smith 2011-06-08 21:30:33 +01:00
parent 2404eb5b6b
commit ff97891dad
7 changed files with 131 additions and 4 deletions

@ -18,6 +18,7 @@ SRC = \
dirname.c \
echo.c \
false.c \
fold.c \
grep.c \
head.c \
ln.c \
@ -70,7 +71,9 @@ install: all
@cd $(DESTDIR)$(MANPREFIX)/man1 && chmod 644 $(MAN)
uninstall:
@echo removing executables from $(DESTDIR)$(PREFIX)/bin
@cd $(DESTDIR)$(PREFIX)/bin && rm -f $(BIN)
@echo removing manual pages from $(DESTDIR)$(MANPREFIX)/man1
@cd $(DESTDIR)$(MANPREFIX)/man1 && rm -f $(MAN)
dist: clean

2
TODO

@ -11,8 +11,6 @@ cut [-bcfs] [-d delim] list [file...]
diff [-ru] file1 file2
fold [-bs] [-w width] [file...]
id [-gnru] [user]
kill [-s signal] [pid...]

25
fold.1 Normal file

@ -0,0 +1,25 @@
.TH FOLD 1 sbase\-VERSION
.SH NAME
fold \- wrap lines to width
.SH SYNOPSIS
.B fold
.RB [ \-bs ]
.RB [ \-w
.IR width ]
.RI [ file ...]
.SH DESCRIPTION
.B fold
reads each file in sequence and prints its lines, broken such that no line
exceeds 80 characters. If no file is given, fold reads from stdin.
.SH OPTIONS
.TP
.B \-b
counts bytes rather than columns.
.TP
.B \-s
breaks only at spaces.
.TP
.BI \-w " width"
uses
.I width
columns instead of 80.

99
fold.c Normal file

@ -0,0 +1,99 @@
/* See LICENSE file for copyright and license details. */
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "text.h"
#include "util.h"
static void fold(FILE *, const char *, long);
static void foldline(const char *, long);
static bool bflag = false;
static bool sflag = false;
int
main(int argc, char *argv[])
{
char c, *end;
long width = 80;
FILE *fp;
while((c = getopt(argc, argv, "bsw:")) != -1)
switch(c) {
case 'b':
bflag = true;
break;
case 's':
sflag = true;
break;
case 'w':
width = strtol(optarg, &end, 0);
if(*end != '\0')
eprintf("%s: not a number\n", optarg);
break;
default:
exit(EXIT_FAILURE);
}
if(optind == argc)
fold(stdin, "<stdin>", width);
else for(; optind < argc; optind++) {
if(!(fp = fopen(argv[optind], "r")))
eprintf("fopen %s:", argv[optind]);
fold(fp, argv[optind], width);
fclose(fp);
}
return EXIT_SUCCESS;
}
void
fold(FILE *fp, const char *str, long width)
{
char *buf = NULL;
size_t size = 0;
while(afgets(&buf, &size, fp))
foldline(buf, width);
free(buf);
}
void
foldline(const char *str, long width)
{
bool space;
long col, i, j, n;
for(i = n = 0; str[i] && str[i] != '\n'; i = n) {
space = false;
for(j = i, col = 0; str[j] && col <= width; j++) {
if(!UTF8_POINT(str[j]) && !bflag)
continue;
if(sflag && isspace(str[j])) {
space = true;
n = j+1;
}
else if(!space)
n = j;
if(!bflag && iscntrl(str[j]))
switch(str[j]) {
case '\b':
col--;
break;
case '\r':
col = 0;
break;
case '\t':
col += (col+1) % 8;
break;
}
else
col++;
}
if(fwrite(&str[i], 1, n-i, stdout) != n-i)
eprintf("<stdout>: write error:");
if(str[n])
putchar('\n');
}
}

2
ls.c

@ -210,7 +210,7 @@ output(Entry *ent)
fmt = "%b %d %H:%M";
strftime(buf, sizeof buf, fmt, localtime(&ent->mtime));
printf("%s %2d %s %s %6lu %s %s", mode, ent->nlink, pw->pw_name,
printf("%s %2ld %s %s %6lu %s %s", mode, (long)ent->nlink, pw->pw_name,
gr->gr_name, (unsigned long)ent->size, buf, ent->name);
if(S_ISLNK(ent->mode)) {
if((len = readlink(ent->name, buf, sizeof buf)) == -1)

2
util.h

@ -1,5 +1,7 @@
/* See LICENSE file for copyright and license details. */
#define UTF8_POINT(c) (((c) & 0xc0) != 0x80)
char *agetcwd(void);
void enmasse(int, char **, int (*)(const char *, const char *));
void eprintf(const char *, ...);

2
wc.c

@ -75,7 +75,7 @@ wc(FILE *fp, const char *str)
long nc = 0, nl = 0, nw = 0;
while((c = fgetc(fp)) != EOF) {
if(cmode != 'm' || (c & 0xc0) != 0x80) /* utf8 */
if(cmode != 'm' || UTF8_POINT(c))
nc++;
if(c == '\n')
nl++;