From: <li...@yo...> - 2007-08-30 14:21:18
|
# [node 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca part 1] diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca src/xine-engine/resample.c --- a/src/xine-engine/resample.c Thu Aug 30 15:20:19 2007 +0100 +++ b/src/xine-engine/resample.c Thu Jun 21 23:28:29 2007 +0100 @@ -24,26 +24,34 @@ #include "config.h" #endif +#include <string.h> #include <inttypes.h> #include "attributes.h" #include "resample.h" /* contributed by paul flinders */ -void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_mono(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); - -#ifdef VERBOSE - printf ("Audio : resample %d samples to %d\n", - in_samples, out_samples); -#endif - - for (osample = 0; osample < out_samples - 1; osample++) { + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; + +#ifdef VERBOSE + printf ("Audio : resample %d samples to %d\n", + in_samples, out_samples); +#endif + + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -58,23 +66,31 @@ void _x_audio_out_resample_mono(int16_t* isample += istep; } - output_samples[out_samples-1] = input_samples[in_samples-1]; -} - -void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples, + last_sample[0] = input_samples[in_samples - 1]; +} + +void _x_audio_out_resample_stereo(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); - -#ifdef VERBOSE - printf ("Audio : resample %d samples to %d\n", - in_samples, out_samples); -#endif - - for (osample = 0; osample < out_samples - 1; osample++) { + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; + +#ifdef VERBOSE + printf ("Audio : resample %d samples to %d\n", + in_samples, out_samples); +#endif + + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*2 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*2+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -94,25 +110,34 @@ void _x_audio_out_resample_stereo(int16_ output_samples[(osample * 2 )+1] = os; isample += istep; } - output_samples[out_samples*2-2] = input_samples[in_samples*2-2]; - output_samples[out_samples*2-1] = input_samples[in_samples*2-1]; -} - - -void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples, + memcpy (last_sample, &input_samples[in_samples*2-2], 2 * sizeof (last_sample[0])); +} + + +void _x_audio_out_resample_4channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); - -#ifdef VERBOSE - printf ("Audio : resample %d samples to %d\n", - in_samples, out_samples); -#endif - - for (osample = 0; osample < out_samples - 1; osample++) { + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; + +#ifdef VERBOSE + printf ("Audio : resample %d samples to %d\n", + in_samples, out_samples); [... 12 lines omitted ...] int s1; int s2; int16_t os; @@ -145,28 +170,35 @@ void _x_audio_out_resample_4channel(int1 isample += istep; } - output_samples[out_samples*4-4] = input_samples[in_samples*4-4]; - output_samples[out_samples*4-3] = input_samples[in_samples*4-3]; - output_samples[out_samples*4-2] = input_samples[in_samples*4-2]; - output_samples[out_samples*4-1] = input_samples[in_samples*4-1]; - -} - - -void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples, + memcpy (last_sample, &input_samples[in_samples*4-4], 4 * sizeof (last_sample[0])); +} + + +void _x_audio_out_resample_5channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); - -#ifdef VERBOSE - printf ("Audio : resample %d samples to %d\n", - in_samples, out_samples); -#endif - - for (osample = 0; osample < out_samples - 1; osample++) { + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; + +#ifdef VERBOSE + printf ("Audio : resample %d samples to %d\n", + in_samples, out_samples); +#endif + + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*5 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*5+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + output_samples[osample*5+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; + output_samples[osample*5+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; + output_samples[osample*5+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -205,29 +237,36 @@ void _x_audio_out_resample_5channel(int1 isample += istep; } - - output_samples[out_samples*5-5] = input_samples[in_samples*5-5]; - output_samples[out_samples*5-4] = input_samples[in_samples*5-4]; - output_samples[out_samples*5-3] = input_samples[in_samples*5-3]; - output_samples[out_samples*5-2] = input_samples[in_samples*5-2]; - output_samples[out_samples*5-1] = input_samples[in_samples*5-1]; -} - - -void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples, + memcpy (last_sample, &input_samples[in_samples*5-5], 5 * sizeof (last_sample[0])); +} + + +void _x_audio_out_resample_6channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); - -#ifdef VERBOSE - printf ("Audio : resample %d samples to %d\n", - in_samples, out_samples); -#endif - - for (osample = 0; osample < out_samples - 1; osample++) { + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; + +#ifdef VERBOSE + printf ("Audio : resample %d samples to %d\n", + in_samples, out_samples); +#endif + + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*6 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*6+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + output_samples[osample*6+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; + output_samples[osample*6+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; + output_samples[osample*6+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16; + output_samples[osample*6+5] = (last_sample[5] * (0x10000-t) + input_samples[5] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -272,13 +311,7 @@ void _x_audio_out_resample_6channel(int1 isample += istep; } - - output_samples[out_samples*6-6] = input_samples[in_samples*6-6]; - output_samples[out_samples*6-5] = input_samples[in_samples*6-5]; - output_samples[out_samples*6-4] = input_samples[in_samples*6-4]; - output_samples[out_samples*6-3] = input_samples[in_samples*6-3]; - output_samples[out_samples*6-2] = input_samples[in_samples*6-2]; - output_samples[out_samples*6-1] = input_samples[in_samples*6-1]; + memcpy (last_sample, &input_samples[in_samples*6-6], 6 * sizeof (last_sample[0])); } void _x_audio_out_resample_8to16(int8_t* input_samples, diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca src/xine-engine/resample.h --- a/src/xine-engine/resample.h Thu Aug 30 15:20:19 2007 +0100 +++ b/src/xine-engine/resample.h Thu Jun 21 23:28:29 2007 +0100 @@ -27,19 +27,26 @@ #ifndef HAVE_RESAMPLE_H #define HAVE_RESAMPLE_H -void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples, +#define RESAMPLE_MAX_CHANNELS 6 + +void _x_audio_out_resample_stereo(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; -void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_mono(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; -void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_4channel(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; -void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_5channel(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; -void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_6channel(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; void _x_audio_out_resample_8to16(int8_t* input_samples, diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca src/xine-engine/video_overlay.c --- a/src/xine-engine/video_overlay.c Thu Aug 30 15:20:19 2007 +0100 +++ b/src/xine-engine/video_overlay.c Thu Jun 21 23:28:29 2007 +0100 @@ -395,6 +395,8 @@ static int video_overlay_event( video_ov #endif /* free any overlay associated with this event */ if (this->events[this_event].event->object.overlay != NULL) { + if( this->events[this_event].event->object.overlay->rle != NULL ) + free( this->events[this_event].event->object.overlay->rle ); free(this->events[this_event].event->object.overlay); this->events[this_event].event->object.overlay = NULL; } @@ -406,9 +408,11 @@ static int video_overlay_event( video_ov printf ("video_overlay: FREE SPU NOW\n"); #endif /* free any overlay associated with this event */ - if (this->events[this_event].event->object.overlay != NULL) { + if( this->events[this_event].event->object.overlay != NULL) { + if( this->events[this_event].event->object.overlay->rle != NULL ) + free( this->events[this_event].event->object.overlay->rle ); free(this->events[this_event].event->object.overlay); - this->events[this_event].event->object.overlay = NULL; + this->events[this_event].event->object.overlay = NULL; } /* this avoid removing this_event from the queue * (it will be removed at the end of this loop) */ diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca src/xine-engine/xine.c --- a/src/xine-engine/xine.c Thu Aug 30 15:20:19 2007 +0100 +++ b/src/xine-engine/xine.c Thu Jun 21 23:28:29 2007 +0100 @@ -130,17 +130,54 @@ void _x_extra_info_merge( extra_info_t * } } +static int acquire_allowed_to_block(xine_ticket_t *this) { + pthread_t own_id = pthread_self(); + unsigned entry; + unsigned new_size; + + for(entry = 0; entry < this->holder_thread_count; ++entry) { + if(this->holder_threads[entry].holder == own_id) { + /* This thread may already hold this ticket */ + this->holder_threads[entry].count++; + return (this->holder_threads[entry].count == 1); + } + } + /* If we get this far, this thread hasn't claimed this ticket before. + We need to give it a new entry in the list, then return true */ + for(entry = 0; entry < this->holder_thread_count; ++entry) { + if(this->holder_threads[entry].count == 0) { + this->holder_threads[entry].holder = own_id; + this->holder_threads[entry].count = 1; + return 1; + } + } + /* List too small. Realloc to larger size */ + new_size = this->holder_thread_count * 2; + lprintf("Reallocing from %d to %d entries\n", this->holder_thread_count, new_size); + + this->holder_threads = realloc(this->holder_threads, sizeof(*this->holder_threads) * new_size); + memset(this->holder_threads + this->holder_thread_count, 0, this->holder_thread_count); + + /* Old size is equivalent to index of first newly allocated entry*/ + this->holder_threads[this->holder_thread_count].count = 1; + this->holder_threads[this->holder_thread_count].holder = own_id; + this->holder_thread_count = new_size; + + return 1; +} + static int ticket_acquire_internal(xine_ticket_t *this, int irrevocable, int nonblocking) { int must_wait = 0; pthread_mutex_lock(&this->lock); + int allowed_to_block = acquire_allowed_to_block(this); if (this->ticket_revoked && !this->irrevocable_tickets) must_wait = !nonblocking; else if (this->atomic_revoke && !pthread_equal(this->atomic_revoker_thread, pthread_self())) must_wait = 1; - if (must_wait) { + if (must_wait && allowed_to_block) { if (nonblocking) { pthread_mutex_unlock(&this->lock); return 0; @@ -165,9 +202,25 @@ static void ticket_acquire(xine_ticket_t ticket_acquire_internal(this, irrevocable, 0); } +static int release_allowed_to_block(xine_ticket_t *this) { + pthread_t own_id = pthread_self(); + unsigned entry; + + for(entry = 0; entry < this->holder_thread_count; ++entry) { + if(this->holder_threads[entry].holder == own_id) { + this->holder_threads[entry].count--; + return this->holder_threads[entry].count == 0; + } + } + lprintf("BUG! Ticket 0x%p released by a thread that never took it! Allowing code to continue\n", this); + _x_assert(0); + return 1; +} + static void ticket_release_internal(xine_ticket_t *this, int irrevocable, int nonblocking) { pthread_mutex_lock(&this->lock); + int allowed_to_block = release_allowed_to_block(this); this->tickets_granted--; if (irrevocable) @@ -175,8 +228,10 @@ static void ticket_release_internal(xine if (this->ticket_revoked && !this->tickets_granted) pthread_cond_broadcast(&this->revoked); - if (this->ticket_revoked && !this->irrevocable_tickets && !nonblocking) - pthread_cond_wait(&this->issued, &this->lock); + if (allowed_to_block) { + if (this->ticket_revoked && !this->irrevocable_tickets && !nonblocking) + pthread_cond_wait(&this->issued, &this->lock); + } pthread_mutex_unlock(&this->lock); } @@ -296,6 +351,8 @@ static xine_ticket_t *ticket_init(void) port_ticket->lock_port_rewiring = ticket_lock_port_rewiring; port_ticket->unlock_port_rewiring = ticket_unlock_port_rewiring; port_ticket->dispose = ticket_dispose; + port_ticket->holder_thread_count = XINE_MAX_TICKET_HOLDER_THREADS; + port_ticket->holder_threads = calloc(XINE_MAX_TICKET_HOLDER_THREADS,sizeof(*port_ticket->holder_threads)); pthread_mutex_init(&port_ticket->lock, NULL); pthread_mutex_init(&port_ticket->revoke_lock, NULL); @@ -498,7 +555,7 @@ static int stream_rewire_audio(xine_post if (stream->audio_out->status(stream->audio_out, stream, &bits, &rate, &mode)) { /* register our stream at the new output port */ - new_port->open(new_port, stream, bits, rate, mode); + (new_port->open) (new_port, stream, bits, rate, mode); stream->audio_out->close(stream->audio_out, stream); } stream->audio_out = new_port; @@ -524,7 +581,7 @@ static int stream_rewire_video(xine_post if (stream->video_out->status(stream->video_out, stream, &width, &height, &img_duration)) { /* register our stream at the new output port */ - new_port->open(new_port, stream); + (new_port->open) (new_port, stream); stream->video_out->close(stream->video_out, stream); } stream->video_out = new_port; @@ -715,7 +772,7 @@ xine_stream_t *xine_stream_new (xine_t * return stream; } -static void mrl_unescape(char *mrl) { +void _x_mrl_unescape(char *mrl) { int i, len = strlen(mrl); for (i = 0; i < len; i++) { @@ -812,7 +869,7 @@ static int open_internal (xine_stream_t _x_meta_info_set_utf8(stream, XINE_META_INFO_INPUT_PLUGIN, (stream->input_plugin->input_class->get_identifier (stream->input_plugin->input_class))); - res = stream->input_plugin->open(stream->input_plugin); + res = (stream->input_plugin->open) (stream->input_plugin); switch(res) { case 1: /* Open successfull */ free(input_source); @@ -863,7 +920,7 @@ static int open_internal (xine_stream_t memcpy(demux_name, tmp, strlen(tmp)); demux_name[strlen(tmp)] = '\0'; } - mrl_unescape(demux_name); + _x_mrl_unescape(demux_name); if (!(stream->demux_plugin = _x_find_demux_plugin_by_name(stream, demux_name, stream->input_plugin))) { xine_log(stream->xine, XINE_LOG_MSG, _("xine: specified demuxer %s failed to start\n"), demux_name); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; @@ -937,7 +994,7 @@ static int open_internal (xine_stream_t memcpy(demux_name, tmp, strlen(tmp)); demux_name[strlen(tmp)] = '\0'; } - mrl_unescape(demux_name); + _x_mrl_unescape(demux_name); if (!(stream->demux_plugin = _x_find_demux_plugin_last_probe(stream, demux_name, stream->input_plugin))) { xine_log(stream->xine, XINE_LOG_MSG, _("xine: last_probed demuxer %s failed to start\n"), demux_name); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; @@ -1024,7 +1081,7 @@ static int open_internal (xine_stream_t memcpy(volume, tmp, strlen(tmp)); volume[strlen(tmp)] = '\0'; } - mrl_unescape(volume); + _x_mrl_unescape(volume); xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME, atoi(volume)); free(volume); } else { @@ -1049,7 +1106,7 @@ static int open_internal (xine_stream_t memcpy(compression, tmp, strlen(tmp)); compression[strlen(tmp)] = '\0'; } - mrl_unescape(compression); + _x_mrl_unescape(compression); xine_set_param(stream, XINE_PARAM_AUDIO_COMPR_LEVEL, atoi(compression)); free(compression); } else { @@ -1074,7 +1131,7 @@ static int open_internal (xine_stream_t memcpy(subtitle_mrl, tmp, strlen(tmp)); subtitle_mrl[strlen(tmp)] = '\0'; } - mrl_unescape(subtitle_mrl); + _x_mrl_unescape(subtitle_mrl); stream->slave = xine_stream_new (stream->xine, NULL, stream->video_out ); stream->slave_affection = XINE_MASTER_SLAVE_PLAY | XINE_MASTER_SLAVE_STOP; if( xine_open( stream->slave, subtitle_mrl ) ) { @@ -1109,7 +1166,7 @@ static int open_internal (xine_stream_t memcpy(config_entry, tmp, strlen(tmp)); config_entry[strlen(tmp)] = '\0'; } - mrl_unescape(config_entry); + _x_mrl_unescape(config_entry); retval = _x_config_change_opt(stream->xine->config, config_entry); if (retval <= 0) { if (retval == 0) { diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca src/xine-engine/xine_internal.h --- a/src/xine-engine/xine_internal.h Thu Aug 30 15:20:19 2007 +0100 +++ b/src/xine-engine/xine_internal.h Thu Jun 21 23:28:29 2007 +0100 @@ -74,6 +74,7 @@ extern "C" { #define XINE_MAX_EVENT_LISTENERS 50 #define XINE_MAX_EVENT_TYPES 100 +#define XINE_MAX_TICKET_HOLDER_THREADS 64 /* used by plugin loader */ #define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION @@ -185,6 +186,11 @@ struct xine_ticket_s { int atomic_revoke; pthread_t atomic_revoker_thread; pthread_mutex_t port_rewiring_lock; + struct { + int count; + pthread_t holder; + } *holder_threads; + unsigned holder_thread_count; #endif }; @@ -464,6 +470,10 @@ void _x_demux_send_mrl_reference (xine_s const char *mrl, const char *title, int start_time, int duration) XINE_PROTECTED; +/* + * MRL escaped-character decoding (overwrites the source string) + */ +void _x_mrl_unescape(char *mrl) XINE_PROTECTED; /* * plugin_loader functions diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca src/xine-utils/xmllexer.c --- a/src/xine-utils/xmllexer.c Thu Aug 30 15:20:19 2007 +0100 +++ b/src/xine-utils/xmllexer.c Thu Jun 21 23:28:29 2007 +0100 @@ -61,9 +61,27 @@ void lexer_init(const char * buf, int si lprintf("buffer length %d\n", size); } +typedef enum { + STATE_UNKNOWN = -1, + STATE_IDLE, + STATE_EOL, + STATE_SEPAR, + STATE_T_M_START, + STATE_T_M_STOP_1, + STATE_T_M_STOP_2, + STATE_T_EQUAL, + STATE_T_STRING_SINGLE, + STATE_T_STRING_DOUBLE, + STATE_T_COMMENT, + STATE_T_TI_STOP, + STATE_T_DASHDASH, + STATE_T_C_STOP, + STATE_IDENT /* must be last */ +} lexer_state_t; + int lexer_get_token(char * tok, int tok_size) { int tok_pos = 0; - int state = 0; + lexer_state_t state = STATE_IDLE; char c; if (tok) { @@ -75,69 +93,70 @@ int lexer_get_token(char * tok, int tok_ /* normal mode */ switch (state) { /* init state */ - case 0: + case STATE_IDLE: switch (c) { case '\n': case '\r': - state = 1; + state = STATE_EOL; tok[tok_pos] = c; tok_pos++; break; case ' ': case '\t': - state = 2; + state = STATE_SEPAR; tok[tok_pos] = c; tok_pos++; break; case '<': - state = 3; + state = STATE_T_M_START; tok[tok_pos] = c; tok_pos++; break; case '>': - state = 4; + state = STATE_T_M_STOP_1; tok[tok_pos] = c; tok_pos++; break; case '/': if (!in_comment) - state = 5; + state = STATE_T_M_STOP_2; tok[tok_pos] = c; tok_pos++; break; case '=': - state = 6; + state = STATE_T_EQUAL; tok[tok_pos] = c; tok_pos++; break; case '\"': /* " */ - state = 7; + state = STATE_T_STRING_DOUBLE; break; case '\'': /* " */ - state = 12; + state = STATE_T_STRING_SINGLE; break; case '-': - state = 10; + state = STATE_T_DASHDASH; tok[tok_pos] = c; tok_pos++; break; case '?': - state = 9; - tok[tok_pos] = c; - tok_pos++; - break; - - default: - state = 100; + if (!in_comment) + state = STATE_T_TI_STOP; + tok[tok_pos] = c; + tok_pos++; + break; + + default: + state = STATE_IDENT; tok[tok_pos] = c; tok_pos++; break; @@ -146,7 +165,7 @@ int lexer_get_token(char * tok, int tok_ break; /* end of line */ - case 1: + case STATE_EOL: if (c == '\n' || (c == '\r')) { tok[tok_pos] = c; [... 33 lines omitted ...] + case STATE_T_M_STOP_1: tok[tok_pos] = '\0'; if (!in_comment) lex_mode = DATA; @@ -207,7 +226,7 @@ int lexer_get_token(char * tok, int tok_ break; /* T_M_STOP_2 */ - case 5: + case STATE_T_M_STOP_2: if (c == '>') { tok[tok_pos] = c; lexbuf_pos++; @@ -223,13 +242,13 @@ int lexer_get_token(char * tok, int tok_ break; /* T_EQUAL */ - case 6: + case STATE_T_EQUAL: tok[tok_pos] = '\0'; return T_EQUAL; break; /* T_STRING */ - case 7: + case STATE_T_STRING_DOUBLE: tok[tok_pos] = c; lexbuf_pos++; if (c == '\"') { /* " */ @@ -240,7 +259,7 @@ int lexer_get_token(char * tok, int tok_ break; /* T_C_START or T_DOCTYPE_START */ - case 8: + case STATE_T_COMMENT: switch (c) { case '-': lexbuf_pos++; @@ -271,12 +290,14 @@ int lexer_get_token(char * tok, int tok_ break; /* T_TI_STOP */ - case 9: + case STATE_T_TI_STOP: if (c == '>') { tok[tok_pos] = c; lexbuf_pos++; tok_pos++; /* FIXME */ tok[tok_pos] = '\0'; + if (!in_comment) + lex_mode = DATA; return T_TI_STOP; } else { tok[tok_pos] = '\0'; @@ -285,24 +306,24 @@ int lexer_get_token(char * tok, int tok_ break; /* -- */ - case 10: + case STATE_T_DASHDASH: switch (c) { case '-': tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 11; - break; - default: - tok[tok_pos] = c; - tok_pos++; - lexbuf_pos++; - state = 100; + state = STATE_T_C_STOP; + break; + default: + tok[tok_pos] = c; + tok_pos++; + lexbuf_pos++; + state = STATE_IDENT; } break; /* --> */ - case 11: + case STATE_T_C_STOP: switch (c) { case '>': tok[tok_pos] = c; @@ -322,12 +343,12 @@ int lexer_get_token(char * tok, int tok_ tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 100; + state = STATE_IDENT; } break; /* T_STRING (single quotes) */ - case 12: + case STATE_T_STRING_SINGLE: tok[tok_pos] = c; lexbuf_pos++; if (c == '\'') { /* " */ @@ -338,7 +359,7 @@ int lexer_get_token(char * tok, int tok_ break; /* IDENT */ - case 100: + case STATE_IDENT: switch (c) { case '<': case '>': @@ -355,13 +376,13 @@ int lexer_get_token(char * tok, int tok_ tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 9; + state = STATE_T_TI_STOP; break; case '-': tok[tok_pos] = c; tok_pos++; lexbuf_pos++; - state = 10; + state = STATE_T_DASHDASH; break; default: tok[tok_pos] = c; diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca src/xine-utils/xmlparser.c --- a/src/xine-utils/xmlparser.c Thu Aug 30 15:20:19 2007 +0100 +++ b/src/xine-utils/xmlparser.c Thu Jun 21 23:28:29 2007 +0100 @@ -152,18 +152,41 @@ void xml_parser_free_tree(xml_node_t *cu xml_parser_free_tree_rec(current_node, 1); } -#define STATE_IDLE 0 -#define STATE_NODE 1 -#define STATE_COMMENT 7 - -static int xml_parser_get_node (xml_node_t *current_node, char *root_name, int rec) { +typedef enum { + /*0*/ + STATE_IDLE, + /* <foo ...> */ + STATE_NODE, + STATE_ATTRIBUTE, + STATE_NODE_CLOSE, + STATE_TAG_TERM, + STATE_ATTRIBUTE_EQUALS, + STATE_STRING, + STATE_TAG_TERM_IGNORE, + /* <?foo ...?> */ + STATE_Q_NODE, + STATE_Q_ATTRIBUTE, + STATE_Q_NODE_CLOSE, + STATE_Q_TAG_TERM, + STATE_Q_ATTRIBUTE_EQUALS, + STATE_Q_STRING, + /* Others */ + STATE_COMMENT, + STATE_DOCTYPE, +} parser_state_t; + +#define Q_STATE(CURRENT,NEW) (STATE_##NEW + state - STATE_##CURRENT) + +static int xml_parser_get_node_internal (xml_node_t *current_node, char *root_names[], int rec, int relaxed) +{ char tok[TOKEN_SIZE]; char property_name[TOKEN_SIZE]; char node_name[TOKEN_SIZE]; - int state = STATE_IDLE; + parser_state_t state = STATE_IDLE; int res = 0; int parse_res; int bypass_get_token = 0; + int retval = 0; /* used when state==4; non-0 if there are missing </...> */ xml_node_t *subtree = NULL; xml_node_t *current_subtree = NULL; xml_property_t *current_property = NULL; @@ -183,22 +206,22 @@ static int xml_parser_get_node (xml_node /* do nothing */ break; case (T_EOF): - return 0; /* normal end */ + return retval; /* normal end */ break; case (T_M_START_1): state = STATE_NODE; break; case (T_M_START_2): - state = 3; + state = STATE_NODE_CLOSE; break; case (T_C_START): state = STATE_COMMENT; break; case (T_TI_START): - state = 8; + state = STATE_Q_NODE; break; case (T_DOCTYPE_START): - state = 9; + state = STATE_DOCTYPE; break; case (T_DATA): /* current data */ @@ -217,6 +240,7 @@ static int xml_parser_get_node (xml_node break; case STATE_NODE: + case STATE_Q_NODE: switch (res) { case (T_IDENT): properties = NULL; @@ -226,8 +250,13 @@ static int xml_parser_get_node (xml_node if (xml_parser_mode == XML_PARSER_CASE_INSENSITIVE) { strtoupper(tok); } - strcpy(node_name, tok); - state = 2; + if (state == STATE_Q_NODE) { + snprintf (node_name, TOKEN_SIZE, "?%s", tok); + state = STATE_Q_ATTRIBUTE; + } else { + strcpy(node_name, tok); + state = STATE_ATTRIBUTE; + } lprintf("info: current node name \"%s\"\n", node_name); break; default: @@ -236,7 +265,8 @@ static int xml_parser_get_node (xml_node break; } break; - case 2: + + case STATE_ATTRIBUTE: switch (res) { case (T_EOL): case (T_SEPAR): @@ -252,8 +282,9 @@ static int xml_parser_get_node (xml_node /* set node propertys */ subtree->props = properties; lprintf("info: rec %d new subtree %s\n", rec, node_name); - parse_res = xml_parser_get_node(subtree, node_name, rec + 1); - if (parse_res != 0) { + root_names[rec + 1] = node_name; + parse_res = xml_parser_get_node_internal(subtree, root_names, rec + 1, relaxed); + if (parse_res == -1 || parse_res > 0) { return parse_res; } if (current_subtree == NULL) { @@ -263,11 +294,16 @@ static int xml_parser_get_node (xml_node current_subtree->next = subtree; current_subtree = subtree; } [... 160 lines omitted ...] default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); @@ -373,7 +478,8 @@ static int xml_parser_get_node (xml_node break; /* string or ident or separator expected */ - case 6: + case STATE_STRING: + case STATE_Q_STRING: switch (res) { case (T_EOL): case (T_SEPAR): @@ -392,7 +498,7 @@ static int xml_parser_get_node (xml_node current_property->name = strdup(property_name); current_property->value = lexer_decode_entities(tok); lprintf("info: new property %s=%s\n", current_property->name, current_property->value); - state = 2; + state = Q_STATE(STRING, ATTRIBUTE); break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); @@ -408,31 +514,30 @@ static int xml_parser_get_node (xml_node state = STATE_IDLE; break; default: - state = STATE_COMMENT; - break; - } - break; - - /* ?> expected */ - case 8: - switch (res) { - case (T_TI_STOP): - state = 0; - break; - default: - state = 8; break; } break; /* > expected */ - case 9: + case STATE_DOCTYPE: switch (res) { case (T_M_STOP_1): state = 0; break; default: - state = 9; + break; + } + break; + + /* > expected (following unmatched "</...") */ + case STATE_TAG_TERM_IGNORE: + switch (res) { + case (T_M_STOP_1): + state = STATE_IDLE; + break; + default: + lprintf("error: unexpected token \"%s\", state %d\n", tok, state); + return -1; break; } break; @@ -453,14 +558,33 @@ static int xml_parser_get_node (xml_node } } -int xml_parser_build_tree(xml_node_t **root_node) { - xml_node_t *tmp_node; +static int xml_parser_get_node (xml_node_t *current_node, int relaxed) +{ + char *root_names[MAX_RECURSION + 1]; + root_names[0] = ""; + return xml_parser_get_node_internal (current_node, root_names, 0, relaxed); +} + +int xml_parser_build_tree_relaxed(xml_node_t **root_node, int relaxed) { + xml_node_t *tmp_node, *pri_node, *q_node = NULL; int res; tmp_node = new_xml_node(); - res = xml_parser_get_node(tmp_node, "", 0); - if ((tmp_node->child) && (!tmp_node->child->next)) { - *root_node = tmp_node->child; + res = xml_parser_get_node(tmp_node, relaxed); + + /* find first non-<?...?> node */; + for (pri_node = tmp_node->child; + pri_node && pri_node->name[0] == '?'; + pri_node = pri_node->next) + q_node = pri_node; /* last <?...?> node (eventually), or NULL */ + + if (pri_node && !pri_node->next) { + /* move the tail to the head (for compatibility reasons) */ + if (q_node) { + pri_node->next = tmp_node->child; + q_node->next = NULL; + } + *root_node = pri_node; free_xml_node(tmp_node); res = 0; } else { @@ -469,6 +593,10 @@ int xml_parser_build_tree(xml_node_t **r res = -1; } return res; +} + +int xml_parser_build_tree(xml_node_t **root_node) { + return xml_parser_build_tree_relaxed (root_node, 0); } const char *xml_parser_get_property (const xml_node_t *node, const char *name) { @@ -589,5 +717,8 @@ static void xml_parser_dump_node (const } void xml_parser_dump_tree (const xml_node_t *node) { - xml_parser_dump_node (node, 0); -} + do { + xml_parser_dump_node (node, 0); + node = node->next; + } while (node); +} diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca src/xine-utils/xmlparser.h --- a/src/xine-utils/xmlparser.h Thu Aug 30 15:20:19 2007 +0100 +++ b/src/xine-utils/xmlparser.h Thu Jun 21 23:28:29 2007 +0100 @@ -57,6 +57,7 @@ void xml_parser_init(const char * buf, i void xml_parser_init(const char * buf, int size, int mode) XINE_PROTECTED; int xml_parser_build_tree(xml_node_t **root_node) XINE_PROTECTED; +int xml_parser_build_tree_relaxed(xml_node_t **root_node, int relaxed) XINE_PROTECTED; void xml_parser_free_tree(xml_node_t *root_node) XINE_PROTECTED; diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca debian/libxine-dev.install --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/libxine-dev.install Thu Jun 21 23:28:29 2007 +0100 @@ -0,0 +1,10 @@ +usr/bin/xine-config +usr/include +usr/lib/libxine.la +usr/lib/libxine*.so +usr/lib/pkgconfig/libxine.pc +usr/lib/xine/plugins/*/*.la +usr/lib/xine/plugins/*/post/*.la +usr/lib/xine/plugins/*/vidix/*.la +usr/share/aclocal/xine.m4 +usr/share/man/man1/xine-config.1 diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca debian/libxine2-doc.install --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debian/libxine2-doc.install Thu Jun 21 23:28:29 2007 +0100 @@ -0,0 +1,1 @@ +usr/share/man/man5/xine.5 diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca debian/libxine2-dev.install --- a/debian/libxine2-dev.install Thu Aug 30 15:20:19 2007 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -usr/bin/xine-config -usr/include -usr/lib/libxine.la -usr/lib/libxine*.so -usr/lib/pkgconfig/libxine.pc -usr/lib/xine/plugins/*/*.la -usr/lib/xine/plugins/*/post/*.la -usr/lib/xine/plugins/*/vidix/*.la -usr/share/aclocal/xine.m4 -usr/share/man/man1/xine-config.1 diff -r de1f9dcd0565c40ea0e198e7084b574e930128e2 -r 3316deabaa0abacebdb0eac0f3df5cdf0b2583ca debian/libxine2-doc.manpages --- a/debian/libxine2-doc.manpages Thu Aug 30 15:20:19 2007 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -debian/tmp/usr/share/man/man5/xine.5 |