mirror of
https://github.com/labwc/labwc.git
synced 2025-11-02 09:01:47 -05:00
Read rc.xml and begin parsing
This commit is contained in:
parent
fdc131049c
commit
6166e9b370
12 changed files with 227 additions and 7 deletions
174
src/config/rcxml.c
Normal file
174
src/config/rcxml.c
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
#define _POSIX_C_SOURCE 200112L
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <stdbool.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "rcxml.h"
|
||||
|
||||
static bool in_keybind = false;
|
||||
static bool is_attribute = false;
|
||||
static bool verbose = false;
|
||||
|
||||
static void rstrip(char *buf, const char *pattern)
|
||||
{
|
||||
char *p = strstr(buf, pattern);
|
||||
if (!p)
|
||||
return;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
static void fill_keybind(xmlNode *n, char *nodename, char *content)
|
||||
{
|
||||
rstrip(nodename, ".keybind.keyboard");
|
||||
if (!strcmp(nodename, "name.action")) {
|
||||
; /* TODO: populate keybind with stuff */
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_bool(const char *s)
|
||||
{
|
||||
if (!s)
|
||||
return false;
|
||||
if (!strcasecmp(s, "yes"))
|
||||
return true;
|
||||
if (!strcasecmp(s, "true"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void entry(xmlNode *node, char *nodename, char *content)
|
||||
{
|
||||
if (!nodename)
|
||||
return;
|
||||
rstrip(nodename, ".openbox_config");
|
||||
if (verbose) {
|
||||
if (is_attribute)
|
||||
printf("@");
|
||||
printf("%s: %s\n", nodename, content);
|
||||
}
|
||||
if (!content)
|
||||
return;
|
||||
if (in_keybind)
|
||||
fill_keybind(node, nodename, content);
|
||||
if (!strcmp(nodename, "csd.wlroots"))
|
||||
rc.client_side_decorations = get_bool(content);
|
||||
}
|
||||
|
||||
static void keybind_begin(void)
|
||||
{
|
||||
/* TODO: xcalloc struct keybind */
|
||||
in_keybind = true;
|
||||
}
|
||||
|
||||
static void keybind_end(void)
|
||||
{
|
||||
in_keybind = false;
|
||||
/* TODO: wl_list_add keybind */
|
||||
}
|
||||
|
||||
static char *nodename(xmlNode *node, char *buf, int len)
|
||||
{
|
||||
if (!node || !node->name)
|
||||
return NULL;
|
||||
|
||||
/* Ignore superflous 'text.' in node name */
|
||||
if (node->parent && !strcmp((char *)node->name, "text"))
|
||||
node = node->parent;
|
||||
|
||||
buf += len;
|
||||
*--buf = 0;
|
||||
len--;
|
||||
|
||||
char *p = buf;
|
||||
p[--len] = 0;
|
||||
for (;;) {
|
||||
const char *name = (char *)node->name;
|
||||
char c;
|
||||
while ((c = *name++) != 0) {
|
||||
*p++ = tolower(c);
|
||||
if (!--len)
|
||||
return buf;
|
||||
}
|
||||
*p = 0;
|
||||
node = node->parent;
|
||||
if (!node || !node->name)
|
||||
return buf;
|
||||
*p++ = '.';
|
||||
if (!--len)
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
static void process_node(xmlNode *node)
|
||||
{
|
||||
char *content;
|
||||
static char buffer[256];
|
||||
char *name;
|
||||
|
||||
content = (char *)node->content;
|
||||
if (xmlIsBlankNode(node))
|
||||
return;
|
||||
name = nodename(node, buffer, sizeof(buffer));
|
||||
entry(node, name, content);
|
||||
}
|
||||
|
||||
static void xml_tree_walk(xmlNode *node);
|
||||
|
||||
static void traverse(xmlNode *n)
|
||||
{
|
||||
process_node(n);
|
||||
is_attribute = true;
|
||||
for (xmlAttr *attr = n->properties; attr; attr = attr->next)
|
||||
xml_tree_walk(attr->children);
|
||||
is_attribute = false;
|
||||
xml_tree_walk(n->children);
|
||||
}
|
||||
|
||||
static void xml_tree_walk(xmlNode *node)
|
||||
{
|
||||
for (xmlNode *n = node; n && n->name; n = n->next) {
|
||||
if (!strcasecmp((char *)n->name, "comment"))
|
||||
continue;
|
||||
if (!strcasecmp((char *)n->name, "keybind")) {
|
||||
keybind_begin();
|
||||
traverse(n);
|
||||
keybind_end();
|
||||
continue;
|
||||
}
|
||||
traverse(n);
|
||||
}
|
||||
}
|
||||
|
||||
static void parse_xml(const char *filename)
|
||||
{
|
||||
xmlDoc *d = xmlReadFile(filename, NULL, 0);
|
||||
if (!d) {
|
||||
fprintf(stderr, "fatal: error reading file '%s'\n", filename);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("info: reading config file '%s'\n", filename);
|
||||
xml_tree_walk(xmlDocGetRootElement(d));
|
||||
xmlFreeDoc(d);
|
||||
xmlCleanupParser();
|
||||
}
|
||||
|
||||
void rcxml_init(struct rcxml *rc)
|
||||
{
|
||||
LIBXML_TEST_VERSION
|
||||
}
|
||||
|
||||
void rcxml_read(const char *filename)
|
||||
{
|
||||
parse_xml(filename);
|
||||
}
|
||||
|
||||
void rcxml_set_verbose(void)
|
||||
{
|
||||
verbose = true;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue