Refactor, getting rid of parsing modes (just use node types instead)

This commit is contained in:
Nathan Fisher 2023-11-04 00:19:11 -04:00
parent e69a1ceaa1
commit ae253cec83
2 changed files with 129 additions and 154 deletions

View file

@ -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,15 +312,15 @@ 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') {
lineBufferReset(&parser->buffer); lineBufferReset(&parser->buffer);
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) {

View file

@ -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