src/config/rcxml.c: parse xml from buffer

Avoid unit tests writing to/from files by using xmlParseMemory() instead
of xmlReadFile().
This commit is contained in:
Johan Malm 2020-06-09 21:40:46 +01:00
parent 40c0b169ef
commit bc51e0ad2f
10 changed files with 86 additions and 9 deletions

View file

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Use <openbox_config> as root element for openbox compatibility -->
<openbox_config xmlns="http://openbox.org/3.4/rc"
xmlns:xi="http://www.w3.org/2001/XInclude">
<openbox_config>
<!-- labwc specific settings - additional to openbox -->
<lab>

23
include/buf.h Normal file
View file

@ -0,0 +1,23 @@
/*
* Very simple C buffer implementation
*
* Copyright Johan Malm 2020
*/
#ifndef BUF_H
#define BUF_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct buf {
char *buf;
int alloc;
int len;
};
void buf_init(struct buf *s);
void buf_add(struct buf *s, const char *data);
#endif /* BUF_H */

View file

@ -4,6 +4,8 @@
#include <stdio.h>
#include <stdbool.h>
#include "buf.h"
struct rcxml {
bool client_side_decorations;
};
@ -11,6 +13,7 @@ struct rcxml {
extern struct rcxml rc;
void rcxml_init(struct rcxml *rc);
void rcxml_parse_xml(struct buf *b);
void rcxml_read(const char *filename);
void rcxml_set_verbose(void);

23
src/common/buf.c Normal file
View file

@ -0,0 +1,23 @@
#include "buf.h"
void buf_init(struct buf *s)
{
s->alloc = 256;
s->buf = malloc(s->alloc);
s->buf[0] = '\0';
s->len = 0;
}
void buf_add(struct buf *s, const char *data)
{
if (!data || data[0] == '\0')
return;
int len = strlen(data);
if (s->alloc <= s->len + len + 1) {
s->alloc = s->alloc + len;
s->buf = realloc(s->buf, s->alloc);
}
memcpy(s->buf + s->len, data, len);
s->len += len;
s->buf[s->len] = 0;
}

3
src/common/meson.build Normal file
View file

@ -0,0 +1,3 @@
labwc_sources += files(
'buf.c',
)

View file

@ -1,4 +1,4 @@
#define _POSIX_C_SOURCE 200112L
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <string.h>
#include <strings.h>
@ -143,11 +143,12 @@ static void xml_tree_walk(xmlNode *node)
}
}
static void parse_xml(const char *filename)
/* Exposed in header file to allow unit tests to parse buffers */
void rcxml_parse_xml(struct buf *b)
{
xmlDoc *d = xmlReadFile(filename, NULL, 0);
xmlDoc *d = xmlParseMemory(b->buf, b->len);
if (!d) {
fprintf(stderr, "fatal: error reading file '%s'\n", filename);
fprintf(stderr, "fatal: xmlParseMemory()\n");
exit(EXIT_FAILURE);
}
xml_tree_walk(xmlDocGetRootElement(d));
@ -162,7 +163,29 @@ void rcxml_init(struct rcxml *rc)
void rcxml_read(const char *filename)
{
parse_xml(filename);
FILE *stream;
char *line = NULL;
size_t len = 0;
ssize_t n_read;
struct buf b;
/* Read <filename> into buffer and then call rcxml_parse_xml() */
stream = fopen(filename, "r");
if (!stream) {
fprintf(stderr, "warn: cannot read '%s'\n", filename);
return;
}
buf_init(&b);
while ((n_read = getline(&line, &len, stream) != -1)) {
char *p = strrchr(line, '\n');
if (p)
*p = '\0';
buf_add(&b, line);
}
free(line);
fclose(stream);
rcxml_parse_xml(&b);
free(b.buf);
}
void rcxml_set_verbose(void)

View file

@ -11,5 +11,6 @@ labwc_sources = files(
'xwl.c',
)
subdir('common')
subdir('config')
subdir('debug')

View file

@ -1,6 +1,6 @@
rcxml_lib = static_library(
'rcxml',
sources: ['../src/config/rcxml.c'],
sources: files('../src/config/rcxml.c', '../src/common/buf.c'),
dependencies: xml2,
include_directories: [labwc_inc],
link_with: library('libxml-2.0'),

View file

@ -33,4 +33,6 @@ int main(int argc, char **argv)
diag("Simple parse rc.xml");
ok1(rc.client_side_decorations);
return exit_status();
}

View file

@ -11,7 +11,7 @@ PROGS = rcxml-print-nodenames
all: $(PROGS)
rcxml-print-nodenames: rcxml-print-nodenames.c
$(CC) $(CFLAGS) -o $@ $^ ../../src/config/rcxml.c $(LDFLAGS)
$(CC) $(CFLAGS) -o $@ $^ ../../src/config/rcxml.c ../../src/common/buf.c $(LDFLAGS)
clean:
rm -f $(PROGS)