break;
default:
result = 0;
- mlt_log_warning( container, "Producer defined inside something that isn't a container\n" );
+ mlt_log_warning( NULL, "[producer_xml] Producer defined inside something that isn't a container\n" );
break;
};
}
else
{
- mlt_log_warning( tractor, "Invalid state for tractor\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid state for tractor\n" );
}
}
}
else
{
- mlt_log_warning( parent, "Invalid multitrack position\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid multitrack position\n" );
}
}
mlt_service service = context_pop_service( context, &type );
if ( service == NULL || type != mlt_multitrack_type )
- mlt_log_warning( service, "End multitrack in the wrong state...\n" );
+ mlt_log_error( NULL, "[producer_xml] End multitrack in the wrong state...\n" );
}
static void on_start_playlist( deserialise_context context, const xmlChar *name, const xmlChar **atts)
}
else
{
- mlt_log_warning( service, "Invalid state of playlist end %d\n", type );
+ mlt_log_error( NULL, "[producer_xml] Invalid state of playlist end %d\n", type );
}
}
if ( !producer && resource )
producer = MLT_SERVICE( mlt_factory_producer( context->profile, NULL, resource ) );
if ( !producer )
- mlt_log_warning( service, "failed to load producer \"%s\"\n", resource );
+ mlt_log_error( NULL, "[producer_xml] failed to load producer \"%s\"\n", resource );
if ( !producer )
producer = MLT_SERVICE( mlt_factory_producer( context->profile, NULL, "+INVALID.txt" ) );
if ( !producer )
}
else
{
- mlt_log_warning( service, "blank without a playlist - a definite no no\n" );
+ mlt_log_error( NULL, "[producer_xml] blank without a playlist - a definite no no\n" );
}
}
}
else
{
- mlt_log_warning( parent, "Entry not part of a playlist...\n" );
+ mlt_log_error( NULL, "[producer_xml] Entry not part of a playlist...\n" );
}
context_push_service( context, parent, parent_type );
if ( entry == NULL && entry_type != mlt_entry_type )
{
- mlt_log_warning( entry, "Invalid state at end of entry\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid state at end of entry\n" );
}
}
else if ( parent_type == mlt_multitrack_type )
multitrack = MLT_MULTITRACK( parent );
else
- mlt_log_warning( track, "track contained in an invalid container\n" );
+ mlt_log_error( NULL, "[producer_xml] track contained in an invalid container\n" );
if ( multitrack != NULL )
{
}
else
{
- mlt_log_warning( track, "Invalid state at end of track\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid state at end of track\n" );
}
}
if ( !filter )
{
- mlt_log_warning( service, "failed to load filter \"%s\"\n", id );
+ mlt_log_error( NULL, "[producer_xml] failed to load filter \"%s\"\n", id );
if ( parent )
context_push_service( context, parent, parent_type );
mlt_service_close( service );
}
else
{
- mlt_log_warning( service, "filter closed with invalid parent...\n" );
+ mlt_log_error( NULL, "[producer_xml] filter closed with invalid parent...\n" );
}
// Close the dummy filter service
}
else
{
- mlt_log_warning( service, "Invalid top of stack on filter close\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid top of stack on filter close\n" );
}
}
if ( !effect )
{
- mlt_log_warning( service, "failed to load transition \"%s\"\n", id );
+ mlt_log_error( NULL, "[producer_xml] failed to load transition \"%s\"\n", id );
if ( parent )
context_push_service( context, parent, parent_type );
mlt_service_close( service );
}
else
{
- mlt_log_warning( service, "Misplaced transition - ignoring\n" );
+ mlt_log_warning( NULL, "[producer_xml] Misplaced transition - ignoring\n" );
}
// Put the parent back on the stack
}
else
{
- mlt_log_warning( service, "transition closed with invalid parent...\n" );
+ mlt_log_error( NULL, "[producer_xml] transition closed with invalid parent...\n" );
}
// Close the dummy filter service
}
else
{
- mlt_log_warning( service, "Invalid top of stack on transition close\n" );
+ mlt_log_error( NULL, "[producer_xml] Invalid top of stack on transition close\n" );
}
}
}
else
{
- mlt_log_warning( service, "Property without a service '%s'?\n", ( const char * )name );
+ mlt_log_error( NULL, "[producer_xml] Property without a service '%s'?\n", ( const char * )name );
}
}
}
else
{
- mlt_log_warning( service, "Property without a service '%s'??\n", (const char *)name );
+ mlt_log_error( NULL, "[producer_xml] Property without a service '%s'??\n", (const char *)name );
}
}
struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx;
deserialise_context context = ( deserialise_context )( xmlcontext->_private );
-//printf("on_start_element: %s\n", name );
if ( context->pass == 0 )
{
if ( xmlStrcmp( name, _x("mlt") ) == 0 ||
struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx;
deserialise_context context = ( deserialise_context )( xmlcontext->_private );
-//printf("on_end_element: %s\n", name );
if ( context->is_value == 1 && context->pass == 1 && xmlStrcmp( name, _x("property") ) != 0 )
context_pop_node( context );
else if ( xmlStrcmp( name, _x("multitrack") ) == 0 )
return e;
}
-/** Handle error messages from the parser.
-*/
-static void on_error( void * ctx, const char * msg, ...)
+static void on_error( void * ctx, const char * msg, ... )
{
- struct _xmlError* err_ptr = xmlCtxtGetLastError(ctx);
- mlt_log_error( NULL, "XML producer parse error: %s\trow: %d\tcol: %d\n",
- err_ptr->message, err_ptr->line, err_ptr->int2 );
+ struct _xmlError* err_ptr = xmlCtxtGetLastError( ctx );
+
+ switch( err_ptr->level )
+ {
+ case XML_ERR_WARNING:
+ mlt_log_warning( NULL, "[producer_xml] parse warning: %s\trow: %d\tcol: %d\n",
+ err_ptr->message, err_ptr->line, err_ptr->int2 );
+ break;
+ case XML_ERR_ERROR:
+ mlt_log_error( NULL, "[producer_xml] parse error: %s\trow: %d\tcol: %d\n",
+ err_ptr->message, err_ptr->line, err_ptr->int2 );
+ break;
+ default:
+ case XML_ERR_FATAL:
+ mlt_log_fatal( NULL, "[producer_xml] parse fatal: %s\trow: %d\tcol: %d\n",
+ err_ptr->message, err_ptr->line, err_ptr->int2 );
+ break;
+ }
}
/** Convert a hexadecimal character to its value.
// We need to track the number of registered filters
mlt_properties_set_int( context->destructors, "registered", 0 );
+ // Setup SAX callbacks for first pass
+ sax->startElement = on_start_element;
+ sax->warning = on_error;
+ sax->error = on_error;
+ sax->fatalError = on_error;
+
// Setup libxml2 SAX parsing
xmlInitParser();
xmlSubstituteEntitiesDefault( 1 );
xmlcontext->sax = sax;
xmlcontext->_private = ( void* )context;
xmlParseDocument( xmlcontext );
+ well_formed = xmlcontext->wellFormed;
// Cleanup after parsing
xmlcontext->sax = NULL;
context->stack_node_size = 0;
context->stack_service_size = 0;
+ // Bad xml - clean up and return NULL
+ if ( !well_formed )
+ {
+ mlt_properties_close( context->producer_map );
+ mlt_properties_close( context->destructors );
+ mlt_properties_close( context->params );
+ xmlFreeDoc( context->entity_doc );
+ free( context );
+ free( sax );
+ free( filename );
+ return NULL;
+ }
+
// Setup the second pass
context->pass ++;
if ( info == 0 )
return NULL;
}
- // Setup SAX callbacks
- sax->startElement = on_start_element;
+ // Setup SAX callbacks for second pass
sax->endElement = on_end_element;
sax->characters = on_characters;
sax->cdataBlock = on_characters;
sax->internalSubset = on_internal_subset;
sax->entityDecl = on_entity_declaration;
sax->getEntity = on_get_entity;
- sax->error = on_error;
- sax->fatalError = on_error;
// Parse
xmlcontext->sax = sax;