From 29d314255dd781669adbf0fd58cc40c43e690221 Mon Sep 17 00:00:00 2001 From: Enno Tensing Date: Tue, 21 Jan 2025 19:51:56 +0100 Subject: [PATCH] smu: Change file reading --- smu.c | 165 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 100 insertions(+), 65 deletions(-) diff --git a/smu.c b/smu.c index 95cca54..8164cff 100644 --- a/smu.c +++ b/smu.c @@ -1,60 +1,61 @@ /* smu - simple markup * Copyright (C) <2007, 2008> Enno Boland + * Copyright (C) 2025 Enno Tensing * * See LICENSE for further informations */ +#define _LARGEFILE64_SOURCE #include #include #include #include #include +#include +#include +#include +#include +#include #define LENGTH(x) sizeof(x) / sizeof(x[0]) -#define ADDC(b, i) \ - if (i % BUFSIZ == 0) { \ - b = realloc(b, (i + BUFSIZ) * sizeof(char)); \ - if (!b) \ - eprint("Malloc failed."); \ - } \ - b[i] +#define ADDC(b, i, a) \ + do { \ + if (i % BUFSIZ == 0) { \ + b = realloc(b, (i + BUFSIZ) * sizeof(char)); \ + if (!b) { \ + eprint("Malloc failed."); \ + return -1; \ + } \ + } \ + b[i] = a; \ + } while (0) typedef int (*Parser)(const char *, const char *, int); -typedef struct { +struct tag { char *search; int process; - char *before, *after; -} Tag; + char *before; + char *after; +}; -static int doamp(const char *begin, const char *end, - int newblock); /* Parser for & */ -static int docomment(const char *begin, const char *end, - int newblock); /* Parser for html-comments */ -static int dogtlt(const char *begin, const char *end, - int newblock); /* Parser for < and > */ -static int dohtml(const char *begin, const char *end, - int newblock); /* Parser for html */ -static int dolineprefix(const char *begin, const char *end, - int newblock); /* Parser for line prefix tags */ -static int dolink(const char *begin, const char *end, - int newblock); /* Parser for links and images */ -static int dolist(const char *begin, const char *end, - int newblock); /* Parser for lists */ -static int doparagraph(const char *begin, const char *end, - int newblock); /* Parser for paragraphs */ -static int doreplace(const char *begin, const char *end, - int newblock); /* Parser for simple replaces */ -static int doshortlink(const char *begin, const char *end, - int newblock); /* Parser for links and images */ -static int dosurround(const char *begin, const char *end, - int newblock); /* Parser for surrounding tags */ -static int dounderline(const char *begin, const char *end, - int newblock); /* Parser for underline tags */ +off64_t get_file_size(const char *); +char *read_file(const char *, off64_t); + +static int doamp(const char *begin, const char *end, int newblock); +static int docomment(const char *begin, const char *end, int newblock); +static int dogtlt(const char *begin, const char *end, int newblock); +static int dohtml(const char *begin, const char *end, int newblock); +static int dolineprefix(const char *begin, const char *end, int newblock); +static int dolink(const char *begin, const char *end, int newblock); +static int dolist(const char *begin, const char *end, int newblock); +static int doparagraph(const char *begin, const char *end, int newblock); +static int doreplace(const char *begin, const char *end, int newblock); +static int doshortlink(const char *begin, const char *end, int newblock); +static int dosurround(const char *begin, const char *end, int newblock); +static int dounderline(const char *begin, const char *end, int newblock); static void *ereallocz(void *p, size_t size); static void eprint(const char *format, ...); -static void hprint(const char *begin, - const char *end); /* escapes HTML and prints it to output */ -static void process(const char *begin, const char *end, - int isblock); /* Processes range between begin and end. */ +static void hprint(const char *begin, const char *end); +static void process(const char *begin, const char *end, int isblock); /* list of parsers */ static Parser parsers[] = { dounderline, docomment, dolineprefix, dolist, @@ -62,7 +63,7 @@ static Parser parsers[] = { dounderline, docomment, dolineprefix, dolist, doshortlink, dohtml, doamp, doreplace }; static int nohtml = 0; -static Tag lineprefix[] = { +static struct tag lineprefix[] = { { " ", 0, "
", "\n
" }, { "\t", 0, "
", "\n
" }, { ">", 2, "
", "
" }, @@ -75,12 +76,13 @@ static Tag lineprefix[] = { { "- - -\n", 1, "
", "" }, }; -static Tag underline[] = { +static struct tag underline[] = { { "=", 1, "

", "

\n" }, { "-", 1, "

", "

\n" }, }; -static Tag surround[] = { +static struct tag surround[] = { + { "```", 0, "", "" }, { "``", 0, "", "" }, { "`", 0, "", "" }, { "___", 1, "", "" }, @@ -102,6 +104,42 @@ static const char *insert[][2] = { { " \n", "
" }, }; +off64_t get_file_size(const char *path) +{ + struct stat st; + + if (stat(path, &st) == 0) + return st.st_size; + + return -1; +} + +char *read_file(const char *path, off64_t file_size) +{ + int fd = open(path, O_LARGEFILE | O_NONBLOCK); + + ssize_t bytes; + char *buf = calloc(file_size + 4, sizeof(char)); + + if (!buf) { + perror(""); + close(fd); + return NULL; + } + + bytes = read(fd, buf, file_size); + if (bytes != file_size) { + perror(""); + close(fd); + free(buf); + return NULL; + } + + close(fd); + + return buf; +} + void eprint(const char *format, ...) { va_list ap; @@ -109,7 +147,6 @@ void eprint(const char *format, ...) va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); - exit(EXIT_FAILURE); } int doamp(const char *begin, const char *end, int newblock) @@ -238,7 +275,7 @@ int dolineprefix(const char *begin, const char *end, int newblock) } while (p < end) { - ADDC(buffer, j) = *p; + ADDC(buffer, j, *p); j++; if (*(p++) == '\n') break; @@ -250,7 +287,7 @@ int dolineprefix(const char *begin, const char *end, int newblock) j--; } - ADDC(buffer, j) = '\0'; + ADDC(buffer, j, '\0'); if (lineprefix[i].process) process(buffer, buffer + strlen(buffer), lineprefix[i].process >= 2); @@ -399,7 +436,7 @@ int dolist(const char *begin, const char *end, int newblock) q++) ; if (*q == '\n') { - ADDC(buffer, i) = '\n'; + ADDC(buffer, i, '\0'); i++; run = 0; isblock++; @@ -428,7 +465,7 @@ int dolist(const char *begin, const char *end, int newblock) j++) ; if (j == indent) { - ADDC(buffer, i) = '\n'; + ADDC(buffer, i, '\n'); i++; p += indent; run = 1; @@ -439,9 +476,9 @@ int dolist(const char *begin, const char *end, int newblock) } else if (j < indent) run = 0; } - ADDC(buffer, i) = *p; + ADDC(buffer, i, *p); } - ADDC(buffer, i) = '\0'; + ADDC(buffer, i, '\0'); fputs("
  • ", stdout); process(buffer, buffer + i, isblock > 1 || (isblock == 1 && run)); @@ -640,7 +677,8 @@ void hprint(const char *begin, const char *end) void process(const char *begin, const char *end, int newblock) { - const char *p, *q; + const char *q; + const char *p; int affected; unsigned int i; @@ -674,9 +712,8 @@ void process(const char *begin, const char *end, int newblock) int main(int argc, char *argv[]) { char *buffer = NULL; - int s, i; - unsigned long len, bsize; - FILE *source = stdin; + const char *path = "STDIN"; + int i; for (i = 1; i < argc; i++) { if (!strcmp("-v", argv[i])) @@ -692,22 +729,20 @@ int main(int argc, char *argv[]) eprint("Usage %s [-n] [file]\n -n escape html strictly\n", argv[0]); } - if (i < argc && !(source = fopen(argv[i], "r"))) - eprint("Cannot open file `%s`\n", argv[i]); - bsize = 2 * BUFSIZ; - buffer = ereallocz(buffer, bsize); - len = 0; - while ((s = fread(buffer + len, 1, BUFSIZ, source))) { - len += s; - if (BUFSIZ + len + 1 > bsize) { - bsize += BUFSIZ; - if (!(buffer = realloc(buffer, bsize))) - eprint("realloc failed."); - } + + if (i < argc) + path = argv[i]; + + off64_t len = get_file_size(path); + if (len == -1) { + eprint("%s: %s: %s\n", argv[0], path, strerror(errno)); + return EXIT_FAILURE; } + buffer = read_file(path, len); + if (!buffer) + return EXIT_FAILURE; buffer[len] = '\0'; process(buffer, buffer + len, 1); - fclose(source); free(buffer); return EXIT_SUCCESS; }