process newline things

This commit is contained in:
Nishi 2025-12-22 19:20:04 +09:00
commit 54806705c5
Signed by: nishi
GPG key ID: 27EF69B208EB9343
3 changed files with 105 additions and 18 deletions

View file

@ -1,5 +1,5 @@
CC = gcc
CFLAGS = -I include -fPIC
CFLAGS = -I include -fPIC -g
LDFLAGS = -shared
LIBS =
@ -25,4 +25,4 @@ libxmllib$(SO): $(OBJS)
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f src/*.o *.so *.dll
rm -f src/*.o *.so *.dll example

View file

@ -1,18 +1,24 @@
#include <xmllib.h>
#define INDENT 2
void recursive(xmllib_node_t* node, int indent) {
int i;
xmllib_node_t* n;
for(i = 0; i < indent; i++) printf(" ");
if(node->name != NULL && node->type == XMLLIB_NODE_NODE) {
printf("<%s>\n", node->name);
if(node->text != NULL) {
for(i = 0; i < indent + INDENT; i++) printf(" ");
printf("%s\n", node->text);
}
} else if(node->text != NULL && node->type == XMLLIB_NODE_COMMENT) {
printf("<!--%s-->\n", node->text);
}
n = node->first_child;
while(n != NULL) {
recursive(n, indent + 2);
recursive(n, indent + INDENT);
n = n->next;
}
@ -30,9 +36,11 @@ int main(int argc, char** argv) {
if(h != NULL) {
printf("%s:\n", argv[i]);
if(xmllib_parse(h)) {
if(h->root != NULL) recursive(h->root, 2);
if(h->root != NULL) recursive(h->root, INDENT);
} else {
printf(" Parse error\n");
int j;
for(j = 0; j < INDENT; j++) printf(" ");
printf("Parse error\n");
}
xmllib_close(h);
}

View file

@ -30,13 +30,15 @@ enum STATES {
{ \
char* old = node; \
char buf[4]; \
int new = xmllib_unicode_32_to_8((x), buf); \
int new = xmllib_unicode_32_to_8((x), &buf[0]); \
\
node = malloc(strlen(old) + new + 1); \
strcpy(node, old); \
memcpy(node + strlen(old), buf, new); \
memcpy(node + strlen(old), &buf[0], new); \
node[strlen(old) + new] = 0; \
node_count++; \
\
free(old); \
}
#define CLEANUP \
@ -52,6 +54,8 @@ enum STATES {
longjmp(err, 1); \
}
#define SKIPPABLE(x) (((x) == ' ') || ((x) == '\t') || ((x) == '\n') || ((x) == '\r'))
#define STATE state[arrlen(state) - 1]
int xmllib_parse(xmllib_t* handle) {
@ -107,7 +111,7 @@ int xmllib_parse(xmllib_t* handle) {
if(strlen(node) > 1 && node[1] == '-') {
/* comment */
if(strlen(node) > (3 + 2)) {
if(strlen(node) > (3 + 2) && nest_level > 0) {
n = malloc(sizeof(*n));
n->type = XMLLIB_NODE_COMMENT;
@ -130,7 +134,46 @@ int xmllib_parse(xmllib_t* handle) {
if(nest_level > 0) {
if(strcmp(current->name, node + 1) != 0) ERROR;
current = current->parent;
if(current->text != NULL) {
int i, inc;
int* l = NULL;
char* txt = current->text;
i = 0;
while(1) {
int icp;
int nb = xmllib_unicode_8_to_32(txt + i, &icp);
if(icp == 0) break;
arrput(l, nb);
i += nb;
}
inc = strlen(txt);
i = arrlen(l) - 1;
while(1) {
int icp;
int nb;
inc -= l[i];
nb = xmllib_unicode_8_to_32(txt + inc, &icp);
if(SKIPPABLE(icp)) {
txt[inc] = 0;
} else {
break;
}
i--;
}
arrfree(l);
}
targ = current->parent;
}
nest_level--;
@ -139,8 +182,6 @@ int xmllib_parse(xmllib_t* handle) {
n = malloc(sizeof(*n));
if(handle->root == NULL) handle->root = n;
n->type = XMLLIB_NODE_NODE;
n->name = malloc(strlen(node) + 1);
n->text = NULL;
@ -148,12 +189,12 @@ int xmllib_parse(xmllib_t* handle) {
strcpy(n->name, node);
i = 0;
while(1) {
int cp;
int nb = xmllib_unicode_8_to_32(n->name + i, &cp);
int icp;
int nb = xmllib_unicode_8_to_32(n->name + i, &icp);
if(cp == 0) break;
if(icp == 0) break;
if(cp == ' ' || cp == '\t' || cp == '\n' || cp == '\r') {
if(SKIPPABLE(icp)) {
n->name[i] = 0;
break;
}
@ -161,9 +202,6 @@ int xmllib_parse(xmllib_t* handle) {
i += nb;
}
n->root = handle->root;
n->parent = current;
if(node[strlen(node) - 1] != '/') {
/* non self-closing tag */
targ = n;
@ -178,6 +216,11 @@ int xmllib_parse(xmllib_t* handle) {
if(n != NULL) {
xmllib_node_t* last = NULL;
if(handle->root == NULL) handle->root = n;
n->root = handle->root;
n->parent = current;
n->first_child = NULL;
if(current != NULL && current->first_child != NULL) {
@ -230,6 +273,27 @@ int xmllib_parse(xmllib_t* handle) {
}
TAKE_AS_NODE(cp);
} else if(STATE == STATE_INITIAL) {
if(current != NULL) {
char* old = current->text;
if(old != NULL) {
char buf[4];
int new = xmllib_unicode_32_to_8(cp, &buf[0]);
current->text = malloc(strlen(old) + new + 1);
strcpy(current->text, old);
memcpy(current->text + strlen(old), &buf[0], new);
current->text[strlen(old) + new] = 0;
free(old);
} else if(!SKIPPABLE(cp)) {
char buf[4];
int new = xmllib_unicode_32_to_8(cp, &buf[0]);
current->text = malloc(new + 1);
memcpy(current->text, &buf[0], new);
current->text[new] = 0;
}
}
} else {
ERROR;
}
@ -240,7 +304,22 @@ int xmllib_parse(xmllib_t* handle) {
return 1;
}
void recursive_free(xmllib_node_t* node) {
xmllib_node_t* n = node->first_child;
while(n != NULL) {
recursive_free(n);
n = n->next;
}
if(node->name != NULL) free(node->name);
if(node->text != NULL) free(node->text);
free(node);
}
void xmllib_close(xmllib_t* handle) {
recursive_free(handle->root);
handle->driver->close(handle);
free(handle);
}