2005-09-20 23:26:39 +10:00
/* -*- mode: C; c-file-style: "gnu" -*- */
/* xdgmimealias.c: Private file. Datastructure for storing the hierarchy.
*
* More info can be found at http : //www.freedesktop.org/standards/
*
* Copyright ( C ) 2004 Red Hat , Inc .
* Copyright ( C ) 2004 Matthias Clasen < mclasen @ redhat . com >
*
* Licensed under the Academic Free License version 2.0
* Or under the following terms :
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2 of the License , or ( at your option ) any later version .
*
* This library 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
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the
* Free Software Foundation , Inc . , 59 Temple Place - Suite 330 ,
* Boston , MA 02111 - 1307 , USA .
*/
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
# include "xdgmimeparent.h"
# include "xdgmimeint.h"
# include <stdlib.h>
# include <stdio.h>
# include <assert.h>
# include <string.h>
# include <fnmatch.h>
# ifndef FALSE
# define FALSE (0)
# endif
# ifndef TRUE
# define TRUE (!FALSE)
# endif
typedef struct XdgMimeParents XdgMimeParents ;
struct XdgMimeParents
{
char * mime ;
char * * parents ;
int n_parents ;
} ;
struct XdgParentList
{
struct XdgMimeParents * parents ;
int n_mimes ;
} ;
XdgParentList *
_xdg_mime_parent_list_new ( void )
{
XdgParentList * list ;
2011-12-26 19:18:46 -08:00
list = ( XdgParentList * ) malloc ( sizeof ( XdgParentList ) ) ;
2005-09-20 23:26:39 +10:00
list - > parents = NULL ;
list - > n_mimes = 0 ;
return list ;
}
2011-12-26 19:18:46 -08:00
void
2005-09-20 23:26:39 +10:00
_xdg_mime_parent_list_free ( XdgParentList * list )
{
int i ;
char * * p ;
if ( list - > parents )
{
for ( i = 0 ; i < list - > n_mimes ; i + + )
{
for ( p = list - > parents [ i ] . parents ; * p ; p + + )
free ( * p ) ;
free ( list - > parents [ i ] . parents ) ;
free ( list - > parents [ i ] . mime ) ;
}
free ( list - > parents ) ;
}
free ( list ) ;
}
static int
parent_entry_cmp ( const void * v1 , const void * v2 )
{
return strcmp ( ( ( XdgMimeParents * ) v1 ) - > mime , ( ( XdgMimeParents * ) v2 ) - > mime ) ;
}
const char * *
_xdg_mime_parent_list_lookup ( XdgParentList * list ,
const char * mime )
{
XdgMimeParents * entry ;
XdgMimeParents key ;
if ( list - > n_mimes > 0 )
{
key . mime = ( char * ) mime ;
key . parents = NULL ;
2011-12-26 19:18:46 -08:00
entry = ( XdgMimeParents * ) bsearch ( & key , list - > parents , list - > n_mimes ,
2005-09-20 23:26:39 +10:00
sizeof ( XdgMimeParents ) , & parent_entry_cmp ) ;
if ( entry )
return ( const char * * ) entry - > parents ;
}
return NULL ;
}
void
_xdg_mime_parent_read_from_file ( XdgParentList * list ,
const char * file_name )
{
FILE * file ;
char line [ 255 ] ;
int i , alloc ;
XdgMimeParents * entry ;
2012-03-02 00:27:40 -08:00
/* OK to not use CLO_EXEC here because mimedb is single threaded */
2005-09-20 23:26:39 +10:00
file = fopen ( file_name , " r " ) ;
if ( file = = NULL )
return ;
/* FIXME: Not UTF-8 safe. Doesn't work if lines are greater than 255 chars.
* Blah */
alloc = list - > n_mimes + 16 ;
2011-12-26 19:18:46 -08:00
list - > parents = ( XdgMimeParents * ) realloc ( list - > parents , alloc * sizeof ( XdgMimeParents ) ) ;
2005-09-20 23:26:39 +10:00
while ( fgets ( line , 255 , file ) ! = NULL )
{
char * sep ;
if ( line [ 0 ] = = ' # ' )
continue ;
sep = strchr ( line , ' ' ) ;
if ( sep = = NULL )
continue ;
* ( sep + + ) = ' \000 ' ;
sep [ strlen ( sep ) - 1 ] = ' \000 ' ;
entry = NULL ;
for ( i = 0 ; i < list - > n_mimes ; i + + )
{
if ( strcmp ( list - > parents [ i ] . mime , line ) = = 0 )
{
entry = & ( list - > parents [ i ] ) ;
break ;
}
}
2011-12-26 19:18:46 -08:00
2005-09-20 23:26:39 +10:00
if ( ! entry )
{
if ( list - > n_mimes = = alloc )
{
alloc < < = 1 ;
2011-12-26 19:18:46 -08:00
list - > parents = ( XdgMimeParents * ) realloc ( list - > parents ,
2005-09-20 23:26:39 +10:00
alloc * sizeof ( XdgMimeParents ) ) ;
}
list - > parents [ list - > n_mimes ] . mime = strdup ( line ) ;
list - > parents [ list - > n_mimes ] . parents = NULL ;
entry = & ( list - > parents [ list - > n_mimes ] ) ;
list - > n_mimes + + ;
}
if ( ! entry - > parents )
{
entry - > n_parents = 1 ;
2011-12-26 19:18:46 -08:00
entry - > parents = ( char * * ) malloc ( ( entry - > n_parents + 1 ) * sizeof ( char * ) ) ;
2005-09-20 23:26:39 +10:00
}
else
{
entry - > n_parents + = 1 ;
2011-12-26 19:18:46 -08:00
entry - > parents = ( char * * ) realloc ( entry - > parents ,
2005-09-20 23:26:39 +10:00
( entry - > n_parents + 2 ) * sizeof ( char * ) ) ;
}
entry - > parents [ entry - > n_parents - 1 ] = strdup ( sep ) ;
entry - > parents [ entry - > n_parents ] = NULL ;
}
2011-12-26 19:18:46 -08:00
list - > parents = ( XdgMimeParents * ) realloc ( list - > parents ,
2005-09-20 23:26:39 +10:00
list - > n_mimes * sizeof ( XdgMimeParents ) ) ;
2011-12-26 19:18:46 -08:00
fclose ( file ) ;
2005-09-20 23:26:39 +10:00
if ( list - > n_mimes > 1 )
2011-12-26 19:18:46 -08:00
qsort ( list - > parents , list - > n_mimes ,
2005-09-20 23:26:39 +10:00
sizeof ( XdgMimeParents ) , & parent_entry_cmp ) ;
}
2011-12-26 19:18:46 -08:00
void
2005-09-20 23:26:39 +10:00
_xdg_mime_parent_list_dump ( XdgParentList * list )
{
int i ;
char * * p ;
if ( list - > parents )
{
for ( i = 0 ; i < list - > n_mimes ; i + + )
{
for ( p = list - > parents [ i ] . parents ; * p ; p + + )
printf ( " %s %s \n " , list - > parents [ i ] . mime , * p ) ;
}
}
}