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

View File

@ -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
View File

@ -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
View 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
View 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
View File

@ -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
View File

@ -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
View File

@ -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++;