summaryrefslogtreecommitdiff
path: root/command/head.c
diff options
context:
space:
mode:
authorTyler Murphy <tylerm@tylerm.dev>2023-05-06 00:39:44 -0400
committerTyler Murphy <tylerm@tylerm.dev>2023-05-06 00:39:44 -0400
commitd8f2c10b7108fff6b7e437291093a1cadc15ab9f (patch)
tree3fc50a19d6fbb9c94a8fe147cd2a6c4ba7f59b8d /command/head.c
parentansii c (diff)
downloadlazysphere-d8f2c10b7108fff6b7e437291093a1cadc15ab9f.tar.gz
lazysphere-d8f2c10b7108fff6b7e437291093a1cadc15ab9f.tar.bz2
lazysphere-d8f2c10b7108fff6b7e437291093a1cadc15ab9f.zip
refactor
Diffstat (limited to 'command/head.c')
-rw-r--r--command/head.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/command/head.c b/command/head.c
new file mode 100644
index 0000000..c28a82c
--- /dev/null
+++ b/command/head.c
@@ -0,0 +1,141 @@
+#include "command.h"
+#include "lslib.h"
+
+#include <stdlib.h>
+
+static struct {
+ int count;
+ bool lines;
+ bool print_headers;
+ bool dont_print_headers;
+} flags;
+
+static void head_file_lines(FILE* file) {
+ size_t len = 0;
+ char* line = NULL;
+
+ int count = flags.count;
+ while(count > 0 && getline(&line, &len, file) != -1) {
+ printf("%s", line);
+ count--;
+ }
+
+ free(line);
+ fclose(file);
+}
+
+static void head_file_chars(FILE* file) {
+ char c;
+ int count = flags.count;
+ while(count > 0 && (c = getc(file)) != EOF) {
+ putchar(c);
+ count--;
+ }
+
+ fclose(file);
+}
+
+static void help(void) {
+ printf("Usage: head [OPTIONS] [FILE]...\n\n");
+ printf("Print first 10 lines of FILEs (or stdin)\n");
+ printf("With more than one FILE, precede each with a filename header.\n\n");
+ printf("\t-c [+]N[bkm]\tPrint first N bytes\n");
+ printf("\t-n N[bkm]\tPrint first N lines\n");
+ printf("\t\t\t(b:*512 k:*1024 m:*1024^2)\n");
+ printf("\t-q\t\tNever print headers\n");
+ printf("\t-v\t\tAlways print headers\n");
+}
+
+static void print_header(char* path, bool many) {
+ if (flags.dont_print_headers) return;
+ if (!many && !flags.print_headers) return;
+ if (streql("-", path)) {
+ printf("\n==> standard input <==\n");
+ } else {
+ printf("\n=>> %s <==\n", path);
+ }
+}
+
+static void head_file(char* path, bool many) {
+ FILE* file = get_file(path, "r");
+ print_header(path, many);
+ if (flags.lines) {
+ head_file_lines(file);
+ } else {
+ head_file_chars(file);
+ }
+}
+
+static int short_arg(char c, char* next) {
+ switch(c) {
+ case 'c': {
+ long int bkm;
+
+ flags.lines = false;
+
+ check_arg(next);
+ bkm = get_blkm(next);
+
+ if (bkm < 1) {
+ error("bkm cannot be less than 1");
+ }
+
+ flags.count = bkm;
+ return ARG_USED;
+ }
+ case 'n': {
+ long int bkm;
+
+ flags.lines = true;
+
+ check_arg(next);
+ bkm = get_blkm(next);
+
+ if (bkm < 1) {
+ error("bkm cannot be less than 1");
+ }
+
+ flags.count = bkm;
+ return ARG_USED;
+ }
+ case 'q':
+ flags.dont_print_headers = true;
+ break;
+ case 'v':
+ flags.print_headers = true;
+ break;
+ default:
+ return ARG_INVALID;
+ }
+ return ARG_UNUSED;
+}
+
+COMMAND(head) {
+
+ int start, count, i;
+
+ flags.count = 10;
+ flags.lines = true;
+ flags.print_headers = false;
+ flags.dont_print_headers = false;
+
+ start = parse_args(argc, argv, help, short_arg, NULL);
+
+ count = argc - start;
+
+ if (count < 1) {
+ head_file_lines(stdin);
+ return EXIT_SUCCESS;
+ }
+
+ if (count == 1) {
+ head_file(argv[start], false);
+ return EXIT_SUCCESS;
+ }
+
+ for (i = 0; i < count; i++) {
+ head_file(argv[start + i], true);
+ }
+
+ return EXIT_SUCCESS;
+}