Refactor, getting rid of parsing modes (just use node types instead)
This commit is contained in:
parent
e69a1ceaa1
commit
ae253cec83
2 changed files with 129 additions and 154 deletions
225
gemtext-parser.c
225
gemtext-parser.c
|
@ -21,7 +21,7 @@ int gemtextParserInit(gemtextParser *parser, FILE *stream) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
parser->stream = stream;
|
parser->stream = stream;
|
||||||
parser->mode = normalMode;
|
parser->nodeType = unset;
|
||||||
parser->state = lineStart;
|
parser->state = lineStart;
|
||||||
parser->linkUrl = NULL;
|
parser->linkUrl = NULL;
|
||||||
ret = lineBufferInit(&parser->buffer);
|
ret = lineBufferInit(&parser->buffer);
|
||||||
|
@ -42,9 +42,9 @@ gemtextParser* gemtextParserNew(FILE *stream) {
|
||||||
void gemtextParserDeinit(gemtextParser *parser) {
|
void gemtextParserDeinit(gemtextParser *parser) {
|
||||||
fclose(parser->stream);
|
fclose(parser->stream);
|
||||||
free(parser->buffer.buf);
|
free(parser->buffer.buf);
|
||||||
if (parser->mode == linkMode && parser->linkUrl != NULL) {
|
if (parser->nodeType == linkNode && parser->linkUrl != NULL) {
|
||||||
free(parser->linkUrl);
|
free(parser->linkUrl);
|
||||||
} else if (parser->mode == preformattedMode && parser->altText != NULL) {
|
} else if (parser->nodeType == preformattedNode && parser->altText != NULL) {
|
||||||
free(parser->altText);
|
free(parser->altText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,66 +54,66 @@ void gemtextParserDestroy(gemtextParser *parser) {
|
||||||
free(parser);
|
free(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gemtextNodeQueueInit(gemtextNodeQueue *queue) {
|
int gemtextNodeQueueInit(gemtextNodeQueue *nq) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
queue->head = NULL;
|
nq->head = NULL;
|
||||||
queue->tail = NULL;
|
nq->tail = NULL;
|
||||||
ret = pthread_mutex_init(&queue->mutex, NULL);
|
ret = pthread_mutex_init(&nq->mutex, NULL);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
return pthread_cond_init(&queue->cond, NULL);
|
return pthread_cond_init(&nq->cond, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gemtextNodeQueuePush(gemtextNodeQueue *queue, gemtextNode *node) {
|
void gemtextNodeQueuePush(gemtextNodeQueue *nq, gemtextNode *node) {
|
||||||
pthread_mutex_lock(&queue->mutex);
|
pthread_mutex_lock(&nq->mutex);
|
||||||
if (queue->tail == NULL) {
|
if (nq->tail == NULL) {
|
||||||
queue->tail = queue->head = node;
|
nq->tail = nq->head = node;
|
||||||
} else {
|
} else {
|
||||||
node->next = queue->tail;
|
node->next = nq->tail;
|
||||||
queue->tail->prev = node;
|
nq->tail->prev = node;
|
||||||
queue->tail = node;
|
nq->tail = node;
|
||||||
}
|
}
|
||||||
queue->count++;
|
nq->count++;
|
||||||
pthread_mutex_unlock(&queue->mutex);
|
pthread_mutex_unlock(&nq->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
gemtextNode* gemtextNodeQueuePop(gemtextNodeQueue *lq) {
|
gemtextNode* gemtextNodeQueuePop(gemtextNodeQueue *nq) {
|
||||||
gemtextNode *node;
|
gemtextNode *node;
|
||||||
|
|
||||||
while (lq->count == 0)
|
while (nq->count == 0)
|
||||||
pthread_cond_wait(&lq->cond, &lq->mutex);
|
pthread_cond_wait(&nq->cond, &nq->mutex);
|
||||||
pthread_mutex_lock(&lq->mutex);
|
pthread_mutex_lock(&nq->mutex);
|
||||||
lq->count++;
|
nq->count++;
|
||||||
node = lq->head;
|
node = nq->head;
|
||||||
if (node->nodeType == endOfStream)
|
if (node->nodeType == endOfStream)
|
||||||
return node;
|
return node;
|
||||||
if (lq->tail == lq->head) {
|
if (nq->tail == nq->head) {
|
||||||
lq->tail = lq->head = NULL;
|
nq->tail = nq->head = NULL;
|
||||||
} else {
|
} else {
|
||||||
lq->head = lq->head->prev;
|
nq->head = nq->head->prev;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&lq->mutex);
|
pthread_mutex_unlock(&nq->mutex);
|
||||||
node->prev = node->next = NULL;
|
node->prev = node->next = NULL;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
gemtextNode* gemtextNodeQueueTryPop(gemtextNodeQueue *lq) {
|
gemtextNode* gemtextNodeQueueTryPop(gemtextNodeQueue *nq) {
|
||||||
gemtextNode *node;
|
gemtextNode *node;
|
||||||
|
|
||||||
if (lq->count == 0)
|
if (nq->count == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
pthread_mutex_lock(&lq->mutex);
|
pthread_mutex_lock(&nq->mutex);
|
||||||
lq->count++;
|
nq->count++;
|
||||||
node = lq->head;
|
node = nq->head;
|
||||||
if (node->nodeType == endOfStream)
|
if (node->nodeType == endOfStream)
|
||||||
return node;
|
return node;
|
||||||
if (lq->tail == lq->head) {
|
if (nq->tail == nq->head) {
|
||||||
lq->tail = lq->head = NULL;
|
nq->tail = nq->head = NULL;
|
||||||
} else {
|
} else {
|
||||||
lq->head = lq->head->prev;
|
nq->head = nq->head->prev;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&lq->mutex);
|
pthread_mutex_unlock(&nq->mutex);
|
||||||
node->prev = node->next = NULL;
|
node->prev = node->next = NULL;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +203,7 @@ void lineBufferReset(lineBuffer *lb) {
|
||||||
lb->cursor = lb->buf;
|
lb->cursor = lb->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gemtextParserSendPreformatted(gemtextParser *parser, gemtextNodeQueue *lq) {
|
int gemtextParserSendPreformatted(gemtextParser *parser, gemtextNodeQueue *nq) {
|
||||||
preformattedBlock *block;
|
preformattedBlock *block;
|
||||||
gemtextNode *node;
|
gemtextNode *node;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
@ -223,14 +223,14 @@ int gemtextParserSendPreformatted(gemtextParser *parser, gemtextNodeQueue *lq) {
|
||||||
parser->altText = NULL;
|
parser->altText = NULL;
|
||||||
block->body = buf;
|
block->body = buf;
|
||||||
node->block = block;
|
node->block = block;
|
||||||
gemtextNodeQueuePush(lq, node);
|
gemtextNodeQueuePush(nq, node);
|
||||||
lineBufferReset(&parser->buffer);
|
lineBufferReset(&parser->buffer);
|
||||||
parser->state = lineStart;
|
parser->state = lineStart;
|
||||||
parser->mode = normalMode;
|
parser->nodeType = unset;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gemtextParserSendLink(gemtextParser *parser, gemtextNodeQueue *lq) {
|
int gemtextParserSendLink(gemtextParser *parser, gemtextNodeQueue *nq) {
|
||||||
gemtextLink *link;
|
gemtextLink *link;
|
||||||
gemtextNode *node;
|
gemtextNode *node;
|
||||||
char *url = NULL, *display = NULL;
|
char *url = NULL, *display = NULL;
|
||||||
|
@ -258,28 +258,28 @@ int gemtextParserSendLink(gemtextParser *parser, gemtextNodeQueue *lq) {
|
||||||
link->display = display;
|
link->display = display;
|
||||||
node->nodeType = linkNode;
|
node->nodeType = linkNode;
|
||||||
node->link = link;
|
node->link = link;
|
||||||
gemtextNodeQueuePush(lq, node);
|
gemtextNodeQueuePush(nq, node);
|
||||||
lineBufferReset(&parser->buffer);
|
lineBufferReset(&parser->buffer);
|
||||||
parser->state = lineStart;
|
parser->state = lineStart;
|
||||||
parser->mode = normalMode;
|
parser->nodeType = unset;
|
||||||
parser->linkUrl = NULL;
|
parser->linkUrl = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gemtextParserSend(gemtextParser *parser, gemtextNodeType lt, gemtextNodeQueue *lq) {
|
int gemtextParserSend(gemtextParser *parser, gemtextNodeQueue *nq) {
|
||||||
gemtextNode *node;
|
gemtextNode *node;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
node = calloc(1, sizeof(gemtextNode));
|
node = calloc(1, sizeof(gemtextNode));
|
||||||
if (node == NULL) return errno;
|
if (node == NULL) return errno;
|
||||||
node->nodeType = lt;
|
node->nodeType = parser->nodeType;
|
||||||
buf = strndup(parser->buffer.buf, parser->buffer.len);
|
buf = strndup(parser->buffer.buf, parser->buffer.len);
|
||||||
if (buf == NULL) return errno;
|
if (buf == NULL) return errno;
|
||||||
node->str = buf;
|
node->str = buf;
|
||||||
gemtextNodeQueuePush(lq, node);
|
gemtextNodeQueuePush(nq, node);
|
||||||
lineBufferReset(&parser->buffer);
|
lineBufferReset(&parser->buffer);
|
||||||
parser->state = lineStart;
|
parser->state = lineStart;
|
||||||
parser->mode = normalMode;
|
parser->nodeType = unset;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ void logParseError(int err) {
|
||||||
//todo
|
//todo
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchMode(gemtextParser *parser, gemtextParserMode mode, char c) {
|
void switchMode(gemtextParser *parser, gemtextNodeType node_type, char c) {
|
||||||
lineBufferReset(&parser->buffer);
|
lineBufferReset(&parser->buffer);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ' ':
|
case ' ':
|
||||||
|
@ -299,11 +299,11 @@ void switchMode(gemtextParser *parser, gemtextParserMode mode, char c) {
|
||||||
lineBufferAppendCharUnchecked(&parser->buffer, c);
|
lineBufferAppendCharUnchecked(&parser->buffer, c);
|
||||||
parser->state = normalState;
|
parser->state = normalState;
|
||||||
}
|
}
|
||||||
parser->mode = mode;
|
parser->nodeType = node_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enterPreformattedMode(gemtextParser *parser) {
|
void enterPreformattedMode(gemtextParser *parser) {
|
||||||
parser->mode = preformattedMode;
|
parser->nodeType = preformattedNode;
|
||||||
parser->state = trimStart;
|
parser->state = trimStart;
|
||||||
lineBufferReset(&parser->buffer);
|
lineBufferReset(&parser->buffer);
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,7 @@ int parseLink(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
|
||||||
assert(parser->mode == linkMode);
|
assert(parser->nodeType == linkNode);
|
||||||
switch (parser->state) {
|
switch (parser->state) {
|
||||||
case lineStart:
|
case lineStart:
|
||||||
if (c != ' ' && c != '\t') {
|
if (c != ' ' && c != '\t') {
|
||||||
|
@ -320,7 +320,7 @@ int parseLink(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
lineBufferAppendCharUnchecked(&parser->buffer, c);
|
lineBufferAppendCharUnchecked(&parser->buffer, c);
|
||||||
parser->state = normalState;
|
parser->state = normalState;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
ret = gemtextParserSend(parser, lq);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case normalState:
|
case normalState:
|
||||||
|
@ -360,7 +360,7 @@ int parseLink(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
int parsePreformatted(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
int parsePreformatted(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
|
||||||
assert(parser->mode == preformattedMode);
|
assert(parser->nodeType == preformattedNode);
|
||||||
switch (parser->state) {
|
switch (parser->state) {
|
||||||
case trimStart:
|
case trimStart:
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
|
@ -437,12 +437,12 @@ int parseQuote(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
lineBufferRewind(&parser->buffer);
|
lineBufferRewind(&parser->buffer);
|
||||||
} else {
|
} else {
|
||||||
lineBufferRewind(&parser->buffer);
|
lineBufferRewind(&parser->buffer);
|
||||||
ret = gemtextParserSend(parser, quoteNode, lq);
|
ret = gemtextParserSend(parser, lq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
ret = fseek(parser->stream, -1, SEEK_CUR);
|
ret = fseek(parser->stream, -1, SEEK_CUR);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
parser->state = lineStart;
|
parser->state = lineStart;
|
||||||
parser->mode = normalMode;
|
parser->nodeType = normalNode;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case normalState:
|
case normalState:
|
||||||
|
@ -456,7 +456,10 @@ int parseQuote(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
parser->buffer.len--;
|
parser->buffer.len--;
|
||||||
parser->buffer.cursor--;
|
parser->buffer.cursor--;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
if (parser->buffer.len == 1) {
|
||||||
|
parser->nodeType = normalNode;
|
||||||
|
}
|
||||||
|
ret = gemtextParserSend(parser, lq);
|
||||||
} else {
|
} else {
|
||||||
parser->state = normalState;
|
parser->state = normalState;
|
||||||
}
|
}
|
||||||
|
@ -469,7 +472,7 @@ int parseQuote(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parseGeneric(gemtextParser *parser, gemtextNodeQueue *lq, gemtextNodeType lt, char c) {
|
int parseGeneric(gemtextParser *parser, gemtextNodeQueue *nq, char c) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
switch (parser->state) {
|
switch (parser->state) {
|
||||||
|
@ -480,14 +483,14 @@ int parseGeneric(gemtextParser *parser, gemtextNodeQueue *lq, gemtextNodeType lt
|
||||||
parser->buffer.len--;
|
parser->buffer.len--;
|
||||||
parser->buffer.cursor--;
|
parser->buffer.cursor--;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, lt, lq);
|
ret = gemtextParserSend(parser, nq);
|
||||||
} else {
|
} else {
|
||||||
parser->state = normalState;
|
parser->state = normalState;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case normalState:
|
case normalState:
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, lt, lq);
|
ret = gemtextParserSend(parser, nq);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -498,7 +501,7 @@ int parseGeneric(gemtextParser *parser, gemtextNodeQueue *lq, gemtextNodeType lt
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
int parseNormal(gemtextParser *parser, gemtextNodeQueue *nq, char c) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (parser->state) {
|
switch (parser->state) {
|
||||||
|
@ -508,12 +511,12 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
parser->state = firstLinkChar;
|
parser->state = firstLinkChar;
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
parser->mode = quoteMode;
|
parser->nodeType = quoteNode;
|
||||||
parser->state = trimStart;
|
parser->state = trimStart;
|
||||||
lineBufferRewind(&parser->buffer);
|
lineBufferRewind(&parser->buffer);
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
parser->mode = listMode;
|
parser->nodeType = listNode;
|
||||||
parser->state = trimStart;
|
parser->state = trimStart;
|
||||||
lineBufferRewind(&parser->buffer);
|
lineBufferRewind(&parser->buffer);
|
||||||
break;
|
break;
|
||||||
|
@ -524,7 +527,8 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
parser->state = firstBacktickChar;
|
parser->state = firstBacktickChar;
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
parser->nodeType = normalNode;
|
||||||
|
ret = gemtextParserSend(parser, nq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -533,10 +537,11 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
break;
|
break;
|
||||||
case firstLinkChar:
|
case firstLinkChar:
|
||||||
if (c == '>') {
|
if (c == '>') {
|
||||||
parser->mode = linkMode;
|
parser->nodeType = linkNode;
|
||||||
parser->state = lineStart;
|
parser->state = lineStart;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
parser->nodeType = normalNode;
|
||||||
|
ret = gemtextParserSend(parser, nq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
} else {
|
} else {
|
||||||
parser->state = normalState;
|
parser->state = normalState;
|
||||||
|
@ -546,52 +551,57 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
if (c == '#') {
|
if (c == '#') {
|
||||||
parser->state = secondHashChar;
|
parser->state = secondHashChar;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
parser->nodeType = normalNode;
|
||||||
|
ret = gemtextParserSend(parser, nq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
} else {
|
} else {
|
||||||
switchMode(parser, h1Mode, c);
|
switchMode(parser, h1Node, c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case secondHashChar:
|
case secondHashChar:
|
||||||
if (c == '#') {
|
if (c == '#') {
|
||||||
parser->mode = h3Mode;
|
parser->nodeType = h3Node;
|
||||||
parser->state = trimStart;
|
parser->state = trimStart;
|
||||||
lineBufferReset(&parser->buffer);
|
lineBufferReset(&parser->buffer);
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
parser->nodeType = normalNode;
|
||||||
|
ret = gemtextParserSend(parser, nq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
} else {
|
} else {
|
||||||
switchMode(parser, h2Mode, c);
|
switchMode(parser, h2Node, c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case thirdHashChar:
|
case thirdHashChar:
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
parser->nodeType = normalNode;
|
||||||
|
ret = gemtextParserSend(parser, nq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
} else {
|
} else {
|
||||||
switchMode(parser, h3Mode, c);
|
switchMode(parser, h3Node, c);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case firstBacktickChar:
|
case firstBacktickChar:
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
parser->nodeType = normalNode;
|
||||||
|
ret = gemtextParserSend(parser, nq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
} else if (c == '`') {
|
} else if (c == '`') {
|
||||||
parser->state = secondBacktickChar;
|
parser->state = secondBacktickChar;
|
||||||
} else {
|
} else {
|
||||||
parser->state = normalState;
|
parser->state = normalState;
|
||||||
parser->mode = normalMode;
|
parser->nodeType = normalNode;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case secondBacktickChar:
|
case secondBacktickChar:
|
||||||
if (c == '`') {
|
if (c == '`') {
|
||||||
enterPreformattedMode(parser);
|
enterPreformattedMode(parser);
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
parser->nodeType = normalNode;
|
||||||
|
ret = gemtextParserSend(parser, nq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
} else {
|
} else {
|
||||||
parser->state = normalState;
|
parser->state = normalState;
|
||||||
parser->mode = normalMode;
|
parser->nodeType = normalNode;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -600,7 +610,7 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq) {
|
int parseGemtext(gemtextParser *parser, gemtextNodeQueue *nq) {
|
||||||
char c;
|
char c;
|
||||||
int ret;
|
int ret;
|
||||||
gemtextNode *node;
|
gemtextNode *node;
|
||||||
|
@ -615,30 +625,15 @@ int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (parser->state != lineStart && parser->state != trimStart) {
|
if (parser->state != lineStart && parser->state != trimStart) {
|
||||||
switch (parser->mode) {
|
switch (parser->nodeType) {
|
||||||
case normalMode:
|
case preformattedNode:
|
||||||
ret = gemtextParserSend(parser, normalNode, lq);
|
ret = gemtextParserSendPreformatted(parser, nq);
|
||||||
break;
|
break;
|
||||||
case preformattedMode:
|
case linkNode:
|
||||||
ret = gemtextParserSendPreformatted(parser, lq);
|
ret = gemtextParserSendLink(parser, nq);
|
||||||
break;
|
break;
|
||||||
case quoteMode:
|
default:
|
||||||
ret = gemtextParserSend(parser, quoteNode, lq);
|
ret = gemtextParserSend(parser, nq);
|
||||||
break;
|
|
||||||
case linkMode:
|
|
||||||
ret = gemtextParserSendLink(parser, lq);
|
|
||||||
break;
|
|
||||||
case h1Mode:
|
|
||||||
ret = gemtextParserSend(parser, h1Node, lq);
|
|
||||||
break;
|
|
||||||
case h2Mode:
|
|
||||||
ret = gemtextParserSend(parser, h2Node, lq);
|
|
||||||
break;
|
|
||||||
case h3Mode:
|
|
||||||
ret = gemtextParserSend(parser, h3Node, lq);
|
|
||||||
break;
|
|
||||||
case listMode:
|
|
||||||
ret = gemtextParserSend(parser, listNode, lq);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
|
@ -648,33 +643,25 @@ int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq) {
|
||||||
node->nodeType = endOfStream;
|
node->nodeType = endOfStream;
|
||||||
node->prev = node->next = NULL;
|
node->prev = node->next = NULL;
|
||||||
node->str = NULL;
|
node->str = NULL;
|
||||||
gemtextNodeQueuePush(lq, node);
|
gemtextNodeQueuePush(nq, node);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (parser->mode) {
|
switch (parser->nodeType) {
|
||||||
case normalMode:
|
case unset:
|
||||||
ret = parseNormal(parser, lq, c);
|
case normalNode:
|
||||||
|
ret = parseNormal(parser, nq, c);
|
||||||
break;
|
break;
|
||||||
case preformattedMode:
|
case preformattedNode:
|
||||||
ret = parsePreformatted(parser, lq, c);
|
ret = parsePreformatted(parser, nq, c);
|
||||||
break;
|
break;
|
||||||
case quoteMode:
|
case quoteNode:
|
||||||
ret = parseQuote(parser, lq, c);
|
ret = parseQuote(parser, nq, c);
|
||||||
break;
|
break;
|
||||||
case linkMode:
|
case linkNode:
|
||||||
ret = parseLink(parser, lq, c);
|
ret = parseLink(parser, nq, c);
|
||||||
break;
|
break;
|
||||||
case h1Mode:
|
default:
|
||||||
ret = parseGeneric(parser, lq, h1Node, c);
|
ret = parseGeneric(parser, nq, c);
|
||||||
break;
|
|
||||||
case h2Mode:
|
|
||||||
ret = parseGeneric(parser, lq, h2Node, c);
|
|
||||||
break;
|
|
||||||
case h3Mode:
|
|
||||||
ret = parseGeneric(parser, lq, h3Node, c);
|
|
||||||
break;
|
|
||||||
case listMode:
|
|
||||||
ret = parseGeneric(parser, lq, listNode, c);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
|
@ -10,19 +10,6 @@
|
||||||
|
|
||||||
#define LBUF_SIZE 512 ///< The default size of a lineBuffer
|
#define LBUF_SIZE 512 ///< The default size of a lineBuffer
|
||||||
|
|
||||||
/** The main modes which the parser can operate in */
|
|
||||||
typedef enum {
|
|
||||||
normalMode, /**< A normal text line is being parsed, or the parser is
|
|
||||||
still determining the line type */
|
|
||||||
preformattedMode, ///< A Preformatted block is being parsed
|
|
||||||
quoteMode, ///< A Quote block is being parsed
|
|
||||||
linkMode, ///< A hyperlink is being parsed
|
|
||||||
h1Mode, ///< An H1 heading is being parsed
|
|
||||||
h2Mode, ///< An H2 heading is being parsed
|
|
||||||
h3Mode, ///< An H3 heading is being parsed
|
|
||||||
listMode, ///< A list member is being parsed
|
|
||||||
} gemtextParserMode;
|
|
||||||
|
|
||||||
/** An enumeration representing the state of the parsing action. These values
|
/** An enumeration representing the state of the parsing action. These values
|
||||||
* are to be taken in context with the current gemtextParserMode */
|
* are to be taken in context with the current gemtextParserMode */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -47,15 +34,16 @@ typedef enum {
|
||||||
* An enum type representing the various line types in gemtext markup
|
* An enum type representing the various line types in gemtext markup
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
normalNode = 0, ///< A normal text line
|
unset = 0, ///< The node type has not yet been set
|
||||||
linkNode = 1, ///< A link line
|
normalNode = 1, ///< A normal text line
|
||||||
listNode = 2, ///< A list member
|
linkNode = 2, ///< A link line
|
||||||
h1Node = 3, ///< An H1 heading
|
listNode = 3, ///< A list member
|
||||||
h2Node = 4, ///< An H2 heading
|
h1Node = 4, ///< An H1 heading
|
||||||
h3Node = 5, ///< An H3 heading
|
h2Node = 5, ///< An H2 heading
|
||||||
preformattedNode = 6, ///< A preformatted text block
|
h3Node = 6, ///< An H3 heading
|
||||||
quoteNode = 7, ///< A Quote block
|
preformattedNode = 7, ///< A preformatted text block
|
||||||
endOfStream = 8, /**< Notifies the receiver that the stream is over and no
|
quoteNode = 8, ///< A Quote block
|
||||||
|
endOfStream = 9, /**< Notifies the receiver that the stream is over and no
|
||||||
more lines are to be expected */
|
more lines are to be expected */
|
||||||
} gemtextNodeType;
|
} gemtextNodeType;
|
||||||
|
|
||||||
|
@ -91,7 +79,7 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FILE *stream; /**< A stream of bytes to read gemtext from */
|
FILE *stream; /**< A stream of bytes to read gemtext from */
|
||||||
gemtextParserMode mode; /**< The current parsing mode */
|
gemtextNodeType nodeType; /**< The current parsing mode */
|
||||||
gemtextParserState state; /**< The state of the parser within each mode */
|
gemtextParserState state; /**< The state of the parser within each mode */
|
||||||
lineBuffer buffer; /**< The internal buffer used to store bytes until
|
lineBuffer buffer; /**< The internal buffer used to store bytes until
|
||||||
a gemtextLine is ready to be sent */
|
a gemtextLine is ready to be sent */
|
||||||
|
@ -170,31 +158,31 @@ void gemtextParserDestroy(gemtextParser *parser);
|
||||||
* ### Return values
|
* ### Return values
|
||||||
* Returns 0 on success. If there is a failure initializing the internal
|
* Returns 0 on success. If there is a failure initializing the internal
|
||||||
* mutex or condition variable, an error code is returned instead.
|
* mutex or condition variable, an error code is returned instead.
|
||||||
* \param queue The already allocated gemtextNodeQueue
|
* \param nq The already allocated gemtextNodeQueue
|
||||||
*/
|
*/
|
||||||
int gemtextNodeQueueInit(gemtextNodeQueue *queue);
|
int gemtextNodeQueueInit(gemtextNodeQueue *nq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pushes a gemtextLine into the queue. This function will not fail, but
|
* Pushes a gemtextLine into the queue. This function will not fail, but
|
||||||
* can block if another thread holds the gemtextQueue's internal mutex.
|
* can block if another thread holds the gemtextQueue's internal mutex.
|
||||||
* \param queue The queue which will receive the gemtext line
|
* \param nq The queue which will receive the gemtext line
|
||||||
* \param line The gemtextLine to be queued
|
* \param node The gemtextNode to be queued
|
||||||
*/
|
*/
|
||||||
void gemtextNodeQueuePush(gemtextNodeQueue *queue, gemtextNode *node);
|
void gemtextNodeQueuePush(gemtextNodeQueue *nq, gemtextNode *node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the oldest line inserted in the queue. This function will either
|
* Gets the oldest line inserted in the queue. This function will either
|
||||||
* return a valid gemtextLine or block until one becomes available.
|
* return a valid gemtextLine or block until one becomes available.
|
||||||
* \param lq The queue from which we are attempting to pop a line
|
* \param nq The queue from which we are attempting to pop a line
|
||||||
*/
|
*/
|
||||||
gemtextNode* gemtextNodeQueuePop(gemtextNodeQueue *lq);
|
gemtextNode* gemtextNodeQueuePop(gemtextNodeQueue *nq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to get the oldest line inserted in the queue. If there are no lines
|
* Attempts to get the oldest line inserted in the queue. If there are no lines
|
||||||
* left in the queue, returns NULL.
|
* left in the queue, returns NULL.
|
||||||
* \param lq The queue from which we are attempting to pop a line
|
* \param nq The queue from which we are attempting to pop a line
|
||||||
*/
|
*/
|
||||||
gemtextNode* gemtextNodeQueueTryPop(gemtextNodeQueue *lq);
|
gemtextNode* gemtextNodeQueueTryPop(gemtextNodeQueue *nq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees all memory associated with a gemtextLine structure
|
* Frees all memory associated with a gemtextLine structure
|
||||||
|
@ -258,8 +246,8 @@ void lineBufferReset(lineBuffer *lb);
|
||||||
* ### Return values
|
* ### Return values
|
||||||
* Returns 0 on success, any other number is an error code
|
* Returns 0 on success, any other number is an error code
|
||||||
* \param parser A gemtextParser struct used to maintain state while parsing
|
* \param parser A gemtextParser struct used to maintain state while parsing
|
||||||
* \param lq A gemtextNodeQueue which will receive gemtextLine elements as they are parsed
|
* \param nq A gemtextNodeQueue which will receive gemtextLine elements as they are parsed
|
||||||
*/
|
*/
|
||||||
int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq);
|
int parseGemtext(gemtextParser *parser, gemtextNodeQueue *nq);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue