girepository: Drop libgio dependency from gdump.c

It’s not particularly necessary, and makes the build-time dependencies
more complex than they need to be, as it means that to generate
GLib-2.0.gir and GObject-2.0.gir, libgio.so (and its generated headers)
already needs to have been built.

See discussion on https://gitlab.gnome.org/GNOME/glib/-/issues/3164

These changes need to be replicated in gobject-introspection.git before
the problem can be solved, though, as that still has its own copy of
`gdump.c` (which it installs and uses).

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3164
This commit is contained in:
Philip Withnall 2023-12-14 03:30:14 +00:00 committed by Emmanuele Bassi
parent 0e475a6e11
commit fa37ab6d06
2 changed files with 126 additions and 77 deletions

View File

@ -33,16 +33,73 @@
#include <glib.h> #include <glib.h>
#include <glib-object.h> #include <glib-object.h>
#include <gio/gio.h> #include <gmodule.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <string.h> #include <string.h>
static void /* Analogue of g_output_stream_write_all(). */
escaped_printf (GOutputStream *out, const char *fmt, ...) G_GNUC_PRINTF (2, 3); static gboolean
write_all (FILE *out,
const void *buffer,
gsize count,
gsize *bytes_written,
GError **error)
{
size_t ret;
ret = fwrite (buffer, 1, count, out);
if (bytes_written != NULL)
*bytes_written = ret;
if (ret < count)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
"Failed to write to file");
return FALSE;
}
return TRUE;
}
/* Analogue of g_data_input_stream_read_line(). */
static char *
read_line (FILE *input,
size_t *len_out)
{
GByteArray *buffer = g_byte_array_new ();
const guint8 nul = '\0';
while (TRUE)
{
size_t ret;
guint8 byte;
ret = fread (&byte, 1, 1, input);
if (ret == 0)
break;
if (byte == '\n')
break;
g_byte_array_append (buffer, &byte, 1);
}
g_byte_array_append (buffer, &nul, 1);
if (len_out != NULL)
*len_out = buffer->len - 1; /* dont include terminating nul */
return (char *) g_byte_array_free (buffer, FALSE);
}
static void static void
escaped_printf (GOutputStream *out, const char *fmt, ...) escaped_printf (FILE *out, const char *fmt, ...) G_GNUC_PRINTF (2, 3);
static void
escaped_printf (FILE *out, const char *fmt, ...)
{ {
char *str; char *str;
va_list args; va_list args;
@ -52,7 +109,7 @@ escaped_printf (GOutputStream *out, const char *fmt, ...)
va_start (args, fmt); va_start (args, fmt);
str = g_markup_vprintf_escaped (fmt, args); str = g_markup_vprintf_escaped (fmt, args);
if (!g_output_stream_write_all (out, str, strlen (str), &written, NULL, &error)) if (!write_all (out, str, strlen (str), &written, &error))
{ {
g_critical ("failed to write to iochannel: %s", error->message); g_critical ("failed to write to iochannel: %s", error->message);
g_clear_error (&error); g_clear_error (&error);
@ -63,11 +120,11 @@ escaped_printf (GOutputStream *out, const char *fmt, ...)
} }
static void static void
goutput_write (GOutputStream *out, const char *str) goutput_write (FILE *out, const char *str)
{ {
gsize written; gsize written;
GError *error = NULL; GError *error = NULL;
if (!g_output_stream_write_all (out, str, strlen (str), &written, NULL, &error)) if (!write_all (out, str, strlen (str), &written, &error))
{ {
g_critical ("failed to write to iochannel: %s", error->message); g_critical ("failed to write to iochannel: %s", error->message);
g_clear_error (&error); g_clear_error (&error);
@ -86,8 +143,8 @@ invoke_get_type (GModule *self, const char *symbol, GError **error)
if (!g_module_symbol (self, symbol, (void**)&sym)) if (!g_module_symbol (self, symbol, (void**)&sym))
{ {
g_set_error (error, g_set_error (error,
G_IO_ERROR, G_FILE_ERROR,
G_IO_ERROR_FAILED, G_FILE_ERROR_FAILED,
"Failed to find symbol '%s'", symbol); "Failed to find symbol '%s'", symbol);
return G_TYPE_INVALID; return G_TYPE_INVALID;
} }
@ -96,8 +153,8 @@ invoke_get_type (GModule *self, const char *symbol, GError **error)
if (ret == G_TYPE_INVALID) if (ret == G_TYPE_INVALID)
{ {
g_set_error (error, g_set_error (error,
G_IO_ERROR, G_FILE_ERROR,
G_IO_ERROR_FAILED, G_FILE_ERROR_FAILED,
"Function '%s' returned G_TYPE_INVALID", symbol); "Function '%s' returned G_TYPE_INVALID", symbol);
} }
return ret; return ret;
@ -111,8 +168,8 @@ invoke_error_quark (GModule *self, const char *symbol, GError **error)
if (!g_module_symbol (self, symbol, (void**)&sym)) if (!g_module_symbol (self, symbol, (void**)&sym))
{ {
g_set_error (error, g_set_error (error,
G_IO_ERROR, G_FILE_ERROR,
G_IO_ERROR_FAILED, G_FILE_ERROR_FAILED,
"Failed to find symbol '%s'", symbol); "Failed to find symbol '%s'", symbol);
return G_TYPE_INVALID; return G_TYPE_INVALID;
} }
@ -191,10 +248,10 @@ value_to_string (const GValue *value)
} }
static void static void
dump_properties (GType type, GOutputStream *out) dump_properties (GType type, FILE *out)
{ {
guint i; guint i;
guint n_properties; guint n_properties = 0;
GParamSpec **props; GParamSpec **props;
if (G_TYPE_FUNDAMENTAL (type) == G_TYPE_OBJECT) if (G_TYPE_FUNDAMENTAL (type) == G_TYPE_OBJECT)
@ -244,7 +301,7 @@ dump_properties (GType type, GOutputStream *out)
} }
static void static void
dump_signals (GType type, GOutputStream *out) dump_signals (GType type, FILE *out)
{ {
guint i; guint i;
guint n_sigs; guint n_sigs;
@ -296,7 +353,7 @@ dump_signals (GType type, GOutputStream *out)
} }
static void static void
dump_object_type (GType type, const char *symbol, GOutputStream *out) dump_object_type (GType type, const char *symbol, FILE *out)
{ {
guint n_interfaces; guint n_interfaces;
guint i; guint i;
@ -350,7 +407,7 @@ dump_object_type (GType type, const char *symbol, GOutputStream *out)
} }
static void static void
dump_interface_type (GType type, const char *symbol, GOutputStream *out) dump_interface_type (GType type, const char *symbol, FILE *out)
{ {
guint n_interfaces; guint n_interfaces;
guint i; guint i;
@ -383,14 +440,14 @@ dump_interface_type (GType type, const char *symbol, GOutputStream *out)
} }
static void static void
dump_boxed_type (GType type, const char *symbol, GOutputStream *out) dump_boxed_type (GType type, const char *symbol, FILE *out)
{ {
escaped_printf (out, " <boxed name=\"%s\" get-type=\"%s\"/>\n", escaped_printf (out, " <boxed name=\"%s\" get-type=\"%s\"/>\n",
g_type_name (type), symbol); g_type_name (type), symbol);
} }
static void static void
dump_flags_type (GType type, const char *symbol, GOutputStream *out) dump_flags_type (GType type, const char *symbol, FILE *out)
{ {
guint i; guint i;
GFlagsClass *klass; GFlagsClass *klass;
@ -410,7 +467,7 @@ dump_flags_type (GType type, const char *symbol, GOutputStream *out)
} }
static void static void
dump_enum_type (GType type, const char *symbol, GOutputStream *out) dump_enum_type (GType type, const char *symbol, FILE *out)
{ {
guint i; guint i;
GEnumClass *klass; GEnumClass *klass;
@ -430,7 +487,7 @@ dump_enum_type (GType type, const char *symbol, GOutputStream *out)
} }
static void static void
dump_fundamental_type (GType type, const char *symbol, GOutputStream *out) dump_fundamental_type (GType type, const char *symbol, FILE *out)
{ {
guint n_interfaces; guint n_interfaces;
guint i; guint i;
@ -484,7 +541,7 @@ dump_fundamental_type (GType type, const char *symbol, GOutputStream *out)
} }
static void static void
dump_type (GType type, const char *symbol, GOutputStream *out) dump_type (GType type, const char *symbol, FILE *out)
{ {
switch (g_type_fundamental (type)) switch (g_type_fundamental (type))
{ {
@ -513,7 +570,7 @@ dump_type (GType type, const char *symbol, GOutputStream *out)
} }
static void static void
dump_error_quark (GQuark quark, const char *symbol, GOutputStream *out) dump_error_quark (GQuark quark, const char *symbol, FILE *out)
{ {
escaped_printf (out, " <error-quark function=\"%s\" domain=\"%s\"/>\n", escaped_printf (out, " <error-quark function=\"%s\" domain=\"%s\"/>\n",
symbol, g_quark_to_string (quark)); symbol, g_quark_to_string (quark));
@ -556,11 +613,8 @@ gi_repository_dump (const char *input_filename,
#endif #endif
{ {
GHashTable *output_types; GHashTable *output_types;
GFile *input_file; FILE *input;
GFile *output_file; FILE *output;
GFileInputStream *input;
GFileOutputStream *output;
GDataInputStream *in;
GModule *self; GModule *self;
gboolean caught_error = FALSE; gboolean caught_error = FALSE;
@ -568,47 +622,47 @@ gi_repository_dump (const char *input_filename,
if (!self) if (!self)
{ {
g_set_error (error, g_set_error (error,
G_IO_ERROR, G_FILE_ERROR,
G_IO_ERROR_FAILED, G_FILE_ERROR_FAILED,
"failed to open self: %s", "failed to open self: %s",
g_module_error ()); g_module_error ());
return FALSE; return FALSE;
} }
input_file = g_file_new_for_path (input_filename); input = fopen (input_filename, "rb");
output_file = g_file_new_for_path (output_filename);
input = g_file_read (input_file, NULL, error);
g_object_unref (input_file);
if (input == NULL) if (input == NULL)
{ {
g_object_unref (output_file); int saved_errno = errno;
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
"Failed to open %s: %s", input_filename, g_strerror (saved_errno));
g_module_close (self);
return FALSE; return FALSE;
} }
output = g_file_replace (output_file, NULL, FALSE, 0, NULL, error); output = fopen (output_filename, "wb");
g_object_unref (output_file);
if (output == NULL) if (output == NULL)
{ {
g_input_stream_close (G_INPUT_STREAM (input), NULL, NULL); int saved_errno = errno;
g_object_unref (input); g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
"Failed to open %s: %s", output_filename, g_strerror (saved_errno));
fclose (input);
g_module_close (self);
return FALSE; return FALSE;
} }
goutput_write (G_OUTPUT_STREAM (output), "<?xml version=\"1.0\"?>\n"); goutput_write (output, "<?xml version=\"1.0\"?>\n");
goutput_write (G_OUTPUT_STREAM (output), "<dump>\n"); goutput_write (output, "<dump>\n");
output_types = g_hash_table_new (NULL, NULL); output_types = g_hash_table_new (NULL, NULL);
in = g_data_input_stream_new (G_INPUT_STREAM (input));
g_object_unref (input);
while (TRUE) while (TRUE)
{ {
gsize len; gsize len;
char *line = g_data_input_stream_read_line (in, &len, NULL, NULL); char *line = read_line (input, &len);
const char *function; const char *function;
if (line == NULL || *line == '\0') if (line == NULL || *line == '\0')
@ -639,7 +693,7 @@ gi_repository_dump (const char *input_filename,
goto next; goto next;
g_hash_table_insert (output_types, (gpointer) type, (gpointer) type); g_hash_table_insert (output_types, (gpointer) type, (gpointer) type);
dump_type (type, function, G_OUTPUT_STREAM (output)); dump_type (type, function, output);
} }
else if (strncmp (line, "error-quark:", strlen ("error-quark:")) == 0) else if (strncmp (line, "error-quark:", strlen ("error-quark:")) == 0)
{ {
@ -655,7 +709,7 @@ gi_repository_dump (const char *input_filename,
break; break;
} }
dump_error_quark (quark, function, G_OUTPUT_STREAM (output)); dump_error_quark (quark, function, output);
} }
@ -665,18 +719,30 @@ gi_repository_dump (const char *input_filename,
g_hash_table_destroy (output_types); g_hash_table_destroy (output_types);
goutput_write (G_OUTPUT_STREAM (output), "</dump>\n"); goutput_write (output, "</dump>\n");
{ {
/* Avoid overwriting an earlier set error */ /* Avoid overwriting an earlier set error */
caught_error |= !g_input_stream_close (G_INPUT_STREAM (in), NULL, if (fclose (input) != 0 && !caught_error)
caught_error ? NULL : error); {
caught_error |= !g_output_stream_close (G_OUTPUT_STREAM (output), NULL, int saved_errno = errno;
caught_error ? NULL : error);
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
"Error closing input file %s: %s", input_filename,
g_strerror (saved_errno));
caught_error = TRUE;
} }
g_object_unref (in); if (fclose (output) != 0 && !caught_error)
g_object_unref (output); {
int saved_errno = errno;
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (saved_errno),
"Error closing output file %s: %s", output_filename,
g_strerror (saved_errno));
caught_error = TRUE;
}
}
return !caught_error; return !caught_error;
} }

View File

@ -24,31 +24,14 @@
*/ */
#include "gdump.c" #include "gdump.c"
#ifdef G_OS_WIN32
#include <windows.h>
#include <io.h> /* For _get_osfhandle() */
#include <gio/gwin32outputstream.h>
#else
#include <gio/gunixoutputstream.h>
#endif
int int
main (int argc, main (int argc,
char **argv) char **argv)
{ {
int i; int i;
GOutputStream *Stdout;
GModule *self; GModule *self;
#if defined(G_OS_WIN32)
HANDLE *hnd = (HANDLE) _get_osfhandle (1);
g_return_val_if_fail (hnd && hnd != INVALID_HANDLE_VALUE, 1);
Stdout = g_win32_output_stream_new (hnd, FALSE);
#else
Stdout = g_unix_output_stream_new (1, FALSE);
#endif
self = g_module_open (NULL, 0); self = g_module_open (NULL, 0);
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
@ -63,7 +46,7 @@ main (int argc,
g_clear_error (&error); g_clear_error (&error);
} }
else else
dump_type (type, argv[i], Stdout); dump_type (type, argv[i], stdout);
} }
return 0; return 0;