about summary refs log tree commit diff stats
path: root/decode.c
diff options
context:
space:
mode:
authorAli Fardan <raiz@stellarbound.info>2020-10-22 13:31:28 +0300
committerAli Fardan <raiz@stellarbound.info>2020-10-22 13:31:28 +0300
commitde22e0ae21c46fc9eb1cc6717832bfb5fa0600e1 (patch)
tree1db412a2eb4974aeda045947db284dd806f021b1 /decode.c
parenta77f42d3c2d19dfa13e0f98935de8f9b59502a6a (diff)
downloadlibgemtext-de22e0ae21c46fc9eb1cc6717832bfb5fa0600e1.tar.gz
- implement the rest of decode.c functions: gemtext_decode_fd() and gemtext_decode_file()
- introduce gemtext_encode() with helper functions gemtext_encode_fd() and gemtext_encode_file()
- simplify handling of unordered lists in decode.c
- add test.c rule to makefile
Diffstat (limited to 'decode.c')
-rw-r--r--decode.c115
1 files changed, 69 insertions, 46 deletions
diff --git a/decode.c b/decode.c
index 227d389..114ed91 100644
--- a/decode.c
+++ b/decode.c
@@ -1,5 +1,10 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "gemtext.h"
 
@@ -311,29 +316,6 @@ _case_pre(char **text)
 	return (struct gemtext *)ret;
 }
 
-static int
-_gemtext_ul_append(struct gemtext_ul *ul, char *text, int len)
-{
-	int nitems;
-	char **items;
-
-	items = ul->items;
-	nitems = ul->nitems;
-
-	items = realloc(items, sizeof(*items)*(nitems+1));
-	if (items == NULL)
-		return -1;
-	ul->items = items;
-
-	nitems++;
-	items[nitems-1] = strndup(text, len);
-	if (items[nitems-1] == NULL)
-		return -1;
-	ul->nitems = nitems;
-
-	return 0;
-}
-
 static struct gemtext *
 _case_ul(char **text)
 {
@@ -343,38 +325,34 @@ _case_ul(char **text)
 
 	ptr = *text;
 
-	/* should always be true, but just in case */
-	if (*ptr != '*')
-		return NULL;
-
 	ret = malloc(sizeof(*ret));
 	if (ret == NULL)
 		return NULL;
 	memset(ret, 0, sizeof(*ret));
 	ret->type = GEMTEXT_UL;
 
-	while (*ptr != '\0' && *ptr == '*') {
-		if (*(ptr+1) == ' ')
-			ptr += 2;
-		else
-			ptr++;
+	if (*(ptr+1) == ' ')
+		ptr += 2;
+	else
+		ptr++;
 
-		cpy = ptr;
-		while (*ptr != '\0' && *ptr != '\r' && *ptr != '\n')
-			ptr++;
-		if (_gemtext_ul_append(ret, cpy, ptr-cpy) == -1) {
-			gemtext_free((struct gemtext *)ret);
-			return NULL;
-		}
+	cpy = ptr;
+	while (*ptr != '\0' && *ptr != '\r' && *ptr != '\n')
+		ptr++;
 
-		if (*ptr == '\r') {
-			if (strncmp(ptr, "\r\n", 2) == 0)
-				ptr += 2;
-			else
-				ptr++;
-		} else if (*ptr == '\n') {
+	ret->text = strndup(cpy, ptr-cpy);
+	if (ret->text == NULL) {
+		gemtext_free((struct gemtext *)ret);
+		return NULL;
+	}
+
+	if (*ptr == '\r') {
+		if (strncmp(ptr, "\r\n", 2) == 0)
+			ptr += 2;
+		else
 			ptr++;
-		}
+	} else if (*ptr == '\n') {
+		ptr++;
 	}
 
 	*text = ptr;
@@ -541,3 +519,48 @@ gemtext_decode(char *text)
 
 	return ret;
 }
+
+struct gemtext **
+gemtext_decode_fd(int fd)
+{
+	struct gemtext **ret;
+	struct stat fst;
+	char *tbuf;
+
+	if (fstat(fd, &fst) == -1)
+		return NULL;
+	tbuf = malloc(fst.st_size+1);
+	if (tbuf == NULL)
+		return NULL;
+
+	if (read(fd, tbuf, fst.st_size) == -1) {
+		free(tbuf);
+		return NULL;
+	}
+	tbuf[fst.st_size-1] = '\0';
+
+	ret = gemtext_decode(tbuf);
+	free(tbuf);
+	if (ret == NULL)
+		return NULL;
+
+	return ret;
+}
+
+struct gemtext **
+gemtext_decode_file(const char *path)
+{
+	struct gemtext **ret;
+	int fd;
+
+	fd = open(path, O_RDONLY);
+	if (fd == -1)
+		return NULL;
+
+	ret = gemtext_decode_fd(fd);
+	close(fd);
+	if (ret == NULL)
+		return NULL;
+
+	return ret;
+}