aboutsummaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorMarvin Borner2021-05-23 14:30:07 +0200
committerMarvin Borner2021-05-23 14:34:52 +0200
commit33fd97e19a12535c02b1cf6804cb854a279e040c (patch)
tree0ea00a9b60b35e42830eb3b13887fea2d356d655 /libs
parent0bf64a113f3d3baa110b362fd6a215ef29182671 (diff)
Cleanup, linting, formatting
Diffstat (limited to 'libs')
-rw-r--r--libs/libc/print.c2
-rw-r--r--libs/libgui/png.c1
-rw-r--r--libs/libnet/Makefile17
-rw-r--r--libs/libnet/dns.c116
-rw-r--r--libs/libnet/dns.h21
-rw-r--r--libs/libnet/http.c134
-rw-r--r--libs/libnet/http.h82
-rw-r--r--libs/libnet/ip.c48
-rw-r--r--libs/libnet/ip.h12
-rw-r--r--libs/libnet/net.h73
-rw-r--r--libs/libtxt/xml.c514
-rw-r--r--libs/libtxt/xml.h51
12 files changed, 1 insertions, 1070 deletions
diff --git a/libs/libc/print.c b/libs/libc/print.c
index 46483cd..2eb119a 100644
--- a/libs/libc/print.c
+++ b/libs/libc/print.c
@@ -188,9 +188,9 @@ int print(const char *str)
// The kernel prints everything into the serial console
#include <drivers/cpu.h>
+#include <drivers/serial.h>
#include <mm.h>
#include <proc.h>
-#include <drivers/serial.h>
static void print_kernel(const char *str)
{
diff --git a/libs/libgui/png.c b/libs/libgui/png.c
index c405c3c..d2053ca 100644
--- a/libs/libgui/png.c
+++ b/libs/libgui/png.c
@@ -408,7 +408,6 @@ u32 png_load_file(u8 **out, u32 *outsize, const char *filename)
/*write given buffer to the file, overwriting the file, it doesn't append to it.*/
u32 png_save_file(const u8 *buffer, u32 buffersize, const char *filename)
{
- err(1, "Not implemented!\n");
if (write(filename, buffer, 0, buffersize) <= 0)
return 79;
return 0;
diff --git a/libs/libnet/Makefile b/libs/libnet/Makefile
deleted file mode 100644
index 53cb7a9..0000000
--- a/libs/libnet/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# MIT License, Copyright (c) 2020 Marvin Borner
-
-COBJS = dns.o http.o ip.o
-
-CFLAGS = $(CFLAGS_DEFAULT) -I$(LIBS) -I$(LIBS)/libc/inc/ -pie -fPIE -fPIC -DUSER
-
-all: libtxt
-
-%.o: %.c
- @$(CC) -c $(CFLAGS) $< -o $@
-
-libtxt: $(COBJS)
- @mkdir -p $(BUILD)
- @$(AR) rcs $(BUILD)/libnet.a $+
-
-clean:
- @find . -name "*.o" -type f -delete
diff --git a/libs/libnet/dns.c b/libs/libnet/dns.c
deleted file mode 100644
index e179bd6..0000000
--- a/libs/libnet/dns.c
+++ /dev/null
@@ -1,116 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-// TODO: Less magic, auto xld splitting
-// TODO: DNS cache
-
-#include <def.h>
-#include <libnet/net.h>
-#include <libnet/socket.h>
-#include <mem.h>
-#include <print.h>
-#include <random.h>
-#include <str.h>
-
-static u32 dns_ip_addr = ip(1, 1, 1, 1);
-
-struct dns_packet {
- u16 qid;
- u16 flags;
- u16 questions;
- u16 answers;
- u16 authorities;
- u16 additional;
- u8 data[];
-} PACKED;
-
-static u32 part_count(const char *name)
-{
- u32 cnt = 0;
- for (u32 i = 0; i < strlen(name); i++) {
- if (name[i] == '.')
- cnt++;
- }
- return cnt + 1;
-}
-
-static u32 part_len(const char *name, u32 index)
-{
- const char *data = name;
-
- u32 cnt = 0;
- for (u32 i = 0; i < strlen(name); i++) {
- if (cnt == index) {
- data += i;
- break;
- }
-
- if (name[i] == '.')
- cnt++;
- }
-
- for (cnt = 0; cnt < strlen(data); cnt++) {
- if (data[cnt] == '.' || data[cnt] == '\0')
- break;
- }
-
- return cnt;
-}
-
-static void dns_make_packet(struct dns_packet *packet, const char *name)
-{
- packet->qid = htons(rand());
- packet->flags = htons(0x0100); // Standard query
- packet->questions = htons(1);
- packet->answers = htons(0);
- packet->authorities = htons(0);
- packet->additional = htons(0);
-
- u8 *data = packet->data;
- u32 cnt = 0;
- for (u32 i = 0; i < part_count(name) * 2; i += 2) {
- data[cnt] = part_len(name, i / 2);
- memcpy(&data[cnt + 1], &name[cnt], data[cnt]);
- cnt += data[cnt] + 1;
- }
-
- packet->data[cnt + 0] = 0x00; // Name end
- packet->data[cnt + 2] = 0x01; // A
- packet->data[cnt + 4] = 0x01; // IN
-}
-
-static u32 dns_handle_packet(struct dns_packet *packet)
-{
- u16 flags = htons(packet->flags);
- u8 reply_code = flags & 0xf;
- if (reply_code != DNS_NOERROR) {
- printf("DNS error: %d\n", reply_code);
- return 0;
- }
-
- u8 *start = &packet->data[1] + strlen((char *)&packet->data[1]);
- printf("TTL of %s: %ds\n", &packet->data[1], (u32)start[14]);
- u8 *ip = &start[17];
- printf("IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
- return ip(ip[0], ip[1], ip[2], ip[3]);
-}
-
-u32 dns_request(const char *name)
-{
- struct socket *socket = net_open(S_UDP);
- if (!socket || !net_connect(socket, dns_ip_addr, 53, NET_TIMEOUT) || part_count(name) == 1)
- return 0;
-
- u32 length = sizeof(struct dns_packet) + strlen(name) + part_count(name) + 4;
- struct dns_packet *packet = malloc(length);
- memset(packet, 0, length);
- dns_make_packet(packet, name);
- net_send(socket, packet, length);
- free(packet);
-
- u8 buf[1024] = { 0 };
- int l = net_receive(socket, buf, 1024, NET_TIMEOUT);
- net_close(socket);
- if (l > 0)
- return dns_handle_packet((void *)buf);
- else
- return 0;
-}
diff --git a/libs/libnet/dns.h b/libs/libnet/dns.h
deleted file mode 100644
index d6673e6..0000000
--- a/libs/libnet/dns.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef DNS_H
-#define DNS_H
-
-#include <def.h>
-
-#define DNS_NOERROR 0
-#define DNS_FORMERR 1
-#define DNS_SERVFAIL 2
-#define DNS_NXDOMAIN 3
-#define DNS_NOTIMP 4
-#define DNS_REFUSED 5
-#define DNS_YXDOMAIN 6
-#define DNS_XRRSET 7
-#define DNS_NOTAUTH 8
-#define DNS_NOTZONE 9
-
-u32 dns_request(const char *name);
-
-#endif
diff --git a/libs/libnet/http.c b/libs/libnet/http.c
deleted file mode 100644
index 808d4c2..0000000
--- a/libs/libnet/http.c
+++ /dev/null
@@ -1,134 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#include <assert.h>
-#include <conv.h>
-#include <def.h>
-#include <libnet/http.h>
-#include <libnet/net.h>
-#include <libnet/socket.h>
-#include <mem.h>
-#include <print.h>
-#include <str.h>
-
-char *http_data(char *r)
-{
- char *h = NULL;
- for (u32 i = 0; i < strlen(r); ++i) {
- if (r[i] == '\r' && r[i + 1] == '\n' && r[i + 2] == '\r' && r[i + 3] == '\n') {
- h = &r[i + 4];
- break;
- }
- }
- return h;
-}
-
-char *http_header_key(char *r, const char *key)
-{
- char *res = NULL;
- for (char *p = r; *p; p++) {
- /* printf("'%c%c%c' vs '%c%c%c'\n", p[0], p[1], p[2], key[0], key[1], key[2]); */
- if (strlen(p) >= strlen(key) && !memcmp(p, key, strlen(key))) {
- char *start = p + strlen(key) + 2;
- char *end = start;
- for (; *end != '\n'; end++)
- ;
- res = malloc(end - start);
- memcpy(res, start, end - start - 1);
- res[end - start] = '\0';
- break;
- }
- }
- return res;
-}
-
-u32 http_content_length(char *r)
-{
- char *value = http_header_key(r, "Content-Length");
- int length = value ? atoi(value) : 0;
- free(value);
- return length;
-}
-
-char *http_code(char *r)
-{
- char *code = malloc(4);
- char tmp = r[12];
- r[12] = '\0';
- memcpy(code, r + 9, 3);
- code[3] = '\0';
- r[12] = tmp;
- return code;
-}
-
-u32 http_response(const char *http_code, u32 content_length, const char *data, char *resp)
-{
- char buf[16] = { 0 };
-
- resp[0] = '\0';
- strcat(resp, "HTTP/1.1 ");
- strcat(resp, buf);
- strcat(resp, http_code);
- strcat(resp, "\r\n");
- strcat(resp, "Content-Length: ");
- strcat(resp, conv_base(content_length, buf, 10, 0));
- strcat(resp, "\r\n");
- strcat(resp, "Server: Melvix\r\n");
- strcat(resp, "Content-Type: text/html\r\n");
- strcat(resp, "Connection: close\r\n\r\n");
- u32 len = strlen(resp);
- memcpy(&resp[len], data, content_length);
-
- return len + content_length;
-}
-
-char *http_query_get(const char *url, const char *path)
-{
- char *query = malloc(27 + strlen(url)); // TODO: Dynamic http length etc
- query[0] = '\0';
- strcat(query, "GET ");
- if (path[0] != '/')
- strcat(query, "/");
- strcat(query, path);
- strcat(query, " HTTP/1.1\r\nHost: ");
- strcat(query, url);
- strcat(query, "\r\n\r\n");
- return query;
-}
-
-char *http_query_path(const char *query, char *path)
-{
- u8 b = 0;
- u32 s = 0;
- u32 e = 0;
-
- while (1) {
- if (!b && query[e] == ' ' && query[++e]) {
- s = e;
- b = 1;
- } else if (b && query[e] == ' ') {
- strncat(path, &query[s], e - s);
- break;
- } else if (query[e] == '\0') {
- return NULL;
- }
- e++;
- }
-
- return path;
-}
-
-char *http_receive(struct socket *socket)
-{
- char buf[4096] = { 0 };
- if (!net_receive(socket, buf, 4096, NET_TIMEOUT))
- return NULL;
-
- u32 length = http_content_length(buf);
- char *data = malloc(strlen(buf) + length);
- memcpy(data, buf, strlen(buf));
- while (strlen(http_data(data)) != length) {
- if (!net_receive(socket, data, length, NET_TIMEOUT))
- break;
- }
- return data;
-}
diff --git a/libs/libnet/http.h b/libs/libnet/http.h
deleted file mode 100644
index b9160ad..0000000
--- a/libs/libnet/http.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef HTTP_H
-#define HTTP_H
-
-#include <def.h>
-#include <libnet/socket.h>
-
-char *http_data(char *response);
-char *http_header_key(char *r, const char *key);
-u32 http_content_length(char *r);
-char *http_code(char *r);
-u32 http_response(const char *http_code, u32 content_length, const char *data, char *resp);
-char *http_query_get(const char *url, const char *path);
-char *http_query_path(const char *query, char *path);
-char *http_receive(struct socket *socket);
-
-#define HTTP_100 "100 Continue"
-#define HTTP_101 "101 Switching Protocol"
-#define HTTP_102 "102 Processing"
-#define HTTP_103 "103 Early Hints"
-#define HTTP_200 "200 OK"
-#define HTTP_201 "201 Created"
-#define HTTP_202 "202 Accepted"
-#define HTTP_203 "203 Non-Authoritative Information"
-#define HTTP_204 "204 No Content"
-#define HTTP_205 "205 Reset Content"
-#define HTTP_206 "206 Partial Content"
-#define HTTP_207 "207 Multi-Status"
-#define HTTP_208 "208 Already Reported"
-#define HTTP_226 "226 IM Used"
-#define HTTP_300 "300 Multiple Choice"
-#define HTTP_301 "301 Moved Permanently"
-#define HTTP_302 "302 Found"
-#define HTTP_303 "303 See Other"
-#define HTTP_304 "304 Not Modified"
-#define HTTP_305 "305 Use Proxy"
-#define HTTP_306 "306 Unused"
-#define HTTP_307 "307 Temporary Redirect"
-#define HTTP_308 "308 Permanent Redirect"
-#define HTTP_400 "400 Bad Request"
-#define HTTP_401 "401 Unauthorized"
-#define HTTP_402 "402 Payment Required"
-#define HTTP_403 "403 Forbidden"
-#define HTTP_404 "404 Not Found"
-#define HTTP_405 "405 Method Not Allowed"
-#define HTTP_406 "406 Not Acceptable"
-#define HTTP_407 "407 Proxy Authentication Required"
-#define HTTP_408 "408 Request Timeout"
-#define HTTP_409 "409 Conflict"
-#define HTTP_410 "410 Gone"
-#define HTTP_411 "411 Length Required"
-#define HTTP_412 "412 Precondition Failed"
-#define HTTP_413 "413 Payload Too Large"
-#define HTTP_414 "414 URI Too Long"
-#define HTTP_415 "415 Unsupported Media Type"
-#define HTTP_416 "416 Range Not Satisfiable"
-#define HTTP_417 "417 Expectation Failed"
-#define HTTP_418 "418 I'm a teapot"
-#define HTTP_421 "421 Misdirected Request"
-#define HTTP_422 "422 Unprocessable Entity"
-#define HTTP_423 "423 Locked"
-#define HTTP_424 "424 Failed Dependency"
-#define HTTP_425 "425 Too Early"
-#define HTTP_426 "426 Upgrade Required"
-#define HTTP_428 "428 Precondition Required"
-#define HTTP_429 "429 Too Many Request"
-#define HTTP_431 "431 Request Header Fields Too Large"
-#define HTTP_451 "451 Unavailable For Legal Reasons"
-#define HTTP_500 "500 Internal Server Error"
-#define HTTP_501 "501 Not Implemented"
-#define HTTP_502 "502 Bad Gateway"
-#define HTTP_503 "503 Service Unavailable"
-#define HTTP_504 "504 Gateway Timeout"
-#define HTTP_505 "505 HTTP Version Not Supported"
-#define HTTP_506 "506 Variant Also Negotiates"
-#define HTTP_507 "507 Insufficient Storage"
-#define HTTP_508 "508 Loop Detected"
-#define HTTP_510 "510 Not Extended"
-#define HTTP_511 "511 Network Authentication Required"
-
-#endif
diff --git a/libs/libnet/ip.c b/libs/libnet/ip.c
deleted file mode 100644
index 66fd8eb..0000000
--- a/libs/libnet/ip.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-// Most net/ip handlers are in the kernel space
-// This is a userspace wrapper for some things
-
-#include <def.h>
-#include <libnet/net.h>
-#include <mem.h>
-#include <str.h>
-
-// Inspired by Paul Vixie, 1996
-int ip_pton(const char *src, u32 *dst)
-{
- const char *end = src + strlen(src);
- u8 tmp[4], *tp;
- int saw_digit = 0;
- int octets = 0;
- *(tp = tmp) = 0;
-
- while (src < end) {
- int ch = *src++;
- if (ch >= '0' && ch <= '9') {
- u32 new = *tp * 10 + (ch - '0');
-
- if ((saw_digit && *tp == 0) || new > 255)
- return 0;
-
- *tp = new;
- if (!saw_digit) {
- if (++octets > 4)
- return 0;
- saw_digit = 1;
- }
- } else if (ch == '.' && saw_digit) {
- if (octets == 4)
- return 0;
- *++tp = 0;
- saw_digit = 0;
- } else {
- return 0;
- }
- }
-
- if (octets < 4)
- return 0;
-
- *dst = htonl(*(u32 *)tmp);
- return 1;
-}
diff --git a/libs/libnet/ip.h b/libs/libnet/ip.h
deleted file mode 100644
index e06aba2..0000000
--- a/libs/libnet/ip.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-// Most net/ip handlers are in the kernel space
-// This is a userspace wrapper for some things
-
-#ifndef IP_H
-#define IP_H
-
-#include <def.h>
-
-int ip_pton(const char *src, u32 *dst);
-
-#endif
diff --git a/libs/libnet/net.h b/libs/libnet/net.h
deleted file mode 100644
index 4bfda2b..0000000
--- a/libs/libnet/net.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef NET_H
-#define NET_H
-
-#include <libnet/dns.h>
-#include <libnet/ip.h>
-#include <libnet/socket.h>
-#include <print.h>
-#include <sys.h>
-
-#define htonl(l) \
- ((((l)&0xff) << 24) | (((l)&0xff00) << 8) | (((l)&0xff0000) >> 8) | \
- (((l)&0xff000000) >> 24))
-#define htons(s) ((((s)&0xff) << 8) | (((s)&0xff00) >> 8))
-#define ntohl(l) htonl((l))
-#define ntohs(s) htons((s))
-#define ip(a, b, c, d) \
- ((((a)&0xff) << 24) | (((b)&0xff) << 16) | (((c)&0xff) << 8) | (((d)&0xff) << 0))
-
-#define NET_TIMEOUT 2000
-#define NET_NO_TIMEOUT 0
-
-static inline int net_data_available(struct socket *socket)
-{
- return (socket && socket->packets && socket->packets->head && socket->packets->head->data &&
- ((struct socket_data *)socket->packets->head->data)->length > 0);
-}
-
-#define net_open(type) (void *)sys1(SYS_NET_OPEN, (int)(type))
-#define net_send(socket, data, len) (void)sys3(SYS_NET_SEND, (int)(socket), (int)(data), (int)(len))
-
-static inline int net_connect(struct socket *socket, u32 ip_addr, u16 dst_port, u32 timeout)
-{
- if (!socket || !ip_addr || !dst_port)
- return 0;
- sys3(SYS_NET_CONNECT, (int)(socket), (int)(ip_addr), (int)(dst_port));
- int time = time();
- while (socket->state != S_CONNECTED) {
- if (socket->state == S_FAILED || (timeout && time() - time >= timeout))
- return 0;
- yield();
- }
- return 1;
-}
-
-static inline int net_close(struct socket *socket)
-{
- if (!socket)
- return 0;
- int res = 0;
- while (socket->state == S_CLOSING || !(res = (int)sys1(SYS_NET_CLOSE, (int)(socket))))
- yield();
- return res;
-}
-
-static inline int net_receive(struct socket *socket, void *buf, u32 len, u32 timeout)
-{
- if (!socket || !buf || !len)
- return 0;
-
- int time = time();
- while (!net_data_available(socket)) {
- if (socket->state == S_FAILED || (timeout && time() - time >= timeout))
- return 0;
- yield();
- }
-
- // TODO: Only return once all segments are received?
- return (int)sys3(SYS_NET_RECEIVE, (int)(socket), (int)(buf), (int)(len));
-}
-
-#endif
diff --git a/libs/libtxt/xml.c b/libs/libtxt/xml.c
deleted file mode 100644
index 9a5fd76..0000000
--- a/libs/libtxt/xml.c
+++ /dev/null
@@ -1,514 +0,0 @@
-// Inspired by sxml (capmar)
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#include <assert.h>
-#include <libtxt/xml.h>
-#include <mem.h>
-#include <str.h>
-
-static const char *str_findchr(const char *start, const char *end, int c)
-{
- const char *it;
-
- assert(start <= end);
- assert(0 <= c && c <= 127);
-
- it = (const char *)memchr((void *)start, c, end - start);
- return (it != NULL) ? it : end;
-}
-
-static const char *str_findstr(const char *start, const char *end, const char *needle)
-{
- u32 needlelen;
- int first;
- assert(start <= end);
-
- needlelen = strlen(needle);
- assert(0 < needlelen);
- first = (u8)needle[0];
-
- while (start + needlelen <= end) {
- const char *it =
- (const char *)memchr((void *)start, first, (end - start) - (needlelen - 1));
- if (it == NULL)
- break;
-
- if (memcmp(it, needle, needlelen) == 0)
- return it;
-
- start = it + 1;
- }
-
- return end;
-}
-
-static int str_starts_with(const char *start, const char *end, const char *prefix)
-{
- long nbytes;
- assert(start <= end);
-
- nbytes = strlen(prefix);
- if (end - start < nbytes)
- return 0;
-
- return memcmp(prefix, start, nbytes) == 0;
-}
-
-static int white_space(int c)
-{
- switch (c) {
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- return 1;
- }
-
- return 0;
-}
-
-static int name_start_char(int c)
-{
- if (0x80 <= c)
- return 1;
-
- return c == ':' || ('A' <= c && c <= 'Z') || c == '_' || ('a' <= c && c <= 'z');
-}
-
-static int name_char(int c)
-{
- return name_start_char(c) || c == '-' || c == '.' || ('0' <= c && c <= '9') || c == 0xB7 ||
- (0x0300 <= c && c <= 0x036F) || (0x203F <= c && c <= 0x2040);
-}
-
-#define is_space(c) (white_space(((u8)(c))))
-#define is_alpha(c) (name_start_char(((u8)(c))))
-#define is_alnum(c) (name_char(((u8)(c))))
-
-static const char *str_ltrim(const char *start, const char *end)
-{
- const char *it;
- assert(start <= end);
-
- for (it = start; it != end && is_space(*it); it++)
- ;
-
- return it;
-}
-
-static const char *str_rtrim(const char *start, const char *end)
-{
- const char *it, *prev;
- assert(start <= end);
-
- for (it = end; start != it; it = prev) {
- prev = it - 1;
- if (!is_space(*prev))
- return it;
- }
-
- return start;
-}
-
-static const char *str_find_notalnum(const char *start, const char *end)
-{
- const char *it;
- assert(start <= end);
-
- for (it = start; it != end && is_alnum(*it); it++)
- ;
-
- return it;
-}
-
-#define buffer_from_offset(args, i) ((args)->buffer + (i))
-#define buffer_tooffset(args, ptr) (unsigned)((ptr) - (args)->buffer)
-#define buffer_getend(args) ((args)->buffer + (args)->buffer_length)
-
-static int state_push_token(struct xml *state, struct xml_args *args, enum xml_type type,
- const char *start, const char *end)
-{
- struct xml_token *token;
- u32 i;
- if (args->num_tokens <= state->ntokens)
- return 0;
-
- i = state->ntokens++;
- token = &args->tokens[i];
- token->type = type;
- token->start_pos = buffer_tooffset(args, start);
- token->end_pos = buffer_tooffset(args, end);
- token->size = 0;
-
- switch (type) {
- case XML_START_TAG:
- state->tag_level++;
- break;
-
- case XML_END_TAG:
- assert(0 < state->tag_level);
- state->tag_level--;
- break;
-
- default:
- break;
- }
-
- return 1;
-}
-
-static enum xml_error state_set_pos(struct xml *state, const struct xml_args *args, const char *ptr)
-{
- state->buffer_pos = buffer_tooffset(args, ptr);
- return (state->ntokens <= args->num_tokens) ? XML_SUCCESS : XML_ERROR_TOKENSFULL;
-}
-
-#define state_commit(dest, src) memcpy((dest), (src), sizeof(struct xml))
-
-#define XML_ERROR_STRICT XML_ERROR_INVALID
-#define ENTITY_MAXLEN 8
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-static enum xml_error parse_characters(struct xml *state, struct xml_args *args, const char *end)
-{
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *limit, *colon, *ampr = str_findchr(start, end, '&');
- assert(end <= buffer_getend(args));
-
- if (ampr != start)
- state_push_token(state, args, XML_CHARACTER, start, ampr);
-
- if (ampr == end)
- return state_set_pos(state, args, ampr);
-
- limit = MIN(ampr + ENTITY_MAXLEN, end);
- colon = str_findchr(ampr, limit, ';');
- if (colon == limit)
- return (limit == end) ? XML_ERROR_BUFFERDRY : XML_ERROR_INVALID;
-
- start = colon + 1;
- state_push_token(state, args, XML_CHARACTER, ampr, start);
- return state_set_pos(state, args, start);
-}
-
-static enum xml_error parse_attrvalue(struct xml *state, struct xml_args *args, const char *end)
-{
- while (buffer_from_offset(args, state->buffer_pos) != end) {
- enum xml_error error = parse_characters(state, args, end);
- if (error != XML_SUCCESS)
- return error;
- }
-
- return XML_SUCCESS;
-}
-
-static enum xml_error parse_attributes(struct xml *state, struct xml_args *args)
-{
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- const char *name = str_ltrim(start, end);
-
- u32 ntokens = state->ntokens;
- assert(0 < ntokens);
-
- while (name != end && is_alpha(*name)) {
- const char *eq, *space, *quot, *value;
- enum xml_error error;
-
- eq = str_findchr(name, end, '=');
- if (eq == end)
- return XML_ERROR_BUFFERDRY;
-
- space = str_rtrim(name, eq);
- state_push_token(state, args, XML_CDATA, name, space);
-
- quot = str_ltrim(eq + 1, end);
- if (quot == end)
- return XML_ERROR_BUFFERDRY;
- else if (*quot != '\'' && *quot != '"')
- return XML_ERROR_INVALID;
-
- value = quot + 1;
- quot = str_findchr(value, end, *quot);
- if (quot == end)
- return XML_ERROR_BUFFERDRY;
-
- state_set_pos(state, args, value);
- error = parse_attrvalue(state, args, quot);
- if (error != XML_SUCCESS)
- return error;
-
- name = str_ltrim(quot + 1, end);
- }
-
- {
- struct xml_token *token = args->tokens + (ntokens - 1);
- token->size = (u16)(state->ntokens - ntokens);
- }
-
- return state_set_pos(state, args, name);
-}
-
-#define TAG_LEN(str) (sizeof(str) - 1)
-#define TAG_MINSIZE 1
-
-static enum xml_error parse_comment(struct xml *state, struct xml_args *args)
-{
- static const char START_TAG[] = "<!--";
- static const char END_TAG[] = "-->";
-
- const char *dash;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- if (end - start < (int)TAG_LEN(START_TAG))
- return XML_ERROR_BUFFERDRY;
-
- if (!str_starts_with(start, end, START_TAG))
- return XML_ERROR_INVALID;
-
- start += TAG_LEN(START_TAG);
- dash = str_findstr(start, end, END_TAG);
- if (dash == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_COMMENT, start, dash);
- return state_set_pos(state, args, dash + TAG_LEN(END_TAG));
-}
-
-static enum xml_error parse_instruction(struct xml *state, struct xml_args *args)
-{
- static const char START_TAG[] = "<?";
- static const char END_TAG[] = "?>";
-
- enum xml_error error;
- const char *quest, *space;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- assert(TAG_MINSIZE <= end - start);
-
- if (!str_starts_with(start, end, START_TAG))
- return XML_ERROR_INVALID;
-
- start += TAG_LEN(START_TAG);
- space = str_find_notalnum(start, end);
- if (space == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_INSTRUCTION, start, space);
-
- state_set_pos(state, args, space);
- error = parse_attributes(state, args);
- if (error != XML_SUCCESS)
- return error;
-
- quest = buffer_from_offset(args, state->buffer_pos);
- if (end - quest < (int)TAG_LEN(END_TAG))
- return XML_ERROR_BUFFERDRY;
-
- if (!str_starts_with(quest, end, END_TAG))
- return XML_ERROR_INVALID;
-
- return state_set_pos(state, args, quest + TAG_LEN(END_TAG));
-}
-
-static enum xml_error parse_doctype(struct xml *state, struct xml_args *args)
-{
- static const char START_TAG[] = "<!DOCTYPE";
- static const char END_TAG[] = ">";
-
- const char *bracket;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- if (end - start < (int)TAG_LEN(START_TAG))
- return XML_ERROR_BUFFERDRY;
-
- if (!str_starts_with(start, end, START_TAG))
- return XML_ERROR_BUFFERDRY;
-
- start += TAG_LEN(START_TAG);
- bracket = str_findstr(start, end, END_TAG);
- if (bracket == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_DOCTYPE, start, bracket);
- return state_set_pos(state, args, bracket + TAG_LEN(END_TAG));
-}
-
-static enum xml_error parse_start(struct xml *state, struct xml_args *args)
-{
- enum xml_error error;
- const char *gt, *name, *space;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- assert(TAG_MINSIZE <= end - start);
-
- if (!(start[0] == '<' && is_alpha(start[1])))
- return XML_ERROR_INVALID;
-
- name = start + 1;
- space = str_find_notalnum(name, end);
- if (space == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_START_TAG, name, space);
-
- state_set_pos(state, args, space);
- error = parse_attributes(state, args);
- if (error != XML_SUCCESS)
- return error;
-
- gt = buffer_from_offset(args, state->buffer_pos);
-
- if (gt != end && *gt == '/') {
- state_push_token(state, args, XML_END_TAG, name, space);
- gt++;
- }
-
- if (gt == end)
- return XML_ERROR_BUFFERDRY;
-
- if (*gt != '>')
- return XML_ERROR_INVALID;
-
- return state_set_pos(state, args, gt + 1);
-}
-
-static enum xml_error parse_end(struct xml *state, struct xml_args *args)
-{
- const char *gt, *space;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- assert(TAG_MINSIZE <= end - start);
-
- if (!(str_starts_with(start, end, "</") && is_alpha(start[2])))
- return XML_ERROR_INVALID;
-
- start += 2;
- gt = str_findchr(start, end, '>');
- if (gt == end)
- return XML_ERROR_BUFFERDRY;
-
- space = str_find_notalnum(start, gt);
- if (str_ltrim(space, gt) != gt)
- return XML_ERROR_STRICT;
-
- state_push_token(state, args, XML_END_TAG, start, space);
- return state_set_pos(state, args, gt + 1);
-}
-
-static enum xml_error parse_cdata(struct xml *state, struct xml_args *args)
-{
- static const char START_TAG[] = "<![CDATA[";
- static const char END_TAG[] = "]]>";
-
- const char *bracket;
- const char *start = buffer_from_offset(args, state->buffer_pos);
- const char *end = buffer_getend(args);
- if (end - start < (int)TAG_LEN(START_TAG))
- return XML_ERROR_BUFFERDRY;
-
- if (!str_starts_with(start, end, START_TAG))
- return XML_ERROR_INVALID;
-
- start += TAG_LEN(START_TAG);
- bracket = str_findstr(start, end, END_TAG);
- if (bracket == end)
- return XML_ERROR_BUFFERDRY;
-
- state_push_token(state, args, XML_CDATA, start, bracket);
- return state_set_pos(state, args, bracket + TAG_LEN(END_TAG));
-}
-
-void xml_init(struct xml *state)
-{
- state->buffer_pos = 0;
- state->ntokens = 0;
- state->tag_level = 0;
-}
-
-#define ROOT_FOUND(state) (0 < (state)->tag_level)
-#define ROOT_PARSED(state) ((state)->tag_level == 0)
-
-enum xml_error xml_parse(struct xml *state, const char *buffer, u32 buffer_length,
- struct xml_token tokens[], u32 num_tokens)
-{
- struct xml temp = *state;
- const char *end = buffer + buffer_length;
-
- struct xml_args args;
- args.buffer = buffer;
- args.buffer_length = buffer_length;
- args.tokens = tokens;
- args.num_tokens = num_tokens;
-
- while (!ROOT_FOUND(&temp)) {
- enum xml_error error;
- const char *start = buffer_from_offset(&args, temp.buffer_pos);
- const char *lt = str_ltrim(start, end);
- state_set_pos(&temp, &args, lt);
- state_commit(state, &temp);
-
- if (end - lt < TAG_MINSIZE)
- return XML_ERROR_BUFFERDRY;
-
- if (*lt != '<')
- return XML_ERROR_INVALID;
-
- switch (lt[1]) {
- case '?':
- error = parse_instruction(&temp, &args);
- break;
- case '!':
- error = (lt[2] == '-') ? parse_comment(&temp, &args) :
- parse_doctype(&temp, &args);
- break;
- default:
- error = parse_start(&temp, &args);
- break;
- }
-
- if (error != XML_SUCCESS)
- return error;
-
- state_commit(state, &temp);
- }
-
- while (!ROOT_PARSED(&temp)) {
- enum xml_error error;
- const char *start = buffer_from_offset(&args, temp.buffer_pos);
- const char *lt = str_findchr(start, end, '<');
- while (buffer_from_offset(&args, temp.buffer_pos) != lt) {
- error = parse_characters(&temp, &args, lt);
- if (error != XML_SUCCESS)
- return error;
-
- state_commit(state, &temp);
- }
-
- if (end - lt < TAG_MINSIZE)
- return XML_ERROR_BUFFERDRY;
-
- switch (lt[1]) {
- case '?':
- error = parse_instruction(&temp, &args);
- break;
- case '/':
- error = parse_end(&temp, &args);
- break;
- case '!':
- error = (lt[2] == '-') ? parse_comment(&temp, &args) :
- parse_cdata(&temp, &args);
- break;
- default:
- error = parse_start(&temp, &args);
- break;
- }
-
- if (error != XML_SUCCESS)
- return error;
-
- state_commit(state, &temp);
- }
-
- return XML_SUCCESS;
-}
diff --git a/libs/libtxt/xml.h b/libs/libtxt/xml.h
deleted file mode 100644
index 3f5c74d..0000000
--- a/libs/libtxt/xml.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Inspired by sxml (capmar)
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef XML_H
-#define XML_H
-
-#include <def.h>
-
-enum xml_error {
- XML_ERROR_INVALID = -1,
- XML_SUCCESS = 0,
- XML_ERROR_BUFFERDRY = 1,
- XML_ERROR_TOKENSFULL = 2
-};
-
-struct xml_token {
- u16 type;
- u16 size;
- u32 start_pos;
- u32 end_pos;
-};
-
-struct xml_args {
- const char *buffer;
- u32 buffer_length;
- struct xml_token *tokens;
- u32 num_tokens;
-};
-
-enum xml_type {
- XML_START_TAG,
- XML_END_TAG,
- XML_CHARACTER,
- XML_CDATA,
- XML_INSTRUCTION,
- XML_DOCTYPE,
- XML_COMMENT
-};
-
-struct xml {
- u32 buffer_pos;
- u32 ntokens;
- u32 tag_level;
-};
-
-enum xml_error xml_parse(struct xml *parser, const char *buffer, u32 buffer_length,
- struct xml_token *tokens, u32 num_tokens) NONNULL;
-
-void xml_init(struct xml *parser) NONNULL;
-
-#endif