cut: improvements

- use agetline().
- code style.
- free allocated list.
- don't close stdin if "-" is given.
This commit is contained in:
Hiltjo Posthuma 2014-06-01 14:39:34 +02:00 committed by sin
parent 97fb4a1f9c
commit 97ca7c8b6d

77
cut.c
View File

@ -31,19 +31,23 @@ insert(Range *r)
Range *l, *p, *t; Range *l, *p, *t;
for(p = NULL, l = list; l; p = l, l = l->next) { for(p = NULL, l = list; l; p = l, l = l->next) {
if(r->max && r->max+1 < l->min) { if(r->max && r->max + 1 < l->min) {
r->next = l; r->next = l;
break; break;
} else if(!l->max || r->min < l->max+2) { } else if(!l->max || r->min < l->max + 2) {
l->min = MIN(r->min, l->min); l->min = MIN(r->min, l->min);
for(p = l, t = l->next; t; p = t, t = t->next) for(p = l, t = l->next; t; p = t, t = t->next)
if(r->max && r->max+1 < t->min) break; if(r->max && r->max + 1 < t->min)
break;
l->max = (p->max && r->max) ? MAX(p->max, r->max) : 0; l->max = (p->max && r->max) ? MAX(p->max, r->max) : 0;
l->next = t; l->next = t;
return; return;
} }
} }
if(p) p->next = r; else list = r; if(p)
p->next = r;
else
list = r;
} }
static void static void
@ -54,8 +58,10 @@ parselist(char *str)
Range *r; Range *r;
for(s = str; *s; s++) { for(s = str; *s; s++) {
if(*s == ' ') *s = ','; if(*s == ' ')
if(*s == ',') n++; *s = ',';
if(*s == ',')
n++;
} }
if(!(r = malloc(n * sizeof(Range)))) if(!(r = malloc(n * sizeof(Range))))
eprintf("malloc:"); eprintf("malloc:");
@ -69,6 +75,18 @@ parselist(char *str)
} }
} }
static void
freelist(void) {
Range *l = list, *next;
while(l) {
next = l->next;
free(l);
l->next = NULL;
l = next;
}
}
static size_t static size_t
seek(const char *s, size_t pos, size_t *prev, size_t count) seek(const char *s, size_t pos, size_t *prev, size_t count)
{ {
@ -79,15 +97,18 @@ seek(const char *s, size_t pos, size_t *prev, size_t count)
if((t = memchr(s, 0, n))) if((t = memchr(s, 0, n)))
return t - s; return t - s;
if(nflag) if(nflag)
while(n && !UTF8_POINT(s[n])) n--; while(n && !UTF8_POINT(s[n]))
n--;
*prev += n; *prev += n;
return n; return n;
} else if(mode == 'c') { } else if(mode == 'c') {
for(n++, t = s; *t; t++) for(n++, t = s; *t; t++)
if(UTF8_POINT(*t) && !--n) break; if(UTF8_POINT(*t) && !--n)
break;
} else { } else {
for(t = (count < 2) ? s : s+1; n && *t; t++) for(t = (count < 2) ? s : s + 1; n && *t; t++)
if(*t == delim && !--n && count) break; if(*t == delim && !--n && count)
break;
} }
*prev = pos; *prev = pos;
return t - s; return t - s;
@ -96,15 +117,14 @@ seek(const char *s, size_t pos, size_t *prev, size_t count)
static void static void
cut(FILE *fp) cut(FILE *fp)
{ {
char *buf = NULL; char *buf = NULL, *s;
size_t size = 0; size_t size = 0, i, n, p;
char *s; ssize_t len;
size_t i, n, p;
Range *r; Range *r;
while(afgets(&buf, &size, fp)) { while((len = agetline(&buf, &size, fp)) != -1) {
if(buf[i = strlen(buf)-1] == '\n') if(len && buf[len - 1] == '\n')
buf[i] = 0; buf[len - 1] = '\0';
if(mode == 'f' && !strchr(buf, delim)) { if(mode == 'f' && !strchr(buf, delim)) {
if(!sflag) if(!sflag)
puts(buf); puts(buf);
@ -112,7 +132,8 @@ cut(FILE *fp)
} }
for(i = 0, p = 1, s = buf, r = list; r; r = r->next, s += n) { for(i = 0, p = 1, s = buf, r = list; r; r = r->next, s += n) {
s += seek(s, r->min, &p, i++); s += seek(s, r->min, &p, i++);
if(!*s) break; if(!*s)
break;
if(!r->max) { if(!r->max) {
fputs(s, stdout); fputs(s, stdout);
break; break;
@ -155,13 +176,21 @@ main(int argc, char *argv[])
usage(); usage();
if(!argc) if(!argc)
cut(stdin); cut(stdin);
else for(; argc--; argv++) { else {
if(!(fp = strcmp(*argv, "-") ? fopen(*argv, "r") : stdin)) { for(; argc--; argv++) {
weprintf("fopen %s:", *argv); if(strcmp(*argv, "-"))
continue; fp = fopen(*argv, "r");
else
fp = stdin;
if(!fp) {
weprintf("fopen %s:", *argv);
continue;
}
cut(fp);
if(fp != stdin)
fclose(fp);
} }
cut(fp);
fclose(fp);
} }
freelist();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }