Audit cut(1)
1) Add check to parselist() to warn about an empty list. 2) Remove all "cut: "-prefixes from error-messages and other style changes. 3) != -1 --> >= 0 and check for ferror on fp after getline. 4) Update usage with argv0. 5) argv-centric loop refactor 6) Properly report exit-status. 7) Add empty line before return.
This commit is contained in:
parent
011c81b21b
commit
c9de9dd3c2
39
cut.c
39
cut.c
|
@ -50,6 +50,8 @@ parselist(char *str)
|
||||||
size_t n = 1;
|
size_t n = 1;
|
||||||
Range *r;
|
Range *r;
|
||||||
|
|
||||||
|
if (!*str)
|
||||||
|
eprintf("empty list\n");
|
||||||
for (s = str; *s; s++) {
|
for (s = str; *s; s++) {
|
||||||
if (*s == ' ')
|
if (*s == ' ')
|
||||||
*s = ',';
|
*s = ',';
|
||||||
|
@ -62,7 +64,7 @@ parselist(char *str)
|
||||||
r->max = (*s == '-') ? strtoul(s + 1, &s, 10) : r->min;
|
r->max = (*s == '-') ? strtoul(s + 1, &s, 10) : r->min;
|
||||||
r->next = NULL;
|
r->next = NULL;
|
||||||
if (!r->min || (r->max && r->max < r->min) || (*s && *s != ','))
|
if (!r->min || (r->max && r->max < r->min) || (*s && *s != ','))
|
||||||
eprintf("cut: bad list value\n");
|
eprintf("bad list value\n");
|
||||||
insert(r++);
|
insert(r++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +105,7 @@ seek(const char *s, size_t pos, size_t *prev, size_t count)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cut(FILE *fp)
|
cut(FILE *fp, char *fname)
|
||||||
{
|
{
|
||||||
static char *buf = NULL;
|
static char *buf = NULL;
|
||||||
static size_t size = 0;
|
static size_t size = 0;
|
||||||
|
@ -112,7 +114,7 @@ cut(FILE *fp)
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
Range *r;
|
Range *r;
|
||||||
|
|
||||||
while ((len = getline(&buf, &size, fp)) != -1) {
|
while ((len = getline(&buf, &size, fp)) >= 0) {
|
||||||
if (len && buf[len - 1] == '\n')
|
if (len && buf[len - 1] == '\n')
|
||||||
buf[len - 1] = '\0';
|
buf[len - 1] = '\0';
|
||||||
if (mode == 'f' && !utfutf(buf, delim)) {
|
if (mode == 'f' && !utfutf(buf, delim)) {
|
||||||
|
@ -132,24 +134,28 @@ cut(FILE *fp)
|
||||||
n = seek(s, r->max + 1, &p, i);
|
n = seek(s, r->max + 1, &p, i);
|
||||||
i += (mode == 'f') ? delimlen : 1;
|
i += (mode == 'f') ? delimlen : 1;
|
||||||
if (fwrite(s, 1, n, stdout) != n)
|
if (fwrite(s, 1, n, stdout) != n)
|
||||||
eprintf("write error:");
|
eprintf("fwrite <stdout>:");
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
if (ferror(fp))
|
||||||
|
eprintf("getline %s:", fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
eprintf("usage: cut -b list [-n] [file ...]\n"
|
eprintf("usage: %s -b list [-n] [file ...]\n"
|
||||||
" cut -c list [file ...]\n"
|
" %s -c list [file ...]\n"
|
||||||
" cut -f list [-d delim] [-s] [file ...]\n");
|
" %s -f list [-d delim] [-s] [file ...]\n",
|
||||||
|
argv0, argv0, argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
case 'b':
|
case 'b':
|
||||||
|
@ -161,7 +167,7 @@ main(int argc, char *argv[])
|
||||||
case 'd':
|
case 'd':
|
||||||
delim = EARGF(usage());
|
delim = EARGF(usage());
|
||||||
if (!*delim)
|
if (!*delim)
|
||||||
eprintf("cut: empty delimiter\n");
|
eprintf("empty delimiter\n");
|
||||||
delimlen = unescape(delim);
|
delimlen = unescape(delim);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
|
@ -176,19 +182,24 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (!mode)
|
if (!mode)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
if (!argc)
|
if (!argc)
|
||||||
cut(stdin);
|
cut(stdin, "<stdin>");
|
||||||
else for (; argc--; argv++) {
|
|
||||||
if (!strcmp(*argv, "-"))
|
|
||||||
cut(stdin);
|
|
||||||
else {
|
else {
|
||||||
|
for (; *argv; argc--, argv++) {
|
||||||
|
if (*argv[0] == '-' && !*argv[1]) {
|
||||||
|
cut(stdin, "<stdin>");
|
||||||
|
} else {
|
||||||
if (!(fp = fopen(*argv, "r"))) {
|
if (!(fp = fopen(*argv, "r"))) {
|
||||||
weprintf("fopen %s:", *argv);
|
weprintf("fopen %s:", *argv);
|
||||||
|
ret = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cut(fp);
|
cut(fp, *argv);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user