summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDarren Salt <linux@youmustbejoking.demon.co.uk>2009-11-05 15:06:18 +0000
committerDarren Salt <linux@youmustbejoking.demon.co.uk>2009-11-05 15:06:18 +0000
commitca2c9c30b5a0f0fcab1ffb52bd065e335ffd4afe (patch)
treee43b190684d36f5ec7c4c089aec4dc42f48714f0 /src
parentcf86264961e27b47d57981bddb98364947ba7018 (diff)
parent2af40655557ffc8197e3e59b9428168c2454a68b (diff)
downloadxine-lib-ca2c9c30b5a0f0fcab1ffb52bd065e335ffd4afe.tar.gz
xine-lib-ca2c9c30b5a0f0fcab1ffb52bd065e335ffd4afe.tar.bz2
Merge from 1.1 (with adaptations).
--HG-- rename : src/xine-engine/scratch.h => include/xine/scratch.h rename : src/xine-utils/xmllexer.h => include/xine/xmllexer.h rename : src/xine-utils/xmlparser.h => include/xine/xmlparser.h rename : src/libspucmml/xine_cmml_decoder.c => src/spu_dec/cmml_decoder.c rename : src/libspuhdmv/xine_hdmv_decoder.c => src/spu_dec/spuhdmv_decoder.c
Diffstat (limited to 'src')
-rw-r--r--src/combined/ffmpeg/ff_video_decoder.c3
-rw-r--r--src/demuxers/demux_asf.c9
-rw-r--r--src/demuxers/demux_flac.c3
-rw-r--r--src/demuxers/demux_real.c3
-rw-r--r--src/input/input_dvb.c2
-rw-r--r--src/input/libdvdnav/dvd_reader.c2
-rw-r--r--src/spu_dec/cmml_decoder.c8
-rw-r--r--src/spu_dec/spuhdmv_decoder.c324
-rw-r--r--src/xine-engine/scratch.c2
-rw-r--r--src/xine-utils/monitor.c46
-rw-r--r--src/xine-utils/xmllexer.c165
-rw-r--r--src/xine-utils/xmlparser.c53
12 files changed, 368 insertions, 252 deletions
diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c
index f412274a0..c69433fbf 100644
--- a/src/combined/ffmpeg/ff_video_decoder.c
+++ b/src/combined/ffmpeg/ff_video_decoder.c
@@ -1180,7 +1180,8 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {
if (this->size == 0) {
/* take over pts when we are about to buffer a frame */
this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);
- this->context->reordered_opaque = ff_tag_pts(this, this->pts);
+ if (this->context) /* shouldn't be NULL */
+ this->context->reordered_opaque = ff_tag_pts(this, this->pts);
this->pts = 0;
}
diff --git a/src/demuxers/demux_asf.c b/src/demuxers/demux_asf.c
index 9d0447ce5..757e7ffd8 100644
--- a/src/demuxers/demux_asf.c
+++ b/src/demuxers/demux_asf.c
@@ -1540,6 +1540,7 @@ static int demux_asf_parse_asx_references( demux_asf_t *this) {
int buf_used = 0;
int len;
xml_node_t *xml_tree, *asx_entry, *asx_ref;
+ xml_parser_t *xml_parser;
int result;
@@ -1562,9 +1563,13 @@ static int demux_asf_parse_asx_references( demux_asf_t *this) {
if(buf_used)
buf[buf_used] = '\0';
- xml_parser_init(buf, buf_used, XML_PARSER_CASE_INSENSITIVE);
- if((result = xml_parser_build_tree(&xml_tree)) != XML_PARSER_OK)
+ xml_parser = xml_parser_init_r(buf, buf_used, XML_PARSER_CASE_INSENSITIVE);
+ if((result = xml_parser_build_tree_r(xml_parser, &xml_tree)) != XML_PARSER_OK) {
+ xml_parser_finalize_r(xml_parser);
goto failure;
+ }
+
+ xml_parser_finalize_r(xml_parser);
if(!strcasecmp(xml_tree->name, "ASX")) {
/* Attributes: VERSION, PREVIEWMODE, BANNERBAR
diff --git a/src/demuxers/demux_flac.c b/src/demuxers/demux_flac.c
index 9a01c9adf..8acddb3c6 100644
--- a/src/demuxers/demux_flac.c
+++ b/src/demuxers/demux_flac.c
@@ -33,6 +33,9 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
#define LOG_MODULE "demux_flac"
#define LOG_VERBOSE
diff --git a/src/demuxers/demux_real.c b/src/demuxers/demux_real.c
index d416ebeca..eecaef915 100644
--- a/src/demuxers/demux_real.c
+++ b/src/demuxers/demux_real.c
@@ -42,6 +42,9 @@
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
#define LOG_MODULE "demux_real"
#define LOG_VERBOSE
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
index 065a57b47..164ac2bc9 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -2863,6 +2863,8 @@ static int dvb_plugin_open(input_plugin_t * this_gen)
if (lastchannel.num_value) {
if (xine_config_lookup_entry(this->class->xine, "media.dvb.last_channel", &lastchannel)){
this->channel = lastchannel.num_value -1;
+ if (this->channel < 0 || this->channel >= num_channels)
+ this->channel = 0; /* out of range? default */
}else{
xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("input_dvb: invalid channel specification, defaulting to channel 0\n"));
this->channel = 0;
diff --git a/src/input/libdvdnav/dvd_reader.c b/src/input/libdvdnav/dvd_reader.c
index 4144b9133..e8e035b10 100644
--- a/src/input/libdvdnav/dvd_reader.c
+++ b/src/input/libdvdnav/dvd_reader.c
@@ -30,7 +30,9 @@
#include <string.h>
#include <unistd.h>
#include <limits.h>
+#ifdef HAVE_DIRENT_H
#include <dirent.h>
+#endif
#ifndef HAVE_GETTIMEOFDAY
# ifdef WIN32
diff --git a/src/spu_dec/cmml_decoder.c b/src/spu_dec/cmml_decoder.c
index 7f800cf20..02ef18540 100644
--- a/src/spu_dec/cmml_decoder.c
+++ b/src/spu_dec/cmml_decoder.c
@@ -239,6 +239,7 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen;
+ xml_parser_t *xml_parser;
xml_node_t *packet_xml_root;
char * anchor_text = NULL;
@@ -248,12 +249,15 @@ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) {
/* parse the CMML */
- xml_parser_init (str, strlen (str), XML_PARSER_CASE_INSENSITIVE);
- if (xml_parser_build_tree(&packet_xml_root) != XML_PARSER_OK) {
+ xml_parser = xml_parser_init_r (str, strlen (str), XML_PARSER_CASE_INSENSITIVE);
+ if (xml_parser_build_tree_r(xml_parser, &packet_xml_root) != XML_PARSER_OK) {
lprintf ("warning: invalid XML packet detected in CMML track\n");
+ xml_parser_finalize_r(xml_parser);
return;
}
+ xml_parser_finalize_r(xml_parser);
+
if (strcasecmp(packet_xml_root->name, "head") == 0) {
/* found a <head>...</head> packet: need to parse the title */
diff --git a/src/spu_dec/spuhdmv_decoder.c b/src/spu_dec/spuhdmv_decoder.c
index f23d34c50..bcd52ee3f 100644
--- a/src/spu_dec/spuhdmv_decoder.c
+++ b/src/spu_dec/spuhdmv_decoder.c
@@ -39,7 +39,7 @@
#define TRACE(x...) printf(x)
/*#define TRACE(x...) */
-#define ERROR(x...) fprintf(stderr, x)
+#define ERROR(x...) fprintf(stderr, "spuhdmv: " x)
/*#define ERROR(x...) lprintf(x) */
/*
@@ -51,6 +51,8 @@ struct subtitle_clut_s {
uint32_t color[256];
uint8_t trans[256];
subtitle_clut_t *next;
+
+ int shown;
};
/*
@@ -66,11 +68,15 @@ struct subtitle_object_s {
uint num_rle;
size_t data_size;
+#if 0
uint8_t *raw_data; /* partial RLE data in HDMV format */
size_t raw_data_len;
size_t raw_data_size;
+#endif
subtitle_object_t *next;
+
+ int shown;
};
/*
@@ -83,6 +89,8 @@ struct window_def_s {
uint16_t width, height;
window_def_t *next;
+
+ int shown;
};
@@ -102,9 +110,79 @@ struct composition_object_s {
uint16_t crop_width, crop_height;
composition_object_t *next;
+
+ int shown;
+};
+
+typedef struct composition_descriptor_s composition_descriptor_t;
+struct composition_descriptor_s {
+ uint16_t number;
+ uint8_t state;
+};
+
+typedef struct presentation_segment_s presentation_segment_t;
+struct presentation_segment_s {
+ composition_descriptor_t comp_descr;
+
+ uint8_t palette_update_flag;
+ uint8_t palette_id_ref;
+ uint8_t object_number;
+
+ composition_object_t *comp_objs;
+
+ presentation_segment_t *next;
+
+ int64_t pts;
+ int shown;
};
/*
+ * list handling
+ */
+
+#define LIST_REPLACE(list, obj, FREE_FUNC) \
+ do { \
+ uint id = obj->id; \
+ \
+ /* insert to list */ \
+ obj->next = list; \
+ list = obj; \
+ \
+ /* remove old */ \
+ while (obj->next && obj->next->id != id) \
+ obj = obj->next; \
+ if (obj->next) { \
+ void *tmp = (void*)obj->next; \
+ obj->next = obj->next->next; \
+ FREE_FUNC(tmp); \
+ } \
+ } while (0);
+
+#define LIST_DESTROY(list, FREE_FUNC) \
+ while (list) { \
+ void *tmp = (void*)list; \
+ list = list->next; \
+ FREE_FUNC(tmp); \
+ }
+
+static void free_subtitle_object(void *ptr)
+{
+ if (ptr) {
+ free(((subtitle_object_t*)ptr)->rle);
+ free(ptr);
+ }
+}
+static void free_presentation_segment(void *ptr)
+{
+ if (ptr) {
+ presentation_segment_t *seg = (presentation_segment_t*)ptr;
+ LIST_DESTROY(seg->comp_objs, free);
+ free(ptr);
+ }
+}
+
+
+/*
* segment_buffer_t
*
* assemble and decode segments
@@ -389,14 +467,14 @@ static subtitle_object_t *segbuf_decode_object(segment_buffer_t *buf)
segbuf_decode_rle (buf, obj);
if (buf->error) {
- free(obj);
+ free_subtitle_object(obj);
return NULL;
}
} else {
ERROR(" TODO: APPEND RLE, length %d bytes\n", buf->segment_len - 4);
/* TODO */
- free(obj);
+ free_subtitle_object(obj);
return NULL;
}
@@ -435,12 +513,6 @@ static int segbuf_decode_video_descriptor(segment_buffer_t *buf)
return buf->error;
}
-typedef struct composition_descriptor_s composition_descriptor_t;
-struct composition_descriptor_s {
- uint16_t number;
- uint8_t state;
-};
-
static int segbuf_decode_composition_descriptor(segment_buffer_t *buf, composition_descriptor_t *descr)
{
descr->number = segbuf_get_u16(buf);
@@ -482,9 +554,38 @@ static composition_object_t *segbuf_decode_composition_object(segment_buffer_t *
return cobj;
}
+static presentation_segment_t *segbuf_decode_presentation_segment(segment_buffer_t *buf)
+{
+ presentation_segment_t *seg = calloc(1, sizeof(presentation_segment_t));
+ int index;
+
+ segbuf_decode_video_descriptor (buf);
+ segbuf_decode_composition_descriptor (buf, &seg->comp_descr);
+
+ seg->palette_update_flag = !!((segbuf_get_u8(buf)) & 0x80);
+ seg->palette_id_ref = segbuf_get_u8 (buf);
+ seg->object_number = segbuf_get_u8 (buf);
+
+ TRACE(" presentation_segment: object_number %d, palette %d\n",
+ seg->object_number, seg->palette_id_ref);
+
+ for (index = 0; index < seg->object_number; index++) {
+ composition_object_t *cobj = segbuf_decode_composition_object (buf);
+ cobj->next = seg->comp_objs;
+ seg->comp_objs = cobj;
+ }
+
+ if (buf->error) {
+ free_presentation_segment(seg);
+ return NULL;
+ }
+
+ return seg;
+}
+
static rle_elem_t *copy_crop_rle(subtitle_object_t *obj, composition_object_t *cobj)
{
- /* TODO: exec cropping here (w,h sized image from pos x,y) */
+ /* TODO: cropping (w,h sized image from pos x,y) */
rle_elem_t *rle = calloc (obj->num_rle, sizeof(rle_elem_t));
memcpy (rle, obj->rle, obj->num_rle * sizeof(rle_elem_t));
@@ -508,57 +609,17 @@ typedef struct spuhdmv_decoder_s {
segment_buffer_t *buf;
- subtitle_clut_t *cluts;
- subtitle_object_t *objects;
- window_def_t *windows;
+ subtitle_clut_t *cluts;
+ subtitle_object_t *objects;
+ window_def_t *windows;
+ presentation_segment_t *segments;
+
int overlay_handles[MAX_OBJECTS];
int64_t pts;
} spuhdmv_decoder_t;
-#define LIST_REPLACE_OLD(type, list, obj) \
- do { \
- /* insert to list */ \
- obj->next = list; \
- list = obj; \
-\
- /* remove old */ \
- type *i = list; \
- while (i->next && i->next->id != obj->id) \
- i = i->next; \
- if (i->next) { \
- void *tmp = (void*)i->next; \
- i->next = i->next->next; \
- free(tmp); \
- } \
- } while (0);
-
-#define LIST_REPLACE(list, obj) \
- do { \
- uint id = obj->id; \
- \
- /* insert to list */ \
- obj->next = list; \
- list = obj; \
- \
- /* remove old */ \
- while (obj->next && obj->next->id != id) \
- obj = obj->next; \
- if (obj->next) { \
- void *tmp = (void*)obj->next; \
- obj->next = obj->next->next; \
- free(tmp); \
- } \
- } while (0);
-
-#define LIST_DESTROY(list) \
- while (list) { \
- void *tmp = (void*)list; \
- list = list->next; \
- free (tmp); \
- }
-
static int decode_palette(spuhdmv_decoder_t *this)
{
/* decode */
@@ -566,7 +627,7 @@ static int decode_palette(spuhdmv_decoder_t *this)
if (!clut)
return 1;
- LIST_REPLACE (this->cluts, clut);
+ LIST_REPLACE (this->cluts, clut, free);
return 0;
}
@@ -578,7 +639,7 @@ static int decode_object(spuhdmv_decoder_t *this)
if (!obj)
return 1;
- LIST_REPLACE (this->objects, obj);
+ LIST_REPLACE (this->objects, obj, free_subtitle_object);
return 0;
}
@@ -590,13 +651,30 @@ static int decode_window_definition(spuhdmv_decoder_t *this)
if (!wnd)
return 1;
- LIST_REPLACE (this->windows, wnd);
+ LIST_REPLACE (this->windows, wnd, free);
+
+ return 0;
+}
+
+static int decode_presentation_segment(spuhdmv_decoder_t *this)
+{
+ /* decode */
+ presentation_segment_t *seg = segbuf_decode_presentation_segment(this->buf);
+ if (!seg)
+ return 1;
+
+ seg->pts = this->pts;
+
+ /* replace */
+ if (this->segments)
+ LIST_DESTROY(this->segments, free_presentation_segment);
+ this->segments = seg;
return 0;
}
static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uint palette_id_ref,
- int overlay_index, int64_t pts)
+ int overlay_index, int64_t pts, int force_update)
{
video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out);
metronom_t *metronom = this->stream->metronom;
@@ -608,21 +686,16 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin
while (clut && clut->id != palette_id_ref)
clut = clut->next;
if (!clut) {
- ERROR(" fill_overlay: clut %d not found !\n", palette_id_ref);
+ TRACE(" show_overlay: clut %d not found !\n", palette_id_ref);
return -1;
}
- /* copy palette to xine overlay */
- overlay.rgb_clut = 0;
- memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256);
- memcpy(overlay.trans, clut->trans, sizeof(uint8_t) * 256);
-
/* find RLE image */
subtitle_object_t *obj = this->objects;
while (obj && obj->id != cobj->object_id_ref)
obj = obj->next;
if (!obj) {
- ERROR(" fill_overlay: object %d not found !\n", cobj->object_id_ref);
+ TRACE(" show_overlay: object %d not found !\n", cobj->object_id_ref);
return -1;
}
@@ -631,10 +704,20 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin
while (wnd && wnd->id != cobj->window_id_ref)
wnd = wnd->next;
if (!wnd) {
- ERROR(" fill_overlay: window %d not found !\n", cobj->window_id_ref);
+ TRACE(" show_overlay: window %d not found !\n", cobj->window_id_ref);
return -1;
}
+ /* do not show again if all elements are unchanged */
+ if (!force_update && clut->shown && obj->shown && wnd->shown && cobj->shown)
+ return 0;
+ clut->shown = obj->shown = wnd->shown = cobj->shown = 1;
+
+ /* copy palette to xine overlay */
+ overlay.rgb_clut = 0;
+ memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256);
+ memcpy(overlay.trans, clut->trans, sizeof(uint8_t) * 256);
+
/* copy and crop RLE image to xine overlay */
overlay.width = obj->width;
overlay.height = obj->height;
@@ -680,41 +763,9 @@ static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, uin
ovl_manager->add_event (ovl_manager, (void *)&event);
- obj->rle = NULL;
-
return 0;
}
-typedef struct presentation_segment_s presentation_segment_t;
-struct presentation_segment_s {
- composition_descriptor_t comp_descr;
-
- uint8_t palette_update_flag;
- uint8_t palette_id_ref;
- uint8_t object_number;
-
- composition_object_t *comp_objs;
-
- presentation_segment_t *next;
-
- int64_t pts;
-};
-
-static void show_overlays(spuhdmv_decoder_t *this, presentation_segment_t *pseg)
-{
- composition_object_t *cobj = pseg->comp_objs;
- int i;
-
- for (i = 0; i < pseg->object_number; i++) {
- if (!cobj) {
- ERROR("show_overlays: composition object %d missing !\n", i);
- } else {
- show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts);
- cobj = cobj->next;
- }
- }
-}
-
static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts)
{
video_overlay_event_t event = {0};
@@ -740,38 +791,46 @@ static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts)
}
}
-static int decode_presentation_segment(spuhdmv_decoder_t *this)
+static void update_overlays(spuhdmv_decoder_t *this)
{
- presentation_segment_t p = {};
- segment_buffer_t *buf = this->buf;
- int index;
+ presentation_segment_t *pseg = this->segments;
- segbuf_decode_video_descriptor (this->buf);
- segbuf_decode_composition_descriptor (this->buf, &p.comp_descr);
+ while (pseg) {
- p.palette_update_flag = !!((segbuf_get_u8(buf)) & 0x80);
- p.palette_id_ref = segbuf_get_u8 (buf);
- p.object_number = segbuf_get_u8 (buf);
+ if (!pseg->comp_descr.state) {
- TRACE(" presentation_segment: object_number %d, palette %d\n",
- p.object_number, p.palette_id_ref);
+ /* HIDE */
+ if (!pseg->shown)
+ hide_overlays (this, pseg->pts);
- p.pts = this->pts; /* !! todo - use it ? */
+ } else {
- for (index = 0; index < p.object_number; index++) {
- composition_object_t *cobj = segbuf_decode_composition_object (this->buf);
- cobj->next = p.comp_objs;
- p.comp_objs = cobj;
- }
+ /* SHOW */
+ composition_object_t *cobj = pseg->comp_objs;
+ int i;
+
+ for (i = 0; i < pseg->object_number; i++) {
+ if (!cobj) {
+ ERROR("show_overlays: composition object %d missing !\n", i);
+ } else {
+ show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts, !pseg->shown);
+ cobj = cobj->next;
+ }
+ }
+ }
- if (!p.comp_descr.state) {
- hide_overlays (this, this->pts);
- } else {
- show_overlays (this, &p);
- LIST_DESTROY (p.comp_objs);
+ pseg->shown = 1;
+
+ pseg = pseg->next;
}
+}
- return buf->error;
+static void free_objs(spuhdmv_decoder_t *this)
+{
+ LIST_DESTROY (this->cluts, free);
+ LIST_DESTROY (this->objects, free_subtitle_object);
+ LIST_DESTROY (this->windows, free);
+ LIST_DESTROY (this->segments, free_presentation_segment);
}
static void decode_segment(spuhdmv_decoder_t *this)
@@ -801,13 +860,8 @@ static void decode_segment(spuhdmv_decoder_t *this)
break;
case 0x80:
TRACE(" segment: END OF DISPLAY\n");
- {
- int64_t pts = xine_get_current_vpts(this->stream) -
- this->stream->metronom->get_option(this->stream->metronom,
- METRONOM_VPTS_OFFSET);
- TRACE(" * current pts = %ld\n", pts);
- }
-
+ /* drop all cached objects */
+ free_objs(this);
break;
default:
ERROR(" segment type 0x%x unknown, skipping\n", this->buf->segment_type);
@@ -816,11 +870,13 @@ static void decode_segment(spuhdmv_decoder_t *this)
if (this->buf->error) {
ERROR("*** DECODE ERROR ***\n");
}
+
+ update_overlays (this);
}
static void close_osd(spuhdmv_decoder_t *this)
{
- video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out);
+ video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out);
int i = 0;
while (this->overlay_handles[i] >= 0) {
@@ -865,9 +921,7 @@ static void spudec_reset (spu_decoder_t * this_gen)
if (this->buf)
segbuf_reset(this->buf);
- LIST_DESTROY (this->cluts);
- LIST_DESTROY (this->objects);
- LIST_DESTROY (this->windows);
+ free_objs(this);
close_osd(this);
}
@@ -886,9 +940,7 @@ static void spudec_dispose (spu_decoder_t *this_gen)
close_osd (this);
segbuf_dispose (this->buf);
- LIST_DESTROY (this->cluts);
- LIST_DESTROY (this->objects);
- LIST_DESTROY (this->windows);
+ free_objs(this);
free (this);
}
diff --git a/src/xine-engine/scratch.c b/src/xine-engine/scratch.c
index f01ea9c7d..02c415e96 100644
--- a/src/xine-engine/scratch.c
+++ b/src/xine-engine/scratch.c
@@ -36,7 +36,7 @@
#include <xine/xineutils.h>
#include <xine/scratch.h>
-static void __attribute__((__format__(__printf__, 2, 0)))
+static void XINE_FORMAT_PRINTF(2, 0)
scratch_printf (scratch_buffer_t *this, const char *format, va_list argp)
{
time_t t;
diff --git a/src/xine-utils/monitor.c b/src/xine-utils/monitor.c
index 59d8a63d2..906cd9278 100644
--- a/src/xine-utils/monitor.c
+++ b/src/xine-utils/monitor.c
@@ -32,41 +32,42 @@
#ifndef NDEBUG
-static long long int profiler_times[MAX_ID] ;
-static long long int profiler_start[MAX_ID] ;
-static long profiler_calls[MAX_ID] ;
-static const char *profiler_label[MAX_ID] ;
+typedef struct {
+ uint64_t p_times;
+ uint64_t p_start;
+ long p_calls;
+ const char *p_label;
+} xine_profiler_t;
+
+static xine_profiler_t profiler[MAX_ID];
void xine_profiler_init () {
- memset(profiler_times, 0, sizeof(profiler_times));
- memset(profiler_start, 0, sizeof(profiler_start));
- memset(profiler_calls, 0, sizeof(profiler_calls));
- memset(profiler_label, 0, sizeof(profiler_label));
+ memset(profiler, 0, sizeof(profiler));
}
int xine_profiler_allocate_slot (const char *label) {
int id;
- for (id = 0; id < MAX_ID && profiler_label[id] != NULL; id++)
+ for (id = 0; id < MAX_ID && profiler[id].p_label != NULL; id++)
;
if (id >= MAX_ID)
return -1;
- profiler_label[id] = label;
+ profiler[id].p_label = label;
return id;
}
#if defined(ARCH_X86_32)
-static __inline__ unsigned long long int rdtsc(void)
+static __inline__ uint64_t rdtsc(void)
{
unsigned long long int x;
__asm__ volatile ("rdtsc\n\t" : "=A" (x));
return x;
}
#elif defined(ARCH_X86_64)
-static __inline__ unsigned long long int rdtsc(void)
+static __inline__ uint64_t rdtsc(void)
{
unsigned long long int a, d;
__asm__ volatile ("rdtsc\n\t" : "=a" (a), "=d" (d));
@@ -78,7 +79,7 @@ void xine_profiler_start_count (int id) {
if ( id >= MAX_ID || id < 0 ) return;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- profiler_start[id] = rdtsc();
+ profiler[id].p_start = rdtsc();
#endif
}
@@ -86,18 +87,19 @@ void xine_profiler_stop_count (int id) {
if ( id >= MAX_ID || id < 0 ) return;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- profiler_times[id] += rdtsc() - profiler_start[id];
+ profiler[id].p_times += rdtsc() - profiler[id].p_start;
#endif
- profiler_calls[id]++;
+ profiler[id].p_calls++;
}
void xine_profiler_print_results (void) {
int i;
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- static long long int cpu_speed; /* cpu cyles/usec */
+ static uint64_t cpu_speed; /* cpu cyles/usec */
+
if (!cpu_speed) {
- long long int tsc_start, tsc_end;
+ uint64_t tsc_start, tsc_end;
struct timeval tv_start, tv_end;
tsc_start = rdtsc();
@@ -119,13 +121,13 @@ void xine_profiler_print_results (void) {
"----------------------------------------------------------------------------\n",
"ID", "name", "cpu cycles", "calls", "cycles/call", "usec/call");
for (i=0; i<MAX_ID; i++) {
- if (profiler_label[i]) {
+ if (profiler[i].p_label) {
printf ("%2d: %-24.24s %12lld %9ld",
- i, profiler_label[i], profiler_times[i], profiler_calls[i]);
- if (profiler_calls[i]) {
- printf(" %12lld", profiler_times[i] / profiler_calls[i]);
+ i, profiler[i].p_label, profiler[i].p_times, profiler[i].p_calls);
+ if (profiler[i].p_calls) {
+ printf(" %12lld", profiler[i].p_times / profiler[i].p_calls);
#if defined(ARCH_X86) || defined(ARCH_X86_64)
- printf(" %9lld", profiler_times[i] / (cpu_speed * profiler_calls[i]));
+ printf(" %9lld", profiler[i].p_times / (cpu_speed * profiler[i].p_calls));
#endif
}
printf ("\n");
diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c
index a535b7aca..c37510903 100644
--- a/src/xine-utils/xmllexer.c
+++ b/src/xine-utils/xmllexer.c
@@ -48,15 +48,11 @@
/* private constants*/
/* private global variables */
-static const char * lexbuf;
-static int lexbuf_size = 0;
-static int lexbuf_pos = 0;
-static int in_comment = 0;
-static char *lex_malloc = NULL;
+struct lexer * static_lexer;
enum utf { UTF32BE, UTF32LE, UTF16BE, UTF16LE };
-static void lex_convert (const char * buf, int size, enum utf utf)
+static void lex_convert (struct lexer * lexer, const char * buf, int size, enum utf utf)
{
char *utf8 = malloc (size * (utf >= UTF16BE ? 3 : 6) + 1);
char *bp = utf8;
@@ -88,8 +84,16 @@ static void lex_convert (const char * buf, int size, enum utf utf)
}
}
*bp = 0;
- lexbuf_size = bp - utf8;
- lexbuf = lex_malloc = realloc (utf8, lexbuf_size + 1);
+ lexer->lexbuf_size = bp - utf8;
+ lexer->lexbuf = lexer->lex_malloc = realloc (utf8, lexer->lexbuf_size + 1);
+}
+
+/* for ABI compatibility */
+void lexer_init(const char * buf, int size) {
+ if (static_lexer) {
+ lexer_finalize_r(static_lexer);
+ }
+ static_lexer = lexer_init_r(buf, size);
}
static enum {
@@ -98,35 +102,40 @@ static enum {
CDATA,
} lex_mode = NORMAL;
-void lexer_init(const char * buf, int size) {
+struct lexer *lexer_init_r(const char * buf, int size) {
static const char boms[] = { 0xFF, 0xFE, 0, 0, 0xFE, 0xFF },
bom_utf8[] = { 0xEF, 0xBB, 0xBF };
+ struct lexer * lexer = calloc (1, sizeof (*lexer));
- free (lex_malloc);
- lex_malloc = NULL;
-
- lexbuf = buf;
- lexbuf_size = size;
+ lexer->lexbuf = buf;
+ lexer->lexbuf_size = size;
if (size >= 4 && !memcmp (buf, boms + 2, 4))
- lex_convert (buf + 4, size - 4, UTF32BE);
+ lex_convert (lexer, buf + 4, size - 4, UTF32BE);
else if (size >= 4 && !memcmp (buf, boms, 4))
- lex_convert (buf + 4, size - 4, UTF32LE);
+ lex_convert (lexer, buf + 4, size - 4, UTF32LE);
else if (size >= 3 && !memcmp (buf, bom_utf8, 3))
{
- lexbuf += 3;
- lexbuf_size -= 3;
+ lexer->lexbuf += 3;
+ lexer->lexbuf_size -= 3;
}
else if (size >= 2 && !memcmp (buf, boms + 4, 2))
- lex_convert (buf + 2, size - 2, UTF16BE);
+ lex_convert (lexer, buf + 2, size - 2, UTF16BE);
else if (size >= 2 && !memcmp (buf, boms, 2))
- lex_convert (buf + 2, size - 2, UTF16LE);
+ lex_convert (lexer, buf + 2, size - 2, UTF16LE);
- lexbuf_pos = 0;
- lex_mode = NORMAL;
- in_comment = 0;
+ lexer->lexbuf_pos = 0;
+ lexer->lex_mode = NORMAL;
+ lexer->in_comment = 0;
lprintf("buffer length %d\n", size);
+ return lexer;
+}
+
+void lexer_finalize_r(struct lexer * lexer)
+{
+ free(lexer->lex_malloc);
+ free(lexer);
}
typedef enum {
@@ -147,19 +156,25 @@ typedef enum {
STATE_IDENT /* must be last */
} lexer_state_t;
+/* for ABI compatibility */
int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
+ return lexer_get_token_d_r(static_lexer, _tok, _tok_size, fixed);
+}
+
+int lexer_get_token_d_r(struct lexer * lexer, char ** _tok, int * _tok_size, int fixed) {
char *tok = *_tok;
int tok_size = *_tok_size;
+
int tok_pos = 0;
lexer_state_t state = STATE_IDLE;
char c;
if (tok) {
- while ((tok_pos < tok_size) && (lexbuf_pos < lexbuf_size)) {
- c = lexbuf[lexbuf_pos];
- lprintf("c=%c, state=%d, lex_mode=%d, in_comment=%d\n", c, state, lex_mode, in_comment);
+ while ((tok_pos < tok_size) && (lexer->lexbuf_pos < lexer->lexbuf_size)) {
+ c = lexer->lexbuf[lexer->lexbuf_pos];
+ lprintf("c=%c, state=%d, in_comment=%d\n", c, state, lexer->in_comment);
- switch (lex_mode) {
+ switch (lexer->lex_mode) {
case NORMAL:
switch (state) {
/* init state */
@@ -192,7 +207,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
break;
case '/':
- if (!in_comment)
+ if (!lexer->in_comment)
state = STATE_T_M_STOP_2;
tok[tok_pos] = c;
tok_pos++;
@@ -219,7 +234,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
break;
case '?':
- if (!in_comment)
+ if (!lexer->in_comment)
state = STATE_T_TI_STOP;
tok[tok_pos] = c;
tok_pos++;
@@ -231,14 +246,14 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
tok_pos++;
break;
}
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
break;
/* end of line */
case STATE_EOL:
if (c == '\n' || (c == '\r')) {
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++;
} else {
tok[tok_pos] = '\0';
@@ -250,7 +265,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case STATE_SEPAR:
if (c == ' ' || (c == '\t')) {
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++;
} else {
tok[tok_pos] = '\0';
@@ -263,20 +278,20 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
switch (c) {
case '/':
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
return T_M_START_2;
break;
case '!':
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++;
state = STATE_T_COMMENT;
break;
case '?':
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
return T_TI_START;
@@ -290,8 +305,8 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
/* T_M_STOP_1 */
case STATE_T_M_STOP_1:
tok[tok_pos] = '\0';
- if (!in_comment)
- lex_mode = DATA;
+ if (!lexer->in_comment)
+ lexer->lex_mode = DATA;
return T_M_STOP_1;
break;
@@ -299,11 +314,11 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case STATE_T_M_STOP_2:
if (c == '>') {
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
- if (!in_comment)
- lex_mode = DATA;
+ if (!lexer->in_comment)
+ lexer->lex_mode = DATA;
return T_M_STOP_2;
} else {
tok[tok_pos] = '\0';
@@ -320,7 +335,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
/* T_STRING */
case STATE_T_STRING_DOUBLE:
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
if (c == '\"') { /* " */
tok[tok_pos] = '\0'; /* FIXME */
return T_STRING;
@@ -332,33 +347,33 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case STATE_T_COMMENT:
switch (c) {
case '-':
- lexbuf_pos++;
- if (lexbuf[lexbuf_pos] == '-')
+ lexer->lexbuf_pos++;
+ if (lexer->lexbuf[lexer->lexbuf_pos] == '-')
{
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok[tok_pos++] = '-'; /* FIXME */
tok[tok_pos++] = '-';
tok[tok_pos] = '\0';
- in_comment = 1;
+ lexer->in_comment = 1;
return T_C_START;
}
break;
case 'D':
- lexbuf_pos++;
- if (strncmp(lexbuf + lexbuf_pos, "OCTYPE", 6) == 0) {
+ lexer->lexbuf_pos++;
+ if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "OCTYPE", 6) == 0) {
strncpy(tok + tok_pos, "DOCTYPE", 7); /* FIXME */
- lexbuf_pos += 6;
+ lexer->lexbuf_pos += 6;
return T_DOCTYPE_START;
} else {
return T_ERROR;
}
break;
case '[':
- lexbuf_pos++;
- if (strncmp(lexbuf + lexbuf_pos, "CDATA[", 6) == 0) {
+ lexer->lexbuf_pos++;
+ if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "CDATA[", 6) == 0) {
strncpy (tok + tok_pos, "[CDATA[", 7); /* FIXME */
- lexbuf_pos += 6;
- lex_mode = CDATA;
+ lexer->lexbuf_pos += 6;
+ lexer->lex_mode = CDATA;
return T_CDATA_START;
} else{
return T_ERROR;
@@ -374,11 +389,11 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case STATE_T_TI_STOP:
if (c == '>') {
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
- if (!in_comment)
- lex_mode = DATA;
+ if (!lexer->in_comment)
+ lexer->lex_mode = DATA;
return T_TI_STOP;
} else {
tok[tok_pos] = '\0';
@@ -392,13 +407,13 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case '-':
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_T_C_STOP;
break;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_IDENT;
}
break;
@@ -409,21 +424,21 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case '>':
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
tok[tok_pos] = '\0'; /* FIX ME */
if (strlen(tok) != 3) {
tok[tok_pos - 3] = '\0';
- lexbuf_pos -= 3;
+ lexer->lexbuf_pos -= 3;
return T_IDENT;
} else {
- in_comment = 0;
+ lexer->in_comment = 0;
return T_C_STOP;
}
break;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_IDENT;
}
break;
@@ -431,7 +446,7 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
/* T_STRING (single quotes) */
case STATE_T_STRING_SINGLE:
tok[tok_pos] = c;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
if (c == '\'') { /* " */
tok[tok_pos] = '\0'; /* FIXME */
return T_STRING;
@@ -458,19 +473,19 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
case '?':
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_T_TI_STOP;
break;
case '-':
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
state = STATE_T_DASHDASH;
break;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
}
break;
default:
@@ -484,12 +499,12 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
{
case '<':
tok[tok_pos] = '\0';
- lex_mode = NORMAL;
+ lexer->lex_mode = NORMAL;
return T_DATA;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
}
break;
@@ -497,26 +512,26 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
switch (c)
{
case ']':
- if (strncmp(lexbuf + lexbuf_pos, "]]>", 3) == 0) {
- lexbuf_pos += 3;
- lex_mode = DATA;
+ if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "]]>", 3) == 0) {
+ lexer->lexbuf_pos += 3;
+ lexer->lex_mode = DATA;
return T_CDATA_STOP;
} else {
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
}
break;
default:
tok[tok_pos] = c;
tok_pos++;
- lexbuf_pos++;
+ lexer->lexbuf_pos++;
}
break;
}
}
lprintf ("loop done tok_pos = %d, tok_size=%d, lexbuf_pos=%d, lexbuf_size=%d\n",
- tok_pos, tok_size, lexbuf_pos, lexbuf_size);
+ tok_pos, tok_size, lexer->lexbuf_pos, lexer->lexbuf_size);
/* pb */
if (tok_pos >= tok_size) {
@@ -527,12 +542,12 @@ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) {
lprintf("token buffer is too small\n");
lprintf("increasing buffer size to %d bytes\n", *_tok_size);
if (*_tok) {
- return lexer_get_token_d (_tok, _tok_size, 0);
+ return lexer_get_token_d_r (lexer, _tok, _tok_size, 0);
} else {
return T_ERROR;
}
} else {
- if (lexbuf_pos >= lexbuf_size) {
+ if (lexer->lexbuf_pos >= lexer->lexbuf_size) {
/* Terminate the current token */
tok[tok_pos] = '\0';
switch (state) {
diff --git a/src/xine-utils/xmlparser.c b/src/xine-utils/xmlparser.c
index c5acf8739..7ae0626eb 100644
--- a/src/xine-utils/xmlparser.c
+++ b/src/xine-utils/xmlparser.c
@@ -55,7 +55,7 @@
#define MAX_RECURSION 10
/* private global variables */
-static int xml_parser_mode;
+xml_parser_t * static_xml_parser;
/* private functions */
@@ -106,10 +106,24 @@ static void free_xml_property(xml_property_t * property) {
free(property);
}
+/* for ABI compatibility */
void xml_parser_init(const char * buf, int size, int mode) {
+ if (static_xml_parser) {
+ xml_parser_finalize_r(static_xml_parser);
+ }
+ static_xml_parser = xml_parser_init_r(buf, size, mode);
+}
- lexer_init(buf, size);
- xml_parser_mode = mode;
+xml_parser_t *xml_parser_init_r(const char * buf, int size, int mode) {
+ xml_parser_t *xml_parser = malloc(sizeof(*xml_parser));
+ xml_parser->lexer = lexer_init_r(buf, size);
+ xml_parser->mode = mode;
+ return xml_parser;
+}
+
+void xml_parser_finalize_r(xml_parser_t *xml_parser) {
+ lexer_finalize_r(xml_parser->lexer);
+ free(xml_parser);
}
static void xml_parser_free_props(xml_property_t *current_property) {
@@ -223,7 +237,9 @@ static xml_node_t *xml_parser_append_text (xml_node_t *node, xml_node_t *subnode
#define Q_STATE(CURRENT,NEW) (STATE_##NEW + state - STATE_##CURRENT)
-static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffer_size,
+
+static int xml_parser_get_node_internal (xml_parser_t *xml_parser,
+ char ** token_buffer, int * token_buffer_size,
char ** pname_buffer, int * pname_buffer_size,
char ** nname_buffer, int * nname_buffer_size,
xml_node_t *current_node, char *root_names[], int rec, int flags)
@@ -245,7 +261,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
memset (tok, 0, *token_buffer_size);
- while ((bypass_get_token) || (res = lexer_get_token_d(token_buffer, token_buffer_size, 0)) != T_ERROR) {
+ while ((bypass_get_token) || (res = lexer_get_token_d_r(xml_parser->lexer, token_buffer, token_buffer_size, 0)) != T_ERROR) {
tok = *token_buffer;
bypass_get_token = 0;
lprintf("info: %d - %d : '%s'\n", state, res, tok);
@@ -302,7 +318,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
current_property = NULL;
/* save node name */
- if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) {
+ if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) {
strtoupper(tok);
}
if (state == STATE_Q_NODE) {
@@ -343,7 +359,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
subtree->props = properties;
lprintf("info: rec %d new subtree %s\n", rec, node_name);
root_names[rec + 1] = strdup (node_name);
- parse_res = xml_parser_get_node_internal (token_buffer, token_buffer_size,
+ parse_res = xml_parser_get_node_internal (xml_parser, token_buffer, token_buffer_size,
pname_buffer, pname_buffer_size,
nname_buffer, nname_buffer_size,
subtree, root_names, rec + 1, flags);
@@ -390,7 +406,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
case (T_IDENT):
/* save property name */
new_prop:
- if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) {
+ if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) {
strtoupper(tok);
}
/* make sure the buffer for the property name is big enough */
@@ -431,7 +447,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
switch (res) {
case (T_IDENT):
/* must be equal to root_name */
- if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) {
+ if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) {
strtoupper(tok);
}
if (strcmp(tok, root_names[rec]) == 0) {
@@ -643,7 +659,7 @@ static int xml_parser_get_node_internal (char ** token_buffer, int * token_buffe
}
}
-static int xml_parser_get_node (xml_node_t *current_node, int flags)
+static int xml_parser_get_node (xml_parser_t *xml_parser, xml_node_t *current_node, int flags)
{
int res = 0;
int token_buffer_size = TOKEN_SIZE;
@@ -655,7 +671,8 @@ static int xml_parser_get_node (xml_node_t *current_node, int flags)
char *root_names[MAX_RECURSION + 1];
root_names[0] = "";
- res = xml_parser_get_node_internal (&token_buffer, &token_buffer_size,
+ res = xml_parser_get_node_internal (xml_parser,
+ &token_buffer, &token_buffer_size,
&pname_buffer, &pname_buffer_size,
&nname_buffer, &nname_buffer_size,
current_node, root_names, 0, flags);
@@ -667,12 +684,17 @@ static int xml_parser_get_node (xml_node_t *current_node, int flags)
return res;
}
+/* for ABI compatibility */
int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) {
+ return xml_parser_build_tree_with_options_r(static_xml_parser, root_node, flags);
+}
+
+int xml_parser_build_tree_with_options_r(xml_parser_t *xml_parser, xml_node_t **root_node, int flags) {
xml_node_t *tmp_node, *pri_node, *q_node;
int res;
tmp_node = new_xml_node();
- res = xml_parser_get_node(tmp_node, flags);
+ res = xml_parser_get_node(xml_parser, tmp_node, flags);
/* delete any top-level [CDATA] nodes */;
pri_node = tmp_node->child;
@@ -715,8 +737,13 @@ int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) {
return res;
}
+/* for ABI compatibility */
int xml_parser_build_tree(xml_node_t **root_node) {
- return xml_parser_build_tree_with_options (root_node, 0);
+ return xml_parser_build_tree_with_options_r (static_xml_parser, root_node, 0);
+}
+
+int xml_parser_build_tree_r(xml_parser_t *xml_parser, xml_node_t **root_node) {
+ return xml_parser_build_tree_with_options_r(xml_parser, root_node, 0);
}
const char *xml_parser_get_property (const xml_node_t *node, const char *name) {