Add optional processing stage

This commit is contained in:
Shav Kinderlehrer 2023-04-17 10:23:52 -04:00
parent 6eadc6dd06
commit a550c7f229
7 changed files with 148 additions and 21 deletions

View File

@ -5,6 +5,7 @@
#define LAT_VERSION "0.4.0" #define LAT_VERSION "0.4.0"
struct config { struct config {
bool process;
bool color; bool color;
bool lines; bool lines;
bool has_read_stdin; bool has_read_stdin;

View File

@ -2,13 +2,6 @@
#define FILE_H #define FILE_H
#include <stdio.h> #include <stdio.h>
struct filedata {
int lc;
size_t len;
int binary;
char *buf;
char *altbuf;
};
struct filedata readfile(FILE *fp); struct filedata readfile(FILE *fp);
#endif #endif

9
include/process.h Normal file
View File

@ -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

22
include/types.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef TYPES_H
#define TYPES_H
#include <stdbool.h>
#include <stddef.h>
struct line {
size_t len;
char *buf;
};
struct filedata {
int lc;
bool binary;
size_t buflen;
char *buf;
struct line *lines;
};
#endif

View File

@ -2,26 +2,29 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "file.h" #include "types.h"
#include "util.h" #include "util.h"
struct filedata readfile(FILE *fp) { struct filedata readfile(FILE *fp) {
struct filedata f; struct filedata f;
f.lc = 0; f.lc = 0;
f.len = 0; f.buflen = 0;
f.binary = 0; f.binary = 0;
f.buf = NULL;
f.lines = NULL;
// expects to be at beginning of file // expects to be at beginning of file
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
f.len = ftell(fp); f.buflen = ftell(fp);
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
f.buf = malloc(f.len); f.buf = malloc(f.buflen);
if (f.buf == NULL) if (f.buf == NULL)
die("malloc"); die("malloc");
if (fread(f.buf, f.len, 1, fp) < 0) { if (fread(f.buf, f.buflen, 1, fp) < 0) {
die("fread"); die("fread");
} }
@ -29,7 +32,7 @@ struct filedata readfile(FILE *fp) {
// guess if printable // guess if printable
// from https://github.com/sharkdp/content_inspector/blob/master/src/lib.rs // 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]; char *testbuf[testlen];
memcpy(testbuf, f.buf, testlen); memcpy(testbuf, f.buf, testlen);

74
src/lib/process.c Normal file
View File

@ -0,0 +1,74 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@ -6,6 +6,8 @@
#include "arg.h" #include "arg.h"
#include "file.h" #include "file.h"
#include "process.h"
#include "types.h"
#include "util.h" #include "util.h"
#define INVERT_T "\x1b[7m" #define INVERT_T "\x1b[7m"
@ -15,7 +17,6 @@
void run(FILE *fp, char *filename, bool tty) { void run(FILE *fp, char *filename, bool tty) {
const char *invert_t = conf.color ? INVERT_T : ""; const char *invert_t = conf.color ? INVERT_T : "";
const char *uinvert_t = conf.color ? UINVERT_T : "";
const char *grey = conf.color ? GREY : ""; const char *grey = conf.color ? GREY : "";
const char *reset = conf.color ? RESET : ""; const char *reset = conf.color ? RESET : "";
@ -25,10 +26,13 @@ void run(FILE *fp, char *filename, bool tty) {
if (tty) { if (tty) {
char *addon = f.binary ? "<binary>" : ""; char *addon = f.binary ? "<binary>" : "";
fprintf(stderr, "\r\x1b[2K%s%s%s%s\r\n", invert_t, basename(filename), 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; // f.lc = 0;
// char pc = '\0'; // char pc = '\0';
@ -53,24 +57,45 @@ void run(FILE *fp, char *filename, bool tty) {
// printf("%c", c); // printf("%c", c);
// } // }
// 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); printf("%s", f.buf);
}
free(f.buf);
fflush(stdout); // prevent timing inconsistencies between stdout and stderr fflush(stdout); // prevent timing inconsistencies between stdout and stderr
if (tty) { if (tty) {
float rounded; float rounded;
char *format = formatbytes(f.len, &rounded); char *format = formatbytes(f.buflen, &rounded);
// char *cnewline = c == '\n' ? "" : "\n"; // char *cnewline = c == '\n' ? "" : "\n";
char *cnewline = ""; char *cnewline = "";
fprintf(stderr, "\r%s%s%.2f %s%s\r\n", cnewline, invert_t, rounded, format, fprintf(stderr, "\r%s%s%.2f %s%s\r\n", cnewline, invert_t, rounded, format,
uinvert_t); reset);
} }
free(f.buf);
} }
void initconf(void) { void initconf(void) {
conf.process = true;
conf.color = true; conf.color = true;
conf.lines = true; conf.lines = true;
conf.has_read_stdin = false; conf.has_read_stdin = false;