hook gvariant vectors up to kdbus
[platform/upstream/glib.git] / gio / glib-compile-resources.c
index 0a9dfa9..6bad64f 100644 (file)
@@ -12,9 +12,7 @@
  * 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.
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: Alexander Larsson <alexl@redhat.com>
  */
 #include <stdio.h>
 #include <locale.h>
 #include <errno.h>
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
+#ifdef G_OS_UNIX
+#include <unistd.h>
+#endif
+#ifdef G_OS_WIN32
+#include <io.h>
 #endif
 
 #include <gio/gmemoryoutputstream.h>
 #include <gio/gzlibcompressor.h>
 #include <gio/gconverteroutputstream.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
 #include <glib.h>
 #include "gvdb/gvdb-builder.h"
 
 #include "gconstructor_as_data.h"
 
+#ifdef G_OS_WIN32
+#include "glib/glib-private.h"
+#endif
+
 typedef struct
 {
   char *filename;
@@ -73,8 +74,9 @@ typedef struct
   GString *string;  /* non-NULL when accepting text */
 } ParseState;
 
-static gchar *sourcedir = NULL;
+static gchar **sourcedirs = NULL;
 static gchar *xmllint = NULL;
+static gchar *gdk_pixbuf_pixdata = NULL;
 
 static void
 file_data_free (FileData *data)
@@ -173,6 +175,28 @@ get_parent (GHashTable *table,
   return parent;
 }
 
+static gchar *
+find_file (const gchar *filename)
+{
+  guint i;
+  gchar *real_file;
+  gboolean exists;
+
+  if (g_path_is_absolute (filename))
+    return g_strdup (filename);
+
+  /* search all the sourcedirs for the correct files in order */
+  for (i = 0; sourcedirs[i] != NULL; i++)
+    {
+       real_file = g_build_path ("/", sourcedirs[i], filename, NULL);
+       exists = g_file_test (real_file, G_FILE_TEST_EXISTS);
+       if (exists)
+         return real_file;
+       g_free (real_file);
+    }
+    return NULL;
+}
+
 static void
 end_element (GMarkupParseContext  *context,
             const gchar          *element_name,
@@ -194,6 +218,7 @@ end_element (GMarkupParseContext  *context,
       gchar *key;
       FileData *data;
       char *tmp_file = NULL;
+      char *tmp_file2 = NULL;
 
       file = state->string->str;
       key = file;
@@ -215,10 +240,28 @@ end_element (GMarkupParseContext  *context,
 
       data = g_new0 (FileData, 1);
 
-      if (sourcedir != NULL)
-       real_file = g_build_filename (sourcedir, file, NULL);
+      if (sourcedirs != NULL)
+        {
+         real_file = find_file (file);
+         if (real_file == NULL)
+           {
+               g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                            _("Failed to locate '%s' in any source directory"), file);
+               return;
+           }
+       }
       else
-       real_file = g_strdup (file);
+        {
+         gboolean exists;
+         exists = g_file_test (file, G_FILE_TEST_EXISTS);
+         if (!exists)
+           {
+             g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                          _("Failed to locate '%s' in current directory"), file);
+             return;
+           }
+         real_file = g_strdup (file);
+       }
 
       data->filename = g_strdup (real_file);
       if (!state->collect_data)
@@ -229,6 +272,7 @@ end_element (GMarkupParseContext  *context,
           gchar **options;
           guint i;
           gboolean xml_stripblanks = FALSE;
+          gboolean to_pixdata = FALSE;
 
           options = g_strsplit (state->preproc_options, ",", -1);
 
@@ -236,10 +280,12 @@ end_element (GMarkupParseContext  *context,
             {
               if (!strcmp (options[i], "xml-stripblanks"))
                 xml_stripblanks = TRUE;
+              else if (!strcmp (options[i], "to-pixdata"))
+                to_pixdata = TRUE;
               else
                 {
                   g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
-                               _("Unknown proprocessing options \"%s\""), options[i]);
+                               _("Unknown processing option \"%s\""), options[i]);
                   g_strfreev (options);
                   goto cleanup;
                 }
@@ -248,8 +294,8 @@ end_element (GMarkupParseContext  *context,
 
           if (xml_stripblanks && xmllint != NULL)
             {
-              gchar *argv[8];
-              int status, fd, argc;
+              int fd;
+             GSubprocess *proc;
 
               tmp_file = g_strdup ("resource-XXXXXXXX");
               if ((fd = g_mkstemp (tmp_file)) == -1)
@@ -265,38 +311,68 @@ end_element (GMarkupParseContext  *context,
                 }
               close (fd);
 
-              argc = 0;
-              argv[argc++] = (gchar *) xmllint;
-              argv[argc++] = "--nonet";
-              argv[argc++] = "--noent";
-              argv[argc++] = "--noblanks";
-              argv[argc++] = "--output";
-              argv[argc++] = tmp_file;
-              argv[argc++] = real_file;
-              argv[argc++] = NULL;
-              g_assert (argc <= G_N_ELEMENTS (argv));
-
-              if (!g_spawn_sync (NULL /* cwd */, argv, NULL /* envv */,
-                                 G_SPAWN_STDOUT_TO_DEV_NULL |
-                                 G_SPAWN_STDERR_TO_DEV_NULL,
-                                 NULL, NULL, NULL, NULL, &status, &my_error))
-                {
-                  g_propagate_error (error, my_error);
+              proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
+                                       xmllint, "--nonet", "--noblanks", "--output", tmp_file, real_file, NULL);
+              g_free (real_file);
+             real_file = NULL;
+
+             if (!proc)
+               goto cleanup;
+
+             if (!g_subprocess_wait_check (proc, NULL, error))
+               {
+                 g_object_unref (proc);
                   goto cleanup;
                 }
-#ifdef HAVE_SYS_WAIT_H
-              if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
+
+             g_object_unref (proc);
+
+              real_file = g_strdup (tmp_file);
+            }
+
+          if (to_pixdata)
+            {
+              int fd;
+             GSubprocess *proc;
+
+              if (gdk_pixbuf_pixdata == NULL)
                 {
                   g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                                      _("Error processing input file with xmllint"));
+                                       "to-pixbuf preprocessing requested but GDK_PIXBUF_PIXDATA "
+                                       "not set and gdk-pixbuf-pixdata not found in path");
                   goto cleanup;
                 }
-#endif
 
+              tmp_file2 = g_strdup ("resource-XXXXXXXX");
+              if ((fd = g_mkstemp (tmp_file2)) == -1)
+                {
+                  int errsv = errno;
+
+                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+                               _("Failed to create temp file: %s"),
+                              g_strerror (errsv));
+                  g_free (tmp_file2);
+                  tmp_file2 = NULL;
+                  goto cleanup;
+                }
+              close (fd);
+
+              proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
+                                       gdk_pixbuf_pixdata, real_file, tmp_file2, NULL);
               g_free (real_file);
