Commit 735bee47 authored by Matthias Clasen's avatar Matthias Clasen

Let query utilities update the cache file directly

This is much more convenient for packagers than having to
redirect the output into the cache file, and much less error-prone.
parent 0b0f176a
......@@ -17,6 +17,7 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>gdk-pixbuf-query-loaders-3.0</command>
<arg choice="opt">--update-cache</arg>
<arg choice="opt" rep="repeat">module</arg>
</cmdsynopsis>
</refsynopsisdiv>
......@@ -25,7 +26,7 @@
<para>
<command>gdk-pixbuf-query-loaders-3.0</command> collects information about
loadable modules for <application>gdk-pixbuf</application> and writes it to
<filename>stdout</filename>.
the default cache file location, or to <filename>stdout</filename>.
</para>
<para>
If called without arguments, it looks for modules in the
......@@ -43,6 +44,16 @@ can be set to point <application>gdk-pixbuf</application> at the file.
</para>
</refsect1>
<refsect1><title>Options</title>
<variablelist>
<varlistentry>
<term>--update-cache</term>
<listitem><para>Write the output to the default cache location instead of
<filename>stdout</filename></para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Environment</title>
<para>
The environment variable <envar>GDK_PIXBUF_MODULEDIR</envar> can be used
......
......@@ -17,6 +17,7 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>gtk-query-immodules-3.0</command>
<arg choice="opt">--update-cache</arg>
<arg choice="opt" rep="repeat">module</arg>
</cmdsynopsis>
</refsynopsisdiv>
......@@ -24,7 +25,8 @@
<refsect1><title>Description</title>
<para>
<command>gtk-query-immodules-3.0</command> collects information about loadable
input method modules for GTK+ and writes it to <filename>stdout</filename>.
input method modules for GTK+ and writes it to the default cache file
location, or to <filename>stdout</filename>.
</para>
<para>
If called without arguments, it looks for modules in the GTK+ input method
......@@ -42,6 +44,16 @@ can be set to point GTK+ at the file.
</para>
</refsect1>
<refsect1><title>Options</title>
<variablelist>
<varlistentry>
<term>--update-cache</term>
<listitem><para>Write the output to the default cache location instead of
<filename>stdout</filename></para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1><title>Environment</title>
<para>
The environment variable <link linkend="GTK_PATH"><envar>GTK_PATH</envar></link>
......
......@@ -50,10 +50,10 @@
#endif
static void
print_escaped (const char *str)
print_escaped (GString *contents, const char *str)
{
gchar *tmp = g_strescape (str, "");
g_printf ("\"%s\" ", tmp);
g_string_append_printf (contents, "\"%s\" ", tmp);
g_free (tmp);
}
......@@ -78,13 +78,13 @@ loader_sanity_check (const char *path, GdkPixbufFormat *info, GdkPixbufModule *v
if (mask_len != prefix_len)
{
error = "mask length mismatch";
goto error;
}
if (strspn (pattern->mask, " !xzn*") < mask_len)
{
error = "bad char in mask";
goto error;
}
}
......@@ -109,48 +109,48 @@ loader_sanity_check (const char *path, GdkPixbufFormat *info, GdkPixbufModule *v
error = "loader claims to support saving but doesn't implement save";
goto error;
}
return 1;
error:
g_fprintf (stderr, "Loader sanity check failed for %s: %s\n",
path, error);
return 0;
}
static void
write_loader_info (const char *path, GdkPixbufFormat *info)
write_loader_info (GString *contents, const char *path, GdkPixbufFormat *info)
{
const GdkPixbufModulePattern *pattern;
char **mime;
char **ext;
g_printf("\"%s\"\n", path);
g_printf ("\"%s\" %u \"%s\" \"%s\" \"%s\"\n",
g_string_append_printf (contents, "\"%s\"\n", path);
g_string_append_printf (contents, "\"%s\" %u \"%s\" \"%s\" \"%s\"\n",
info->name,
info->flags,
info->domain ? info->domain : GETTEXT_PACKAGE,
info->description,
info->license ? info->license : "");
for (mime = info->mime_types; *mime; mime++) {
g_printf ("\"%s\" ", *mime);
g_string_append_printf (contents, "\"%s\" ", *mime);
}
g_printf ("\"\"\n");
g_string_append (contents, "\"\"\n");
for (ext = info->extensions; *ext; ext++) {
g_printf ("\"%s\" ", *ext);
g_string_append_printf (contents, "\"%s\" ", *ext);
}
g_printf ("\"\"\n");
g_string_append (contents, "\"\"\n");
for (pattern = info->signature; pattern->prefix; pattern++) {
print_escaped (pattern->prefix);
print_escaped (pattern->mask ? (const char *)pattern->mask : "");
g_printf ("%d\n", pattern->relevance);
print_escaped (contents, pattern->prefix);
print_escaped (contents, pattern->mask ? (const char *)pattern->mask : "");
g_string_append_printf (contents, "%d\n", pattern->relevance);
}
g_printf ("\n");
g_string_append_c (contents, '\n');
}
static void
query_module (const char *dir, const char *file)
query_module (GString *contents, const char *dir, const char *file)
{
char *path;
GModule *module;
......@@ -170,7 +170,7 @@ query_module (const char *dir, const char *file)
g_module_symbol (module, "fill_vtable", &fill_vtable_ptr)) {
GdkPixbufFormat *info;
GdkPixbufModule *vtable;
#ifdef G_OS_WIN32
/* Replace backslashes in path with forward slashes, so that
* it reads in without problems.
......@@ -194,10 +194,10 @@ query_module (const char *dir, const char *file)
(*fill_info) (info);
(*fill_vtable) (vtable);
if (loader_sanity_check (path, info, vtable))
write_loader_info (path, info);
write_loader_info (contents, path, info);
g_free (info);
g_free (vtable);
}
......@@ -213,10 +213,24 @@ query_module (const char *dir, const char *file)
g_free (path);
}
static gchar *
gdk_pixbuf_get_module_file (void)
{
gchar *result = g_strdup (g_getenv ("GDK_PIXBUF_MODULE_FILE"));
if (!result)
result = g_build_filename (GTK_LIBDIR, "gtk-3.0", GTK_BINARY_VERSION, "loaders.cache", NULL);
return result;
}
int main (int argc, char **argv)
{
gint i;
gchar *prgname;
GString *contents;
gchar *cache_file = NULL;
gint first_file = 1;
#ifdef G_OS_WIN32
gchar *libdir;
......@@ -269,15 +283,24 @@ int main (int argc, char **argv)
#define PIXBUF_LIBDIR libdir
#endif
if (argc > 1 && strcmp (argv[1], "--update-cache") == 0) {
cache_file = gdk_pixbuf_get_module_file ();
first_file = 2;
}
contents = g_string_new ("");
prgname = g_get_prgname ();
g_printf ("# GdkPixbuf Image Loader Modules file\n"
"# Automatically generated file, do not edit\n"
"# Created by %s from gtk+-%s\n"
"#\n",
(prgname ? prgname : "gdk-pixbuf-query-loaders-3.0"),
GDK_PIXBUF_VERSION);
if (argc == 1) {
g_string_append_printf (contents,
"# GdkPixbuf Image Loader Modules file\n"
"# Automatically generated file, do not edit\n"
"# Created by %s from gtk+-%s\n"
"#\n",
(prgname ? prgname : "gdk-pixbuf-query-loaders-3.0"),
GDK_PIXBUF_VERSION);
if (argc == first_file) {
#ifdef USE_GMODULE
const char *path;
GDir *dir;
......@@ -290,7 +313,7 @@ int main (int argc, char **argv)
if (path == NULL || *path == '\0')
path = PIXBUF_LIBDIR;
g_printf ("# LoaderDir = %s\n#\n", path);
g_string_append_printf (contents, "# LoaderDir = %s\n#\n", path);
dir = g_dir_open (path, 0, NULL);
if (dir) {
......@@ -300,13 +323,13 @@ int main (int argc, char **argv)
gint len = strlen (dent);
if (len > SOEXT_LEN &&
strcmp (dent + len - SOEXT_LEN, SOEXT) == 0) {
query_module (path, dent);
query_module (contents, path, dent);
}
}
g_dir_close (dir);
}
#else
g_printf ("# dynamic loading of modules not supported\n");
g_string_append_printf (contents, "# dynamic loading of modules not supported\n");
#endif
}
else {
......@@ -318,10 +341,21 @@ int main (int argc, char **argv)
infilename = g_locale_to_utf8 (infilename,
-1, NULL, NULL, NULL);
#endif
query_module (cwd, infilename);
query_module (contents, cwd, infilename);
}
g_free (cwd);
}
if (cache_file) {
GError *err;
err = NULL;
if (!g_file_set_contents (cache_file, contents->str, -1, &err)) {
g_fprintf (stderr, "%s\n", err->message);
}
}
else
g_print ("%s\n", contents->str);
return 0;
}
......@@ -41,11 +41,9 @@
#include "gtk/gtkimmodule.h"
#include "gtk/gtkversion.h"
static char *
escape_string (const char *str)
static void
escape_string (GString *contents, const char *str)
{
GString *result = g_string_new (NULL);
while (TRUE)
{
char c = *str++;
......@@ -55,38 +53,38 @@ escape_string (const char *str)
case '\0':
goto done;
case '\n':
g_string_append (result, "\\n");
g_string_append (contents, "\\n");
break;
case '\"':
g_string_append (result, "\\\"");
g_string_append (contents, "\\\"");
break;
#ifdef G_OS_WIN32
/* Replace backslashes in path with forward slashes, so that
* it reads in without problems.
*/
case '\\':
g_string_append (result, "/");
g_string_append (contents, "/");
break;
#endif
default:
g_string_append_c (result, c);
g_string_append_c (contents, c);
}
}
done:
return g_string_free (result, FALSE);
done:;
}
static void
print_escaped (const char *str)
print_escaped (GString *contents, const char *str)
{
char *tmp = escape_string (str);
g_printf ("\"%s\" ", tmp);
g_free (tmp);
g_string_append_c (contents, '"');
escape_string (contents, str);
g_string_append_c (contents, '"');
g_string_append_c (contents, ' ');
}
static gboolean
query_module (const char *dir, const char *name)
query_module (const char *dir, const char *name, GString *contents)
{
void (*list) (const GtkIMContextInfo ***contexts,
guint *n_contexts);
......@@ -131,21 +129,21 @@ query_module (const char *dir, const char *name)
exit = exit_ptr;
create = create_ptr;
print_escaped (path);
fputs ("\n", stdout);
print_escaped (contents, path);
g_string_append_c (contents, '\n');
(*list) (&contexts, &n_contexts);
for (i=0; i<n_contexts; i++)
for (i = 0; i < n_contexts; i++)
{
print_escaped (contexts[i]->context_id);
print_escaped (contexts[i]->context_name);
print_escaped (contexts[i]->domain);
print_escaped (contexts[i]->domain_dirname);
print_escaped (contexts[i]->default_locales);
fputs ("\n", stdout);
print_escaped (contents, contexts[i]->context_id);
print_escaped (contents, contexts[i]->context_name);
print_escaped (contents, contexts[i]->domain);
print_escaped (contents, contexts[i]->domain_dirname);
print_escaped (contents, contexts[i]->default_locales);
g_string_append_c (contents, '\n');
}
fputs ("\n", stdout);
g_string_append_c (contents, '\n');
}
else
{
......@@ -167,16 +165,26 @@ int main (int argc, char **argv)
int i;
char *path;
gboolean error = FALSE;
gchar *cache_file = NULL;
gint first_file = 1;
GString *contents;
g_printf ("# GTK+ Input Method Modules file\n"
"# Automatically generated file, do not edit\n"
"# Created by %s from gtk+-%d.%d.%d\n"
"#\n",
argv[0],
GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
if (argc > 1 && strcmp (argv[1], "--update-cache") == 0)
{
cache_file = gtk_rc_get_im_module_file ();
first_file = 2;
}
contents = g_string_new ("");
g_string_append_printf (contents,
"# GTK+ Input Method Modules file\n"
"# Automatically generated file, do not edit\n"
"# Created by %s from gtk+-%d.%d.%d\n"
"#\n",
argv[0],
GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
if (argc == 1) /* No arguments given */
if (argc == first_file) /* No file arguments given */
{
char **dirs;
int i;
......@@ -184,7 +192,7 @@ int main (int argc, char **argv)
path = gtk_rc_get_im_module_path ();
g_printf ("# ModulesPath = %s\n#\n", path);
g_string_append_printf (contents, "# ModulesPath = %s\n#\n", path);
dirs = pango_split_file_list (path);
dirs_done = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
......@@ -200,7 +208,7 @@ int main (int argc, char **argv)
while ((dent = g_dir_read_name (dir)))
{
if (g_str_has_suffix (dent, SOEXT))
error |= query_module (dirs[i], dent);
error |= query_module (dirs[i], dent, contents);
}
g_dir_close (dir);
......@@ -215,11 +223,28 @@ int main (int argc, char **argv)
{
cwd = g_get_current_dir ();
for (i = 1; i < argc; i++)
error |= query_module (cwd, argv[i]);
for (i = first_file; i < argc; i++)
error |= query_module (cwd, argv[i], contents);
g_free (cwd);
}
if (!error)
{
if (cache_file)
{
GError *err;
err = NULL;
if (!g_file_set_contents (cache_file, contents->str, -1, &err))
{
g_fprintf (stderr, "%s\n", err->message);
error = 1;
}
}
else
g_print ("%s\n", contents->str);
}
return error ? 1 : 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment