Periodic commit

This commit is contained in:
Nathan Fisher 2023-10-07 13:24:32 -04:00
parent 72679eff07
commit 5d3e09a6ae
3 changed files with 151 additions and 14 deletions

View file

@ -33,7 +33,8 @@
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .o .c .SUFFIXES: .o .c
CFLAGS += -Wall -Werror CFLAGS += -Wall
CFLAGS += -Werror
CFLAGS += -Iinclude CFLAGS += -Iinclude
hdrs += include/gemtext-parser.h hdrs += include/gemtext-parser.h

View file

@ -1,3 +1,4 @@
#include <errno.h> // errno
#include <stddef.h> // NULL, size_t #include <stddef.h> // NULL, size_t
#include <stdio.h> // fclose #include <stdio.h> // fclose
#include <stdlib.h> // calloc, free #include <stdlib.h> // calloc, free
@ -64,7 +65,7 @@ gemtextLine* gemtextLineQueuePop(gemtextLineQueue *lq) {
return line; return line;
} }
lineBuffer* lineBufferInit() { lineBuffer* lineBufferNew() {
char *buf; char *buf;
lineBuffer *lb = calloc(1, sizeof(lineBuffer)); lineBuffer *lb = calloc(1, sizeof(lineBuffer));
@ -81,6 +82,16 @@ lineBuffer* lineBufferInit() {
return lb; return lb;
} }
int lineBufferInit(lineBuffer *lb) {
char *buf = calloc(1, LBUF_SIZE);
if (buf == NULL) return 2;
lb->len = 0;
lb->capacity = LBUF_SIZE;
lb->buf = buf;
lb->cursor = buf;
return 0;
}
void lineBufferDeinit(lineBuffer *lb) { void lineBufferDeinit(lineBuffer *lb) {
free(lb->buf); free(lb->buf);
free(lb); free(lb);
@ -143,6 +154,7 @@ void lineBufferReset(lineBuffer *lb) {
gemtextLink* readLink(FILE *stream, lineBuffer *lb) { gemtextLink* readLink(FILE *stream, lineBuffer *lb) {
char c; char c;
char *buf;
int ret = 0; int ret = 0;
gemtextLink *link = calloc(1, sizeof(gemtextLink)); gemtextLink *link = calloc(1, sizeof(gemtextLink));
@ -154,14 +166,16 @@ gemtextLink* readLink(FILE *stream, lineBuffer *lb) {
case '\t': case '\t':
if (lb->len == 0) if (lb->len == 0)
continue; continue;
link->url = strndup(lb->buf, lb->len); buf = strndup(lb->buf, lb->len);
link->url = buf;
break; break;
case '\n': case '\n':
if (lb->len == 0) { if (lb->len == 0) {
free(link); free(link);
return NULL; return NULL;
} }
link->url = strndup(lb->buf, lb->len); buf = strndup(lb->buf, lb->len);
link->url = buf;
return link; return link;
default: default:
ret = lineBufferAppendChar(lb, c); ret = lineBufferAppendChar(lb, c);
@ -190,11 +204,6 @@ gemtextLink* readLink(FILE *stream, lineBuffer *lb) {
return link; return link;
} }
int parseNormal(gemtextParser *parser, gemtextLineQueue *lq) {
// todo
return 0;
}
int parsePreformatted(gemtextParser *parser, gemtextLineQueue *lq) { int parsePreformatted(gemtextParser *parser, gemtextLineQueue *lq) {
// todo // todo
return 0; return 0;
@ -205,6 +214,130 @@ int parseQuote(gemtextParser *parser, gemtextLineQueue *lq) {
return 0; return 0;
} }
int parseNormal(gemtextParser *parser, gemtextLineQueue *lq) {
char c;
int ret;
gemtextLine *line;
gemtextLink *link;
lineBuffer lb;
char *buf;
ret = lineBufferInit(&lb);
if (ret != 0) return ret;
while (1) {
ret = fread(&c, 1, 1, parser->stream);
if (c != 1) {
line = calloc(1, sizeof(gemtextLine));
if (line == NULL) return errno;
line->lineType = endOfStream;
line->prev = line->next = NULL;
line->str = NULL;
gemtextLineQueuePush(lq, line);
}
switch (parser->state) {
case lineStart:
switch (c) {
case '=':
ret = lineBufferAppendChar(&lb, c);
if (ret != 0) {
free(lb.buf);
return ret;
}
parser->state = firstLinkChar;
break;
case '>':
parser->mode = quoteMode;
ret = parseQuote(parser, lq);
if (ret != 0) {
free(lb.buf);
return ret;
}
break;
case '#':
ret = lineBufferAppendChar(&lb, c);
if (ret != 0) {
free(lb.buf);
return ret;
}
parser->state = firstHashChar;
break;
case '`':
ret = lineBufferAppendChar(&lb, c);
if (ret != 0) {
free(lb.buf);
return ret;
}
parser->state = firstBacktickChar;
break;
case '\n':
line = calloc(1, sizeof(gemtextLine));
if (line == NULL) return errno;
line->lineType = normalLine;
buf = strndup("\n", 1);
if (buf == NULL) {
free(lb.buf);
return errno;
}
line->str = buf;
gemtextLineQueuePush(lq, line);
break;
default:
ret = lineBufferAppendChar(&lb, c);
if (ret != 0) {
free(lb.buf);
return ret;
}
parser->state = normalState;
break;
}
break;
case firstLinkChar:
ret = lineBufferAppendChar(&lb, c);
if (ret != 0) {
free(lb.buf);
return ret;
}
if (c == '>') {
parser->state = secondLinkChar;
} else if (c == '\n') {
// todo - send a 'normal' line to the lineQueue and reset the
// lineBuffer
} else {
parser->state = normalState;
}
case secondLinkChar:
line = calloc(1, sizeof(gemtextLine));
if (line == NULL) return errno;
link = readLink(parser->stream, &lb);
if (link == NULL) {
line->lineType = normalLine;
buf = strndup(lb.buf, lb.len);
if (buf == NULL) {
free(lb.buf);
free(line);
return errno;
}
line->str = buf;
gemtextLineQueuePush(lq, line);
} else {
line->lineType = linkLine;
line->link = link;
gemtextLineQueuePush(lq, line);
}
lineBufferReset(&lb);
break;
case firstHashChar:
case secondHashChar:
case thirdHashChar:
case firstBacktickChar:
case secondBacktickChar:
case thirdBacktickChar:
case normalState:
}
}
return 0;
}
int parseGemtext(gemtextParser *parser, gemtextLineQueue *lq) { int parseGemtext(gemtextParser *parser, gemtextLineQueue *lq) {
// todo // todo
return 0; return 0;

View file

@ -1,9 +1,9 @@
#ifndef GEMTEXT_PARSER_H #ifndef GEMTEXT_PARSER_H
#define GEMTEXT_PARSER_H 1 #define GEMTEXT_PARSER_H 1
#include <pthread.h> #include <pthread.h> // pthread_mutex_t, pthread_cond_t
#include <stddef.h> #include <stddef.h> // size_t
#include <stdio.h> #include <stdio.h> // FILE
#define LBUF_SIZE 512 #define LBUF_SIZE 512
@ -16,7 +16,7 @@ typedef enum {
typedef enum { typedef enum {
lineStart, lineStart,
firstLinkChar, firstLinkChar,
firstLinkWord, secondLinkChar,
firstHashChar, firstHashChar,
secondHashChar, secondHashChar,
thirdHashChar, thirdHashChar,
@ -60,7 +60,10 @@ struct _gemtextLine {
struct _gemtextLine *next; struct _gemtextLine *next;
struct _gemtextLine *prev; struct _gemtextLine *prev;
gemtextLineType lineType; gemtextLineType lineType;
char *line; union {
char *str;
gemtextLink *link;
};
}; };
typedef struct _gemtextLine gemtextLine; typedef struct _gemtextLine gemtextLine;