-              real_file = g_strdup (tmp_file);
+              real_file = NULL;
+
+             if (!g_subprocess_wait_check (proc, NULL, error))
+               {
+                 g_object_unref (proc);
+                  goto cleanup;
+               }
+
+             g_object_unref (proc);
+
+              real_file = g_strdup (tmp_file2);
             }
-        }
+       }
 
       if (!g_file_get_contents (real_file, &data->content, &data->size, &my_error))
        {
@@ -352,11 +428,18 @@ end_element (GMarkupParseContext  *context,
       state->preproc_options = NULL;
 
       g_free (real_file);
+
       if (tmp_file)
         {
           unlink (tmp_file);
           g_free (tmp_file);
         }
+
+      if (tmp_file2)
+        {
+          unlink (tmp_file2);
+          g_free (tmp_file2);
+        }
     }
 }
 
@@ -496,24 +579,26 @@ main (int argc, char **argv)
   gboolean generate_source = FALSE;
   gboolean generate_header = FALSE;
   gboolean manual_register = FALSE;
+  gboolean internal = FALSE;
   gboolean generate_dependencies = FALSE;
   char *c_name = NULL;
   char *c_name_no_underscores;
+  const char *linkage = "extern";
   GOptionContext *context;
   GOptionEntry entries[] = {
     { "target", 0, 0, G_OPTION_ARG_FILENAME, &target, N_("name of the output file"), N_("FILE") },
-    { "sourcedir", 0, 0, G_OPTION_ARG_FILENAME, &sourcedir, N_("The directory where files are to be read from (default to current directory)"), N_("DIRECTORY") },
+    { "sourcedir", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &sourcedirs, N_("The directories where files are to be read from (default to current directory)"), N_("DIRECTORY") },
     { "generate", 0, 0, G_OPTION_ARG_NONE, &generate_automatic, N_("Generate output in the format selected for by the target filename extension"), NULL },
     { "generate-header", 0, 0, G_OPTION_ARG_NONE, &generate_header, N_("Generate source header"), NULL },
     { "generate-source", 0, 0, G_OPTION_ARG_NONE, &generate_source, N_("Generate sourcecode used to link in the resource file into your code"), NULL },
     { "generate-dependencies", 0, 0, G_OPTION_ARG_NONE, &generate_dependencies, N_("Generate dependency list"), NULL },
     { "manual-register", 0, 0, G_OPTION_ARG_NONE, &manual_register, N_("Don't automatically create and register resource"), NULL },
+    { "internal", 0, 0, G_OPTION_ARG_NONE, &internal, N_("Don't export functions; declare them G_GNUC_INTERNAL"), NULL },
     { "c-name", 0, 0, G_OPTION_ARG_STRING, &c_name, N_("C identifier name used for the generated source code"), NULL },
     { NULL }
   };
 
 #ifdef G_OS_WIN32
