smu: Change file reading
This commit is contained in:
parent
c702617acd
commit
29d314255d
1 changed files with 100 additions and 65 deletions
157
smu.c
157
smu.c
|
@ -1,60 +1,61 @@
|
|||
/* smu - simple markup
|
||||
* Copyright (C) <2007, 2008> Enno Boland <g s01 de>
|
||||
* Copyright (C) 2025 Enno Tensing <tenno+smu@suij.in>
|
||||
*
|
||||
* See LICENSE for further informations
|
||||
*/
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define LENGTH(x) sizeof(x) / sizeof(x[0])
|
||||
#define ADDC(b, i) \
|
||||
#define ADDC(b, i, a) \
|
||||
do { \
|
||||
if (i % BUFSIZ == 0) { \
|
||||
b = realloc(b, (i + BUFSIZ) * sizeof(char)); \
|
||||
if (!b) \
|
||||
if (!b) { \
|
||||
eprint("Malloc failed."); \
|
||||
return -1; \
|
||||
} \
|
||||
b[i]
|
||||
} \
|
||||
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, "<pre><code>", "\n</code></pre>" },
|
||||
{ "\t", 0, "<pre><code>", "\n</code></pre>" },
|
||||
{ ">", 2, "<blockquote>", "</blockquote>" },
|
||||
|
@ -75,12 +76,13 @@ static Tag lineprefix[] = {
|
|||
{ "- - -\n", 1, "<hr />", "" },
|
||||
};
|
||||
|
||||
static Tag underline[] = {
|
||||
static struct tag underline[] = {
|
||||
{ "=", 1, "<h1>", "</h1>\n" },
|
||||
{ "-", 1, "<h2>", "</h2>\n" },
|
||||
};
|
||||
|
||||
static Tag surround[] = {
|
||||
static struct tag surround[] = {
|
||||
{ "```", 0, "<code>", "</code>" },
|
||||
{ "``", 0, "<code>", "</code>" },
|
||||
{ "`", 0, "<code>", "</code>" },
|
||||
{ "___", 1, "<strong><em>", "</em></strong>" },
|
||||
|
@ -102,6 +104,42 @@ static const char *insert[][2] = {
|
|||
{ " \n", "<br />" },
|
||||
};
|
||||
|
||||
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("<li>", 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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue