]> git.sesse.net Git - mlt/blobdiff - src/modules/xml/producer_xml.c
Convert producer_xml to use mlt_log rather than fprintf.
[mlt] / src / modules / xml / producer_xml.c
index 516d54950aaf1573117fe220e691084a29fa0a3f..f38c96c882ac48887b71fdac46bd0aa0641bfd04 100644 (file)
@@ -274,7 +274,7 @@ static int add_producer( deserialise_context context, mlt_service service, mlt_p
                                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;
                };
 
@@ -403,7 +403,7 @@ static void on_end_tractor( deserialise_context context, const xmlChar *name )
        }
        else
        {
-               mlt_log_warning( tractor, "Invalid state for tractor\n" );
+               mlt_log_error( NULL, "[producer_xml] Invalid state for tractor\n" );
        }
 }
 
@@ -446,7 +446,7 @@ static void on_start_multitrack( deserialise_context context, const xmlChar *nam
        }
        else
        {
-               mlt_log_warning( parent, "Invalid multitrack position\n" );
+               mlt_log_error( NULL, "[producer_xml] Invalid multitrack position\n" );
        }
 }
 
@@ -457,7 +457,7 @@ static void on_end_multitrack( deserialise_context context, const xmlChar *name
        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)
@@ -506,7 +506,7 @@ static void on_end_playlist( deserialise_context context, const xmlChar *name )
        }
        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 );
        }
 }
 
@@ -605,7 +605,7 @@ static void on_end_producer( deserialise_context context, const xmlChar *name )
                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 )
@@ -746,7 +746,7 @@ static void on_start_blank( deserialise_context context, const xmlChar *name, co
        }
        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" );
        }
 }
 
@@ -800,7 +800,7 @@ static void on_start_entry( deserialise_context context, const xmlChar *name, co
                }
                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 );
@@ -820,7 +820,7 @@ static void on_end_entry( deserialise_context context, const xmlChar *name )
 
        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" );
        }
 }
 
@@ -870,7 +870,7 @@ static void on_end_track( deserialise_context context, const xmlChar *name )
                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 )
                {
@@ -915,7 +915,7 @@ static void on_end_track( deserialise_context context, const xmlChar *name )
        }
        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" );
        }
 }
 
@@ -951,7 +951,7 @@ static void on_end_filter( deserialise_context context, const xmlChar *name )
 
                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 );
@@ -993,7 +993,7 @@ static void on_end_filter( deserialise_context context, const xmlChar *name )
                }
                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
@@ -1001,7 +1001,7 @@ static void on_end_filter( deserialise_context context, const xmlChar *name )
        }
        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" );
        }
 }
 
@@ -1037,7 +1037,7 @@ static void on_end_transition( deserialise_context context, const xmlChar *name
 
                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 );
@@ -1074,7 +1074,7 @@ static void on_end_transition( deserialise_context context, const xmlChar *name
                        }
                        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
@@ -1082,7 +1082,7 @@ static void on_end_transition( deserialise_context context, const xmlChar *name
                }
                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
@@ -1090,7 +1090,7 @@ static void on_end_transition( deserialise_context context, const xmlChar *name
        }
        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" );
        }
 }
 
@@ -1196,7 +1196,7 @@ static void on_start_property( deserialise_context context, const xmlChar *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 );
        }
 }
 
@@ -1237,7 +1237,7 @@ static void on_end_property( deserialise_context context, const xmlChar *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 );
        }
 }
 
@@ -1246,7 +1246,6 @@ static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **at
        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 ||
@@ -1321,7 +1320,6 @@ static void on_end_element( void *ctx, const xmlChar *name )
        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 )
@@ -1469,13 +1467,26 @@ static xmlEntityPtr on_get_entity( void *ctx, const xmlChar* name )
        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.
@@ -1616,6 +1627,12 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
        // 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 );
@@ -1642,6 +1659,7 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
        xmlcontext->sax = sax;
        xmlcontext->_private = ( void* )context;        
        xmlParseDocument( xmlcontext );
+       well_formed = xmlcontext->wellFormed;
        
        // Cleanup after parsing
        xmlcontext->sax = NULL;
@@ -1650,6 +1668,19 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
        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 )
@@ -1670,16 +1701,13 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
                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;