version 1.23, 2021/12/02 15:15:29 |
version 1.24, 2021/12/03 15:15:22 |
|
|
* Author: John Kunze, UCB |
* Author: John Kunze, UCB |
*/ |
*/ |
|
|
#include <sys/param.h> /* NOFILE_MAX */ |
#include <sys/types.h> |
|
|
#include <ctype.h> |
#include <ctype.h> |
#include <err.h> |
#include <err.h> |
#include <locale.h> |
#include <locale.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
|
#include <limits.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
|
|
|
char eol; /* end of line character */ |
char eol; /* end of line character */ |
char align; /* '0' for zero fill, '-' for left align */ |
char align; /* '0' for zero fill, '-' for left align */ |
char *sepstring; /* string to print before each line */ |
char *sepstring; /* string to print before each line */ |
} input[NOFILE_MAX + 1]; /* last one is for the last -s arg. */ |
} *input; |
#define INPUTSIZE sizeof(input) / sizeof(*input) |
int inputsize; /* number of openfile entries */ |
|
|
int numfiles; /* number of open files */ |
int output; /* line output produced */ |
int nofinalnl; /* normally append \n to each output line */ |
int nofinalnl; /* normally append \n to each output line */ |
char line[BIGBUFSIZ]; |
char line[BIGBUFSIZ]; |
char *linep; |
char *linep; |
|
|
if (pledge("stdio rpath", NULL) == -1) |
if (pledge("stdio rpath", NULL) == -1) |
err(1, "pledge"); |
err(1, "pledge"); |
|
|
/* Process arguments, set numfiles to file argument count. */ |
|
getargs(argc, argv); |
getargs(argc, argv); |
if (numfiles == 0) |
if (inputsize == 0) |
usage(); |
usage(); |
|
|
if (pledge("stdio", NULL) == -1) |
if (pledge("stdio", NULL) == -1) |
|
|
for (;;) { |
for (;;) { |
linep = line; |
linep = line; |
/* |
/* |
* For each file that has a line to print, numfile is |
* For each file that has a line to print, output is |
* incremented. Thus if numfiles is 0, we are done. |
* incremented. Thus if numfiles is 0, we are done. |
*/ |
*/ |
numfiles = 0; |
output = 0; |
for (i = 0; i < INPUTSIZE - 1 && input[i].fp != NULL; i++) |
for (i = 0; i < inputsize && input[i].fp != NULL; i++) |
linep = gatherline(&input[i]); |
linep = gatherline(&input[i]); |
if (numfiles == 0) |
if (output == 0) |
exit(0); |
exit(0); |
fputs(line, stdout); |
fputs(line, stdout); |
/* Print terminating -s argument. */ |
/* Print terminating -s argument. */ |
|
|
void |
void |
getargs(int argc, char *argv[]) |
getargs(int argc, char *argv[]) |
{ |
{ |
struct openfile *ip = input; |
struct openfile *ip; |
const char *errstr; |
const char *errstr; |
char *p, *q; |
char *p, *q; |
|
void *tmp; |
int ch, P, S, F, T; |
int ch, P, S, F, T; |
|
|
|
input = calloc(inputsize+1, sizeof *input); |
|
if (input == NULL) |
|
errx(1, "too many files"); |
|
ip = &input[inputsize]; |
|
|
P = S = F = T = 0; /* capitalized options */ |
P = S = F = T = 0; /* capitalized options */ |
while (optind < argc) { |
while (optind < argc) { |
switch (ch = getopt(argc, argv, "F:f:P:p:S:s:T:t:")) { |
switch (ch = getopt(argc, argv, "F:f:P:p:S:s:T:t:")) { |
|
|
if (optind >= argc) |
if (optind >= argc) |
break; /* to support "--" */ |
break; /* to support "--" */ |
/* This is a file, not a flag. */ |
/* This is a file, not a flag. */ |
++numfiles; |
|
if (numfiles >= INPUTSIZE) |
|
errx(1, "too many files"); |
|
if (strcmp(argv[optind], "-") == 0) |
if (strcmp(argv[optind], "-") == 0) |
ip->fp = stdin; |
ip->fp = stdin; |
else if ((ip->fp = fopen(argv[optind], "r")) == NULL) |
else if ((ip->fp = fopen(argv[optind], "r")) == NULL) |
|
|
} else |
} else |
ip->maxwidth = INT_MAX; |
ip->maxwidth = INT_MAX; |
} |
} |
ip++; |
|
|
++inputsize; |
|
|
|
/* Prepare for next file argument */ |
|
tmp = recallocarray(input, inputsize, |
|
inputsize+1, sizeof *input); |
|
if (tmp == NULL) |
|
errx(1, "too many files"); |
|
input = tmp; |
|
ip = &input[inputsize]; |
optind++; |
optind++; |
break; |
break; |
default: |
default: |
|
|
} |
} |
|
|
/* |
/* |
* Grab line from file, appending to linep. Increments numfiles if file |
* Grab line from file, appending to linep. Increments printed if file |
* is still open. |
* is still open. |
*/ |
*/ |
char * |
char * |
|
|
return (pad(ip)); |
return (pad(ip)); |
} |
} |
/* Something will be printed. */ |
/* Something will be printed. */ |
numfiles++; |
output++; |
n = strlcpy(lp, ip->sepstring, line + sizeof(line) - lp); |
n = strlcpy(lp, ip->sepstring, line + sizeof(line) - lp); |
lp += (n < line + sizeof(line) - lp) ? n : strlen(lp); |
lp += (n < line + sizeof(line) - lp) ? n : strlen(lp); |
width = mbswidth_truncate(s, ip->maxwidth); |
width = mbswidth_truncate(s, ip->maxwidth); |