-  extern gchar *_glib_get_locale_dir (void);
   gchar *tmp;
 #endif
 
@@ -532,8 +617,6 @@ main (int argc, char **argv)
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 #endif
 
-  g_type_init ();
-
   context = g_option_context_new (N_("FILE"));
   g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
   g_option_context_set_summary (context,
@@ -557,10 +640,10 @@ main (int argc, char **argv)
       return 1;
     }
 
-  srcfile = argv[1];
+  if (internal)
+    linkage = "G_GNUC_INTERNAL";
 
-  if (sourcedir == NULL)
-    sourcedir = "";
+  srcfile = argv[1];
 
   xmllint = g_strdup (g_getenv ("XMLLINT"));
   if (xmllint == NULL)
@@ -568,6 +651,10 @@ main (int argc, char **argv)
   if (xmllint == NULL)
     g_printerr ("XMLLINT not set and xmllint not found in path; skipping xml preprocessing.\n");
 
+  gdk_pixbuf_pixdata = g_strdup (g_getenv ("GDK_PIXBUF_PIXDATA"));
+  if (gdk_pixbuf_pixdata == NULL)
+    gdk_pixbuf_pixdata = g_find_program_in_path ("gdk-pixbuf-pixdata");
+
   if (target == NULL)
     {
       char *dirname = g_path_get_dirname (srcfile);
@@ -697,16 +784,16 @@ main (int argc, char **argv)
               "\n"
               "#include <gio/gio.h>\n"
               "\n"
-              "extern GResource *%s_get_resource (void);\n",
-              c_name, c_name, c_name);
+              "%s GResource *%s_get_resource (void);\n",
+              c_name, c_name, linkage, c_name);
 
       if (manual_register)
        fprintf (file,
                 "\n"
-                "extern void %s_register_resource (void);\n"
-                "extern void %s_unregister_resource (void);\n"
+                "%s void %s_register_resource (void);\n"
+                "%s void %s_unregister_resource (void);\n"
                 "\n",
-                c_name, c_name);
+                linkage, c_name, linkage, c_name);
 
       fprintf (file,
               "#endif\n");
@@ -761,31 +848,31 @@ main (int argc, char **argv)
 
       fprintf (file,
               "\n"
-              "static GStaticResource static_resource = { %s_resource_data.data, sizeof (%s_resource_data.data) };\n"
-              "extern GResource *%s_get_resource (void);\n"
+              "static GStaticResource static_resource = { %s_resource_data.data, sizeof (%s_resource_data.data), NULL, NULL, NULL };\n"
+              "%s GResource *%s_get_resource (void);\n"
               "GResource *%s_get_resource (void)\n"
               "{\n"
               "  return g_static_resource_get_resource (&static_resource);\n"
               "}\n",
-              c_name, c_name, c_name, c_name);
+              c_name, c_name, linkage, c_name, c_name);
 
 
       if (manual_register)
        {
          fprintf (file,
                   "\n"
-                  "extern void %s_unregister_resource (void);\n"
+                  "%s void %s_unregister_resource (void);\n"
                   "void %s_unregister_resource (void)\n"
                   "{\n"
                   "  g_static_resource_fini (&static_resource);\n"
                   "}\n"
                   "\n"
-                  "extern void %s_register_resource (void);\n"
+                  "%s void %s_register_resource (void);\n"
                   "void %s_register_resource (void)\n"
                   "{\n"
                   "  g_static_resource_init (&static_resource);\n"
                   "}\n",
-                  c_name, c_name, c_name, c_name);
+                  linkage, c_name, c_name, linkage, c_name, c_name);
        }
       else
        {