diff --git a/include/arg.h b/include/arg.h index 985daa4..1bf23f4 100644 --- a/include/arg.h +++ b/include/arg.h @@ -5,6 +5,7 @@ #define LAT_VERSION "0.4.0" struct config { + bool process; bool color; bool lines; bool has_read_stdin; diff --git a/include/file.h b/include/file.h index d440c87..5518d17 100644 --- a/include/file.h +++ b/include/file.h @@ -2,13 +2,6 @@ #define FILE_H #include -struct filedata { - int lc; - size_t len; - int binary; - char *buf; - char *altbuf; -}; struct filedata readfile(FILE *fp); #endif diff --git a/include/process.h b/include/process.h new file mode 100644 index 0000000..29e066f --- /dev/null +++ b/include/process.h @@ -0,0 +1,9 @@ +#ifndef PROCESS_H +#define PROCESS_H +#include "types.h" + +void loadlines(struct filedata *f); + +char *linepad(int lc, int total); + +#endif diff --git a/include/types.h b/include/types.h new file mode 100644 index 0000000..9fb7809 --- /dev/null +++ b/include/types.h @@ -0,0 +1,22 @@ +#ifndef TYPES_H +#define TYPES_H + +#include +#include + +struct line { + size_t len; + char *buf; +}; + +struct filedata { + int lc; + bool binary; + + size_t buflen; + + char *buf; + struct line *lines; +}; + +#endif diff --git a/src/lib/file.c b/src/lib/file.c index f1efa04..f8453d2 100644 --- a/src/lib/file.c +++ b/src/lib/file.c @@ -2,26 +2,29 @@ #include #include -#include "file.h" +#include "types.h" #include "util.h" struct filedata readfile(FILE *fp) { struct filedata f; f.lc = 0; - f.len = 0; + f.buflen = 0; f.binary = 0; + f.buf = NULL; + f.lines = NULL; + // expects to be at beginning of file fseek(fp, 0, SEEK_END); - f.len = ftell(fp); + f.buflen = ftell(fp); fseek(fp, 0, SEEK_SET); - f.buf = malloc(f.len); + f.buf = malloc(f.buflen); if (f.buf == NULL) die("malloc"); - if (fread(f.buf, f.len, 1, fp) < 0) { + if (fread(f.buf, f.buflen, 1, fp) < 0) { die("fread"); } @@ -29,7 +32,7 @@ struct filedata readfile(FILE *fp) { // guess if printable // from https://github.com/sharkdp/content_inspector/blob/master/src/lib.rs - int testlen = f.len >= 64 ? 64 : f.len; + int testlen = f.buflen >= 64 ? 64 : f.buflen; char *testbuf[testlen]; memcpy(testbuf, f.buf, testlen); diff --git a/src/lib/process.c b/src/lib/process.c new file mode 100644 index 0000000..61261d9 --- /dev/null +++ b/src/lib/process.c @@ -0,0 +1,74 @@ +#include +#include +#include + +#include "types.h" +#include "util.h" + +void appendline(struct filedata *f, char *data, size_t len) { + f->lines = realloc(f->lines, sizeof(struct line) * (f->lc + 1)); + + size_t loc = f->lc; + + f->lines[loc].len = len; + f->lines[loc].buf = malloc(len + 1); + memcpy(f->lines[loc].buf, data, len); + f->lines[loc].buf[len] = '\0'; +} + +void loadlines(struct filedata *f) { + f->lc = 0; + + size_t offset = 0; + size_t linelen = 4096; + char *line = malloc(linelen); + if (line == NULL) + die("malloc"); + + for (size_t i = 0; i < f->buflen; i++) { + char c = f->buf[i]; + if (c == '\n') { + if (offset < linelen) { + char *new_line = realloc(line, offset); + if (new_line == NULL) + die("realloc"); + line = new_line; + } + + appendline(f, line, offset); + f->lc++; + + free(line); + offset = 0; + line = malloc(linelen); + if (line == NULL) + die("malloc"); + + } else { + if (offset == linelen) { + linelen *= 2; + + char *new_line = realloc(line, linelen); + if (new_line == NULL) + die("realloc"); + + line = new_line; + } + + line[offset++] = c; + } + } +} + +char *linepad(int lc, int total) { + int padlen = intlen(total) - intlen(lc); + char *padding = malloc(padlen + 1); + if (padding == NULL) + die("malloc"); + + if (padlen) + memset(padding, ' ', padlen); + padding[padlen] = '\0'; + + return padding; +} diff --git a/src/main.c b/src/main.c index e07a22a..1d4a036 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,8 @@ #include "arg.h" #include "file.h" +#include "process.h" +#include "types.h" #include "util.h" #define INVERT_T "\x1b[7m" @@ -15,7 +17,6 @@ void run(FILE *fp, char *filename, bool tty) { const char *invert_t = conf.color ? INVERT_T : ""; - const char *uinvert_t = conf.color ? UINVERT_T : ""; const char *grey = conf.color ? GREY : ""; const char *reset = conf.color ? RESET : ""; @@ -25,10 +26,13 @@ void run(FILE *fp, char *filename, bool tty) { if (tty) { char *addon = f.binary ? "" : ""; fprintf(stderr, "\r\x1b[2K%s%s%s%s\r\n", invert_t, basename(filename), - addon, uinvert_t); + addon, reset); } - int lcpad = intlen(f.lc); + conf.process = (tty && !f.binary); + if (conf.process) { // file display processing + loadlines(&f); + } // f.lc = 0; // char pc = '\0'; @@ -53,24 +57,45 @@ void run(FILE *fp, char *filename, bool tty) { // printf("%c", c); // } - printf("%s", f.buf); + // printf("%s", f.buf); + + printf("%d - %d\n", conf.process, conf.lines); + + if (conf.process) { + int linecount = 0; + + for (int i = 0; i < f.lc; i++) { + if (conf.lines) { + char *padding = linepad(linecount, f.lc); + printf("%s%s%d:%s %s\n", grey, padding, i, reset, f.lines[i].buf); + free(padding); + linecount++; + } else { + printf("%s\n", f.lines[i].buf); + } + + free(f.lines[i].buf); + } + } else { + printf("%s", f.buf); + } + free(f.buf); fflush(stdout); // prevent timing inconsistencies between stdout and stderr if (tty) { float rounded; - char *format = formatbytes(f.len, &rounded); + char *format = formatbytes(f.buflen, &rounded); // char *cnewline = c == '\n' ? "" : "\n"; char *cnewline = ""; fprintf(stderr, "\r%s%s%.2f %s%s\r\n", cnewline, invert_t, rounded, format, - uinvert_t); + reset); } - - free(f.buf); } void initconf(void) { + conf.process = true; conf.color = true; conf.lines = true; conf.has_read_stdin = false;