Rename several data structures

This commit is contained in:
Nathan Fisher 2023-11-03 18:37:35 -04:00
parent bb0b5a1bcc
commit e69a1ceaa1
4 changed files with 259 additions and 257 deletions

View file

@ -42,8 +42,10 @@ gemtextParser* gemtextParserNew(FILE *stream) {
void gemtextParserDeinit(gemtextParser *parser) {
fclose(parser->stream);
free(parser->buffer.buf);
if (parser->linkUrl != NULL) {
if (parser->mode == linkMode && parser->linkUrl != NULL) {
free(parser->linkUrl);
} else if (parser->mode == preformattedMode && parser->altText != NULL) {
free(parser->altText);
}
}
@ -52,7 +54,7 @@ void gemtextParserDestroy(gemtextParser *parser) {
free(parser);
}
int gemtextLineQueueInit(gemtextLineQueue *queue) {
int gemtextNodeQueueInit(gemtextNodeQueue *queue) {
int ret;
queue->head = NULL;
@ -63,82 +65,82 @@ int gemtextLineQueueInit(gemtextLineQueue *queue) {
return pthread_cond_init(&queue->cond, NULL);
}
void gemtextLineQueuePush(gemtextLineQueue *queue, gemtextLine *line) {
void gemtextNodeQueuePush(gemtextNodeQueue *queue, gemtextNode *node) {
pthread_mutex_lock(&queue->mutex);
if (queue->tail == NULL) {
queue->tail = queue->head = line;
queue->tail = queue->head = node;
} else {
line->next = queue->tail;
queue->tail->prev = line;
queue->tail = line;
node->next = queue->tail;
queue->tail->prev = node;
queue->tail = node;
}
queue->count++;
pthread_mutex_unlock(&queue->mutex);
}
gemtextLine* gemtextLineQueuePop(gemtextLineQueue *lq) {
gemtextLine *line;
gemtextNode* gemtextNodeQueuePop(gemtextNodeQueue *lq) {
gemtextNode *node;
while (lq->count == 0)
pthread_cond_wait(&lq->cond, &lq->mutex);
pthread_mutex_lock(&lq->mutex);
lq->count++;
line = lq->head;
if (line->lineType == endOfStream)
return line;
node = lq->head;
if (node->nodeType == endOfStream)
return node;
if (lq->tail == lq->head) {
lq->tail = lq->head = NULL;
} else {
lq->head = lq->head->prev;
}
pthread_mutex_unlock(&lq->mutex);
line->prev = line->next = NULL;
return line;
node->prev = node->next = NULL;
return node;
}
gemtextLine* gemtextLineQueueTryPop(gemtextLineQueue *lq) {
gemtextLine *line;
gemtextNode* gemtextNodeQueueTryPop(gemtextNodeQueue *lq) {
gemtextNode *node;
if (lq->count == 0)
return NULL;
pthread_mutex_lock(&lq->mutex);
lq->count++;
line = lq->head;
if (line->lineType == endOfStream)
return line;
node = lq->head;
if (node->nodeType == endOfStream)
return node;
if (lq->tail == lq->head) {
lq->tail = lq->head = NULL;
} else {
lq->head = lq->head->prev;
}
pthread_mutex_unlock(&lq->mutex);
line->prev = line->next = NULL;
return line;
node->prev = node->next = NULL;
return node;
}
void gemtextLineDeinit(gemtextLine *line) {
switch (line->lineType) {
case linkLine:
if (line->link->display != NULL) {
free(line->link->display);
void gemtextNodeDeinit(gemtextNode *node) {
switch (node->nodeType) {
case linkNode:
if (node->link->display != NULL) {
free(node->link->display);
}
free(line->link->url);
free(line->link);
free(node->link->url);
free(node->link);
break;
case preformattedLine:
if (line->node->altText != NULL) {
free(line->node->altText);
case preformattedNode:
if (node->block->altText != NULL) {
free(node->block->altText);
}
free(line->node->body);
free(line->node);
free(node->block->body);
free(node->block);
break;
case endOfStream:
break;
default:
free(line->str);
free(node->str);
break;
}
free(line);
free(node);
}
int lineBufferExtend(lineBuffer *lb, size_t len) {
@ -201,43 +203,43 @@ void lineBufferReset(lineBuffer *lb) {
lb->cursor = lb->buf;
}
int gemtextParserSendPreformatted(gemtextParser *parser, gemtextLineQueue *lq) {
preformattedNode *node;
gemtextLine *line;
char *buf;
int gemtextParserSendPreformatted(gemtextParser *parser, gemtextNodeQueue *lq) {
preformattedBlock *block;
gemtextNode *node;
char *buf;
line = calloc(1, sizeof(gemtextLine));
if (line == NULL) return errno;
line->lineType = preformattedLine;
node = calloc(1, sizeof(preformattedNode));
node = calloc(1, sizeof(gemtextNode));
if (node == NULL) return errno;
node->nodeType = preformattedNode;
block = calloc(1, sizeof(preformattedBlock));
if (block == NULL) return errno;
// back up our cursor four spaces and insert a lf char
parser->buffer.cursor -= 4;
parser->buffer.len -= 4;
lineBufferAppendCharUnchecked(&parser->buffer, '\n');
buf = strndup(parser->buffer.buf, parser->buffer.len);
if (buf == NULL) return errno;
node->altText = parser->altText;
block->altText = parser->altText;
parser->altText = NULL;
node->body = buf;
line->node = node;
gemtextLineQueuePush(lq, line);
block->body = buf;
node->block = block;
gemtextNodeQueuePush(lq, node);
lineBufferReset(&parser->buffer);
parser->state = lineStart;
parser->mode = normalMode;
return 0;
}
int gemtextParserSendLink(gemtextParser *parser, gemtextLineQueue *lq) {
int gemtextParserSendLink(gemtextParser *parser, gemtextNodeQueue *lq) {
gemtextLink *link;
gemtextLine *line;
gemtextNode *node;
char *url = NULL, *display = NULL;
link = calloc(1, sizeof(gemtextLink));
if (link == NULL) return errno;
link->display = link->url = NULL;
line = calloc(1, sizeof(gemtextLine));
if (line == NULL) {
node = calloc(1, sizeof(gemtextNode));
if (node == NULL) {
free(link);
return errno;
}
@ -248,15 +250,15 @@ int gemtextParserSendLink(gemtextParser *parser, gemtextLineQueue *lq) {
display = strndup(parser->buffer.buf, parser->buffer.len);
if (display == NULL) {
free(link);
free(line);
free(node);
return errno;
}
}
link->url = url;
link->display = display;
line->lineType = linkLine;
line->link = link;
gemtextLineQueuePush(lq, line);
node->nodeType = linkNode;
node->link = link;
gemtextNodeQueuePush(lq, node);
lineBufferReset(&parser->buffer);
parser->state = lineStart;
parser->mode = normalMode;
@ -264,17 +266,17 @@ int gemtextParserSendLink(gemtextParser *parser, gemtextLineQueue *lq) {
return 0;
}
int gemtextParserSend(gemtextParser *parser, gemtextLineType lt, gemtextLineQueue *lq) {
gemtextLine *line;
int gemtextParserSend(gemtextParser *parser, gemtextNodeType lt, gemtextNodeQueue *lq) {
gemtextNode *node;
char *buf;
line = calloc(1, sizeof(gemtextLine));
if (line == NULL) return errno;
line->lineType = lt;
node = calloc(1, sizeof(gemtextNode));
if (node == NULL) return errno;
node->nodeType = lt;
buf = strndup(parser->buffer.buf, parser->buffer.len);
if (buf == NULL) return errno;
line->str = buf;
gemtextLineQueuePush(lq, line);
node->str = buf;
gemtextNodeQueuePush(lq, node);
lineBufferReset(&parser->buffer);
parser->state = lineStart;
parser->mode = normalMode;
@ -306,7 +308,7 @@ void enterPreformattedMode(gemtextParser *parser) {
lineBufferReset(&parser->buffer);
}
int parseLink(gemtextParser *parser, gemtextLineQueue *lq, char c) {
int parseLink(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
int ret = 0;
char *buf = NULL;
@ -318,7 +320,7 @@ int parseLink(gemtextParser *parser, gemtextLineQueue *lq, char c) {
lineBufferAppendCharUnchecked(&parser->buffer, c);
parser->state = normalState;
} else if (c == '\n') {
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
}
break;
case normalState:
@ -355,7 +357,7 @@ int parseLink(gemtextParser *parser, gemtextLineQueue *lq, char c) {
return ret;
}
int parsePreformatted(gemtextParser *parser, gemtextLineQueue *lq, char c) {
int parsePreformatted(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
char *buf = NULL;
assert(parser->mode == preformattedMode);
@ -425,7 +427,7 @@ int parsePreformatted(gemtextParser *parser, gemtextLineQueue *lq, char c) {
return 0;
}
int parseQuote(gemtextParser *parser, gemtextLineQueue *lq, char c) {
int parseQuote(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
int ret = 0;
switch (parser->state) {
@ -435,7 +437,7 @@ int parseQuote(gemtextParser *parser, gemtextLineQueue *lq, char c) {
lineBufferRewind(&parser->buffer);
} else {
lineBufferRewind(&parser->buffer);
ret = gemtextParserSend(parser, quoteLine, lq);
ret = gemtextParserSend(parser, quoteNode, lq);
if (ret) return ret;
ret = fseek(parser->stream, -1, SEEK_CUR);
if (ret) return ret;
@ -454,7 +456,7 @@ int parseQuote(gemtextParser *parser, gemtextLineQueue *lq, char c) {
parser->buffer.len--;
parser->buffer.cursor--;
} else if (c == '\n') {
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
} else {
parser->state = normalState;
}
@ -467,7 +469,7 @@ int parseQuote(gemtextParser *parser, gemtextLineQueue *lq, char c) {
return ret;
}
int parseGeneric(gemtextParser *parser, gemtextLineQueue *lq, gemtextLineType lt, char c) {
int parseGeneric(gemtextParser *parser, gemtextNodeQueue *lq, gemtextNodeType lt, char c) {
int ret = 0;
switch (parser->state) {
@ -496,7 +498,7 @@ int parseGeneric(gemtextParser *parser, gemtextLineQueue *lq, gemtextLineType lt
return ret;
}
int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
int parseNormal(gemtextParser *parser, gemtextNodeQueue *lq, char c) {
int ret;
switch (parser->state) {
@ -522,7 +524,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
parser->state = firstBacktickChar;
break;
case '\n':
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
if (ret) return ret;
break;
default:
@ -534,7 +536,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
parser->mode = linkMode;
parser->state = lineStart;
} else if (c == '\n') {
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
if (ret) return ret;
} else {
parser->state = normalState;
@ -544,7 +546,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
if (c == '#') {
parser->state = secondHashChar;
} else if (c == '\n') {
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
if (ret) return ret;
} else {
switchMode(parser, h1Mode, c);
@ -556,7 +558,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
parser->state = trimStart;
lineBufferReset(&parser->buffer);
} else if (c == '\n') {
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
if (ret) return ret;
} else {
switchMode(parser, h2Mode, c);
@ -564,7 +566,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
break;
case thirdHashChar:
if (c == '\n') {
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
if (ret) return ret;
} else {
switchMode(parser, h3Mode, c);
@ -572,7 +574,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
break;
case firstBacktickChar:
if (c == '\n') {
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
if (ret) return ret;
} else if (c == '`') {
parser->state = secondBacktickChar;
@ -585,7 +587,7 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
if (c == '`') {
enterPreformattedMode(parser);
} else if (c == '\n') {
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
if (ret) return ret;
} else {
parser->state = normalState;
@ -598,10 +600,10 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
return 0;
}
int parseGemtext(gemtextParser *parser, gemtextLineQueue *lq) {
int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq) {
char c;
int ret;
gemtextLine *line;
gemtextNode *node;
for (;;) {
ret = fread(&c, 1, 1, parser->stream);
@ -615,38 +617,38 @@ int parseGemtext(gemtextParser *parser, gemtextLineQueue *lq) {
if (parser->state != lineStart && parser->state != trimStart) {
switch (parser->mode) {
case normalMode:
ret = gemtextParserSend(parser, normalLine, lq);
ret = gemtextParserSend(parser, normalNode, lq);
break;
case preformattedMode:
ret = gemtextParserSendPreformatted(parser, lq);
break;
case quoteMode:
ret = gemtextParserSend(parser, quoteLine, lq);
ret = gemtextParserSend(parser, quoteNode, lq);
break;
case linkMode:
ret = gemtextParserSendLink(parser, lq);
break;
case h1Mode:
ret = gemtextParserSend(parser, h1Line, lq);
ret = gemtextParserSend(parser, h1Node, lq);
break;
case h2Mode:
ret = gemtextParserSend(parser, h2Line, lq);
ret = gemtextParserSend(parser, h2Node, lq);
break;
case h3Mode:
ret = gemtextParserSend(parser, h3Line, lq);
ret = gemtextParserSend(parser, h3Node, lq);
break;
case listMode:
ret = gemtextParserSend(parser, listLine, lq);
ret = gemtextParserSend(parser, listNode, lq);
break;
}
if (ret) return ret;
}
line = calloc(1, sizeof(gemtextLine));
if (line == NULL) return errno;
line->lineType = endOfStream;
line->prev = line->next = NULL;
line->str = NULL;
gemtextLineQueuePush(lq, line);
node = calloc(1, sizeof(gemtextNode));
if (node == NULL) return errno;
node->nodeType = endOfStream;
node->prev = node->next = NULL;
node->str = NULL;
gemtextNodeQueuePush(lq, node);
break;
}
switch (parser->mode) {
@ -663,16 +665,16 @@ int parseGemtext(gemtextParser *parser, gemtextLineQueue *lq) {
ret = parseLink(parser, lq, c);
break;
case h1Mode:
ret = parseGeneric(parser, lq, h1Line, c);
ret = parseGeneric(parser, lq, h1Node, c);
break;
case h2Mode:
ret = parseGeneric(parser, lq, h2Line, c);
ret = parseGeneric(parser, lq, h2Node, c);
break;
case h3Mode:
ret = parseGeneric(parser, lq, h3Line, c);
ret = parseGeneric(parser, lq, h3Node, c);
break;
case listMode:
ret = parseGeneric(parser, lq, listLine, c);
ret = parseGeneric(parser, lq, listNode, c);
break;
}
if (ret) {

View file

@ -47,17 +47,17 @@ typedef enum {
* An enum type representing the various line types in gemtext markup
*/
typedef enum {
normalLine = 0, ///< A normal text line
linkLine = 1, ///< A link line
listLine = 2, ///< A list member
h1Line = 3, ///< An H1 heading
h2Line = 4, ///< An H2 heading
h3Line = 5, ///< An H3 heading
preformattedLine = 6, ///< A preformatted text block
quoteLine = 7, ///< A Quote block
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
more lines are to be expected */
} gemtextLineType;
} gemtextNodeType;
/**
* A growable byte array
@ -84,7 +84,7 @@ typedef struct {
char *altText; /**< Some descriptive text to be read by screen readers if
this is ascii art */
char *body; ///< The body of the preformatted block
} preformattedNode;
} preformattedBlock;
/**
* The main Gemtext parser
@ -101,19 +101,19 @@ typedef struct {
};
} gemtextParser;
struct _gemtextLine {
struct _gemtextLine *next; ///< The next line in the queue
struct _gemtextLine *prev; ///< The previous line in the queue
gemtextLineType lineType; ///< Identifies the type of line
struct _gemtextNode {
struct _gemtextNode *next; ///< The next line in the queue
struct _gemtextNode *prev; ///< The previous line in the queue
gemtextNodeType nodeType; ///< Identifies the type of line
union {
char *str; ///< The text body of most line types
gemtextLink *link; ///< The body of a link line
preformattedNode *node; ///< The body and alt text of a preformatted block
char *str; ///< The text body of most line types
gemtextLink *link; ///< The body of a link line
preformattedBlock *block; ///< The body and alt text of a preformatted block
};
};
/** A Gemtext node */
typedef struct _gemtextLine gemtextLine;
typedef struct _gemtextNode gemtextNode;
/**
* A fifo queue used to pass gemtextLine elements from the worker thread to the
@ -123,9 +123,9 @@ typedef struct {
pthread_cond_t cond; ///< Signals the rendering thread to wait for an incoming line
size_t count; ///< The number of elements currently in the queue
pthread_mutex_t mutex; ///< The lock ensuring exclusive access
gemtextLine *head; ///< The oldest line in the queue
gemtextLine *tail; ///< The newest line in the queue
} gemtextLineQueue;
gemtextNode *head; ///< The oldest line in the queue
gemtextNode *tail; ///< The newest line in the queue
} gemtextNodeQueue;
/**
* Initialize a lineBuffer struct to it's default values.
@ -166,13 +166,13 @@ void gemtextParserDeinit(gemtextParser *parser);
void gemtextParserDestroy(gemtextParser *parser);
/**
* Initializes a gemtextLineQueue with default values.
* Initializes a gemtextNodeQueue with default values.
* ### 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 gemtextLineQueue
* \param queue The already allocated gemtextNodeQueue
*/
int gemtextLineQueueInit(gemtextLineQueue *queue);
int gemtextNodeQueueInit(gemtextNodeQueue *queue);
/**
* Pushes a gemtextLine into the queue. This function will not fail, but
@ -180,27 +180,27 @@ int gemtextLineQueueInit(gemtextLineQueue *queue);
* \param queue The queue which will receive the gemtext line
* \param line The gemtextLine to be queued
*/
void gemtextLineQueuePush(gemtextLineQueue *queue, gemtextLine *line);
void gemtextNodeQueuePush(gemtextNodeQueue *queue, 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
*/
gemtextLine* gemtextLineQueuePop(gemtextLineQueue *lq);
gemtextNode* gemtextNodeQueuePop(gemtextNodeQueue *lq);
/**
* 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
*/
gemtextLine* gemtextLineQueueTryPop(gemtextLineQueue *lq);
gemtextNode* gemtextNodeQueueTryPop(gemtextNodeQueue *lq);
/**
* Frees all memory associated with a gemtextLine structure
* \param lq The gemtextLine to be de-allocated
*/
void gemtextLineDeinit(gemtextLine *line);
void gemtextNodeDeinit(gemtextNode *node);
/**
* Extends the LineBuffer lb by len bytes.
@ -254,12 +254,12 @@ void lineBufferRewind(lineBuffer *lb);
void lineBufferReset(lineBuffer *lb);
/**
* Parses gemtext into a series of nodes to be places in the gemtextLineQueue lq.
* Parses gemtext into a series of nodes to be places in the gemtextNodeQueue lq.
* ### 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 gemtextLineQueue which will receive gemtextLine elements as they are parsed
* \param lq A gemtextNodeQueue which will receive gemtextLine elements as they are parsed
*/
int parseGemtext(gemtextParser *parser, gemtextLineQueue *lq);
int parseGemtext(gemtextParser *parser, gemtextNodeQueue *lq);
#endif

View file

@ -4,98 +4,98 @@
#include <string.h>
#include "gemtext-parser.h"
gemtextLineQueue lq;
gemtextNodeQueue lq;
gemtextParser parser;
int main() {
int ret = 0;
FILE *stream = NULL;
gemtextLine *line = NULL;
gemtextNode *node = NULL;
stream = fopen("test0.gmi", "r");
assert(stream != NULL);
ret = gemtextLineQueueInit(&lq);
ret = gemtextNodeQueueInit(&lq);
assert(ret == 0);
ret = gemtextParserInit(&parser, stream);
assert(ret == 0);
ret = parseGemtext(&parser, &lq);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType = h1Line);
assert(memcmp(line->str, "A Test Gemtext file", 19) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == h1Node);
assert(memcmp(node->str, "A Test Gemtext file", 19) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType = h2Line);
assert(memcmp(line->str, "Used for testing the parser in normal operation", 47) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == h2Node);
assert(memcmp(node->str, "Used for testing the parser in normal operation", 47) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(*line->str == '\n');
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(*node->str == '\n');
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(memcmp(line->str, "This is", 7) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(memcmp(node->str, "This is", 7) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(*line->str == '\n');
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(*node->str == '\n');
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == quoteLine);
assert(memcmp(line->str, "Walk before you run.\n- Anonymous", 32) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == quoteNode);
assert(memcmp(node->str, "Walk before you run.\n- Anonymous", 32) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(*line->str == '\n');
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(*node->str == '\n');
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == h3Line);
assert(memcmp(line->str, "Let's check a list", 18) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == h3Node);
assert(memcmp(node->str, "Let's check a list", 18) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == listLine);
assert(memcmp(line->str, "First item", 9) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == listNode);
assert(memcmp(node->str, "First item", 9) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == listLine);
assert(memcmp(line->str, "second item", 11) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == listNode);
assert(memcmp(node->str, "second item", 11) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(*line->str == '\n');
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(*node->str == '\n');
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == linkLine);
assert(memcmp(line->link->url, "gemini://example.org/test.gmi", 29) == 0);
assert(memcmp(line->link->display, "This is a link", 14) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == linkNode);
assert(memcmp(node->link->url, "gemini://example.org/test.gmi", 29) == 0);
assert(memcmp(node->link->display, "This is a link", 14) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(*line->str == '\n');
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(*node->str == '\n');
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == preformattedLine);
assert(memcmp(line->node->altText, "Test preformatted block", 23) == 0);
assert(memcmp(line->node->body, "This is a preformatted block", 28) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == preformattedNode);
assert(memcmp(node->block->altText, "Test preformatted block", 23) == 0);
assert(memcmp(node->block->body, "This is a preformatted block", 28) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line != NULL);
assert(line->lineType == endOfStream);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node != NULL);
assert(node->nodeType == endOfStream);
gemtextNodeDeinit(node);
gemtextParserDeinit(&parser);
return ret;

View file

@ -4,7 +4,7 @@
#include <string.h>
#include "gemtext-parser.h"
gemtextLineQueue lq;
gemtextNodeQueue lq;
gemtextParser parser;
char * preBlk =
@ -14,93 +14,93 @@ char * preBlk =
int main() {
int ret = 0;
FILE *stream = NULL;
gemtextLine *line = NULL;
gemtextNode *node = NULL;
stream = fopen("test1.gmi", "r");
assert(stream != NULL);
ret = gemtextLineQueueInit(&lq);
ret = gemtextNodeQueueInit(&lq);
assert(ret == 0);
ret = gemtextParserInit(&parser, stream);
assert(ret == 0);
ret = parseGemtext(&parser, &lq);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType = h1Line);
assert(memcmp(line->str, "A more complicated example", 26) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType = h2Node);
assert(memcmp(node->str, "A more complicated example", 26) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == listLine);
assert(memcmp(line->str, "list item with no leading space", 30) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == listNode);
assert(memcmp(node->str, "list item with no leading space", 30) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == listLine);
assert(memcmp(line->str, "list item with several leading spaces", 37) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == listNode);
assert(memcmp(node->str, "list item with several leading spaces", 37) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == h2Line);
assert(memcmp(line->str, "After this H2, an empty quote", 29) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == h2Node);
assert(memcmp(node->str, "After this H2, an empty quote", 29) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(memcmp(line->str, "\n", 1) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(memcmp(node->str, "\n", 1) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == h3Line);
assert(memcmp(line->str, "Now we'll", 9) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == h3Node);
assert(memcmp(node->str, "Now we'll", 9) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(memcmp(line->str, "``", 2) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(memcmp(node->str, "``", 2) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(memcmp(line->str, "=", 1) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(memcmp(node->str, "=", 1) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(memcmp(line->str, "And maybe", 9) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(memcmp(node->str, "And maybe", 9) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == linkLine);
assert(memcmp(line->link->url, "spartan://example.org", 21) == 0);
assert(line->link->display == NULL);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == linkNode);
assert(memcmp(node->link->url, "spartan://example.org", 21) == 0);
assert(node->link->display == NULL);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(memcmp(line->str, "Let's enter", 11) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(memcmp(node->str, "Let's enter", 11) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == preformattedLine);
assert(line->node->altText == NULL);
assert(memcmp(line->node->body, preBlk, 50) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == preformattedNode);
assert(node->block->altText == NULL);
assert(memcmp(node->block->body, preBlk, 50) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == normalLine);
assert(memcmp(line->str, "And we'll finish", 16) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == normalNode);
assert(memcmp(node->str, "And we'll finish", 16) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line->lineType == linkLine);
assert(line->link->display == NULL);
assert(memcmp(line->link->url, "finger://example.org/joe", 24) == 0);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node->nodeType == linkNode);
assert(node->link->display == NULL);
assert(memcmp(node->link->url, "finger://example.org/joe", 24) == 0);
gemtextNodeDeinit(node);
line = gemtextLineQueueTryPop(&lq);
assert(line != NULL);
assert(line->lineType == endOfStream);
gemtextLineDeinit(line);
node = gemtextNodeQueueTryPop(&lq);
assert(node != NULL);
assert(node->nodeType == endOfStream);
gemtextNodeDeinit(node);
return ret;
}