Add head util

This commit is contained in:
g1n 2022-06-30 17:36:01 +03:00
parent 67a02be008
commit 44cbb98694
Signed by: g1n
GPG Key ID: 8D352193D65D4E2C
1 changed files with 81 additions and 0 deletions

81
src/head.c Normal file
View File

@ -0,0 +1,81 @@
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int usage(char *argv0) {
printf("Usage: %s [-n number] [file ...]\n", argv0);
return 2;
}
int main(int argc, char *argv[]) {
char ch;
int opt;
FILE *file = stdin;
int number = 10;
int line = 0;
bool multiple_files = false;
while ((opt = getopt(argc, argv, "n:")) != -1) {
switch (opt) {
case 'n':
if (optarg[0] == '-') {
optarg++;
}
for (size_t i = 0; i < strlen(optarg); i++) {
if (!isdigit(optarg[i])) {
fprintf(stderr, "%s: invalid number of lines: '%s'\n", argv[0], optarg);
return 1;
}
}
number = atoi(optarg);
break;
case '?':
fprintf(stderr, "%s: invalid option -- '%c'\n", argv[0], optopt);
return usage(argv[0]);
}
}
if (optind == argc) { // FIXME: this code is not clean
goto READ_STDIN;
}
if (argc - optind > 1) {
multiple_files = true;
}
for (; optind < argc; optind++) {
if (strcmp(argv[optind], "-")) {
file = fopen(argv[optind], "r");
if (file == NULL) {
fprintf(stderr, "%s: ", argv[0]);
perror(argv[optind]);
return -1;
}
if (multiple_files) {
printf("%s==> %s <==\n", (optind - 1 > argc - optind ? "\n" : ""), argv[optind]);
}
} else {
file = stdin;
if (multiple_files) {
printf("%s==> %s <==\n", (optind - 1 > argc - optind ? "\n" : ""), "standard input");
}
}
READ_STDIN:
line = 0;
while ((ch = fgetc(file)) != EOF && line < number) {
putchar(ch);
if (ch == '\n') {
line++;
}
}
if (file != NULL && file != stdin) {
fclose(file);
}
}
return 0;
}