aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2006-01-24 01:45:00 +1000
committerGravatar axel <axel@liljencrantz.se>2006-01-24 01:45:00 +1000
commit7d645ccc5300e04d2398965b077371b323149336 (patch)
tree2c8b04f20ae0e506020649e9a8a0225f341a30bd
parent820da6e7f7b5a447e612db433782a9cfe3264073 (diff)
Use gettext to translate mimedb command. Also try to respect users locale setting when choosing language on file descriptions.
darcs-hash:20060123154500-ac50b-2a2eb9c24f41d2bbe05fc4c40dca31aaaca71979.gz
-rw-r--r--mimedb.c189
1 files changed, 165 insertions, 24 deletions
diff --git a/mimedb.c b/mimedb.c
index bd3b75ec..a77f1a06 100644
--- a/mimedb.c
+++ b/mimedb.c
@@ -30,11 +30,18 @@ license. Read the source code of the library for more information.
#include <fcntl.h>
#include <libgen.h>
#include <errno.h>
+#include <regex.h>
+#include <locale.h>
+
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
+#if HAVE_LIBINTL_H
+#include <libintl.h>
+#endif
+
#include "xdgmime.h"
#include "util.h"
@@ -53,20 +60,30 @@ license. Read the source code of the library for more information.
#define MIME_SUFFIX ".xml"
/**
- Start tag for comment
+ Start tag for langauge-specific comment
*/
-#define START_TAG "<comment>"
+#define START_TAG "<comment *(| +xml:lang *= *(\"%s\"|'%s') *)>"
/**
End tab for comment
*/
-#define STOP_TAG "</comment>"
+#define STOP_TAG "</comment *>"
/**
File contains cached list of mime actions
*/
#define DESKTOP_DEFAULT "applications/defaults.list"
+/**
+ Size for temporary string buffer used to make a regex for language
+ specific descriptions
+*/
+#define BUFF_SIZE 1024
+
+/*
+ Program name
+*/
+#define MIMEDB "mimedb"
/**
All types of input and output possible
@@ -82,6 +99,8 @@ enum
}
;
+static regex_t *start_re=0, *stop_re=0;
+
/**
Error flag. Non-zero if something bad happened.
*/
@@ -101,6 +120,12 @@ static int launch_len=0;
*/
static int launch_pos=0;
+#if HAVE_GETTEXT
+#define _(string) gettext(string)
+#else
+#define _(string) (string)
+#endif
+
/**
Dynamically generated function, made from the documentation in doc_src.
*/
@@ -115,7 +140,7 @@ void *my_malloc( size_t s )
if( !s )
{
error=1;
- fprintf( stderr, "mimedb: Out of memory\n" );
+ fprintf( stderr, _("%s: Out of memory\n"), MIMEDB );
}
return res;
}
@@ -129,7 +154,7 @@ char *my_strdup( char *s )
if( !s )
{
error=1;
- fprintf( stderr, "mimedb: Out of memory\n" );
+ fprintf( stderr, _("%s: Out of memory\n"), MIMEDB );
}
return res;
}
@@ -364,12 +389,57 @@ static char *munge( char *in )
}
in++;
}
- fprintf( stderr, "mimedb: Unknown error in munge()\n" );
+ fprintf( stderr, _( "%s: Unknown error in munge()\n"), MIMEDB );
error=1;
return 0;
}
/**
+ Return a regular expression that matches all strings specifying the current locale
+*/
+static char *get_lang_re()
+{
+
+ static char buff[BUFF_SIZE];
+ const char *lang = setlocale( LC_MESSAGES, 0 );
+ int close=0;
+ char *out=buff;
+
+ if( (1+strlen(lang)*4) >= BUFF_SIZE )
+ {
+ fprintf( stderr, _( "%s: Locale string too long\n"), MIMEDB );
+ error = 1;
+ return 0;
+ }
+
+ for( ; *lang; lang++ )
+ {
+ switch( *lang )
+ {
+ case '@':
+ case '.':
+ case '_':
+ if( close )
+ *out++ = ')';
+
+ close=1;
+ *out++ = '(';
+ *out++ = '|';
+ *out++ = *lang;
+ break;
+
+ default:
+ *out++ = *lang;
+ }
+ }
+
+ if( close )
+ *out++ = ')';
+ *out++=0;
+ return buff;
+}
+
+/**
Get description for a specified mimetype.
*/
static char *get_description( const char *mimetype )
@@ -380,8 +450,36 @@ static char *get_description( const char *mimetype )
int fd;
struct stat st;
char *contents;
- char *start, *stop;
+ char *start=0, *stop=0;
+
+ if( !start_re )
+ {
+ char *lang;
+ char buff[BUFF_SIZE];
+ lang = get_lang_re();
+ if( !lang )
+ return 0;
+
+ snprintf( buff, BUFF_SIZE, START_TAG, lang, lang );
+
+ start_re = my_malloc( sizeof(regex_t));
+ stop_re = my_malloc( sizeof(regex_t));
+
+ if( regcomp( start_re, buff, REG_EXTENDED ) ||
+ regcomp( stop_re, STOP_TAG, REG_EXTENDED ) )
+ {
+ fprintf( stderr, _( "%s: Could not compile regular expressions\n"), MIMEDB );
+ error=1;
+
+ free( start_re );
+ free( stop_re );
+ start_re = stop_re = 0;
+
+ return 0;
+ }
+ }
+
fn_part = my_malloc( strlen(MIME_DIR) + strlen( mimetype) + strlen(MIME_SUFFIX) + 1 );
if( !fn_part )
@@ -436,15 +534,40 @@ static char *get_description( const char *mimetype )
free( fn );
contents[st.st_size]=0;
-
- start = strstr( contents, START_TAG );
- if( start )
+ regmatch_t match[1];
+ int w = -1;
+
+ start=contents;
+
+ /*
+ On multiple matches, use the longest match, should be a pretty
+ good heuristic for best match...
+ */
+ while( !regexec(start_re, start, 1, match, 0) )
{
- start += strlen(START_TAG);
- stop = strstr( start, STOP_TAG );
- if( stop )
+ int new_w = match[0].rm_eo - match[0].rm_so;
+
+ if( new_w > w )
{
+ /*
+ New match is for a longer match then the previous
+ match, so we use the new match
+ */
+ w=new_w;
+ start += match[0].rm_eo;
+ }
+ }
+
+ if( w != -1 )
+ {
+ if( !regexec(stop_re, start, 1, match, 0) )
+ {
+ /*
+ We've found the beginning and the end of a suitable description
+ */
char *res;
+
+ stop = start + match[0].rm_so;
*stop = '\0';
res = munge( start );
free( contents );
@@ -452,7 +575,7 @@ static char *get_description( const char *mimetype )
}
}
free( contents );
- fprintf( stderr, "mimedb: No description for type %s\n", mimetype );
+ fprintf( stderr, _( "%s: No description for type %s\n"), MIMEDB, mimetype );
error=1;
return 0;
@@ -516,7 +639,7 @@ static char *get_action( const char *mimetype )
if( !launcher )
{
- fprintf( stderr, "Could not parse launcher string %s\n", launcher_str );
+ fprintf( stderr, _("%s: Could not parse launcher string '%s'\n"), MIMEDB, launcher_str );
error=1;
return 0;
}
@@ -549,7 +672,7 @@ static char *get_action( const char *mimetype )
if( !launcher_command_str )
{
fprintf( stderr,
- "mimedb: Default launcher %s does not specify how to start\n",
+ _( "%s: Default launcher '%s' does not specify how to start\n"), MIMEDB,
launcher_filename );
free( launcher_filename );
return 0;
@@ -929,7 +1052,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
}
default:
- fprintf( stderr, "Unsupported switch %c in launch string %s\n", *filter, filter_org );
+ fprintf( stderr, _("%s: Unsupported switch '%c' in launch string '%s'\n"), MIMEDB, *filter, filter_org );
launch_len=0;
break;
@@ -950,7 +1073,7 @@ static void launch( char *filter, array_list_t *files, int fileno )
case -1:
{
launch_len = 0;
- fprintf( stderr, "mimedb: Out of memory\n" );
+ fprintf( stderr, _( "%s: Out of memory\n"), MIMEDB );
return;
}
case 0:
@@ -996,6 +1119,15 @@ static void clear_entry( const void *key, const void *val )
}
+static void locale_init()
+{
+ setlocale( LC_ALL, "" );
+#if HAVE_GETTEXT
+ bindtextdomain( PACKAGE_NAME, LOCALEDIR );
+ textdomain( PACKAGE_NAME );
+#endif
+}
+
/**
Main function. Parses options and calls helper function for any heavy lifting.
@@ -1011,8 +1143,9 @@ int main (int argc, char *argv[])
int i;
hash_table_t launch_hash;
-
+ locale_init();
+
/*
Parse options
*/
@@ -1118,7 +1251,7 @@ int main (int argc, char *argv[])
exit(0);
case 'v':
- printf( "mimedb, version %s\n", PACKAGE_VERSION );
+ printf( _("%s, version %s\n"), MIMEDB, PACKAGE_VERSION );
exit( 0 );
case '?':
@@ -1129,7 +1262,7 @@ int main (int argc, char *argv[])
if( ( output_type == LAUNCH )&&(input_type==MIMETYPE))
{
- fprintf( stderr, "Can not launch a mimetype\n" );
+ fprintf( stderr, _("%s: Can not launch a mimetype\n"), MIMEDB );
print_help();
exit(1);
}
@@ -1161,7 +1294,7 @@ int main (int argc, char *argv[])
mimetype = xdg_mime_unalias_mime_type (mimetype);
if( !mimetype )
{
- fprintf( stderr, "mimedb: Could not parse mimetype from argument %s\n", argv[i] );
+ fprintf( stderr, _( "%s: Could not parse mimetype from argument '%s'\n"), MIMEDB, argv[i] );
error=1;
return 1;
}
@@ -1227,7 +1360,7 @@ int main (int argc, char *argv[])
/*
Perform the actual launching
*/
- if( output_type == LAUNCH )
+ if( output_type == LAUNCH && !error )
{
int i;
array_list_t mimes;
@@ -1239,7 +1372,7 @@ int main (int argc, char *argv[])
array_list_t *files = (array_list_t *)hash_get( &launch_hash, mimetype );
if( !files )
{
- fprintf( stderr, "mimedb: Unknown error\n" );
+ fprintf( stderr, _( "%s: Unknown error\n"), MIMEDB );
error=1;
break;
}
@@ -1260,6 +1393,14 @@ int main (int argc, char *argv[])
if( launch_buff )
free( launch_buff );
+ if( start_re )
+ {
+ regfree( start_re );
+ regfree( stop_re );
+ free( start_re );
+ free( stop_re );
+ }
+
xdg_mime_shutdown();
return error;