gnetworking.h.in: move "#undef interface"
[platform/upstream/glib.git] / gio / glib-compile-resources.c
index eaad38f..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;
@@ -71,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)
@@ -171,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,
@@ -192,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;
@@ -213,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)
@@ -227,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);
 
@@ -234,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;
                 }
@@ -246,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)
@@ -263,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))
        {
@@ -350,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);
+        }
     }
 }
 
@@ -494,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
 
@@ -530,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,
@@ -555,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)
@@ -566,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);
@@ -695,16 +784,16 @@ main (int argc, char **argv)
               "\n"
               "#include <gio/gio.h>\n"
               "\n"
-              "extern GResource *%s_resource;\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");
@@ -717,7 +806,6 @@ main (int argc, char **argv)
       guint8 *data;
       gsize data_size;
       gsize i;
-      char *static_str;
 
       if (!g_file_get_contents (binary_target, (char **)&data,
                                &data_size, NULL))
@@ -758,13 +846,37 @@ main (int argc, char **argv)
 
       fprintf (file, "} };\n");
 
+      fprintf (file,
+              "\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, linkage, c_name, c_name);
+
+
       if (manual_register)
        {
-         static_str = "";
+         fprintf (file,
+                  "\n"
+                  "%s void %s_unregister_resource (void);\n"
+                  "void %s_unregister_resource (void)\n"
+                  "{\n"
+                  "  g_static_resource_fini (&static_resource);\n"
+                  "}\n"
+                  "\n"
+                  "%s void %s_register_resource (void);\n"
+                  "void %s_register_resource (void)\n"
+                  "{\n"
+                  "  g_static_resource_init (&static_resource);\n"
+                  "}\n",
+                  linkage, c_name, c_name, linkage, c_name, c_name);
        }
       else
        {
-         static_str = "static ";
+         fprintf (file, "%s", gconstructor_code);
          fprintf (file,
                   "\n"
                   "#ifdef G_HAS_CONSTRUCTORS\n"
@@ -781,48 +893,18 @@ main (int argc, char **argv)
                   "#else\n"
                   "#warning \"Constructor not supported on this compiler, linking in resources will not work\"\n"
                   "#endif\n"
-                  "\n");
+                  "\n"
+                  "static void resource_constructor (void)\n"
+                  "{\n"
+                  "  g_static_resource_init (&static_resource);\n"
+                  "}\n"
+                  "\n"
+                  "static void resource_destructor (void)\n"
+                  "{\n"
+                  "  g_static_resource_fini (&static_resource);\n"
+                  "}\n");
        }
 
-      fprintf (file,
-              "\n"
-              "GResource *%s_resource = NULL;\n"
-              "\n"
-              "%svoid %s_unregister_resource (void)\n"
-              "{\n"
-              "  if (%s_resource)\n"
-              "    {\n"
-              "      g_resources_unregister (%s_resource);\n"
-              "      g_resource_unref (%s_resource);\n"
-              "      %s_resource = NULL;\n"
-              "    }\n"
-              "}\n"
-              "\n"
-              "%svoid %s_register_resource (void)\n"
-              "{\n"
-              "  if (%s_resource == NULL)\n"
-              "    {\n"
-              "      GBytes *bytes = g_bytes_new_static (%s_resource_data.data, sizeof (%s_resource_data.data));\n"
-              "      %s_resource = g_resource_new_from_data (bytes, NULL);\n"
-              "      if (%s_resource)\n"
-              "        g_resources_register (%s_resource);\n"
-              "       g_bytes_unref (bytes);\n"
-              "    }\n"
-              "}\n", c_name, static_str, c_name, c_name, c_name, c_name, c_name, static_str, c_name, c_name, c_name, c_name, c_name, c_name, c_name);
-
-      if (!manual_register)
-       fprintf (file,
-                "\n"
-                "static void resource_constructor (void)\n"
-                "{\n"
-                "  %s_register_resource ();\n"
-                "}\n"
-                "\n"
-                "static void resource_destructor (void)\n"
-                "{\n"
-                "  %s_unregister_resource ();\n"
-                "}\n", c_name, c_name);
-
       fclose (file);
 
       g_free (data);