fixed head
This commit is contained in:
parent
87abbeffa3
commit
a3270dd18a
@ -10,46 +10,102 @@
|
||||
|
||||
char v_flag;
|
||||
char c_flag;
|
||||
char n_flag;
|
||||
|
||||
long parse_long(const char *str) {
|
||||
char *ptr;
|
||||
long ret = strtol(str, &ptr, 0);
|
||||
if (*ptr) {
|
||||
fprintf(stderr, "head: %s invalid number\n", ptr);
|
||||
fprintf(stderr, "head: invalid number %s\n", ptr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void print(const char *file, FILE *fp, long lines, long bytes) {
|
||||
int print(const char *file, FILE *fp, long lines, long bytes) {
|
||||
if (v_flag)
|
||||
printf(HEAD_FMT, file);
|
||||
|
||||
long lcount = 0;
|
||||
long bcount = 0;
|
||||
|
||||
while (1) {
|
||||
int c = getc(fp);
|
||||
bcount++;
|
||||
if (c == '\n')
|
||||
lcount++;
|
||||
/* If lines or bytes < 0 */
|
||||
if (lines < 0 || bytes < 0) {
|
||||
long lmax = 0;
|
||||
long bmax = 0;
|
||||
|
||||
if (c == EOF || lcount == lines || (c_flag && bcount == bytes))
|
||||
break;
|
||||
size_t buf_size = 0;
|
||||
char *buf = malloc(1);
|
||||
if (buf == NULL) {
|
||||
fprintf(stderr, "head: malloc: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
putchar(c);
|
||||
while (1) {
|
||||
int c = getc(fp);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
char *tmp = realloc(buf, buf_size + 2);
|
||||
if (tmp == NULL) {
|
||||
fprintf(stderr, "head: realloc: %s\n", strerror(errno));
|
||||
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
buf = tmp;
|
||||
buf[buf_size] = c;
|
||||
if (c == '\n')
|
||||
lmax++;
|
||||
bmax++;
|
||||
buf_size++;
|
||||
}
|
||||
|
||||
buf[buf_size] = '\0';
|
||||
|
||||
for (size_t i = 0; i < buf_size; i++) {
|
||||
if (buf[i] == '\n')
|
||||
lcount++;
|
||||
|
||||
bcount++;
|
||||
putchar(buf[i]);
|
||||
if ((n_flag && lcount == lmax + lines) || (c_flag && bcount == bmax + bytes))
|
||||
break;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
else {
|
||||
while (1) {
|
||||
int c = getc(fp);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
if (c == '\n')
|
||||
lcount++;
|
||||
bcount++;
|
||||
putchar(c);
|
||||
|
||||
if ((n_flag && lcount == lines) || (c_flag && bcount == bytes))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
long lines = 10;
|
||||
long lines = 0;
|
||||
long bytes = 0;
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "n:c:v")) != -1) {
|
||||
switch (opt) {
|
||||
case 'n':
|
||||
n_flag = 1;
|
||||
lines = parse_long(optarg);
|
||||
break;
|
||||
|
||||
@ -63,7 +119,7 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("head [ncv] [file1 file2...]\n\t-n Print N lines\n\t-c Print N bytes\n\t-v Print headers\n");
|
||||
printf("head [ncv] [file1 file2...]\n\t-n Print [-]N lines\n\t-c Print [-]N bytes\n\t-v Print headers\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -74,6 +130,7 @@ int main(int argc, char **argv) {
|
||||
if (argc == 0)
|
||||
print("-", stdin, lines, bytes);
|
||||
|
||||
int ret = 0;
|
||||
for (int i = 0; i < argc; i++) {
|
||||
FILE *fp = NULL;
|
||||
if (argv[i][0] == '-')
|
||||
@ -84,10 +141,14 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "head: %s: %s\n", argv[i], strerror(errno));
|
||||
return 1;
|
||||
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
print(argv[i], fp, lines, bytes);
|
||||
if (print(argv[i], fp, lines, bytes))
|
||||
ret = 1;
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user