mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-23 16:09:47 +00:00
Add custom xml parser. Use as fallback.
This commit is contained in:
parent
49709b90bf
commit
276b588217
11
Makefile
11
Makefile
@ -18,6 +18,7 @@ OBJ = retroarch.o \
|
||||
fifo_buffer.o \
|
||||
compat/compat.o \
|
||||
audio/null.o \
|
||||
cheats.o \
|
||||
gfx/null.o \
|
||||
conf/config_file.o \
|
||||
input/null.o \
|
||||
@ -238,10 +239,11 @@ ifeq ($(HAVE_CG), 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XML), 1)
|
||||
OBJ += cheats.o
|
||||
LIBS += $(XML_LIBS)
|
||||
DEFINES += $(XML_CFLAGS)
|
||||
ifeq ($(HAVE_LIBXML2), 1)
|
||||
LIBS += $(LIBXML2_LIBS)
|
||||
DEFINES += $(LIBXML2_CFLAGS)
|
||||
else
|
||||
OBJ += compat/rxml/rxml.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DYLIB), 1)
|
||||
@ -380,6 +382,7 @@ clean:
|
||||
rm -f gfx/py_state/*.o
|
||||
rm -f gfx/scaler/*.o
|
||||
rm -f compat/*.o
|
||||
rm -f compat/rxml/*.o
|
||||
rm -f record/*.o
|
||||
rm -f input/*.o
|
||||
rm -f tools/*.o
|
||||
|
15
Makefile.win
15
Makefile.win
@ -17,6 +17,7 @@ OBJ = retroarch.o \
|
||||
patch.o \
|
||||
compat/compat.o \
|
||||
screenshot.o \
|
||||
cheats.o \
|
||||
audio/utils.o \
|
||||
audio/null.o \
|
||||
input/null.o \
|
||||
@ -60,7 +61,7 @@ DYNAMIC = 1
|
||||
ifeq ($(SLIM),)
|
||||
HAVE_SDL = 1
|
||||
HAVE_SDL_IMAGE = 1
|
||||
HAVE_XML = 1
|
||||
HAVE_LIBXML2 = 1
|
||||
HAVE_FREETYPE = 1
|
||||
HAVE_RSOUND = 1
|
||||
HAVE_FBO = 1
|
||||
@ -103,8 +104,8 @@ ifeq ($(HAVE_THREADS), 1)
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_OPENGL), 1)
|
||||
OBJ += gfx/gl.o gfx/math/matrix.o gfx/fonts/gl_font.o gfx/fonts/gl_raster_font.o gfx/gfx_context.o gfx/context/wgl_ctx.o
|
||||
DEFINES += -DHAVE_OPENGL -DHAVE_OVERLAY
|
||||
OBJ += gfx/gl.o gfx/math/matrix.o gfx/fonts/gl_font.o gfx/fonts/gl_raster_font.o gfx/gfx_context.o gfx/context/wgl_ctx.o gfx/shader_glsl.o
|
||||
DEFINES += -DHAVE_OPENGL -DHAVE_OVERLAY -DHAVE_GLSL
|
||||
LIBS += -lopengl32 -lgdi32
|
||||
endif
|
||||
|
||||
@ -145,10 +146,11 @@ ifeq ($(HAVE_RSOUND), 1)
|
||||
LIBS += -lrsound
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_XML), 1)
|
||||
OBJ += gfx/shader_glsl.o cheats.o
|
||||
DEFINES += -Ilibxml2 -DHAVE_XML -DHAVE_GLSL
|
||||
ifeq ($(HAVE_LIBXML2), 1)
|
||||
DEFINES += -Ilibxml2 -DHAVE_LIBXML2 -DHAVE_GLSL
|
||||
LIBS += -lxml2 -liconv
|
||||
else
|
||||
OBJ += compat/rxml/rxml.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_DYLIB), 1)
|
||||
@ -258,6 +260,7 @@ clean:
|
||||
rm -f audio/*.o
|
||||
rm -f audio/xaudio-c/*.o
|
||||
rm -f compat/*.o
|
||||
rm -f compat/rxml/*.o
|
||||
rm -f conf/*.o
|
||||
rm -f gfx/scaler/*.o
|
||||
rm -f gfx/*.o
|
||||
|
7
cheats.c
7
cheats.c
@ -30,8 +30,13 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#else
|
||||
#define RXML_LIBXML2_COMPAT
|
||||
#include "compat/rxml/rxml.h"
|
||||
#endif
|
||||
|
||||
struct cheat
|
||||
{
|
||||
@ -252,11 +257,13 @@ cheat_manager_t *cheat_manager_new(const char *path)
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
if (ctx->valid == 0)
|
||||
{
|
||||
RARCH_ERR("Cannot validate XML file: %s\n", path);
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
head = xmlDocGetRootElement(doc);
|
||||
for (cur = head; cur; cur = cur->next)
|
||||
|
20
compat/rxml/Makefile
Normal file
20
compat/rxml/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
TARGET := rxml
|
||||
|
||||
SOURCES := $(wildcard *.c)
|
||||
OBJS := $(SOURCES:.c=.o)
|
||||
|
||||
CFLAGS += -Wall -pedantic -std=gnu99 -O3 -g
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS)
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) $(OBJS)
|
||||
|
||||
.PHONY: clean
|
||||
|
426
compat/rxml/rxml.c
Normal file
426
compat/rxml/rxml.c
Normal file
@ -0,0 +1,426 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "rxml.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include "../../boolean.h"
|
||||
#include "../../general.h"
|
||||
|
||||
struct rxml_document
|
||||
{
|
||||
struct rxml_node *root_node;
|
||||
};
|
||||
|
||||
struct rxml_node *rxml_root_node(rxml_document_t *doc)
|
||||
{
|
||||
return doc->root_node;
|
||||
}
|
||||
|
||||
static void rxml_free_node(struct rxml_node *node)
|
||||
{
|
||||
for (struct rxml_node *head = node->children; head; )
|
||||
{
|
||||
struct rxml_node *next_node = head->next;
|
||||
rxml_free_node(head);
|
||||
head = next_node;
|
||||
}
|
||||
|
||||
for (struct rxml_attrib_node *head = node->attrib; head; )
|
||||
{
|
||||
struct rxml_attrib_node *next_attrib = head->next;
|
||||
|
||||
free(head->attrib);
|
||||
free(head->value);
|
||||
free(head);
|
||||
|
||||
head = next_attrib;
|
||||
}
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
static bool validate_header(const char **ptr)
|
||||
{
|
||||
if (memcmp(*ptr, "<?xml", 5) == 0)
|
||||
{
|
||||
const char *eol = strstr(*ptr, "?>\n");
|
||||
if (!eol)
|
||||
return false;
|
||||
|
||||
// Always use UTF-8. Don't really care to check.
|
||||
*ptr = eol + 3;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool range_is_space(const char *begin, const char *end)
|
||||
{
|
||||
for (; begin < end; begin++)
|
||||
if (!isspace(*begin))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void skip_spaces(const char **ptr_)
|
||||
{
|
||||
const char *ptr = *ptr_;
|
||||
while (isspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
*ptr_ = ptr;
|
||||
}
|
||||
|
||||
static char *strdup_range(const char *begin, const char *end)
|
||||
{
|
||||
ptrdiff_t len = end - begin;
|
||||
|
||||
char *ret = (char*)malloc(len + 1);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
||||
memcpy(ret, begin, len);
|
||||
ret[len] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *strdup_range_escape(const char *begin, const char *end)
|
||||
{
|
||||
return strdup_range(begin, end); // Escaping is ignored. Assume we don't deal with that.
|
||||
}
|
||||
|
||||
static struct rxml_attrib_node *rxml_parse_attrs(const char *str)
|
||||
{
|
||||
char *copy = strdup(str);
|
||||
if (!copy)
|
||||
return NULL;
|
||||
|
||||
char *last_char = copy + strlen(copy) - 1;
|
||||
if (*last_char == '/')
|
||||
*last_char = '\0';
|
||||
|
||||
struct rxml_attrib_node *list = NULL;
|
||||
struct rxml_attrib_node *tail = NULL;
|
||||
|
||||
char *save;
|
||||
const char *elem = strtok_r(copy, " ", &save);
|
||||
while (elem)
|
||||
{
|
||||
const char *eq = strstr(elem, "=\"");
|
||||
if (!eq)
|
||||
goto end;
|
||||
|
||||
const char *end = strrchr(eq + 2, '\"');
|
||||
if (!end || end != (elem + strlen(elem) - 1))
|
||||
goto end;
|
||||
|
||||
char *attrib = strdup_range_escape(elem, eq);
|
||||
char *value = strdup_range_escape(eq + 2, end);
|
||||
if (!attrib || !value)
|
||||
goto end;
|
||||
|
||||
struct rxml_attrib_node *new_node = (struct rxml_attrib_node*)calloc(1, sizeof(*new_node));
|
||||
if (!new_node)
|
||||
goto end;
|
||||
|
||||
new_node->attrib = attrib;
|
||||
new_node->value = value;
|
||||
|
||||
if (tail)
|
||||
{
|
||||
tail->next = new_node;
|
||||
tail = new_node;
|
||||
}
|
||||
else
|
||||
list = tail = new_node;
|
||||
|
||||
elem = strtok_r(NULL, " ", &save);
|
||||
}
|
||||
|
||||
end:
|
||||
free(copy);
|
||||
return list;
|
||||
}
|
||||
|
||||
static bool rxml_parse_tag(struct rxml_node *node, const char *str)
|
||||
{
|
||||
const char *str_ptr = str;
|
||||
skip_spaces(&str_ptr);
|
||||
|
||||
const char *name_end = strchr(str_ptr, ' ');
|
||||
if (name_end)
|
||||
{
|
||||
node->name = strdup_range(str_ptr, name_end);
|
||||
if (!node->name || !*node->name)
|
||||
return false;
|
||||
|
||||
node->attrib = rxml_parse_attrs(name_end);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->name = strdup(str_ptr);
|
||||
return node->name && *node->name;
|
||||
}
|
||||
}
|
||||
|
||||
static struct rxml_node *rxml_parse_node(const char **ptr_)
|
||||
{
|
||||
const char *ptr = NULL;
|
||||
const char *closing = NULL;
|
||||
char *str = NULL;
|
||||
bool is_closing = false;
|
||||
|
||||
struct rxml_node *node = (struct rxml_node*)calloc(1, sizeof(*node));
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
skip_spaces(ptr_);
|
||||
|
||||
ptr = *ptr_;
|
||||
if (*ptr != '<')
|
||||
goto error;
|
||||
|
||||
closing = strchr(ptr, '>');
|
||||
if (!closing)
|
||||
goto error;
|
||||
|
||||
str = strdup_range(ptr + 1, closing);
|
||||
if (!str)
|
||||
goto error;
|
||||
|
||||
if (!rxml_parse_tag(node, str))
|
||||
goto error;
|
||||
|
||||
is_closing = strstr(ptr, "/>") + 1 == closing; // Are spaces between / and > allowed?
|
||||
|
||||
// Look for more data. Either child nodes or data.
|
||||
if (!is_closing)
|
||||
{
|
||||
size_t closing_tag_size = strlen(node->name) + 4;
|
||||
char *closing_tag = (char*)malloc(closing_tag_size);
|
||||
|
||||
const char *cdata_start = NULL;
|
||||
const char *child_start = NULL;
|
||||
const char *closing_start = NULL;
|
||||
|
||||
if (!closing_tag)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
snprintf(closing_tag, closing_tag_size, "</%s>", node->name);
|
||||
|
||||
cdata_start = strstr(closing + 1, "<![CDATA[");
|
||||
child_start = strchr(closing + 1, '<');
|
||||
closing_start = strstr(closing + 1, closing_tag);
|
||||
|
||||
if (!closing_start)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cdata_start && range_is_space(closing + 1, cdata_start)) // CDATA section
|
||||
{
|
||||
const char *cdata_end = strstr(cdata_start, "]]>");
|
||||
if (!cdata_end)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
node->data = strdup_range(cdata_start + strlen("<![CDATA["), cdata_end);
|
||||
}
|
||||
else if (closing_start && closing_start == child_start) // Simple Data
|
||||
node->data = strdup_range(closing + 1, closing_start);
|
||||
else // Parse all child nodes.
|
||||
{
|
||||
struct rxml_node *list = NULL;
|
||||
struct rxml_node *tail = NULL;
|
||||
|
||||
const char *ptr = child_start;
|
||||
|
||||
const char *first_start = strchr(ptr, '<');
|
||||
const char *first_closing = strstr(ptr, "</");
|
||||
while (first_start && first_closing && first_start < first_closing)
|
||||
{
|
||||
struct rxml_node *new_node = rxml_parse_node(&ptr);
|
||||
if (!new_node)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tail)
|
||||
{
|
||||
tail->next = new_node;
|
||||
tail = new_node;
|
||||
}
|
||||
else
|
||||
list = tail = new_node;
|
||||
|
||||
first_start = strchr(ptr, '<');
|
||||
first_closing = strstr(ptr, "</");
|
||||
}
|
||||
|
||||
node->children = list;
|
||||
|
||||
closing_start = strstr(ptr, closing_tag);
|
||||
if (!closing_start)
|
||||
{
|
||||
free(closing_tag);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr_ = closing_start + strlen(closing_tag);
|
||||
free(closing_tag);
|
||||
}
|
||||
else
|
||||
*ptr_ = closing + 1;
|
||||
|
||||
free(str);
|
||||
return node;
|
||||
|
||||
error:
|
||||
free(str);
|
||||
rxml_free_node(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *purge_xml_comments(const char *str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
char *new_str = (char*)malloc(len + 1);
|
||||
if (!new_str)
|
||||
return NULL;
|
||||
|
||||
new_str[len] = '\0';
|
||||
|
||||
char *copy_dest = new_str;
|
||||
const char *copy_src = str;
|
||||
for (;;)
|
||||
{
|
||||
const char *comment_start = strstr(copy_src, "<!--");
|
||||
const char *comment_end = strstr(copy_src, "-->");
|
||||
|
||||
if (!comment_start || !comment_end)
|
||||
break;
|
||||
|
||||
ptrdiff_t copy_len = comment_start - copy_src;
|
||||
memcpy(copy_dest, copy_src, copy_len);
|
||||
|
||||
copy_dest += copy_len;
|
||||
copy_src = comment_end + strlen("-->");
|
||||
}
|
||||
|
||||
// Avoid strcpy() as OpenBSD is anal and hates you for using it even when it's perfectly safe.
|
||||
len = strlen(copy_src);
|
||||
memcpy(copy_dest, copy_src, len);
|
||||
copy_dest[len] = '\0';
|
||||
|
||||
return new_str;
|
||||
}
|
||||
|
||||
rxml_document_t *rxml_load_document(const char *path)
|
||||
{
|
||||
RARCH_WARN("Using RXML as drop in for libxml2. Behavior might be very buggy.\n");
|
||||
|
||||
char *memory_buffer = NULL;
|
||||
char *new_memory_buffer = NULL;
|
||||
const char *mem_ptr = NULL;
|
||||
long len = 0;
|
||||
|
||||
FILE *file = fopen(path, "r");
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
rxml_document_t *doc = (rxml_document_t*)calloc(1, sizeof(*doc));
|
||||
if (!doc)
|
||||
goto error;
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
len = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
memory_buffer = (char*)malloc(len + 1);
|
||||
if (!memory_buffer)
|
||||
goto error;
|
||||
|
||||
memory_buffer[len] = '\0';
|
||||
if (fread(memory_buffer, 1, len, file) != (size_t)len)
|
||||
goto error;
|
||||
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
|
||||
mem_ptr = memory_buffer;
|
||||
|
||||
if (!validate_header(&mem_ptr))
|
||||
goto error;
|
||||
|
||||
new_memory_buffer = purge_xml_comments(mem_ptr);
|
||||
if (!new_memory_buffer)
|
||||
goto error;
|
||||
|
||||
free(memory_buffer);
|
||||
mem_ptr = memory_buffer = new_memory_buffer;
|
||||
|
||||
doc->root_node = rxml_parse_node(&mem_ptr);
|
||||
if (!doc->root_node)
|
||||
goto error;
|
||||
|
||||
free(memory_buffer);
|
||||
return doc;
|
||||
|
||||
error:
|
||||
free(memory_buffer);
|
||||
if (file)
|
||||
fclose(file);
|
||||
rxml_free_document(doc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void rxml_free_document(rxml_document_t *doc)
|
||||
{
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
if (doc->root_node)
|
||||
rxml_free_node(doc->root_node);
|
||||
|
||||
free(doc);
|
||||
}
|
||||
|
||||
char *rxml_node_attrib(struct rxml_node *node, const char *attrib)
|
||||
{
|
||||
for (struct rxml_attrib_node *attribs = node->attrib; attribs; attribs = attribs->next)
|
||||
{
|
||||
if (!strcmp(attrib, attribs->attrib))
|
||||
return attribs->value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
77
compat/rxml/rxml.h
Normal file
77
compat/rxml/rxml.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RXML_H__
|
||||
#define RXML_H__
|
||||
|
||||
// Total NIH. Very trivial "XML" implementation for use in RetroArch.
|
||||
// Error checking is minimal. Invalid documents may lead to very buggy behavior, but
|
||||
// memory corruption should never happen.
|
||||
//
|
||||
// Only parts of standard that RetroArch cares about is supported.
|
||||
// Nothing more, nothing less. "Clever" XML documents will probably break the implementation.
|
||||
//
|
||||
// Do *NOT* try to use this for anything else. You have been warned.
|
||||
|
||||
typedef struct rxml_document rxml_document_t;
|
||||
|
||||
struct rxml_attrib_node
|
||||
{
|
||||
char *attrib;
|
||||
char *value;
|
||||
struct rxml_attrib_node *next;
|
||||
};
|
||||
|
||||
struct rxml_node
|
||||
{
|
||||
char *name;
|
||||
char *data;
|
||||
struct rxml_attrib_node *attrib;
|
||||
|
||||
struct rxml_node *children;
|
||||
struct rxml_node *next;
|
||||
|
||||
int type; // Dummy. Used by libxml2 compat. Is always set to 0, so XML_ELEMENT_NODE check goes through.
|
||||
};
|
||||
|
||||
rxml_document_t *rxml_load_document(const char *path);
|
||||
void rxml_free_document(rxml_document_t *doc);
|
||||
|
||||
struct rxml_node *rxml_root_node(rxml_document_t *doc);
|
||||
|
||||
// Drop const-correctness here to avoid warnings when used as libxml2 compat.
|
||||
// xmlGetProp() returns xmlChar*, which is supposed to be passed to xmlFree().
|
||||
char *rxml_node_attrib(struct rxml_node *node, const char *attrib);
|
||||
|
||||
#ifdef RXML_LIBXML2_COMPAT
|
||||
// Compat for part of libxml2 that RetroArch uses.
|
||||
#define LIBXML_TEST_VERSION ((void)0)
|
||||
typedef char xmlChar; // It's really unsigned char, but it doesn't matter.
|
||||
typedef struct rxml_node *xmlNodePtr;
|
||||
typedef void *xmlParserCtxtPtr;
|
||||
typedef rxml_document_t *xmlDocPtr;
|
||||
#define XML_ELEMENT_NODE (0)
|
||||
#define xmlNewParserCtxt() ((void*)-1)
|
||||
#define xmlCtxtReadFile(ctx, path, ...) rxml_load_document(path)
|
||||
#define xmlGetProp(node, prop) rxml_node_attrib(node, prop)
|
||||
#define xmlFree(p) ((void)0)
|
||||
#define xmlNodeGetContent(node) (node->data)
|
||||
#define xmlDocGetRootElement(doc) rxml_root_node(doc)
|
||||
#define xmlFreeDoc(doc) rxml_free_document(doc)
|
||||
#define xmlFreeParserCtxt(ctx) ((void)0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
58
compat/rxml/rxml_test.c
Normal file
58
compat/rxml/rxml_test.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "rxml.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void print_siblings(struct rxml_node *node, unsigned level)
|
||||
{
|
||||
fprintf(stderr, "\n%*sName: %s\n", level * 4, "", node->name);
|
||||
if (node->data)
|
||||
fprintf(stderr, "%*sData: %s\n", level * 4, "", node->data);
|
||||
|
||||
for (const struct rxml_attrib_node *attrib = node->attrib; attrib; attrib = attrib->next)
|
||||
fprintf(stderr, "%*s Attrib: %s = %s\n", level * 4, "", attrib->attrib, attrib->value);
|
||||
|
||||
if (node->childs)
|
||||
print_siblings(node->childs, level + 1);
|
||||
|
||||
if (node->next)
|
||||
print_siblings(node->next, level);
|
||||
}
|
||||
|
||||
static void rxml_log_document(const char *path)
|
||||
{
|
||||
rxml_document_t *doc = rxml_load_document(path);
|
||||
if (!doc)
|
||||
{
|
||||
fprintf(stderr, "rxml: Failed to load document: %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
print_siblings(rxml_root_node(doc), 0);
|
||||
rxml_free_document(doc);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <path>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rxml_log_document(argv[1]);
|
||||
}
|
||||
|
@ -116,10 +116,10 @@ static const bool _cg_supp = true;
|
||||
static const bool _cg_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
static const bool _xml_supp = true;
|
||||
#ifdef HAVE_LIBXML2
|
||||
static const bool _libxml2_supp = true;
|
||||
#else
|
||||
static const bool _xml_supp = false;
|
||||
static const bool _libxml2_supp = false;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL_IMAGE
|
||||
|
6
driver.c
6
driver.c
@ -561,7 +561,6 @@ error:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
static void deinit_shader_dir(void)
|
||||
{
|
||||
// It handles NULL, no worries :D
|
||||
@ -588,7 +587,6 @@ static void init_shader_dir(void)
|
||||
for (unsigned i = 0; i < g_extern.shader_dir.list->size; i++)
|
||||
RARCH_LOG("Found shader \"%s\"\n", g_extern.shader_dir.list->elems[i].data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void deinit_pixel_converter(void)
|
||||
{
|
||||
@ -628,9 +626,7 @@ void init_video_input(void)
|
||||
init_filter(g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
init_shader_dir();
|
||||
#endif
|
||||
|
||||
const struct retro_game_geometry *geom = &g_extern.system.av_info.geometry;
|
||||
unsigned max_dim = max(geom->max_width, geom->max_height);
|
||||
@ -776,9 +772,7 @@ void uninit_video_input(void)
|
||||
deinit_filter();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
deinit_shader_dir();
|
||||
#endif
|
||||
}
|
||||
|
||||
driver_t driver;
|
||||
|
2
file.c
2
file.c
@ -277,10 +277,8 @@ static ssize_t read_rom_file(FILE *file, void **buf)
|
||||
}
|
||||
|
||||
g_extern.cart_crc = crc32_calculate(ret_buf, ret);
|
||||
#ifdef HAVE_XML
|
||||
sha256_hash(g_extern.sha256, ret_buf, ret);
|
||||
RARCH_LOG("SHA256 sum: %s\n", g_extern.sha256);
|
||||
#endif
|
||||
*buf = ret_buf;
|
||||
return ret;
|
||||
}
|
||||
|
@ -466,9 +466,7 @@ struct global
|
||||
|
||||
char sha256[64 + 1];
|
||||
|
||||
#ifdef HAVE_XML
|
||||
cheat_manager_t *cheat;
|
||||
#endif
|
||||
|
||||
// Settings and/or global state that is specific to a console-style implementation.
|
||||
struct
|
||||
|
10
gfx/gl.c
10
gfx/gl.c
@ -236,7 +236,7 @@ static bool gl_shader_init(gl_t *gl)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
#ifdef HAVE_GLSL
|
||||
if (*g_settings.video.bsnes_shader_path)
|
||||
{
|
||||
backend = &gl_glsl_backend;
|
||||
@ -253,7 +253,7 @@ static bool gl_shader_init(gl_t *gl)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
#ifdef HAVE_GLSL
|
||||
case RARCH_SHADER_BSNES:
|
||||
backend = &gl_glsl_backend;
|
||||
shader_path = g_settings.video.bsnes_shader_path;
|
||||
@ -1604,7 +1604,7 @@ static bool gl_focus(void *data)
|
||||
return context_has_focus_func();
|
||||
}
|
||||
|
||||
#if defined(HAVE_XML) || defined(HAVE_CG)
|
||||
#if defined(HAVE_GLSL) || defined(HAVE_CG)
|
||||
static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
@ -1618,7 +1618,7 @@ static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *p
|
||||
|
||||
switch (type)
|
||||
{
|
||||
#ifdef HAVE_XML
|
||||
#ifdef HAVE_GLSL
|
||||
case RARCH_SHADER_BSNES:
|
||||
if (!gl_glsl_init(path))
|
||||
return false;
|
||||
@ -1897,7 +1897,7 @@ const video_driver_t video_gl = {
|
||||
gl_alive,
|
||||
gl_focus,
|
||||
|
||||
#if defined(HAVE_XML) || defined(HAVE_CG)
|
||||
#if defined(HAVE_GLSL) || defined(HAVE_CG)
|
||||
gl_set_shader,
|
||||
#else
|
||||
NULL,
|
||||
|
@ -52,9 +52,12 @@
|
||||
#include "gfx_context.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_XML
|
||||
#ifdef HAVE_LIBXML2
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#else
|
||||
#define RXML_LIBXML2_COMPAT
|
||||
#include "../compat/rxml/rxml.h"
|
||||
#endif
|
||||
|
||||
#include "gl_common.h"
|
||||
@ -248,7 +251,6 @@ static const char *stock_fragment_modern =
|
||||
" gl_FragColor = color * texture2D(rubyTexture, tex_coord);\n"
|
||||
"}";
|
||||
|
||||
#ifdef HAVE_XML
|
||||
static bool xml_get_prop(char *buf, size_t size, xmlNodePtr node, const char *prop)
|
||||
{
|
||||
if (!size)
|
||||
@ -685,11 +687,13 @@ static unsigned get_xml_shaders(const char *path, struct shader_program *prog, s
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
if (ctx->valid == 0)
|
||||
{
|
||||
RARCH_ERR("Cannot validate XML shader: %s\n", path);
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
head = xmlDocGetRootElement(doc);
|
||||
|
||||
@ -818,7 +822,6 @@ error:
|
||||
xmlFreeParserCtxt(ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif // HAVE_XML
|
||||
|
||||
static void print_shader_log(GLuint obj)
|
||||
{
|
||||
@ -1072,7 +1075,6 @@ bool gl_glsl_init(const char *path)
|
||||
|
||||
unsigned num_progs = 0;
|
||||
struct shader_program progs[RARCH_GLSL_MAX_SHADERS] = {{0}};
|
||||
#ifdef HAVE_XML
|
||||
if (path)
|
||||
{
|
||||
num_progs = get_xml_shaders(path, progs, RARCH_GLSL_MAX_SHADERS - 1);
|
||||
@ -1084,7 +1086,6 @@ bool gl_glsl_init(const char *path)
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RARCH_WARN("[GL]: Stock GLSL shaders will be used.\n");
|
||||
num_progs = 1;
|
||||
@ -1126,7 +1127,6 @@ bool gl_glsl_init(const char *path)
|
||||
if (!compile_programs(&gl_program[1], progs, num_progs))
|
||||
return false;
|
||||
|
||||
#ifdef HAVE_XML
|
||||
// RetroArch custom two-pass with two different files.
|
||||
if (num_progs == 1 && *g_settings.video.second_pass_shader && g_settings.video.render_to_texture)
|
||||
{
|
||||
@ -1142,7 +1142,6 @@ bool gl_glsl_init(const char *path)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (unsigned i = 0; i <= num_progs; i++)
|
||||
find_uniforms(gl_program[i], &gl_uniforms[i]);
|
||||
@ -1152,7 +1151,6 @@ bool gl_glsl_init(const char *path)
|
||||
RARCH_WARN("Detected GL error in GLSL.\n");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
if (gl_tracker_info_cnt > 0)
|
||||
{
|
||||
struct state_tracker_info info = {0};
|
||||
@ -1170,7 +1168,6 @@ bool gl_glsl_init(const char *path)
|
||||
if (!gl_state_tracker)
|
||||
RARCH_WARN("Failed to init state tracker.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
glsl_enable = true;
|
||||
gl_num_programs = num_progs;
|
||||
|
@ -162,7 +162,7 @@ if [ "$HAVE_KMS" != "no" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
check_pkgconf XML libxml-2.0
|
||||
check_pkgconf LIBXML2 libxml-2.0
|
||||
|
||||
if [ "$HAVE_EGL" = "yes" ]; then
|
||||
if [ "$HAVE_GLES" != "no" ]; then
|
||||
@ -205,6 +205,6 @@ check_macro NEON __ARM_NEON__
|
||||
add_define_make OS "$OS"
|
||||
|
||||
# Creates config.mk and config.h.
|
||||
VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL GLES VG EGL KMS GBM DRM DYLIB GETOPT_LONG THREADS CG XML SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE FREETYPE XVIDEO X11 XEXT XF86VM XINERAMA NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 SINC BSV_MOVIE VIDEOCORE NEON"
|
||||
VARS="ALSA OSS OSS_BSD OSS_LIB AL RSOUND ROAR JACK COREAUDIO PULSE SDL OPENGL GLES VG EGL KMS GBM DRM DYLIB GETOPT_LONG THREADS CG LIBXML2 SDL_IMAGE LIBPNG DYNAMIC FFMPEG AVCODEC AVFORMAT AVUTIL SWSCALE FREETYPE XVIDEO X11 XEXT XF86VM XINERAMA NETPLAY NETWORK_CMD STDIN_CMD COMMAND SOCKET_LEGACY FBO STRL PYTHON FFMPEG_ALLOC_CONTEXT3 FFMPEG_AVCODEC_OPEN2 FFMPEG_AVIO_OPEN FFMPEG_AVFORMAT_WRITE_HEADER FFMPEG_AVFORMAT_NEW_STREAM FFMPEG_AVCODEC_ENCODE_AUDIO2 FFMPEG_AVCODEC_ENCODE_VIDEO2 SINC BSV_MOVIE VIDEOCORE NEON"
|
||||
create_config_make config.mk $VARS
|
||||
create_config_header config.h $VARS
|
||||
|
@ -14,7 +14,7 @@ HAVE_KMS=auto # Enable KMS context support
|
||||
HAVE_EGL=auto # Enable EGL context support
|
||||
HAVE_VG=auto # Enable OpenVG support
|
||||
HAVE_CG=auto # Enable Cg shader support
|
||||
HAVE_XML=auto # Enable bSNES-style XML shader support
|
||||
HAVE_LIBXML2=auto # Enable libxml2 support
|
||||
HAVE_FBO=auto # Enable render-to-texture (FBO) support
|
||||
HAVE_ALSA=auto # Enable ALSA support
|
||||
HAVE_OSS=auto # Enable OSS support
|
||||
|
14
retroarch.c
14
retroarch.c
@ -594,7 +594,7 @@ static void print_features(void)
|
||||
_PSUPP(al, "OpenAL", "audio driver");
|
||||
_PSUPP(dylib, "External", "External filter and plugin support");
|
||||
_PSUPP(cg, "Cg", "Cg pixel shaders");
|
||||
_PSUPP(xml, "XML", "bSNES XML pixel shaders");
|
||||
_PSUPP(libxml2, "libxml2", "libxml2 XML parsing");
|
||||
_PSUPP(sdl_image, "SDL_image", "SDL_image image loading");
|
||||
_PSUPP(libpng, "libpng", "libpng screenshot support");
|
||||
_PSUPP(fbo, "FBO", "OpenGL render-to-texture (multi-pass shaders)");
|
||||
@ -1413,7 +1413,6 @@ void rarch_deinit_msg_queue(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_XML
|
||||
static void init_cheats(void)
|
||||
{
|
||||
if (*g_settings.cheat_database)
|
||||
@ -1425,7 +1424,6 @@ static void deinit_cheats(void)
|
||||
if (g_extern.cheat)
|
||||
cheat_manager_free(g_extern.cheat);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void init_rewind(void)
|
||||
{
|
||||
@ -2295,7 +2293,6 @@ static void check_turbo(void)
|
||||
input_input_state_func(binds, i, RETRO_DEVICE_JOYPAD, 0, RARCH_TURBO_ENABLE);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XML
|
||||
static void check_shader_dir(void)
|
||||
{
|
||||
static bool old_pressed_next;
|
||||
@ -2377,7 +2374,6 @@ static void check_cheats(void)
|
||||
old_pressed_next = pressed_next;
|
||||
old_pressed_toggle = pressed_toggle;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SCREENSHOTS) && !defined(_XBOX)
|
||||
static void check_screenshot(void)
|
||||
@ -2549,10 +2545,8 @@ static void do_state_checks(void)
|
||||
check_movie();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
check_shader_dir();
|
||||
check_cheats();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DYLIB
|
||||
check_dsp_config();
|
||||
@ -2677,9 +2671,7 @@ int rarch_main_init(int argc, char *argv[])
|
||||
pretro_init();
|
||||
|
||||
g_extern.use_sram = true;
|
||||
#ifdef HAVE_XML
|
||||
bool allow_cheats = true;
|
||||
#endif
|
||||
|
||||
fill_pathnames();
|
||||
set_savestate_auto_index();
|
||||
@ -2736,7 +2728,6 @@ int rarch_main_init(int argc, char *argv[])
|
||||
init_autosave();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
#ifdef HAVE_NETPLAY
|
||||
allow_cheats &= !g_extern.netplay;
|
||||
#endif
|
||||
@ -2745,7 +2736,6 @@ int rarch_main_init(int argc, char *argv[])
|
||||
#endif
|
||||
if (allow_cheats)
|
||||
init_cheats();
|
||||
#endif
|
||||
|
||||
g_extern.error_in_init = false;
|
||||
return 0;
|
||||
@ -2878,9 +2868,7 @@ void rarch_main_deinit(void)
|
||||
#endif
|
||||
deinit_rewind();
|
||||
|
||||
#ifdef HAVE_XML
|
||||
deinit_cheats();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BSV_MOVIE
|
||||
deinit_movie();
|
||||
|
@ -180,7 +180,7 @@ void config_set_defaults(void)
|
||||
g_settings.video.msg_color_g = ((message_color >> 8) & 0xff) / 255.0f;
|
||||
g_settings.video.msg_color_b = ((message_color >> 0) & 0xff) / 255.0f;
|
||||
|
||||
#if defined(HAVE_CG) || defined(HAVE_XML)
|
||||
#if defined(HAVE_CG) || defined(HAVE_GLSL)
|
||||
g_settings.video.render_to_texture = render_to_texture;
|
||||
g_settings.video.fbo.scale_x = fbo_scale_x;
|
||||
g_settings.video.fbo.scale_y = fbo_scale_y;
|
||||
@ -412,7 +412,6 @@ bool config_load_file(const char *path)
|
||||
CONFIG_GET_PATH(video.filter_path, "video_filter");
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CG) || defined(HAVE_XML)
|
||||
if (config_get_array(conf, "video_shader_type", tmp_str, sizeof(tmp_str)))
|
||||
{
|
||||
if (strcmp("cg", tmp_str) == 0)
|
||||
@ -424,11 +423,8 @@ bool config_load_file(const char *path)
|
||||
else if (strcmp("none", tmp_str) == 0)
|
||||
g_settings.video.shader_type = RARCH_SHADER_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_XML)
|
||||
CONFIG_GET_PATH(video.shader_dir, "video_shader_dir");
|
||||
#endif
|
||||
|
||||
CONFIG_GET_FLOAT(input.axis_threshold, "input_axis_threshold");
|
||||
CONFIG_GET_BOOL(input.netplay_client_swap_input, "netplay_client_swap_input");
|
||||
|
Loading…
Reference in New Issue
Block a user