First successful parsing tests
This commit is contained in:
parent
0a1a4e8803
commit
56e4b87fcb
6 changed files with 307 additions and 31 deletions
11
Makefile
11
Makefile
|
@ -43,7 +43,7 @@ srcs += gemtext-parser.c
|
||||||
|
|
||||||
objs = $(srcs:.c=.o)
|
objs = $(srcs:.c=.o)
|
||||||
|
|
||||||
libname = libgemtext-parser
|
libname = libgemtext
|
||||||
staticlib = $(libname).a
|
staticlib = $(libname).a
|
||||||
|
|
||||||
all: static
|
all: static
|
||||||
|
@ -56,7 +56,14 @@ $(staticlib): $(objs)
|
||||||
docs: Doxyfile $(hdrs)
|
docs: Doxyfile $(hdrs)
|
||||||
doxygen
|
doxygen
|
||||||
|
|
||||||
|
test: static
|
||||||
|
$(MAKE) -C test
|
||||||
|
|
||||||
|
testclean:
|
||||||
|
$(MAKE) -C test clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(objs) $(staticlib) doc
|
rm -rf $(objs) $(staticlib) doc
|
||||||
|
$(MAKE) -C test clean
|
||||||
|
|
||||||
.PHONY: all docs clean
|
.PHONY: all docs clean static test testclean
|
||||||
|
|
7
config.mk
Normal file
7
config.mk
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
bindir = $(DESTDIR)$(PREFIX)/bin
|
||||||
|
includedir = $(DESTDIR)$(PREFIX)/include
|
||||||
|
libdir = $(DESTDIR)$(PREFIX)/lib
|
||||||
|
sharedir = $(DESTDIR)$(PREFIX)/share
|
||||||
|
mandir = $(sharedir)/man
|
||||||
|
docdir = $(sharedir)/doc/gemini
|
111
gemtext-parser.c
111
gemtext-parser.c
|
@ -45,6 +45,10 @@ void gemtextParserDeinit(gemtextParser *parser) {
|
||||||
if (parser->linkUrl != NULL) {
|
if (parser->linkUrl != NULL) {
|
||||||
free(parser->linkUrl);
|
free(parser->linkUrl);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gemtextParserDestroy(gemtextParser *parser) {
|
||||||
|
gemtextParserDeinit(parser);
|
||||||
free(parser);
|
free(parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +96,51 @@ gemtextLine* gemtextLineQueuePop(gemtextLineQueue *lq) {
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gemtextLine* gemtextLineQueueTryPop(gemtextLineQueue *lq) {
|
||||||
|
gemtextLine *line;
|
||||||
|
|
||||||
|
if (lq->count == 0)
|
||||||
|
return NULL;
|
||||||
|
pthread_mutex_lock(&lq->mutex);
|
||||||
|
lq->count++;
|
||||||
|
line = lq->head;
|
||||||
|
if (line->lineType == endOfStream)
|
||||||
|
return line;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gemtextLineDeinit(gemtextLine *line) {
|
||||||
|
switch (line->lineType) {
|
||||||
|
case linkLine:
|
||||||
|
if (line->link->display != NULL) {
|
||||||
|
free(line->link->display);
|
||||||
|
}
|
||||||
|
free(line->link->url);
|
||||||
|
free(line->link);
|
||||||
|
break;
|
||||||
|
case preformattedLine:
|
||||||
|
if (line->node->altText != NULL) {
|
||||||
|
free(line->node->altText);
|
||||||
|
}
|
||||||
|
free(line->node->body);
|
||||||
|
free(line->node);
|
||||||
|
break;
|
||||||
|
case endOfStream:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
free(line->str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
|
||||||
int lineBufferExtend(lineBuffer *lb, size_t len) {
|
int lineBufferExtend(lineBuffer *lb, size_t len) {
|
||||||
char *buf = calloc(1, lb->capacity + len);
|
char *buf = calloc(1, lb->capacity + len);
|
||||||
if (buf == NULL) return 2;
|
if (buf == NULL) return 2;
|
||||||
|
@ -264,12 +313,12 @@ int parseLink(gemtextParser *parser, gemtextLineQueue *lq, char c) {
|
||||||
assert(parser->mode == linkMode);
|
assert(parser->mode == linkMode);
|
||||||
switch (parser->state) {
|
switch (parser->state) {
|
||||||
case lineStart:
|
case lineStart:
|
||||||
if (c == ' ' || c == '\t') {
|
if (c != ' ' && c != '\t') {
|
||||||
lineBufferRewind(&parser->buffer);
|
lineBufferReset(&parser->buffer);
|
||||||
|
lineBufferAppendCharUnchecked(&parser->buffer, c);
|
||||||
|
parser->state = normalState;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalLine, lq);
|
ret = gemtextParserSend(parser, normalLine, lq);
|
||||||
} else {
|
|
||||||
parser->state = normalState;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case normalState:
|
case normalState:
|
||||||
|
@ -367,13 +416,15 @@ int parseQuote(gemtextParser *parser, gemtextLineQueue *lq, char c) {
|
||||||
case lineStart:
|
case lineStart:
|
||||||
if (c == '>') {
|
if (c == '>') {
|
||||||
parser->state = trimStart;
|
parser->state = trimStart;
|
||||||
|
lineBufferRewind(&parser->buffer);
|
||||||
} else {
|
} else {
|
||||||
parser->buffer.len--;
|
lineBufferRewind(&parser->buffer);
|
||||||
parser->buffer.cursor--;
|
|
||||||
ret = gemtextParserSend(parser, quoteLine, lq);
|
ret = gemtextParserSend(parser, quoteLine, lq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
lineBufferAppendCharUnchecked(&parser->buffer, c);
|
ret = fseek(parser->stream, -1, SEEK_CUR);
|
||||||
parser->state = normalState;
|
if (ret) return ret;
|
||||||
|
parser->state = lineStart;
|
||||||
|
parser->mode = normalMode;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case normalState:
|
case normalState:
|
||||||
|
@ -405,6 +456,7 @@ int parseGeneric(gemtextParser *parser, gemtextLineQueue *lq, gemtextLineType lt
|
||||||
|
|
||||||
switch (parser->state) {
|
switch (parser->state) {
|
||||||
case lineStart:
|
case lineStart:
|
||||||
|
case trimStart:
|
||||||
if (c == ' ' || c == '\t') {
|
if (c == ' ' || c == '\t') {
|
||||||
// rewind the cursor to trim the line start
|
// rewind the cursor to trim the line start
|
||||||
parser->buffer.len--;
|
parser->buffer.len--;
|
||||||
|
@ -417,7 +469,7 @@ int parseGeneric(gemtextParser *parser, gemtextLineQueue *lq, gemtextLineType lt
|
||||||
break;
|
break;
|
||||||
case normalState:
|
case normalState:
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, h1Line, lq);
|
ret = gemtextParserSend(parser, lt, lq);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -439,11 +491,14 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
parser->mode = quoteMode;
|
parser->mode = quoteMode;
|
||||||
parser->state = lineStart;
|
parser->state = trimStart;
|
||||||
|
lineBufferRewind(&parser->buffer);
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
parser->mode = listMode;
|
parser->mode = listMode;
|
||||||
parser->state = normalState;
|
parser->state = trimStart;
|
||||||
|
lineBufferRewind(&parser->buffer);
|
||||||
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
parser->state = firstHashChar;
|
parser->state = firstHashChar;
|
||||||
break;
|
break;
|
||||||
|
@ -460,7 +515,8 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
|
||||||
break;
|
break;
|
||||||
case firstLinkChar:
|
case firstLinkChar:
|
||||||
if (c == '>') {
|
if (c == '>') {
|
||||||
switchMode(parser, linkMode, c);
|
parser->mode = linkMode;
|
||||||
|
parser->state = lineStart;
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalLine, lq);
|
ret = gemtextParserSend(parser, normalLine, lq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
|
@ -480,7 +536,9 @@ int parseNormal(gemtextParser *parser, gemtextLineQueue *lq, char c) {
|
||||||
break;
|
break;
|
||||||
case secondHashChar:
|
case secondHashChar:
|
||||||
if (c == '#') {
|
if (c == '#') {
|
||||||
parser->state = thirdHashChar;
|
parser->mode = h3Mode;
|
||||||
|
parser->state = trimStart;
|
||||||
|
lineBufferReset(&parser->buffer);
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
ret = gemtextParserSend(parser, normalLine, lq);
|
ret = gemtextParserSend(parser, normalLine, lq);
|
||||||
if (ret) return ret;
|
if (ret) return ret;
|
||||||
|
@ -536,6 +594,33 @@ int parseGemtext(gemtextParser *parser, gemtextLineQueue *lq) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
switch (parser->mode) {
|
||||||
|
case normalMode:
|
||||||
|
ret = gemtextParserSend(parser, normalLine, lq);
|
||||||
|
break;
|
||||||
|
case preformattedMode:
|
||||||
|
ret = gemtextParserSendPreformatted(parser, lq);
|
||||||
|
break;
|
||||||
|
case quoteMode:
|
||||||
|
ret = gemtextParserSend(parser, quoteLine, lq);
|
||||||
|
break;
|
||||||
|
case linkMode:
|
||||||
|
ret = gemtextParserSendLink(parser, lq);
|
||||||
|
break;
|
||||||
|
case h1Mode:
|
||||||
|
ret = gemtextParserSend(parser, h1Line, lq);
|
||||||
|
break;
|
||||||
|
case h2Mode:
|
||||||
|
ret = gemtextParserSend(parser, h2Line, lq);
|
||||||
|
break;
|
||||||
|
case h3Mode:
|
||||||
|
ret = gemtextParserSend(parser, h3Line, lq);
|
||||||
|
break;
|
||||||
|
case listMode:
|
||||||
|
ret = gemtextParserSend(parser, listLine, lq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret) return ret;
|
||||||
line = calloc(1, sizeof(gemtextLine));
|
line = calloc(1, sizeof(gemtextLine));
|
||||||
if (line == NULL) return errno;
|
if (line == NULL) return errno;
|
||||||
line->lineType = endOfStream;
|
line->lineType = endOfStream;
|
||||||
|
|
|
@ -26,21 +26,21 @@ typedef enum {
|
||||||
/** 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 {
|
||||||
lineStart, ///< The cursor is at the start of a new line
|
lineStart = 0, ///< The cursor is at the start of a new line
|
||||||
lineEnd, ///< The cursor is at the end of a line
|
lineEnd = 1, ///< The cursor is at the end of a line
|
||||||
firstLinkChar, ///< The first link character was the previous character
|
firstLinkChar = 2, ///< The first link character was the previous character
|
||||||
linkDisplayStart, /**< The url of a link has been parsed and the cursor is at the
|
linkDisplayStart = 3, /**< The url of a link has been parsed and the cursor is at the
|
||||||
beginning of the display element */
|
beginning of the display element */
|
||||||
linkDisplay, ///< The link's display element is being parsed
|
linkDisplay = 4, ///< The link's display element is being parsed
|
||||||
firstHashChar, ///< A Single '#' character has been encountered
|
firstHashChar = 5, ///< A Single '#' character has been encountered
|
||||||
secondHashChar, ///< Two '#' characters have been encountered sequentially
|
secondHashChar = 6, ///< Two '#' characters have been encountered sequentially
|
||||||
thirdHashChar, ///< Three '#' characters have been encountered sequentially
|
thirdHashChar = 7, ///< Three '#' characters have been encountered sequentially
|
||||||
firstBacktickChar, ///< A single '`' character has been encountered
|
firstBacktickChar = 8, ///< A single '`' character has been encountered
|
||||||
secondBacktickChar, ///< Two '`' characters have been encountered sequentially
|
secondBacktickChar = 9, ///< Two '`' characters have been encountered sequentially
|
||||||
thirdBacktickChar, ///< Three '`' characters have been encountered sequentially
|
thirdBacktickChar = 10, ///< Three '`' characters have been encountered sequentially
|
||||||
preformattedAlt, ///< A Preformatted block's alt text is being parsed
|
preformattedAlt = 11, ///< A Preformatted block's alt text is being parsed
|
||||||
trimStart, ///< The *mode* is known and leading whitespace is being trimmed
|
trimStart = 12, ///< The *mode* is known and leading whitespace is being trimmed
|
||||||
normalState, ///< The *mode* is known and normal parsing is occurring
|
normalState = 13, ///< The *mode* is known and normal parsing is occurring
|
||||||
} gemtextParserState;
|
} gemtextParserState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,11 +152,18 @@ int gemtextParserInit(gemtextParser *parser, FILE *stream);
|
||||||
*/
|
*/
|
||||||
gemtextParser* gemtextParserNew(FILE *stream);
|
gemtextParser* gemtextParserNew(FILE *stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees all memory associated with pointer members of this parser and closes
|
||||||
|
* the internal FILE stream.
|
||||||
|
* \param parser The gemtextParser to be finalized
|
||||||
|
*/
|
||||||
|
void gemtextParserDeinit(gemtextParser *parser);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees all memory associated with this gemtextParser.
|
* Frees all memory associated with this gemtextParser.
|
||||||
* \param parser The gemtextParser to be freed
|
* \param parser The gemtextParser to be freed
|
||||||
*/
|
*/
|
||||||
void gemtextParserDeinit(gemtextParser *parser);
|
void gemtextParserDestroy(gemtextParser *parser);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a gemtextLineQueue with default values.
|
* Initializes a gemtextLineQueue with default values.
|
||||||
|
@ -182,6 +189,19 @@ void gemtextLineQueuePush(gemtextLineQueue *queue, gemtextLine *line);
|
||||||
*/
|
*/
|
||||||
gemtextLine* gemtextLineQueuePop(gemtextLineQueue *lq);
|
gemtextLine* gemtextLineQueuePop(gemtextLineQueue *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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees all memory associated with a gemtextLine structure
|
||||||
|
* \param lq The gemtextLine to be de-allocated
|
||||||
|
*/
|
||||||
|
void gemtextLineDeinit(gemtextLine *line);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends the LineBuffer lb by len bytes.
|
* Extends the LineBuffer lb by len bytes.
|
||||||
* ### Return values
|
* ### Return values
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
# _,.---._ .-._ .--.-. ,--.--------.
|
||||||
|
# _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\
|
||||||
|
# /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./
|
||||||
|
# |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \
|
||||||
|
# |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \
|
||||||
|
# |==|,| | -|==| , '=' |==| - _ | |==|- |
|
||||||
|
# |==| '=' /\==\ - ,_ /|==| /\ , | |==|, |
|
||||||
|
# |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/
|
||||||
|
# `-.`.____.' `--`--'' `--`./ `--` `--`--`
|
||||||
|
# _ __ ,---. .-._ .=-.-. _,.----.
|
||||||
|
# .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \
|
||||||
|
# /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-'
|
||||||
|
# |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | .
|
||||||
|
# |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \
|
||||||
|
# |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , |
|
||||||
|
# |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. /
|
||||||
|
# /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||||
|
# `--`---' `--` `--`./ `--``--`-`
|
||||||
|
#
|
||||||
|
# @(#)Copyright (c) 2023, Nathan D. Fisher.
|
||||||
|
#
|
||||||
|
# This is free software. It comes with NO WARRANTY.
|
||||||
|
# Permission to use, modify and distribute this source code
|
||||||
|
# is granted subject to the following conditions.
|
||||||
|
# 1/ that the above copyright notice and this notice
|
||||||
|
# are preserved in all copies and that due credit be given
|
||||||
|
# to the author.
|
||||||
|
# 2/ that any changes to this code are clearly commented
|
||||||
|
# as such so that the author does not get blamed for bugs
|
||||||
|
# other than his own.
|
||||||
|
#
|
||||||
|
|
||||||
|
include ../config.mk
|
||||||
|
|
||||||
|
CFLAGS += -I../include
|
||||||
|
LDLIBS += ../libgemtext.a
|
||||||
|
LDLIBS += $(LIBS)
|
||||||
|
|
||||||
|
tests += parse-gemtext0
|
||||||
|
|
||||||
|
total != echo $(tests) | wc -w | awk '{ print $$1 }'
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test: $(tests) output
|
||||||
|
@echo -e "\n\t=== \e[0;33mRunning $(total) tests\e[0m ===\n"
|
||||||
|
@idx=1 ; success=0 ; fail=0; skip=0; for t in $(tests) ; \
|
||||||
|
do printf "[%02i/$(total)] %-25s" $${idx} $${t} ; \
|
||||||
|
idx=$$(expr $${idx} + 1) ; \
|
||||||
|
./$${t} ; \
|
||||||
|
retval=$$? ; \
|
||||||
|
if [ $${retval} -eq 0 ] ; \
|
||||||
|
then echo -e '\e[0;32mSuccess\e[0m' ; \
|
||||||
|
success=$$(expr $${success} + 1) ; \
|
||||||
|
elif [ $${retval} -eq 255 ] ; \
|
||||||
|
then echo Skipped ; \
|
||||||
|
skip=$$(expr $${skip} + 1) ; \
|
||||||
|
else echo -e '\e[0;31mFailure\e[0m' ; \
|
||||||
|
fail=$$(expr $${fail} + 1) ; \
|
||||||
|
fi ; done || true ; \
|
||||||
|
if [ $${fail} == 0 ] ; \
|
||||||
|
then echo -e '\nResults: \e[0;32mOk\e[0m.' "$${success} succeeded; $${fail} failed; $${skip} skipped" ; \
|
||||||
|
else echo -e '\nResults: \e[0;31mFAILED\e[0m.' "$${success} succeeded; $${fail} failed; $${skip} skipped" ; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
output:
|
||||||
|
@ [-d $@ ] 2>/dev/null || install -d $@
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(tests) output/*
|
87
test/parse-gemtext0.c
Normal file
87
test/parse-gemtext0.c
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "gemtext-parser.h"
|
||||||
|
|
||||||
|
gemtextLineQueue lq;
|
||||||
|
gemtextParser parser;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int ret = 0;
|
||||||
|
FILE *stream = NULL;
|
||||||
|
gemtextLine *line = NULL;
|
||||||
|
|
||||||
|
stream = fopen("test0.gmi", "r");
|
||||||
|
assert(stream != NULL);
|
||||||
|
ret = gemtextLineQueueInit(&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);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType = h2Line);
|
||||||
|
assert(memcmp(line->str, "Used for testing the parser in normal operation", 47) == 0);
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == normalLine);
|
||||||
|
assert(*line->str == '\n');
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == normalLine);
|
||||||
|
assert(memcmp(line->str, "This is", 7) == 0);
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == normalLine);
|
||||||
|
assert(*line->str == '\n');
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == quoteLine);
|
||||||
|
assert(memcmp(line->str, "Walk before you run.\n- Anonymous", 32) == 0);
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == normalLine);
|
||||||
|
assert(*line->str == '\n');
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == h3Line);
|
||||||
|
assert(memcmp(line->str, "Let's check a list", 18) == 0);
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == listLine);
|
||||||
|
assert(memcmp(line->str, "First item", 9) == 0);
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == listLine);
|
||||||
|
assert(memcmp(line->str, "second item", 11) == 0);
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
line = gemtextLineQueueTryPop(&lq);
|
||||||
|
assert(line->lineType == normalLine);
|
||||||
|
assert(*line->str == '\n');
|
||||||
|
gemtextLineDeinit(line);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
gemtextLineDeinit(lq.head);
|
||||||
|
gemtextParserDeinit(&parser);
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue