cut: improvements
- use agetline(). - code style. - free allocated list. - don't close stdin if "-" is given.
This commit is contained in:
parent
97fb4a1f9c
commit
97ca7c8b6d
63
cut.c
63
cut.c
|
@ -37,13 +37,17 @@ insert(Range *r)
|
||||||
} 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++) {
|
||||||
|
if(strcmp(*argv, "-"))
|
||||||
|
fp = fopen(*argv, "r");
|
||||||
|
else
|
||||||
|
fp = stdin;
|
||||||
|
if(!fp) {
|
||||||
weprintf("fopen %s:", *argv);
|
weprintf("fopen %s:", *argv);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cut(fp);
|
cut(fp);
|
||||||
|
if(fp != stdin)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
freelist();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user