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;
|
||||
|
||||
parser->stream = stream;
|
||||
parser->mode = normalMode;
|
||||
parser->nodeType = unset;
|
||||
parser->state = lineStart;
|
||||
parser->linkUrl = NULL;
|
||||
ret = lineBufferInit(&parser->buffer);
|
||||
|
@ -42,9 +42,9 @@ gemtextParser* gemtextParserNew(FILE *stream) {
|
|||
void gemtextParserDeinit(gemtextParser *parser) {
|
||||
fclose(parser->stream);
|
||||
free(parser->buffer.buf);
|
||||
if (parser->mode == linkMode && parser->linkUrl != NULL) {
|
||||
if (parser->nodeType == linkNode && parser->linkUrl != NULL) {
|
||||
free(parser->linkUrl);
|
||||
} else if (parser->mode == preformattedMode && parser->altText != NULL) {
|
||||
} else if (parser->nodeType == preformattedNode && parser->altText != NULL) {
|
||||
free(parser->altText);
|
||||
}
|
||||
}
|
||||
|
@ -54,66 +54,66 @@ void gemtextParserDestroy(gemtextParser *parser) {
|
|||
free(parser);
|
||||
}
|
||||
|
||||
int gemtextNodeQueueInit(gemtextNodeQueue *queue) {
|
||||
int gemtextNodeQueueInit(gemtextNodeQueue *nq) {
|
||||
int ret;
|
||||
|
||||
queue->head = NULL;
|
||||
queue->tail = NULL;
|
||||
ret = pthread_mutex_init(&queue->mutex, NULL);
|
||||
nq->head = NULL;
|
||||
nq->tail = NULL;
|
||||
ret = pthread_mutex_init(&nq->mutex, NULL);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
return pthread_cond_init(&queue->cond, NULL);
|
||||
return pthread_cond_init(&nq->cond, NULL);
|
||||
}
|
||||
|
||||
void gemtextNodeQueuePush(gemtextNodeQueue *queue, gemtextNode *node) {
|
||||
pthread_mutex_lock(&queue->mutex);
|
||||
if (queue->tail == NULL) {
|
||||
queue->tail = queue->head = node;
|
||||
void gemtextNodeQueuePush(gemtextNodeQueue *nq, gemtextNode *node) {
|
||||
pthread_mutex_lock(&nq->mutex);
|
||||
if (nq->tail == NULL) {
|
||||
nq->tail = nq->head = node;
|
||||
} else {
|
||||
node->next = queue->tail;
|
||||
queue->tail->prev = node;
|
||||
queue->tail = node;
|
||||
node->next = nq->tail;
|
||||
nq->tail->prev = node;
|
||||
nq->tail = node;
|
||||
}
|
||||
queue->count++;
|
||||
pthread_mutex_unlock(&queue->mutex);
|
||||
nq->count++;
|
||||
pthread_mutex_unlock(&nq->mutex);
|
||||
}
|
||||
|
||||
gemtextNode* gemtextNodeQueuePop(gemtextNodeQueue *lq) {
|
||||
gemtextNode* gemtextNodeQueuePop(gemtextNodeQueue *nq) {
|
||||
gemtextNode *node;
|
||||
|
||||
while (lq->count == 0)
|
||||
pthread_cond_wait(&lq->cond, &lq->mutex);
|
||||
pthread_mutex_lock(&lq->mutex);
|
||||
lq->count++;
|
||||
node = lq->head;
|
||||
while (nq->count == 0)
|
||||
pthread_cond_wait(&nq->cond, &nq->mutex);
|
||||
pthread_mutex_lock(&nq->mutex);
|
||||
nq->count++;
|
||||
node = nq->head;
|
||||
if (node->nodeType == endOfStream)
|
||||
return node;
|
||||
if (lq->tail == lq->head) {
|
||||
lq->tail = lq->head = NULL;
|
||||
if (nq->tail == nq->head) {
|
||||
nq->tail = nq->head = NULL;
|
||||
} 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;
|
||||
return node;
|
||||
}
|
||||
|
||||
gemtextNode* gemtextNodeQueueTryPop(gemtextNodeQueue *lq) {
|
||||
gemtextNode* gemtextNodeQueueTryPop(gemtextNodeQueue *nq) {
|
||||
gemtextNode *node;
|
||||
|
||||
if (lq->count == 0)
|
||||
if (nq->count == 0)
|
||||
return NULL;
|
||||
pthread_mutex_lock(&lq->mutex);
|
||||
lq->count++;
|
||||
node = lq->head;
|
||||
pthread_mutex_lock(&nq->mutex);
|
||||
nq->count++;
|
||||
node = nq->head;
|
||||
if (node->nodeType == endOfStream)
|
||||
return node;
|
||||
if (lq->tail == lq->head) {
|
||||
lq->tail = lq->head = NULL;
|
||||
if (nq->tail == nq->head) {
|
||||
nq->tail = nq->head = NULL;
|
||||
} 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;
|
||||
return node;
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ void lineBufferReset(lineBuffer *lb) {
|
|||
lb->cursor = lb->buf;
|
||||
}
|
||||
|
||||
int gemtextParserSendPreformatted(gemtextParser *parser, gemtextNodeQueue *lq) {
|
||||
int gemtextParserSendPreformatted(gemtextParser *parser, gemtextNodeQueue *nq) {
|
||||
preformattedBlock *block;
|
||||
gemtextNode *node;
|
||||
char *buf;
|
||||
|
@ -223,14 +223,14 @@ int gemtextParserSendPreformatted(gemtextParser *parser, gemtextNodeQueue *lq) {
|
|||
parser->altText = NULL;
|
||||
block->body = buf;
|
||||
node->block = block;
|
||||
gemtextNodeQueuePush(lq, node);
|
||||
gemtextNodeQueuePush(nq, node);
|
||||
lineBufferReset(&parser->buffer);
|
||||
parser->state = lineStart;
|
||||
parser->mode = normalMode;
|
||||
parser->nodeType = unset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gemtextParserSendLink(gemtextParser *parser, gemtextNodeQueue *lq) {
|
||||
int gemtextParserSendLink(gemtextParser *parser, gemtextNodeQueue *nq) {
|
||||
gemtextLink *link;
|
||||
gemtextNode *node;
|
||||
char *url = NULL, *display = NULL;
|
||||
|
@ -258,28 +258,28 @@ int gemtextParserSendLink(gemtextParser *parser, gemtextNodeQueue *lq) {
|
|||
link->display = display;
|
||||
node->nodeType = linkNode;
|
||||
node->link = link;
|
||||
gemtextNodeQueuePush(lq, node);
|
||||
gemtextNodeQueuePush(nq, node);
|
||||
lineBufferReset(&parser->buffer);
|
||||
parser->state = lineStart;
|
||||
parser->mode = normalMode;
|
||||
parser->nodeType = unset;
|
||||
parser->linkUrl = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gemtextParserSend(gemtextParser *parser, gemtextNodeType lt, gemtextNodeQueue *lq) {
|
||||
int gemtextParserSend(gemtextParser *parser, gemtextNodeQueue *nq) {
|
||||
gemtextNode *node;
|
||||
char *buf;
|
||||
|
||||
node = calloc(1, sizeof(gemtextNode));
|
||||
if (node == NULL) return errno;
|
||||
node->nodeType = lt;
|
||||
node->nodeType = parser->nodeType;
|
||||
buf = strndup(parser->buffer.buf, parser->buffer.len);
|
||||
if (buf == NULL) return errno;
|
||||
node->str = buf;
|
||||
gemtextNodeQueuePush(lq, node);
|
||||
gemtextNodeQueuePush(nq, node);
|
||||
lineBufferReset(&parser->buffer);
|
||||
parser->state = lineStart;
|
||||
parser->mode = normalMode;
|
||||
parser->nodeType = unset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,7 @@ void logParseError(int err) {
|
|||
//todo
|
||||
}
|
||||
|
||||
void switchMode(gemtextParser *parser, gemtextParserMode mode, char c) {
|
||||
void switchMode(gemtextParser *parser, gemtextNodeType node_type, char c) {
|
||||
lineBufferReset(&parser->buffer);
|
||||
switch (c) {
|
||||
case ' ':
|
||||
|
@ -299,11 +299,11 @@ void switchMode(gemtextParser *parser, gemtextParserMode mode, char c) {
|
|||
lineBufferAppendCharUnchecked(&parser->buffer, c);
|
||||
parser->state = normalState;
|
||||
}
|
||||
parser->mode = mode;
|
||||
parser->nodeType = node_type;
|
||||
}
|
||||
|
||||
void enterPreformattedMode(gemtextParser *parser) {
|
||||
parser->mode = preformattedMode;
|
||||
parser->nodeType = preformattedNode;
|
||||
parser->state = trimStart;
|
||||
lineBufferReset(&parser->buffer);
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ int parseLink(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
int ret = 0;
|
||||
char *buf = NULL;
|
||||
|
||||
assert(parser->mode == linkMode);
|
||||
assert(parser->nodeType == linkNode);
|
||||
switch (parser->state) {
|
||||
case lineStart:
|
||||
if (c != ' ' && c != '\t') {
|
||||
|
@ -320,7 +320,7 @@ int parseLink(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
lineBufferAppendCharUnchecked(&parser->buffer, c);
|
||||
parser->state = normalState;
|
||||
} else if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
ret = gemtextParserSend(parser, lq);
|
||||
}
|
||||
break;
|
||||
case normalState:
|
||||
|
@ -360,7 +360,7 @@ int parseLink(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
int parsePreformatted(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||
char *buf = NULL;
|
||||
|
||||
assert(parser->mode == preformattedMode);
|
||||
assert(parser->nodeType == preformattedNode);
|
||||
switch (parser->state) {
|
||||
case trimStart:
|
||||
if (c == '\n') {
|
||||
|
@ -437,12 +437,12 @@ int parseQuote(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
lineBufferRewind(&parser->buffer);
|
||||
} else {
|
||||
lineBufferRewind(&parser->buffer);
|
||||
ret = gemtextParserSend(parser, quoteNode, lq);
|
||||
ret = gemtextParserSend(parser, lq);
|
||||
if (ret) return ret;
|
||||
ret = fseek(parser->stream, -1, SEEK_CUR);
|
||||
if (ret) return ret;
|
||||
parser->state = lineStart;
|
||||
parser->mode = normalMode;
|
||||
parser->nodeType = normalNode;
|
||||
}
|
||||
break;
|
||||
case normalState:
|
||||
|
@ -456,7 +456,10 @@ int parseQuote(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
parser->buffer.len--;
|
||||
parser->buffer.cursor--;
|
||||
} else if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
if (parser->buffer.len == 1) {
|
||||
parser->nodeType = normalNode;
|
||||
}
|
||||
ret = gemtextParserSend(parser, lq);
|
||||
} else {
|
||||
parser->state = normalState;
|
||||
}
|
||||
|
@ -469,7 +472,7 @@ int parseQuote(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int parseGeneric(gemtextParser *parser, gemtextNodeQueue *lq, gemtextNodeType lt, char c) {
|
||||
int parseGeneric(gemtextParser *parser, gemtextNodeQueue *nq, char c) {
|
||||
int ret = 0;
|
||||
|
||||
switch (parser->state) {
|
||||
|
@ -480,14 +483,14 @@ int parseGeneric(gemtextParser *parser, gemtextNodeQueue *lq, gemtextNodeType lt
|
|||
parser->buffer.len--;
|
||||
parser->buffer.cursor--;
|
||||
} else if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, lt, lq);
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
} else {
|
||||
parser->state = normalState;
|
||||
}
|
||||
break;
|
||||
case normalState:
|
||||
if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, lt, lq);
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -498,7 +501,7 @@ int parseGeneric(gemtextParser *parser, gemtextNodeQueue *lq, gemtextNodeType lt
|
|||
return ret;
|
||||
}
|
||||
|
||||
int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
||||
int parseNormal(gemtextParser *parser, gemtextNodeQueue *nq, char c) {
|
||||
int ret;
|
||||
|
||||
switch (parser->state) {
|
||||
|
@ -508,12 +511,12 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
parser->state = firstLinkChar;
|
||||
break;
|
||||
case '>':
|
||||
parser->mode = quoteMode;
|
||||
parser->nodeType = quoteNode;
|
||||
parser->state = trimStart;
|
||||
lineBufferRewind(&parser->buffer);
|
||||
break;
|
||||
case '*':
|
||||
parser->mode = listMode;
|
||||
parser->nodeType = listNode;
|
||||
parser->state = trimStart;
|
||||
lineBufferRewind(&parser->buffer);
|
||||
break;
|
||||
|
@ -524,7 +527,8 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
parser->state = firstBacktickChar;
|
||||
break;
|
||||
case '\n':
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
parser->nodeType = normalNode;
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
if (ret) return ret;
|
||||
break;
|
||||
default:
|
||||
|
@ -533,10 +537,11 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
break;
|
||||
case firstLinkChar:
|
||||
if (c == '>') {
|
||||
parser->mode = linkMode;
|
||||
parser->nodeType = linkNode;
|
||||
parser->state = lineStart;
|
||||
} else if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
parser->nodeType = normalNode;
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
if (ret) return ret;
|
||||
} else {
|
||||
parser->state = normalState;
|
||||
|
@ -546,52 +551,57 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
if (c == '#') {
|
||||
parser->state = secondHashChar;
|
||||
} else if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
parser->nodeType = normalNode;
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
if (ret) return ret;
|
||||
} else {
|
||||
switchMode(parser, h1Mode, c);
|
||||
switchMode(parser, h1Node, c);
|
||||
}
|
||||
break;
|
||||
case secondHashChar:
|
||||
if (c == '#') {
|
||||
parser->mode = h3Mode;
|
||||
parser->nodeType = h3Node;
|
||||
parser->state = trimStart;
|
||||
lineBufferReset(&parser->buffer);
|
||||
} else if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
parser->nodeType = normalNode;
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
if (ret) return ret;
|
||||
} else {
|
||||
switchMode(parser, h2Mode, c);
|
||||
switchMode(parser, h2Node, c);
|
||||
}
|
||||
break;
|
||||
case thirdHashChar:
|
||||
if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
parser->nodeType = normalNode;
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
if (ret) return ret;
|
||||
} else {
|
||||
switchMode(parser, h3Mode, c);
|
||||
switchMode(parser, h3Node, c);
|
||||
}
|
||||
break;
|
||||
case firstBacktickChar:
|
||||
if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
parser->nodeType = normalNode;
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
if (ret) return ret;
|
||||
} else if (c == '`') {
|
||||
parser->state = secondBacktickChar;
|
||||
} else {
|
||||
parser->state = normalState;
|
||||
parser->mode = normalMode;
|
||||
parser->nodeType = normalNode;
|
||||
}
|
||||
break;
|
||||
case secondBacktickChar:
|
||||
if (c == '`') {
|
||||
enterPreformattedMode(parser);
|
||||
} else if (c == '\n') {
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
parser->nodeType = normalNode;
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
if (ret) return ret;
|
||||
} else {
|
||||
parser->state = normalState;
|
||||
parser->mode = normalMode;
|
||||
parser->nodeType = normalNode;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -600,7 +610,7 @@ int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq) {
|
||||
int parseGemtext(gemtextParser *parser, gemtextNodeQueue *nq) {
|
||||
char c;
|
||||
int ret;
|
||||
gemtextNode *node;
|
||||
|
@ -615,30 +625,15 @@ int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq) {
|
|||
}
|
||||
} else {
|
||||
if (parser->state != lineStart && parser->state != trimStart) {
|
||||
switch (parser->mode) {
|
||||
case normalMode:
|
||||
ret = gemtextParserSend(parser, normalNode, lq);
|
||||
switch (parser->nodeType) {
|
||||
case preformattedNode:
|
||||
ret = gemtextParserSendPreformatted(parser, nq);
|
||||
break;
|
||||
case preformattedMode:
|
||||
ret = gemtextParserSendPreformatted(parser, lq);
|
||||
case linkNode:
|
||||
ret = gemtextParserSendLink(parser, nq);
|
||||
break;
|
||||
case quoteMode:
|
||||
ret = gemtextParserSend(parser, quoteNode, lq);
|
||||
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);
|
||||
default:
|
||||
ret = gemtextParserSend(parser, nq);
|
||||
break;
|
||||
}
|
||||
if (ret) return ret;
|
||||
|
@ -648,33 +643,25 @@ int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq) {
|
|||
node->nodeType = endOfStream;
|
||||
node->prev = node->next = NULL;
|
||||
node->str = NULL;
|
||||
gemtextNodeQueuePush(lq, node);
|
||||
gemtextNodeQueuePush(nq, node);
|
||||
break;
|
||||
}
|
||||
switch (parser->mode) {
|
||||
case normalMode:
|
||||
ret = parseNormal(parser, lq, c);
|
||||
switch (parser->nodeType) {
|
||||
case unset:
|
||||
case normalNode:
|
||||
ret = parseNormal(parser, nq, c);
|
||||
break;
|
||||
case preformattedMode:
|
||||
ret = parsePreformatted(parser, lq, c);
|
||||
case preformattedNode:
|
||||
ret = parsePreformatted(parser, nq, c);
|
||||
break;
|
||||
case quoteMode:
|
||||
ret = parseQuote(parser, lq, c);
|
||||
case quoteNode:
|
||||
ret = parseQuote(parser, nq, c);
|
||||
break;
|
||||
case linkMode:
|
||||
ret = parseLink(parser, lq, c);
|
||||
case linkNode:
|
||||
ret = parseLink(parser, nq, c);
|
||||
break;
|
||||
case h1Mode:
|
||||
ret = parseGeneric(parser, lq, h1Node, 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);
|
||||
default:
|
||||
ret = parseGeneric(parser, nq, c);
|
||||
break;
|
||||
}
|
||||
if (ret) {
|
||||
|
|
|
@ -10,19 +10,6 @@
|
|||
|
||||
#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
|
||||
* are to be taken in context with the current gemtextParserMode */
|
||||
typedef enum {
|
||||
|
@ -47,15 +34,16 @@ typedef enum {
|
|||
* An enum type representing the various line types in gemtext markup
|
||||
*/
|
||||
typedef enum {
|
||||
normalNode = 0, ///< A normal text line
|
||||
linkNode = 1, ///< A link line
|
||||
listNode = 2, ///< A list member
|
||||
h1Node = 3, ///< An H1 heading
|
||||
h2Node = 4, ///< An H2 heading
|
||||
h3Node = 5, ///< An H3 heading
|
||||
preformattedNode = 6, ///< A preformatted text block
|
||||
quoteNode = 7, ///< A Quote block
|
||||
endOfStream = 8, /**< Notifies the receiver that the stream is over and no
|
||||
unset = 0, ///< The node type has not yet been set
|
||||
normalNode = 1, ///< A normal text line
|
||||
linkNode = 2, ///< A link line
|
||||
listNode = 3, ///< A list member
|
||||
h1Node = 4, ///< An H1 heading
|
||||
h2Node = 5, ///< An H2 heading
|
||||
h3Node = 6, ///< An H3 heading
|
||||
preformattedNode = 7, ///< A preformatted text block
|
||||
quoteNode = 8, ///< A Quote block
|
||||
endOfStream = 9, /**< Notifies the receiver that the stream is over and no
|
||||
more lines are to be expected */
|
||||
} gemtextNodeType;
|
||||
|
||||
|
@ -91,7 +79,7 @@ typedef struct {
|
|||
*/
|
||||
typedef struct {
|
||||
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 */
|
||||
lineBuffer buffer; /**< The internal buffer used to store bytes until
|
||||
a gemtextLine is ready to be sent */
|
||||
|
@ -170,31 +158,31 @@ void gemtextParserDestroy(gemtextParser *parser);
|
|||
* ### Return values
|
||||
* Returns 0 on success. If there is a failure initializing the internal
|
||||
* 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
|
||||
* can block if another thread holds the gemtextQueue's internal mutex.
|
||||
* \param queue The queue which will receive the gemtext line
|
||||
* \param line The gemtextLine to be queued
|
||||
* \param nq The queue which will receive the gemtext line
|
||||
* \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
|
||||
* 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
|
||||
* 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
|
||||
|
@ -258,8 +246,8 @@ void lineBufferReset(lineBuffer *lb);
|
|||
* ### Return values
|
||||
* Returns 0 on success, any other number is an error code
|
||||
* \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
|
||||
|
|
Loading…
Add table
Reference in a new issue