diff -Nru glib2.0-2.59.2/debian/changelog glib2.0-2.59.3/debian/changelog --- glib2.0-2.59.2/debian/changelog 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/changelog 2019-03-04 09:01:42.000000000 +0000 @@ -1,3 +1,42 @@ +glib2.0 (2.59.3-2+201903040901~ubuntu19.04.1) disco; urgency=low + + * Auto build. + + -- Khurshid Alam Mon, 04 Mar 2019 09:01:42 +0000 + +glib2.0 (2.59.3-2) experimental; urgency=medium + + [ Philip Withnall ] + * debian: Drop GVariant alignment patches which are no longer needed. + The upstream 2.59.0 release contained commit + 0f2a6c61c9c5e34d57293fb6987b21f3d1feb1cb, which automatically aligns + GVariants at construction time. The realignment in the tests was a + workaround for this. + See upstream issue https://gitlab.gnome.org/GNOME/glib/issues/1342. + + [ Iain Lane ] + * Cherry-pick fixes for upstream bug #1679 to fix a flaky test. + This is apparently more flaky on the autopkgtest machines than elsewhere + - it's quite consistently failing there. + + -- Iain Lane Wed, 27 Feb 2019 10:21:40 +0000 + +glib2.0 (2.59.3-1) experimental; urgency=medium + + * New upstream release + + Fix support for g_get_user_special_dir() on macOS, including support for + the Downloads directory + + Ensure that cancelling a GTask cannot cause its callback to be called + synchronously (in the same call chain as the original *_async() call) + + Further fixes to the Happy Eyeballs (RFC 8305) implementation + + Various fixes for installation of installed tests + * Refresh and drop patches. + Drop gio-tests-Install-test1.overlay-file-when-building-instal.patch, + tests-Install-the-slow-connect-preload.so-library-and-use.patch, + fixed upstream. + + -- Iain Lane Wed, 20 Feb 2019 14:25:13 +0000 + glib2.0 (2.59.2-2) experimental; urgency=medium * Install `test1.overlay' file, which is needed for the installed tests. diff -Nru glib2.0-2.59.2/debian/git-build-recipe.manifest glib2.0-2.59.3/debian/git-build-recipe.manifest --- glib2.0-2.59.2/debian/git-build-recipe.manifest 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/debian/git-build-recipe.manifest 2019-03-04 09:01:42.000000000 +0000 @@ -0,0 +1,2 @@ +# git-build-recipe format 0.4 deb-version {debversion}+201903040901 +lp:~khurshid-alam/glib/+git/2.59.3 git-commit:61df86f4b59cbdc303bc2f7a87e7162678fa8799 diff -Nru glib2.0-2.59.2/debian/patches/0001-timer-test-use-volatile-for-locals.patch glib2.0-2.59.3/debian/patches/0001-timer-test-use-volatile-for-locals.patch --- glib2.0-2.59.2/debian/patches/0001-timer-test-use-volatile-for-locals.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/0001-timer-test-use-volatile-for-locals.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -From: Ryan Lortie -Date: Tue, 4 Mar 2014 09:20:38 -0500 -Subject: timer test: use 'volatile' for locals - -GCC seems to be failing to follow the letter of the C spec by allowing extra -precision in floating point values to persist across assignments which are -optimised away. - -Force its hand by using 'volatile' on the locals in question. - -Bug: https://gitlab.gnome.org/GNOME/glib/issues/820 -Forwarded: yes ---- - glib/tests/timer.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/glib/tests/timer.c b/glib/tests/timer.c -index 5b2e711..4cd5fba 100644 ---- a/glib/tests/timer.c -+++ b/glib/tests/timer.c -@@ -27,7 +27,7 @@ static void - test_timer_basic (void) - { - GTimer *timer; -- gdouble elapsed; -+ volatile gdouble elapsed; - gulong micros; - - timer = g_timer_new (); -@@ -44,7 +44,7 @@ static void - test_timer_stop (void) - { - GTimer *timer; -- gdouble elapsed, elapsed2; -+ volatile gdouble elapsed, elapsed2; - - timer = g_timer_new (); - diff -Nru glib2.0-2.59.2/debian/patches/01_gettext-desktopfiles.patch glib2.0-2.59.3/debian/patches/01_gettext-desktopfiles.patch --- glib2.0-2.59.2/debian/patches/01_gettext-desktopfiles.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/01_gettext-desktopfiles.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,171 +0,0 @@ -From: Debian GNOME Maintainers - -Date: Wed, 13 Jun 2007 10:52:27 +0200 -Subject: If a .desktop file does not have inline translations, - fall back to calling gettext - -Patch from OpenSUSE via Ubuntu, original author unknown. Martin Pitt and -Vincent Untz appear to be the main authors. - -Bug: https://bugzilla.gnome.org/show_bug.cgi?id=569829 -Bug-Ubuntu: https://launchpad.net/bugs/3935 -Applied-upstream: no, rejected because "this will be solved soon" (in 2013) ---- - glib/gkeyfile.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - glib/gkeyfile.h | 4 ++++ - 2 files changed, 76 insertions(+) - -diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c -index 41883e9..e79f8ed 100644 ---- a/glib/gkeyfile.c -+++ b/glib/gkeyfile.c -@@ -511,6 +511,7 @@ struct _GKeyFile - GKeyFileFlags flags; - - gchar **locales; -+ gchar *gettext_domain; - - volatile gint ref_count; - }; -@@ -636,6 +637,7 @@ g_key_file_init (GKeyFile *key_file) - key_file->list_separator = ';'; - key_file->flags = 0; - key_file->locales = g_strdupv ((gchar **)g_get_language_names ()); -+ key_file->gettext_domain = NULL; - } - - static void -@@ -655,6 +657,12 @@ g_key_file_clear (GKeyFile *key_file) - key_file->parse_buffer = NULL; - } - -+ if (key_file->gettext_domain) -+ { -+ g_free (key_file->gettext_domain); -+ key_file->gettext_domain = NULL; -+ } -+ - tmp = key_file->groups; - while (tmp != NULL) - { -@@ -874,6 +882,11 @@ g_key_file_load_from_fd (GKeyFile *key_file, - return FALSE; - } - -+ key_file->gettext_domain = g_key_file_get_string (key_file, -+ G_KEY_FILE_DESKTOP_GROUP, -+ G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, -+ NULL); -+ - return TRUE; - } - -@@ -930,6 +943,11 @@ g_key_file_load_from_file (GKeyFile *key_file, - return FALSE; - } - -+ key_file->gettext_domain = g_key_file_get_string (key_file, -+ G_KEY_FILE_DESKTOP_GROUP, -+ G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, -+ NULL); -+ - return TRUE; - } - -@@ -2213,6 +2231,8 @@ g_key_file_get_locale_string (GKeyFile *key_file, - GError *key_file_error; - gchar **languages; - gboolean free_languages = FALSE; -+ gboolean try_gettext = FALSE; -+ const gchar *msg_locale; - gint i; - - g_return_val_if_fail (key_file != NULL, NULL); -@@ -2234,6 +2254,25 @@ g_key_file_get_locale_string (GKeyFile *key_file, - free_languages = FALSE; - } - -+ /* we're only interested in gettext translation if we don't have a -+ * translation in the .desktop file itself and if the key is one of the keys -+ * we know we want to translate: Name, GenericName, Comment, Keywords. -+ * Blindly doing this for all keys can give strange result for the icons, -+ * since the Icon is a locale string in the spec, eg. We also only get -+ * translation in the mo file if the requested locale is the LC_MESSAGES one. -+ * Ideally, we should do more and change LC_MESSAGES to use the requested -+ * locale, but there's no guarantee it's installed on the system and it might -+ * have some side-effects. Since this is a corner case, let's ignore it. */ -+ msg_locale = setlocale (LC_MESSAGES, NULL); -+ try_gettext = msg_locale && key_file->gettext_domain && -+ (strcmp (group_name, G_KEY_FILE_DESKTOP_GROUP) == 0 || -+ g_str_has_prefix (group_name, G_KEY_FILE_DESKTOP_ACTION_GROUP_PREFIX)) && -+ (strcmp (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0 || -+ strcmp (key, G_KEY_FILE_DESKTOP_KEY_FULLNAME) == 0 || -+ strcmp (key, G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME) == 0 || -+ strcmp (key, G_KEY_FILE_DESKTOP_KEY_KEYWORDS) == 0 || -+ strcmp (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0); -+ - for (i = 0; languages[i]; i++) - { - candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); -@@ -2250,6 +2289,39 @@ g_key_file_get_locale_string (GKeyFile *key_file, - translated_value = NULL; - } - -+ /* Fallback to gettext */ -+ if (try_gettext && !translated_value) -+ { -+ gchar *orig_value = g_key_file_get_string (key_file, group_name, key, NULL); -+ -+ if (orig_value) -+ { -+ gboolean codeset_set; -+ const gchar *translated; -+ gboolean has_gettext; -+ -+ codeset_set = bind_textdomain_codeset (key_file->gettext_domain, "UTF-8") != NULL; -+ translated = NULL; -+ -+ translated = g_dgettext (key_file->gettext_domain, -+ orig_value); -+ has_gettext = translated != orig_value; -+ -+ g_free (orig_value); -+ -+ if (has_gettext) -+ { -+ if (codeset_set) -+ translated_value = g_strdup (translated); -+ else -+ translated_value = g_locale_to_utf8 (translated, -+ -1, NULL, NULL, NULL); -+ } -+ else -+ translated_value = NULL; -+ } -+ } -+ - /* Fallback to untranslated key - */ - if (!translated_value) -diff --git a/glib/gkeyfile.h b/glib/gkeyfile.h -index 7a10048..aef9113 100644 ---- a/glib/gkeyfile.h -+++ b/glib/gkeyfile.h -@@ -298,6 +298,7 @@ gboolean g_key_file_remove_group (GKeyFile *key_file, - - /* Defines for handling freedesktop.org Desktop files */ - #define G_KEY_FILE_DESKTOP_GROUP "Desktop Entry" -+#define G_KEY_FILE_DESKTOP_ACTION_GROUP_PREFIX "Desktop Action" - - #define G_KEY_FILE_DESKTOP_KEY_TYPE "Type" - #define G_KEY_FILE_DESKTOP_KEY_VERSION "Version" -@@ -320,6 +321,9 @@ gboolean g_key_file_remove_group (GKeyFile *key_file, - #define G_KEY_FILE_DESKTOP_KEY_URL "URL" - #define G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE "DBusActivatable" - #define G_KEY_FILE_DESKTOP_KEY_ACTIONS "Actions" -+#define G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN "X-GNOME-Gettext-Domain" -+#define G_KEY_FILE_DESKTOP_KEY_FULLNAME "X-GNOME-FullName" -+#define G_KEY_FILE_DESKTOP_KEY_KEYWORDS "Keywords" - - #define G_KEY_FILE_DESKTOP_TYPE_APPLICATION "Application" - #define G_KEY_FILE_DESKTOP_TYPE_LINK "Link" diff -Nru glib2.0-2.59.2/debian/patches/81-skip-monitor-test-on-non-linux.patch glib2.0-2.59.3/debian/patches/81-skip-monitor-test-on-non-linux.patch --- glib2.0-2.59.2/debian/patches/81-skip-monitor-test-on-non-linux.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/81-skip-monitor-test-on-non-linux.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -From: Emilio Pozuelo Monfort -Date: Sun, 9 Mar 2014 15:06:31 +0100 -Subject: Skip the monitor test on non-linux as it currently hangs - -Forwarded: no ---- - gio/tests/monitor.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/gio/tests/monitor.c b/gio/tests/monitor.c -index 4d64fa8..01d91a0 100644 ---- a/gio/tests/monitor.c -+++ b/gio/tests/monitor.c -@@ -214,7 +214,9 @@ main (int argc, char *argv[]) - { - g_test_init (&argc, &argv, NULL); - -+#ifdef __linux__ - g_test_add ("/monitor/directory", Fixture, NULL, setup, test_directory_monitor, teardown); -+#endif - - return g_test_run (); - } diff -Nru glib2.0-2.59.2/debian/patches/debian/02_gettext-desktopfiles-ubuntu.patch glib2.0-2.59.3/debian/patches/debian/02_gettext-desktopfiles-ubuntu.patch --- glib2.0-2.59.2/debian/patches/debian/02_gettext-desktopfiles-ubuntu.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/02_gettext-desktopfiles-ubuntu.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -From: Martin Pitt -Date: Tue, 24 Feb 2009 16:08:05 +0100 -Subject: Provide backwards compatibility for 01_gettext-desktopfiles.patch - for X-{Debian,Ubuntu}-Gettext-Domain - -Ubuntu-specific. 01_gettext-desktopfiles.patch was changed to use -X-GNOME-, so this is necessary until all our .desktop files are converted. - -Forwarded: no ---- - glib/gkeyfile.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c -index e79f8ed..7b634e9 100644 ---- a/glib/gkeyfile.c -+++ b/glib/gkeyfile.c -@@ -886,6 +886,16 @@ g_key_file_load_from_fd (GKeyFile *key_file, - G_KEY_FILE_DESKTOP_GROUP, - G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, - NULL); -+ if (!key_file->gettext_domain) -+ key_file->gettext_domain = g_key_file_get_string (key_file, -+ G_KEY_FILE_DESKTOP_GROUP, -+ "X-Ubuntu-Gettext-Domain", -+ NULL); -+ if (!key_file->gettext_domain) -+ key_file->gettext_domain = g_key_file_get_string (key_file, -+ G_KEY_FILE_DESKTOP_GROUP, -+ "X-Debian-Gettext-Domain", -+ NULL); - - return TRUE; - } -@@ -947,6 +957,16 @@ g_key_file_load_from_file (GKeyFile *key_file, - G_KEY_FILE_DESKTOP_GROUP, - G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, - NULL); -+ if (!key_file->gettext_domain) -+ key_file->gettext_domain = g_key_file_get_string (key_file, -+ G_KEY_FILE_DESKTOP_GROUP, -+ "X-Ubuntu-Gettext-Domain", -+ NULL); -+ if (!key_file->gettext_domain) -+ key_file->gettext_domain = g_key_file_get_string (key_file, -+ G_KEY_FILE_DESKTOP_GROUP, -+ "X-Debian-Gettext-Domain", -+ NULL); - - return TRUE; - } diff -Nru glib2.0-2.59.2/debian/patches/debian/03_disble_glib_compile_schemas_warning.patch glib2.0-2.59.3/debian/patches/debian/03_disble_glib_compile_schemas_warning.patch --- glib2.0-2.59.2/debian/patches/debian/03_disble_glib_compile_schemas_warning.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/03_disble_glib_compile_schemas_warning.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -From: Iain Lane -Date: Mon, 10 Sep 2012 16:25:18 +0100 -Subject: Disable confusing (to users) warning about deprecated schema paths - -Disable a warning when compiling schemas which are installed -into 'deprecated' locations. Users see this very often due to -glib-compile-schemas being called from libglib2.0-0's trigger and it is -not very useful for them. - -Forwarded: not-needed ---- - gio/glib-compile-schemas.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c -index 5e1bebb..7bd8cfb 100644 ---- a/gio/glib-compile-schemas.c -+++ b/gio/glib-compile-schemas.c -@@ -1233,6 +1233,9 @@ parse_state_start_schema (ParseState *state, - return; - } - -+ // Disable this warning: it confuses users and there is unlikely to be much -+ // progress towards fixing -+ /* - if (path && (g_str_has_prefix (path, "/apps/") || - g_str_has_prefix (path, "/desktop/") || - g_str_has_prefix (path, "/system/"))) -@@ -1245,6 +1248,7 @@ parse_state_start_schema (ParseState *state, - g_printerr ("%s\n", message); - g_free (message); - } -+ */ - - state->schema_state = schema_state_new (path, gettext_domain, - extends, extends_name, list_of); diff -Nru glib2.0-2.59.2/debian/patches/debian/04_homedir_env.patch glib2.0-2.59.3/debian/patches/debian/04_homedir_env.patch --- glib2.0-2.59.2/debian/patches/debian/04_homedir_env.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/04_homedir_env.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -From: Iain Lane -Date: Sat, 23 Feb 2013 19:27:38 +0100 -Subject: Handle the G_HOME environment variable - -g_get_home_dir() now respects the HOME environment variable but we'll keep -G_HOME for now as packages in Debian rely on it. - -Modified from an earlier patch by Josselin Mouette. - -Forwarded: not-needed, Debian-specific ---- - docs/reference/glib/running.xml | 18 ++++++++++++++++++ - glib/gutils.c | 10 +++++++++- - 2 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/docs/reference/glib/running.xml b/docs/reference/glib/running.xml -index 8e4ffec..ec33ea6 100644 ---- a/docs/reference/glib/running.xml -+++ b/docs/reference/glib/running.xml -@@ -256,6 +256,24 @@ How to run and debug your GLib application - - - -+ -+ <envar>G_HOME</envar> -+ -+ -+ Historically, GLib applications ignored the HOME -+ environment variable on Unix systems, instead using the user directory -+ as specified by the passwd entry. As of GLib 2.35.3, -+ this is no longer true: HOME is respected. -+ -+ -+ The G_HOME environment variable will override any -+ other setting for the home directory. It is not meant for daily usage, but -+ it is useful in testing or building environments. As HOME is -+ now supported by GLib, G_HOME is deprecated and will be -+ removed in a future release. -+ -+ -+ - - - -diff --git a/glib/gutils.c b/glib/gutils.c -index 6fe4737..d5fc432 100644 ---- a/glib/gutils.c -+++ b/glib/gutils.c -@@ -801,7 +801,9 @@ g_build_home_dir (void) - gchar *home_dir; - - /* We first check HOME and use it if it is set */ -- home_dir = g_strdup (g_getenv ("HOME")); -+ home_dir = g_strdup (g_getenv ("G_HOME")); -+ if (!home_dir) -+ home_dir = g_strdup (g_getenv ("HOME")); - - #ifdef G_OS_WIN32 - /* Only believe HOME if it is an absolute path and exists. -@@ -889,6 +891,12 @@ g_build_home_dir (void) - * should either directly check the `HOME` environment variable yourself - * or unset it before calling any functions in GLib. - * -+ * When the pre-2.36 behaviour was in effect, Debian provided the -+ * G_HOME environment variable for testing and development -+ * purposes. This is now unnecessary as HOME can be used -+ * directly, but is retained for compatibility. It is deprecated and will be -+ * removed in a future release. -+ * - * Returns: (type filename): the current user's home directory - */ - const gchar * diff -Nru glib2.0-2.59.2/debian/patches/debian/06_thread_test_ignore_prctl_fail.patch glib2.0-2.59.3/debian/patches/debian/06_thread_test_ignore_prctl_fail.patch --- glib2.0-2.59.2/debian/patches/debian/06_thread_test_ignore_prctl_fail.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/06_thread_test_ignore_prctl_fail.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From: Martin Pitt -Date: Tue, 26 Jun 2012 19:28:14 +0200 -Subject: Do not fail the /thread/thread4 test if prctrl() fails - -This happens on the Debian buildds. - -Forwarded: no, Debian buildd specific ---- - glib/tests/thread.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/glib/tests/thread.c b/glib/tests/thread.c -index b9f8796..43e682e 100644 ---- a/glib/tests/thread.c -+++ b/glib/tests/thread.c -@@ -147,8 +147,11 @@ test_thread4 (void) - getrlimit (RLIMIT_NPROC, &nl); - nl.rlim_cur = 1; - -- if ((ret = prlimit (getpid (), RLIMIT_NPROC, &nl, &ol)) != 0) -- g_error ("prlimit failed: %s", g_strerror (errno)); -+ if ((ret = prlimit (getpid(), RLIMIT_NPROC, &nl, &ol)) != 0) -+ { -+ g_debug ("prlimit failed: %s\n", g_strerror (errno)); -+ return; -+ } - - error = NULL; - thread = g_thread_try_new ("a", thread1_func, NULL, &error); diff -Nru glib2.0-2.59.2/debian/patches/debian/61_glib-compile-binaries-path.patch glib2.0-2.59.3/debian/patches/debian/61_glib-compile-binaries-path.patch --- glib2.0-2.59.2/debian/patches/debian/61_glib-compile-binaries-path.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/61_glib-compile-binaries-path.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -From: =?utf-8?q?Sebastian_Dr=C3=B6ge?= -Date: Tue, 13 Jul 2010 14:06:28 +0200 -Subject: Adjust path to glib-compile-schemas in the pkg-config file - -This is because gio-querymodules and glib-compile-schemas have been put in -a private, versioned directory in libglib2.0-0 to avoid a dependency loop. - -Forwarded: not-needed, specific to Debian packaging ---- - gio/meson.build | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gio/meson.build b/gio/meson.build -index d7f4f3f..990b1b5 100644 ---- a/gio/meson.build -+++ b/gio/meson.build -@@ -828,7 +828,7 @@ pkg.generate(libgio, - 'schemasdir=' + join_paths('${datadir}', schemas_subdir), - 'bindir=' + join_paths('${prefix}', get_option('bindir')), - 'giomoduledir=' + giomodulesdir, -- 'glib_compile_schemas=' + join_paths('${bindir}', 'glib-compile-schemas'), -+ 'glib_compile_schemas=' + join_paths('${libdir}', 'glib-2.0', 'glib-compile-schemas'), - 'glib_compile_resources=' + join_paths('${bindir}', 'glib-compile-resources'), - 'gdbus_codegen=' + join_paths('${bindir}', 'gdbus-codegen')], - version : glib_version, diff -Nru glib2.0-2.59.2/debian/patches/debian/90_gio-modules-multiarch-compat.patch glib2.0-2.59.3/debian/patches/debian/90_gio-modules-multiarch-compat.patch --- glib2.0-2.59.2/debian/patches/debian/90_gio-modules-multiarch-compat.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/90_gio-modules-multiarch-compat.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -From: Steve Langasek -Date: Sat, 16 Jul 2011 13:12:48 -0700 -Subject: gio: add fallback directory for pre-multiarch compatibility - -Origin: vendor, Ubuntu -Bug-Debian: https://bugs.debian.org/634099 -Forwarded: no, specific to Debian and its derivatives ---- - gio/giomodule.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/gio/giomodule.c b/gio/giomodule.c -index b92162d..cdb20ca 100644 ---- a/gio/giomodule.c -+++ b/gio/giomodule.c -@@ -1206,6 +1206,9 @@ _g_io_modules_ensure_loaded (void) - - g_io_module_scope_free (scope); - -+ /* Hard-coded fallback directory for pre-multiarch compatibility */ -+ g_io_modules_scan_all_in_directory ("/usr/lib/gio/modules"); -+ - /* Initialize types from built-in "modules" */ - g_type_ensure (g_null_settings_backend_get_type ()); - g_type_ensure (g_memory_settings_backend_get_type ()); diff -Nru glib2.0-2.59.2/debian/patches/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch glib2.0-2.59.3/debian/patches/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch --- glib2.0-2.59.2/debian/patches/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -From: Simon McVittie -Date: Thu, 3 Jan 2019 09:01:03 +0000 -Subject: closures test: Skip on arm* unless flaky tests are allowed - -Choosing the right number of iterations to avoid either taking literally -hours on some hardware, or getting spurious failures when one thread -starves another, seems to be too hard to get right in practice. -Make this test opt-in so that its failures aren't release-critical. -We can run it as a separate autopkgtest that is marked flaky. - -Signed-off-by: Simon McVittie -Bug-Debian: https://bugs.debian.org/880883 -Bug-Debian: https://bugs.debian.org/917983 -Forwarded: not-needed ---- - tests/refcount/closures.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/tests/refcount/closures.c b/tests/refcount/closures.c -index a4c2831..4e9bf36 100644 ---- a/tests/refcount/closures.c -+++ b/tests/refcount/closures.c -@@ -237,6 +237,14 @@ main (int argc, - GTest *object; - guint i; - -+#if defined(__aarch64__) || defined(__arm__) -+ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") != NULL) -+ { -+ g_print ("SKIP: Test is known to be flaky on arm* (#880883, #917983)\n"); -+ return 0; -+ } -+#endif -+ - g_print ("START: %s\n", argv[0]); - g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); - diff -Nru glib2.0-2.59.2/debian/patches/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch glib2.0-2.59.3/debian/patches/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch --- glib2.0-2.59.2/debian/patches/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -From: Martin Pitt -Date: Thu, 27 Sep 2012 11:22:56 +0200 -Subject: Disable some tests on slow architectures which keep failing the - tests - -[smcv: Modified to use g_test_skip() instead of omitting those test cases -completely, and allow them to be re-enabled with a Debian-specific -environment variable] - -Co-authored-by: Simon McVittie -Forwarded: no ---- - gio/tests/socket.c | 8 ++++++++ - glib/tests/mainloop.c | 24 ++++++++++++++++++++++++ - glib/tests/timeout.c | 9 +++++++++ - 3 files changed, 41 insertions(+) - -diff --git a/gio/tests/socket.c b/gio/tests/socket.c -index 8410a3e..5eba57a 100644 ---- a/gio/tests/socket.c -+++ b/gio/tests/socket.c -@@ -1111,6 +1111,14 @@ test_timed_wait (void) - gint64 start_time; - gint poll_duration; - -+#if defined(__arm__) -+ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) -+ { -+ g_test_skip ("Not reliable on older ARM hardware"); -+ return; -+ } -+#endif -+ - data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error); - if (error != NULL) - { -diff --git a/glib/tests/mainloop.c b/glib/tests/mainloop.c -index cf114fd..9beefd3 100644 ---- a/glib/tests/mainloop.c -+++ b/glib/tests/mainloop.c -@@ -168,6 +168,14 @@ test_timeouts (void) - GMainLoop *loop; - GSource *source; - -+#if defined(__arm__) -+ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) -+ { -+ g_test_skip ("Not reliable on older ARM hardware"); -+ return; -+ } -+#endif -+ - a = b = c = 0; - - ctx = g_main_context_new (); -@@ -451,6 +459,14 @@ test_child_sources (void) - GMainLoop *loop; - GSource *parent, *child_b, *child_c, *end; - -+#if defined(__arm__) -+ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) -+ { -+ g_test_skip ("Not reliable on older ARM hardware"); -+ return; -+ } -+#endif -+ - ctx = g_main_context_new (); - loop = g_main_loop_new (ctx, FALSE); - -@@ -529,6 +545,14 @@ test_recursive_child_sources (void) - GMainLoop *loop; - GSource *parent, *child_b, *child_c, *end; - -+#if defined(__arm__) -+ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) -+ { -+ g_test_skip ("Not reliable on older ARM hardware"); -+ return; -+ } -+#endif -+ - ctx = g_main_context_new (); - loop = g_main_loop_new (ctx, FALSE); - -diff --git a/glib/tests/timeout.c b/glib/tests/timeout.c -index 8f44e75..430be91 100644 ---- a/glib/tests/timeout.c -+++ b/glib/tests/timeout.c -@@ -175,6 +175,15 @@ test_func (gpointer data) - static void - test_rounding (void) - { -+ -+#if defined(__arm__) -+ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) -+ { -+ g_test_skip ("Not reliable on older ARM hardware"); -+ return; -+ } -+#endif -+ - loop = g_main_loop_new (NULL, FALSE); - - last_time = g_get_monotonic_time (); diff -Nru glib2.0-2.59.2/debian/patches/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch glib2.0-2.59.3/debian/patches/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch --- glib2.0-2.59.2/debian/patches/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -From: Simon McVittie -Date: Wed, 1 Aug 2018 09:40:38 +0100 -Subject: Look for gio-launch-desktop in $(libdir)/glib-2.0 - -In Debian, we install it in the shared library package to avoid -needing a circular dependency between libglib2.0-0 and -libglib2.0-bin. - -Forwarded: not-needed, Debian-specific ---- - gio/gdesktopappinfo.c | 4 ++-- - gio/meson.build | 1 + - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c -index 7d7425e..36f3cfb 100644 ---- a/gio/gdesktopappinfo.c -+++ b/gio/gdesktopappinfo.c -@@ -2741,9 +2741,9 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info, - /* Allow test suite to specify path to gio-launch-desktop */ - tmp = g_getenv ("GIO_LAUNCH_DESKTOP"); - -- /* Fall back on usual searching in $PATH */ - if (tmp == NULL) -- tmp = "gio-launch-desktop"; -+ tmp = GIO_LIBDIR "/glib-2.0/gio-launch-desktop"; -+ - g_once_init_leave (&gio_launch_desktop_path, tmp); - } - -diff --git a/gio/meson.build b/gio/meson.build -index 990b1b5..84c5af1 100644 ---- a/gio/meson.build -+++ b/gio/meson.build -@@ -1,6 +1,7 @@ - gio_c_args = [ - '-DG_LOG_DOMAIN="GLib-GIO"', - '-DGIO_COMPILATION', -+ '-DGIO_LIBDIR="@0@"'.format(glib_libdir), - '-DGIO_MODULE_DIR="@0@"'.format(glib_giomodulesdir), - ] - diff -Nru glib2.0-2.59.2/debian/patches/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch glib2.0-2.59.3/debian/patches/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch --- glib2.0-2.59.2/debian/patches/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -From: Iain Lane -Date: Tue, 18 Mar 2014 15:43:35 +0000 -Subject: Skip test which performs some unreliable floating point comparisons - -[smcv: Modified to use g_test_skip() instead of omitting those test cases -completely, and allow them to be re-enabled with a Debian-specific -environment variable] - -Co-authored-by: Simon McVittie -Bug: https://gitlab.gnome.org/GNOME/glib/issues/820 -Forwarded: no ---- - glib/tests/timer.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/glib/tests/timer.c b/glib/tests/timer.c -index 4cd5fba..3c0642b 100644 ---- a/glib/tests/timer.c -+++ b/glib/tests/timer.c -@@ -30,6 +30,12 @@ test_timer_basic (void) - volatile gdouble elapsed; - gulong micros; - -+ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) -+ { -+ g_test_skip ("Not reliable due to floating-point rounding (glib#820)"); -+ return; -+ } -+ - timer = g_timer_new (); - - elapsed = g_timer_elapsed (timer, µs); diff -Nru glib2.0-2.59.2/debian/patches/debian/Skip-unreliable-test_threaded_singleton-by-default.patch glib2.0-2.59.3/debian/patches/debian/Skip-unreliable-test_threaded_singleton-by-default.patch --- glib2.0-2.59.2/debian/patches/debian/Skip-unreliable-test_threaded_singleton-by-default.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/debian/Skip-unreliable-test_threaded_singleton-by-default.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,41 +0,0 @@ -From: Simon McVittie -Date: Fri, 4 Jan 2019 08:37:20 +0000 -Subject: Skip unreliable test_threaded_singleton() by default - -This test aims to reproduce a race condition between last-unref of the -global singleton GDBusConnection and g_bus_get_sync(). However, test -setup intermittently times out with: - - # GLib-GIO-DEBUG: run 0: refcount is 2, sleeping - Bail out! GLib-GIO-FATAL-ERROR: connection had too many refs - -The current theory upstream is that this might be a reference leak in -test_delivery_in_thread(). - -Demote test_threaded_singleton() to be run as one of the "flaky" -autopkgtests, but not at build time or in the part of the autopkgtest -run that gates progress into testing. - -Bug: https://gitlab.gnome.org/GNOME/glib/issues/1515 -Forwarded: no ---- - gio/tests/gdbus-threading.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/gio/tests/gdbus-threading.c b/gio/tests/gdbus-threading.c -index 3e4dc92..165dbb7 100644 ---- a/gio/tests/gdbus-threading.c -+++ b/gio/tests/gdbus-threading.c -@@ -499,6 +499,12 @@ test_threaded_singleton (void) - guint unref_wins = 0; - guint get_wins = 0; - -+ if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) -+ { -+ g_test_skip ("Not reliable (glib#1515)"); -+ return; -+ } -+ - if (g_test_thorough ()) - n = 100000; - else diff -Nru glib2.0-2.59.2/debian/patches/gio-tests-Install-test1.overlay-file-when-building-instal.patch glib2.0-2.59.3/debian/patches/gio-tests-Install-test1.overlay-file-when-building-instal.patch --- glib2.0-2.59.2/debian/patches/gio-tests-Install-test1.overlay-file-when-building-instal.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/gio-tests-Install-test1.overlay-file-when-building-instal.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -From: Iain Lane -Date: Mon, 11 Feb 2019 10:21:13 +0000 -Subject: gio tests: Install test1.overlay file when building installed tests - -This is used as a GResource overlay, so it must be available to the -test. - -Forwarded: https://gitlab.gnome.org/GNOME/glib/merge_requests/649 ---- - gio/tests/meson.build | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gio/tests/meson.build b/gio/tests/meson.build -index 8bf555c..2af1446 100644 ---- a/gio/tests/meson.build -+++ b/gio/tests/meson.build -@@ -428,6 +428,7 @@ if installed_tests_enabled - 'appinfo-test-static.desktop', - 'file.c', - 'org.gtk.test.dbusappinfo.desktop', -+ 'test1.overlay', - install_dir : installed_tests_execdir, - ) - install_subdir('x-content', install_dir : installed_tests_execdir) diff -Nru glib2.0-2.59.2/debian/patches/gvariant-test-Also-force-alignment-for-tuple-test-data.patch glib2.0-2.59.3/debian/patches/gvariant-test-Also-force-alignment-for-tuple-test-data.patch --- glib2.0-2.59.2/debian/patches/gvariant-test-Also-force-alignment-for-tuple-test-data.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/gvariant-test-Also-force-alignment-for-tuple-test-data.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ -From: Simon McVittie -Date: Thu, 3 Jan 2019 08:21:40 +0000 -Subject: gvariant test: Also force alignment for tuple test data - -glib!552 (commit 9eed22b3) fixed this for the tests that failed on i686, -but this additional test failed on Debian's s390x port -(IBM z/Architecture, 64-bit big-endian). - -Signed-off-by: Simon McVittie -Bug-Debian: https://bugs.debian.org/917980 -Forwarded: https://gitlab.gnome.org/GNOME/glib/merge_requests/569 -Applied-upstream: 2.58.3 ---- - glib/tests/gvariant.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index 7cb685c..06a80bc 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -4944,6 +4944,7 @@ test_normal_checking_array_offsets (void) - static void - test_normal_checking_tuple_offsets (void) - { -+ gpointer aligned_data; - const guint8 data[] = { - 0x07, 0xe5, 0x00, 0x07, 0x00, 0x07, - '(', 'a', 's', 'a', 's', 'a', 's', 'a', 's', 'a', 's', 'a', 's', ')', -@@ -4979,13 +4980,15 @@ test_normal_checking_empty_object_path (void) - GVariant *variant = NULL; - GVariant *normal_variant = NULL; - -- variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, -- FALSE, NULL, NULL); -+ aligned_data = g_memdup (data, size); /* guarantee alignment */ -+ variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, -+ size, FALSE, NULL, NULL); - g_assert_nonnull (variant); - - normal_variant = g_variant_get_normal_form (variant); - g_assert_nonnull (normal_variant); - -+ g_free (aligned_data); - g_variant_unref (normal_variant); - g_variant_unref (variant); - } diff -Nru glib2.0-2.59.2/debian/patches/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch glib2.0-2.59.3/debian/patches/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch --- glib2.0-2.59.2/debian/patches/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -From: Simon McVittie -Date: Mon, 18 Dec 2017 18:06:05 +0000 -Subject: gwakeuptest: Be less parallel unless invoked with -m slow - -This is a workaround for test failures on the reproducible-builds -infrastructure, where a multi-threaded stress-test sometimes takes longer -to finish on x86_64 than it would have done on slow architectures like -arm and mips on the official Debian autobuilders. It is not clear why. - -This change will make this test more likely to pass, but less likely to -detect bugs. - -Signed-off-by: Simon McVittie -Bug-Debian: https://bugs.debian.org/884659 -Forwarded: no ---- - glib/tests/gwakeuptest.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/glib/tests/gwakeuptest.c b/glib/tests/gwakeuptest.c -index 461a7d3..2c3eccd 100644 ---- a/glib/tests/gwakeuptest.c -+++ b/glib/tests/gwakeuptest.c -@@ -89,6 +89,9 @@ struct context - #define NUM_TOKENS 5 - #define TOKEN_TTL 100000 - -+static gint num_threads = NUM_THREADS; -+static gint token_ttl = TOKEN_TTL; -+ - static struct context contexts[NUM_THREADS]; - static GThread *threads[NUM_THREADS]; - static GWakeup *last_token_wakeup; -@@ -158,7 +161,7 @@ dispatch_token (struct token *token) - struct context *ctx; - gint next_ctx; - -- next_ctx = g_test_rand_int_range (0, NUM_THREADS); -+ next_ctx = g_test_rand_int_range (0, num_threads); - ctx = &contexts[next_ctx]; - token->owner = ctx; - token->ttl--; -@@ -213,6 +216,12 @@ test_threaded (void) - { - gint i; - -+ if (!g_test_slow ()) -+ { -+ num_threads = NUM_THREADS / 10; -+ token_ttl = TOKEN_TTL / 10; -+ } -+ - /* make sure we don't block forever */ - alarm (60); - -@@ -230,7 +239,7 @@ test_threaded (void) - last_token_wakeup = g_wakeup_new (); - - /* create contexts, assign to threads */ -- for (i = 0; i < NUM_THREADS; i++) -+ for (i = 0; i < num_threads; i++) - { - context_init (&contexts[i]); - threads[i] = g_thread_new ("test", thread_func, &contexts[i]); -@@ -238,13 +247,13 @@ test_threaded (void) - - /* dispatch tokens */ - for (i = 0; i < NUM_TOKENS; i++) -- dispatch_token (token_new (TOKEN_TTL)); -+ dispatch_token (token_new (token_ttl)); - - /* wait until all tokens are gone */ - wait_for_signaled (last_token_wakeup); - - /* ask threads to quit, join them, cleanup */ -- for (i = 0; i < NUM_THREADS; i++) -+ for (i = 0; i < num_threads; i++) - { - context_quit (&contexts[i]); - g_thread_join (threads[i]); diff -Nru glib2.0-2.59.2/debian/patches/series glib2.0-2.59.3/debian/patches/series --- glib2.0-2.59.2/debian/patches/series 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -gio-tests-Install-test1.overlay-file-when-building-instal.patch -tests-Install-the-slow-connect-preload.so-library-and-use.patch -tests-Allocate-gvariant-data-from-the-heap-to-guarantee-a.patch -01_gettext-desktopfiles.patch -81-skip-monitor-test-on-non-linux.patch -0001-timer-test-use-volatile-for-locals.patch -gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch -gvariant-test-Also-force-alignment-for-tuple-test-data.patch -debian/02_gettext-desktopfiles-ubuntu.patch -debian/03_disble_glib_compile_schemas_warning.patch -debian/04_homedir_env.patch -debian/06_thread_test_ignore_prctl_fail.patch -debian/61_glib-compile-binaries-path.patch -debian/90_gio-modules-multiarch-compat.patch -debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch -debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch -debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch -debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch -debian/Skip-unreliable-test_threaded_singleton-by-default.patch diff -Nru glib2.0-2.59.2/debian/patches/tests-Allocate-gvariant-data-from-the-heap-to-guarantee-a.patch glib2.0-2.59.3/debian/patches/tests-Allocate-gvariant-data-from-the-heap-to-guarantee-a.patch --- glib2.0-2.59.2/debian/patches/tests-Allocate-gvariant-data-from-the-heap-to-guarantee-a.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/tests-Allocate-gvariant-data-from-the-heap-to-guarantee-a.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -From: Mart Raudsepp -Date: Wed, 19 Dec 2018 16:22:21 +0200 -Subject: tests: Allocate gvariant data from the heap to guarantee alignment - -On glib-2-58 branch we don't have !455, thus we need aligned data -for the gvariant tests to not fail on i686. - -Fixes #1626 - -Applied-upstream: 2.58.3, commit:9eed22b3b8650fe98ceb85c6bd2d92b964661d7b ---- - glib/tests/gvariant.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c -index 33caaf0..7cb685c 100644 ---- a/glib/tests/gvariant.c -+++ b/glib/tests/gvariant.c -@@ -4788,6 +4788,7 @@ test_stack_dict_init (void) - static void - test_normal_checking_tuples (void) - { -+ gpointer aligned_data; - const guint8 data[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, - 'a', '(', 'a', 'o', 'a', 'o', 'a', 'a', 'o', 'a', 'a', 'o', ')' -@@ -4796,13 +4797,15 @@ test_normal_checking_tuples (void) - GVariant *variant = NULL; - GVariant *normal_variant = NULL; - -- variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, -+ aligned_data = g_memdup (data, size); /* guarantee alignment */ -+ variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size, - FALSE, NULL, NULL); - g_assert_nonnull (variant); - - normal_variant = g_variant_get_normal_form (variant); - g_assert_nonnull (normal_variant); - -+ g_free (aligned_data); - g_variant_unref (normal_variant); - g_variant_unref (variant); - } -@@ -4914,6 +4917,7 @@ test_recursion_limits_array_in_variant (void) - static void - test_normal_checking_array_offsets (void) - { -+ gpointer aligned_data; - const guint8 data[] = { - 0x07, 0xe5, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'g', -@@ -4922,13 +4926,15 @@ test_normal_checking_array_offsets (void) - GVariant *variant = NULL; - GVariant *normal_variant = NULL; - -- variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, -+ aligned_data = g_memdup (data, size); /* guarantee alignment */ -+ variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size, - FALSE, NULL, NULL); - g_assert_nonnull (variant); - - normal_variant = g_variant_get_normal_form (variant); - g_assert_nonnull (normal_variant); - -+ g_free (aligned_data); - g_variant_unref (normal_variant); - g_variant_unref (variant); - } -@@ -4946,13 +4952,15 @@ test_normal_checking_tuple_offsets (void) - GVariant *variant = NULL; - GVariant *normal_variant = NULL; - -- variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, data, size, -+ aligned_data = g_memdup (data, size); /* guarantee alignment */ -+ variant = g_variant_new_from_data (G_VARIANT_TYPE_VARIANT, aligned_data, size, - FALSE, NULL, NULL); - g_assert_nonnull (variant); - - normal_variant = g_variant_get_normal_form (variant); - g_assert_nonnull (normal_variant); - -+ g_free (aligned_data); - g_variant_unref (normal_variant); - g_variant_unref (variant); - } -@@ -4962,6 +4970,7 @@ test_normal_checking_tuple_offsets (void) - static void - test_normal_checking_empty_object_path (void) - { -+ gpointer aligned_data; - const guint8 data[] = { - 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, - '(', 'h', '(', 'a', 'i', 'a', 'b', 'i', 'o', ')', ')', diff -Nru glib2.0-2.59.2/debian/patches/tests-Install-the-slow-connect-preload.so-library-and-use.patch glib2.0-2.59.3/debian/patches/tests-Install-the-slow-connect-preload.so-library-and-use.patch --- glib2.0-2.59.2/debian/patches/tests-Install-the-slow-connect-preload.so-library-and-use.patch 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/patches/tests-Install-the-slow-connect-preload.so-library-and-use.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,80 +0,0 @@ -From: Iain Lane -Date: Mon, 11 Feb 2019 12:02:20 +0000 -Subject: tests: Install the slow-connect-preload.so library and use it - -The gsocketclient-slow test needs this, otherwise connect() succeeds -immeidately and the test fails, because it is checking that cancellation -works. We weren't installing it for installed tests. - -(cherry picked from commit a380ddada199d0d88c31dadea3ef09270d47be8d) ---- - gio/tests/meson.build | 13 +++++++++++++ - meson.build | 3 +++ - template-tap.test.in | 2 +- - 3 files changed, 17 insertions(+), 1 deletion(-) - -diff --git a/gio/tests/meson.build b/gio/tests/meson.build -index 2af1446..c53c445 100644 ---- a/gio/tests/meson.build -+++ b/gio/tests/meson.build -@@ -140,11 +140,16 @@ if host_machine.system() != 'windows' - 'slow-connect-preload.c', - name_prefix : '', - dependencies: cc.find_library('dl'), -+ install_dir : installed_tests_execdir, -+ install: installed_tests_enabled - ) - ], - 'env' : { - 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(meson.current_build_dir()) - }, -+ 'installed_tests_env' : { -+ 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(installed_tests_execdir) -+ }, - 'suite': ['flaky'], - }, - 'gschema-compile' : {'install' : false}, -@@ -593,11 +598,19 @@ foreach test_name, extra_args : gio_tests - source = extra_args.get('source', test_name + '.c') - extra_sources = extra_args.get('extra_sources', []) - install = installed_tests_enabled and extra_args.get('install', true) -+ installed_tests_env = extra_args.get('installed_tests_env', {}) - - if install - test_conf = configuration_data() - test_conf.set('installed_tests_dir', installed_tests_execdir) - test_conf.set('program', test_name) -+ if installed_tests_env != {} -+ envs = [] -+ foreach var, value : installed_tests_env -+ envs += '@0@=@1@'.format(var, value) -+ endforeach -+ test_conf.set('env', '@0@ @1@ '.format(env_program.path(), ' '.join(envs))) -+ endif - configure_file( - input: installed_tests_template_tap, - output: test_name + '.test', -diff --git a/meson.build b/meson.build -index 98907ca..ad8c4cd 100644 ---- a/meson.build -+++ b/meson.build -@@ -1893,6 +1893,9 @@ endif - have_bash = find_program('bash', required : false).found() # For completion scripts - have_sh = find_program('sh', required : false).found() # For glib-gettextize - -+# Some installed tests require a custom environment -+env_program = find_program('env', required: installed_tests_enabled) -+ - # FIXME: How to detect Solaris? https://github.com/mesonbuild/meson/issues/1578 - if host_system == 'sunos' - glib_conf.set('_XOPEN_SOURCE_EXTENDED', 1) -diff --git a/template-tap.test.in b/template-tap.test.in -index 6adf73f..30cd166 100644 ---- a/template-tap.test.in -+++ b/template-tap.test.in -@@ -1,4 +1,4 @@ - [Test] - Type=session --Exec=@installed_tests_dir@/@program@ --tap -+Exec=@env@@installed_tests_dir@/@program@ --tap - Output=TAP diff -Nru glib2.0-2.59.2/debian/source/format glib2.0-2.59.3/debian/source/format --- glib2.0-2.59.2/debian/source/format 2019-02-11 10:25:27.000000000 +0000 +++ glib2.0-2.59.3/debian/source/format 2019-03-04 09:01:42.000000000 +0000 @@ -1 +1 @@ -3.0 (quilt) +3.0 (native) diff -Nru glib2.0-2.59.2/docs/reference/gio/.gitignore glib2.0-2.59.3/docs/reference/gio/.gitignore --- glib2.0-2.59.2/docs/reference/gio/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/gio/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -*.1 -gio-overrides.txt -tmpl diff -Nru glib2.0-2.59.2/docs/reference/gio/xml/gtkdocentities.ent.in glib2.0-2.59.3/docs/reference/gio/xml/gtkdocentities.ent.in --- glib2.0-2.59.2/docs/reference/gio/xml/gtkdocentities.ent.in 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/gio/xml/gtkdocentities.ent.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - - - - - - - diff -Nru glib2.0-2.59.2/docs/reference/gio/xml/meson.build glib2.0-2.59.3/docs/reference/gio/xml/meson.build --- glib2.0-2.59.2/docs/reference/gio/xml/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/gio/xml/meson.build 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -ent_conf = configuration_data() -ent_conf.set('PACKAGE', 'glib') -ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new') -ent_conf.set('PACKAGE_NAME', 'glib') -ent_conf.set('PACKAGE_STRING', 'glib') -ent_conf.set('PACKAGE_TARNAME', 'glib') -ent_conf.set('PACKAGE_URL', 'FIXME') -ent_conf.set('PACKAGE_VERSION', glib_version) -ent_conf.set('PACKAGE_API_VERSION', glib_api_version) -configure_file( - input: 'gtkdocentities.ent.in', - output: 'gtkdocentities.ent', - configuration: ent_conf -) diff -Nru glib2.0-2.59.2/docs/reference/.gitignore glib2.0-2.59.3/docs/reference/.gitignore --- glib2.0-2.59.2/docs/reference/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -*-decl-list.txt -*-decl.txt -*-unused.txt -*-undocumented.txt -*-undeclared.txt -*.args -*.hierarchy -*.interfaces -*.prerequisites -*.signals -*.stamp -html -xml -*.bak -version.xml -*.1 diff -Nru glib2.0-2.59.2/docs/reference/glib/running.xml glib2.0-2.59.3/docs/reference/glib/running.xml --- glib2.0-2.59.2/docs/reference/glib/running.xml 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/glib/running.xml 2019-03-04 09:01:41.000000000 +0000 @@ -256,6 +256,24 @@ + + <envar>G_HOME</envar> + + + Historically, GLib applications ignored the HOME + environment variable on Unix systems, instead using the user directory + as specified by the passwd entry. As of GLib 2.35.3, + this is no longer true: HOME is respected. + + + The G_HOME environment variable will override any + other setting for the home directory. It is not meant for daily usage, but + it is useful in testing or building environments. As HOME is + now supported by GLib, G_HOME is deprecated and will be + removed in a future release. + + + diff -Nru glib2.0-2.59.2/docs/reference/glib/xml/gtkdocentities.ent.in glib2.0-2.59.3/docs/reference/glib/xml/gtkdocentities.ent.in --- glib2.0-2.59.2/docs/reference/glib/xml/gtkdocentities.ent.in 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/glib/xml/gtkdocentities.ent.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - - - - - - - diff -Nru glib2.0-2.59.2/docs/reference/glib/xml/meson.build glib2.0-2.59.3/docs/reference/glib/xml/meson.build --- glib2.0-2.59.2/docs/reference/glib/xml/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/glib/xml/meson.build 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -ent_conf = configuration_data() -ent_conf.set('PACKAGE', 'glib') -ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new') -ent_conf.set('PACKAGE_NAME', 'glib') -ent_conf.set('PACKAGE_STRING', 'glib') -ent_conf.set('PACKAGE_TARNAME', 'glib') -ent_conf.set('PACKAGE_URL', 'FIXME') -ent_conf.set('PACKAGE_VERSION', glib_version) -ent_conf.set('PACKAGE_API_VERSION', glib_api_version) -configure_file( - input: 'gtkdocentities.ent.in', - output: 'gtkdocentities.ent', - configuration: ent_conf -) diff -Nru glib2.0-2.59.2/docs/reference/gobject/xml/gtkdocentities.ent.in glib2.0-2.59.3/docs/reference/gobject/xml/gtkdocentities.ent.in --- glib2.0-2.59.2/docs/reference/gobject/xml/gtkdocentities.ent.in 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/gobject/xml/gtkdocentities.ent.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - - - - - - - - diff -Nru glib2.0-2.59.2/docs/reference/gobject/xml/meson.build glib2.0-2.59.3/docs/reference/gobject/xml/meson.build --- glib2.0-2.59.2/docs/reference/gobject/xml/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/docs/reference/gobject/xml/meson.build 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -ent_conf = configuration_data() -ent_conf.set('PACKAGE', 'glib') -ent_conf.set('PACKAGE_BUGREPORT', 'https://gitlab.gnome.org/GNOME/glib/issues/new') -ent_conf.set('PACKAGE_NAME', 'glib') -ent_conf.set('PACKAGE_STRING', 'glib') -ent_conf.set('PACKAGE_TARNAME', 'glib') -ent_conf.set('PACKAGE_URL', 'FIXME') -ent_conf.set('PACKAGE_VERSION', glib_version) -ent_conf.set('PACKAGE_API_VERSION', glib_api_version) -configure_file( - input: 'gtkdocentities.ent.in', - output: 'gtkdocentities.ent', - configuration: ent_conf -) diff -Nru glib2.0-2.59.2/gio/completion/gapplication glib2.0-2.59.3/gio/completion/gapplication --- glib2.0-2.59.2/gio/completion/gapplication 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/completion/gapplication 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ - -# Check for bash -[ -z "$BASH_VERSION" ] && return - -#################################################################################################### - -__app() { - case "${COMP_CWORD}" in - 1) - COMPREPLY=($(compgen -W "help version list-apps launch action list-actions" -- "${COMP_WORDS[1]}")) - return 0 - ;; - - 2) - case "${COMP_WORDS[1]}" in - launch|action|list-actions) - COMPREPLY=($(compgen -W "`gapplication list-apps`" -- "${COMP_WORDS[2]}")) - return 0 - ;; - - *) - COMPREPLY=() - return 0 - ;; - esac - ;; - esac - - # Otherwise, what we will do is based on the command in ${COMP_WORDS[1]} - case "${COMP_WORDS[1]}" in - action) - # Word 3 is the action name. This is the only one we can help with. - if [ "${COMP_CWORD}" == 3 ]; then - COMPREPLY=($(compgen -W "`gapplication list-actions "${COMP_WORDS[2]}"`" -- "${COMP_WORDS[3]}")) - return 0 - else - COMPREPLY=() - return 0 - fi - ;; - launch) - # Filenames... - COMPREPLY=($(compgen -A file "${COMP_WORDS[COMP_CWORD]}")) - return 0 - ;; - *) - # Nothing else should be out this far... - COMPREPLY=() - return 0 - esac -} - -#################################################################################################### - -complete -F __app gapplication diff -Nru glib2.0-2.59.2/gio/completion/gdbus glib2.0-2.59.3/gio/completion/gdbus --- glib2.0-2.59.2/gio/completion/gdbus 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/completion/gdbus 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ - -# Check for bash -[ -z "$BASH_VERSION" ] && return - -#################################################################################################### - - -__gdbus() { - local IFS=$'\n' - local cur=`_get_cword :` - - local suggestions=$(gdbus complete "${COMP_LINE}" ${COMP_POINT}) - COMPREPLY=($(compgen -W "$suggestions" -- "$cur")) - - # Remove colon-word prefix from COMPREPLY items - case "$cur" in - *:*) - case "$COMP_WORDBREAKS" in - *:*) - local colon_word=${cur%${cur##*:}} - local i=${#COMPREPLY[*]} - while [ $((--i)) -ge 0 ]; do - COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"} - done - ;; - esac - ;; - esac -} - -#################################################################################################### - -complete -o nospace -F __gdbus gdbus diff -Nru glib2.0-2.59.2/gio/completion/.gitignore glib2.0-2.59.3/gio/completion/.gitignore --- glib2.0-2.59.2/gio/completion/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/completion/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -!gio diff -Nru glib2.0-2.59.2/gio/completion/gresource glib2.0-2.59.3/gio/completion/gresource --- glib2.0-2.59.2/gio/completion/gresource 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/completion/gresource 1970-01-01 00:00:00.000000000 +0000 @@ -1,58 +0,0 @@ - -# Check for bash -[ -z "$BASH_VERSION" ] && return - -#################################################################################################### - -__gresource() { - local choices coffset section - - if [ ${COMP_CWORD} -gt 2 ]; then - if [ ${COMP_WORDS[1]} = --section ]; then - section=${COMP_WORDS[2]} - coffset=2 - else - coffset=0 - fi - else - coffset=0 - fi - - case "$((${COMP_CWORD}-$coffset))" in - 1) - choices=$'--section \nhelp \nsections \nlist \ndetails \nextract ' - ;; - - 2) - case "${COMP_WORDS[$(($coffset+1))]}" in - --section) - return 0 - ;; - - help) - choices=$'sections\nlist\ndetails\nextract' - ;; - - sections|list|details|extract) - COMPREPLY=($(compgen -f -- ${COMP_WORDS[${COMP_CWORD}]})) - return 0 - ;; - esac - ;; - - 3) - case "${COMP_WORDS[$(($coffset+1))]}" in - list|details|extract) - choices="$(gresource list ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null | sed -e 's.$. .')" - ;; - esac - ;; - esac - - local IFS=$'\n' - COMPREPLY=($(compgen -W "${choices}" -- "${COMP_WORDS[${COMP_CWORD}]}")) -} - -#################################################################################################### - -complete -o nospace -F __gresource gresource diff -Nru glib2.0-2.59.2/gio/completion/gsettings glib2.0-2.59.3/gio/completion/gsettings --- glib2.0-2.59.2/gio/completion/gsettings 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/completion/gsettings 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ - -# Check for bash -[ -z "$BASH_VERSION" ] && return - -#################################################################################################### - -__gsettings() { - local choices coffset schemadir - - if [ ${COMP_CWORD} -gt 2 ]; then - if [ ${COMP_WORDS[1]} = --schemadir ]; then - # this complexity is needed to perform correct tilde expansion - schemadir=$(eval "echo --schemadir ${COMP_WORDS[2]}") - coffset=2 - else - coffset=0 - fi - else - coffset=0 - fi - - case "$((${COMP_CWORD}-$coffset))" in - 1) - choices=$'--schemadir\n--version\nhelp \nlist-schemas\nlist-relocatable-schemas\nlist-keys \nlist-children \nlist-recursively \nget \nrange \nset \nreset \nreset-recursively \nwritable \nmonitor \ndescribe ' - ;; - - 2) - case "${COMP_WORDS[$(($coffset+1))]}" in - --schemadir) - COMPREPLY=($(compgen -o dirnames -- ${COMP_WORDS[${COMP_CWORD}]})) - return 0 - ;; - - help) - choices=$'list-schemas\nlist-relocatable-schemas\nlist-keys\nlist-children\nlist-recursively\nget\nrange\nset\nreset\nreset-recursively\nwritable\nmonitor' - ;; - list-keys|list-children|list-recursively|reset-recursively) - choices="$(gsettings $schemadir list-schemas 2> /dev/null)"$'\n'"$(gsettings $schemadir list-relocatable-schemas 2> /dev/null | sed -e 's.$.:/.')" - ;; - list-schemas) - COMPREPLY=($(compgen -W "--print-paths" -- ${COMP_WORDS[${COMP_CWORD}]})) - return 0 - ;; - - get|range|set|reset|writable|monitor|describe) - choices="$(gsettings $schemadir list-schemas 2> /dev/null | sed -e 's.$. .')"$'\n'"$(gsettings $schemadir list-relocatable-schemas 2> /dev/null | sed -e 's.$.:/.')" - ;; - esac - ;; - - 3) - case "${COMP_WORDS[$(($coffset+1))]}" in - set) - choices="$(gsettings $schemadir list-keys ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null | sed -e 's.$. .')" - ;; - - get|range|reset|writable|monitor|describe) - choices="$(gsettings $schemadir list-keys ${COMP_WORDS[$(($coffset+2))]} 2> /dev/null)" - ;; - esac - ;; - - 4) - case "${COMP_WORDS[$(($coffset+2))]}" in - set) - range=($(gsettings $schemadir range ${COMP_WORDS[$(($coffset+2))]} ${COMP_WORDS[$(($coffset+3))]} 2> /dev/null)) - case "${range[0]}" in - enum) - unset range[0] - ;; - *) - unset range - ;; - esac - local IFS=$'\n' - choices="${range[*]}" - ;; - esac - ;; - esac - - local IFS=$'\n' - COMPREPLY=($(compgen -W "${choices}" -- "${COMP_WORDS[${COMP_CWORD}]}")) -} - -#################################################################################################### - -complete -o nospace -F __gsettings gsettings diff -Nru glib2.0-2.59.2/gio/gdbus-2.0/codegen/.gitignore glib2.0-2.59.3/gio/gdbus-2.0/codegen/.gitignore --- glib2.0-2.59.2/gio/gdbus-2.0/codegen/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gdbus-2.0/codegen/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -*.pyc -config.py -gdbus-codegen diff -Nru glib2.0-2.59.2/gio/gdbusprivate.c glib2.0-2.59.3/gio/gdbusprivate.c --- glib2.0-2.59.2/gio/gdbusprivate.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gdbusprivate.c 2019-03-04 09:01:42.000000000 +0000 @@ -809,11 +809,11 @@ out: g_mutex_unlock (&worker->read_lock); - /* gives up the reference acquired when calling g_input_stream_read_async() */ - _g_dbus_worker_unref (worker); - /* check if there is any pending close */ schedule_pending_close (worker); + + /* gives up the reference acquired when calling g_input_stream_read_async() */ + _g_dbus_worker_unref (worker); } /* called in private thread shared by all GDBusConnection instances (with read-lock held) */ diff -Nru glib2.0-2.59.2/gio/gdesktopappinfo.c glib2.0-2.59.3/gio/gdesktopappinfo.c --- glib2.0-2.59.2/gio/gdesktopappinfo.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gdesktopappinfo.c 2019-03-04 09:01:42.000000000 +0000 @@ -2741,9 +2741,9 @@ /* Allow test suite to specify path to gio-launch-desktop */ tmp = g_getenv ("GIO_LAUNCH_DESKTOP"); - /* Fall back on usual searching in $PATH */ if (tmp == NULL) - tmp = "gio-launch-desktop"; + tmp = GIO_LIBDIR "/glib-2.0/gio-launch-desktop"; + g_once_init_leave (&gio_launch_desktop_path, tmp); } diff -Nru glib2.0-2.59.2/gio/giomodule.c glib2.0-2.59.3/gio/giomodule.c --- glib2.0-2.59.2/gio/giomodule.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/giomodule.c 2019-03-04 09:01:42.000000000 +0000 @@ -1206,6 +1206,9 @@ g_io_module_scope_free (scope); + /* Hard-coded fallback directory for pre-multiarch compatibility */ + g_io_modules_scan_all_in_directory ("/usr/lib/gio/modules"); + /* Initialize types from built-in "modules" */ g_type_ensure (g_null_settings_backend_get_type ()); g_type_ensure (g_memory_settings_backend_get_type ()); diff -Nru glib2.0-2.59.2/gio/.gitignore glib2.0-2.59.3/gio/.gitignore --- glib2.0-2.59.2/gio/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -gapplication -gconstructor_as_data.h -gdbus -objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Animal.xml -objectmanager-gen-org.gtk.GDBus.Example.ObjectManager.Cat.xml -objectmanager-gen.[ch] -gdbus-daemon-generated.[ch] -gio -gio_probes.h -gio-marshal.[ch] -gio-public-headers.txt -gio-querymodules -gioenumtypes.[ch] -glib-compile-resources -glib-compile-schemas -gnetworking.h -gresource -gschema-compile -gsettings -xdp-dbus.[ch] diff -Nru glib2.0-2.59.2/gio/glib-compile-schemas.c glib2.0-2.59.3/gio/glib-compile-schemas.c --- glib2.0-2.59.2/gio/glib-compile-schemas.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/glib-compile-schemas.c 2019-03-04 09:01:42.000000000 +0000 @@ -1233,6 +1233,9 @@ return; } + // Disable this warning: it confuses users and there is unlikely to be much + // progress towards fixing + /* if (path && (g_str_has_prefix (path, "/apps/") || g_str_has_prefix (path, "/desktop/") || g_str_has_prefix (path, "/system/"))) @@ -1245,6 +1248,7 @@ g_printerr ("%s\n", message); g_free (message); } + */ state->schema_state = schema_state_new (path, gettext_domain, extends, extends_name, list_of); diff -Nru glib2.0-2.59.2/gio/gnetworkaddress.c glib2.0-2.59.3/gio/gnetworkaddress.c --- glib2.0-2.59.2/gio/gnetworkaddress.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gnetworkaddress.c 2019-03-04 09:01:42.000000000 +0000 @@ -38,6 +38,10 @@ #include +/* As recommended by RFC 8305 this is the time it waits for a following + DNS response to come in (ipv4 waiting on ipv6 generally) + */ +#define HAPPY_EYEBALLS_RESOLUTION_DELAY_MS 50 /** * SECTION:gnetworkaddress @@ -879,6 +883,12 @@ #define G_TYPE_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (_g_network_address_address_enumerator_get_type ()) #define G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_NETWORK_ADDRESS_ADDRESS_ENUMERATOR, GNetworkAddressAddressEnumerator)) +typedef enum { + RESOLVE_STATE_NONE = 0, + RESOLVE_STATE_WAITING_ON_IPV4 = 1 << 0, + RESOLVE_STATE_WAITING_ON_IPV6 = 1 << 1, +} ResolveState; + typedef struct { GSocketAddressEnumerator parent_instance; @@ -887,9 +897,11 @@ GList *last_tail; /* (unowned) (nullable) */ GList *current_item; /* (unowned) (nullable) */ GTask *queued_task; /* (owned) (nullable) */ + GTask *waiting_task; /* (owned) (nullable) */ GError *last_error; /* (owned) (nullable) */ GSource *wait_source; /* (owned) (nullable) */ GMainContext *context; /* (owned) (nullable) */ + ResolveState state; } GNetworkAddressAddressEnumerator; typedef struct { @@ -912,6 +924,7 @@ g_clear_pointer (&addr_enum->wait_source, g_source_unref); } g_clear_object (&addr_enum->queued_task); + g_clear_object (&addr_enum->waiting_task); g_clear_error (&addr_enum->last_error); g_object_unref (addr_enum->addr); g_clear_pointer (&addr_enum->addresses, g_list_free); @@ -1093,20 +1106,54 @@ return g_object_ref (sockaddr); } +/* + * Each enumeration lazily initializes the internal address list from the + * master list. It does this since addresses come in asynchronously and + * they need to be resorted into the list already in use. + */ +static GSocketAddress * +init_and_query_next_address (GNetworkAddressAddressEnumerator *addr_enum) +{ + GNetworkAddress *addr = addr_enum->addr; + GSocketAddress *sockaddr; + + if (addr_enum->addresses == NULL) + { + addr_enum->current_item = addr_enum->addresses = list_copy_interleaved (addr->priv->sockaddrs); + addr_enum->last_tail = g_list_last (addr_enum->addr->priv->sockaddrs); + if (addr_enum->current_item) + sockaddr = g_object_ref (addr_enum->current_item->data); + else + sockaddr = NULL; + } + else + { + GList *parent_tail = g_list_last (addr_enum->addr->priv->sockaddrs); + + if (addr_enum->last_tail != parent_tail) + { + addr_enum->current_item = list_concat_interleaved (addr_enum->current_item, g_list_next (addr_enum->last_tail)); + addr_enum->last_tail = parent_tail; + } + + if (addr_enum->current_item->next) + { + addr_enum->current_item = g_list_next (addr_enum->current_item); + sockaddr = g_object_ref (addr_enum->current_item->data); + } + else + sockaddr = NULL; + } + + return sockaddr; +} + static void complete_queued_task (GNetworkAddressAddressEnumerator *addr_enum, GTask *task, GError *error) { - GSocketAddress *sockaddr; - - addr_enum->current_item = addr_enum->addresses = list_copy_interleaved (addr_enum->addr->priv->sockaddrs); - addr_enum->last_tail = g_list_last (addr_enum->addr->priv->sockaddrs); - - if (addr_enum->current_item) - sockaddr = g_object_ref (addr_enum->current_item->data); - else - sockaddr = NULL; + GSocketAddress *sockaddr = init_and_query_next_address (addr_enum); if (error) g_task_return_error (task, error); @@ -1123,10 +1170,12 @@ /* Upon completion it may get unref'd by the owner */ g_object_ref (addr_enum); - /* If ipv6 didn't come in yet, just complete the task */ if (addr_enum->queued_task != NULL) - complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task), - g_steal_pointer (&addr_enum->last_error)); + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task), + g_steal_pointer (&addr_enum->last_error)); + else if (addr_enum->waiting_task != NULL) + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task), + NULL); g_clear_pointer (&addr_enum->wait_source, g_source_unref); g_object_unref (addr_enum); @@ -1144,6 +1193,8 @@ GList *addresses; GError *error = NULL; + addr_enum->state ^= RESOLVE_STATE_WAITING_ON_IPV6; + addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error); if (!error) { @@ -1163,30 +1214,39 @@ g_clear_pointer (&addr_enum->wait_source, g_source_unref); } - /* If we got an error before ipv4 then let it handle it. + /* If we got an error before ipv4 then let its response handle it. * If we get ipv6 response first or error second then * immediately complete the task. */ - if (error != NULL && !addr_enum->last_error) + if (error != NULL && !addr_enum->last_error && (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4)) { addr_enum->last_error = g_steal_pointer (&error); - /* This shouldn't happen often but avoid never responding. */ - addr_enum->wait_source = g_timeout_source_new_seconds (1); + addr_enum->wait_source = g_timeout_source_new (HAPPY_EYEBALLS_RESOLUTION_DELAY_MS); g_source_set_callback (addr_enum->wait_source, on_address_timeout, addr_enum, NULL); g_source_attach (addr_enum->wait_source, addr_enum->context); } + else if (addr_enum->waiting_task != NULL) + { + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task), NULL); + } else if (addr_enum->queued_task != NULL) { + GError *task_error = NULL; + + /* If both errored just use the ipv6 one, + but if ipv6 errored and ipv4 didn't we don't error */ + if (error != NULL && addr_enum->last_error) + task_error = g_steal_pointer (&error); + g_clear_error (&addr_enum->last_error); complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task), - g_steal_pointer (&error)); + g_steal_pointer (&task_error)); } - else if (error != NULL) - g_clear_error (&error); + g_clear_error (&error); g_object_unref (addr_enum); } @@ -1200,6 +1260,8 @@ GList *addresses; GError *error = NULL; + addr_enum->state ^= RESOLVE_STATE_WAITING_ON_IPV4; + addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error); if (!error) { @@ -1216,8 +1278,9 @@ } /* If ipv6 already came in and errored then we return. - * If ipv6 returned successfully then we don't need to do anything. - * Otherwise we should wait a short while for ipv6 as RFC 8305 suggests. + * If ipv6 returned successfully then we don't need to do anything unless + * another enumeration was waiting on us. + * If ipv6 hasn't come we should wait a short while for it as RFC 8305 suggests. */ if (addr_enum->last_error) { @@ -1226,18 +1289,21 @@ complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->queued_task), g_steal_pointer (&error)); } + else if (addr_enum->waiting_task != NULL) + { + complete_queued_task (addr_enum, g_steal_pointer (&addr_enum->waiting_task), NULL); + } else if (addr_enum->queued_task != NULL) { addr_enum->last_error = g_steal_pointer (&error); - addr_enum->wait_source = g_timeout_source_new (50); + addr_enum->wait_source = g_timeout_source_new (HAPPY_EYEBALLS_RESOLUTION_DELAY_MS); g_source_set_callback (addr_enum->wait_source, on_address_timeout, addr_enum, NULL); g_source_attach (addr_enum->wait_source, addr_enum->context); } - else if (error != NULL) - g_clear_error (&error); + g_clear_error (&error); g_object_unref (addr_enum); } @@ -1251,12 +1317,11 @@ G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (enumerator); GSocketAddress *sockaddr; GTask *task; - GNetworkAddress *addr = addr_enum->addr; task = g_task_new (addr_enum, cancellable, callback, user_data); g_task_set_source_tag (task, g_network_address_address_enumerator_next_async); - if (addr_enum->addresses == NULL) + if (addr_enum->addresses == NULL && addr_enum->state == RESOLVE_STATE_NONE) { GNetworkAddress *addr = addr_enum->addr; GResolver *resolver = g_resolver_get_default (); @@ -1280,6 +1345,7 @@ * times before the initial callback has been called */ g_assert (addr_enum->queued_task == NULL); + addr_enum->state = RESOLVE_STATE_WAITING_ON_IPV4 | RESOLVE_STATE_WAITING_ON_IPV6; addr_enum->queued_task = g_steal_pointer (&task); /* Lookup in parallel as per RFC 8305 */ g_resolver_lookup_by_name_with_flags_async (resolver, @@ -1300,34 +1366,17 @@ g_object_unref (resolver); } - if (addr_enum->addresses == NULL) + sockaddr = init_and_query_next_address (addr_enum); + if (sockaddr == NULL && (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4 || + addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV6)) { - g_assert (addr->priv->sockaddrs); - - addr_enum->current_item = addr_enum->addresses = list_copy_interleaved (addr->priv->sockaddrs); - sockaddr = g_object_ref (addr_enum->current_item->data); + addr_enum->waiting_task = task; } else { - GList *parent_tail = g_list_last (addr_enum->addr->priv->sockaddrs); - - if (addr_enum->last_tail != parent_tail) - { - addr_enum->current_item = list_concat_interleaved (addr_enum->current_item, g_list_next (addr_enum->last_tail)); - addr_enum->last_tail = parent_tail; - } - - if (addr_enum->current_item->next) - { - addr_enum->current_item = g_list_next (addr_enum->current_item); - sockaddr = g_object_ref (addr_enum->current_item->data); - } - else - sockaddr = NULL; + g_task_return_pointer (task, sockaddr, g_object_unref); + g_object_unref (task); } - - g_task_return_pointer (task, sockaddr, g_object_unref); - g_object_unref (task); } static GSocketAddress * diff -Nru glib2.0-2.59.2/gio/gpollableoutputstream.h glib2.0-2.59.3/gio/gpollableoutputstream.h --- glib2.0-2.59.2/gio/gpollableoutputstream.h 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gpollableoutputstream.h 2019-03-04 09:01:42.000000000 +0000 @@ -35,7 +35,7 @@ /** * GPollableOutputStream: * - * An interface for a #GOutputStream that can be polled for readability. + * An interface for a #GOutputStream that can be polled for writeability. * * Since: 2.28 */ diff -Nru glib2.0-2.59.2/gio/gresource.c glib2.0-2.59.3/gio/gresource.c --- glib2.0-2.59.2/gio/gresource.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gresource.c 2019-03-04 09:01:42.000000000 +0000 @@ -151,7 +151,7 @@ * When debugging a program or testing a change to an installed version, it is often useful to be able to * replace resources in the program or library, without recompiling, for debugging or quick hacking and testing * purposes. Since GLib 2.50, it is possible to use the `G_RESOURCE_OVERLAYS` environment variable to selectively overlay - * resources with replacements from the filesystem. It is a colon-separated list of substitutions to perform + * resources with replacements from the filesystem. It is a %G_SEARCHPATH_SEPARATOR-separated list of substitutions to perform * during resource lookups. * * A substitution has the form @@ -332,7 +332,7 @@ gchar **parts; gint i, j; - parts = g_strsplit (envvar, ":", 0); + parts = g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, 0); /* Sanity check the parts, dropping those that are invalid. * 'i' may grow faster than 'j'. @@ -378,9 +378,9 @@ continue; } - if (eq[1] != '/') + if (!g_path_is_absolute (eq + 1)) { - g_critical ("G_RESOURCE_OVERLAYS segment '%s' lacks leading '/' after '='. Ignoring", part); + g_critical ("G_RESOURCE_OVERLAYS segment '%s' does not have an absolute path after '='. Ignoring", part); g_free (part); continue; } diff -Nru glib2.0-2.59.2/gio/gsocket.c glib2.0-2.59.3/gio/gsocket.c --- glib2.0-2.59.2/gio/gsocket.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gsocket.c 2019-03-04 09:01:42.000000000 +0000 @@ -4609,7 +4609,13 @@ cancellable, error); if (res == G_POLLABLE_RETURN_WOULD_BLOCK) - socket_set_error_lazy (error, EWOULDBLOCK, _("Error sending message: %s")); + { +#ifndef G_OS_WIN32 + socket_set_error_lazy (error, EWOULDBLOCK, _("Error sending message: %s")); +#else + socket_set_error_lazy (error, WSAEWOULDBLOCK, _("Error sending message: %s")); +#endif + } return res == G_POLLABLE_RETURN_OK ? bytes_written : -1; } @@ -5056,7 +5062,13 @@ cancellable, &msg_error); if (pollable_result == G_POLLABLE_RETURN_WOULD_BLOCK) - socket_set_error_lazy (&msg_error, EWOULDBLOCK, _("Error sending message: %s")); + { +#ifndef G_OS_WIN32 + socket_set_error_lazy (&msg_error, EWOULDBLOCK, _("Error sending message: %s")); +#else + socket_set_error_lazy (&msg_error, WSAEWOULDBLOCK, _("Error sending message: %s")); +#endif + } result = pollable_result == G_POLLABLE_RETURN_OK ? bytes_written : -1; diff -Nru glib2.0-2.59.2/gio/gsocketclient.c glib2.0-2.59.3/gio/gsocketclient.c --- glib2.0-2.59.2/gio/gsocketclient.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gsocketclient.c 2019-03-04 09:01:42.000000000 +0000 @@ -1567,7 +1567,7 @@ GProxy *proxy; const gchar *protocol; - if (g_cancellable_is_cancelled (attempt->cancellable) || task_completed_or_cancelled (data->task)) + if (task_completed_or_cancelled (data->task) || g_cancellable_is_cancelled (attempt->cancellable)) { g_object_unref (data->task); connection_attempt_unref (attempt); diff -Nru glib2.0-2.59.2/gio/gsocketlistener.c glib2.0-2.59.3/gio/gsocketlistener.c --- glib2.0-2.59.2/gio/gsocketlistener.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gsocketlistener.c 2019-03-04 09:01:42.000000000 +0000 @@ -773,6 +773,19 @@ return connection; } +typedef struct +{ + GList *sources; /* (element-type GSource) */ + gboolean returned_yet; +} AcceptSocketAsyncData; + +static void +accept_socket_async_data_free (AcceptSocketAsyncData *data) +{ + free_sources (data->sources); + g_free (data); +} + static gboolean accept_ready (GSocket *accept_socket, GIOCondition condition, @@ -782,6 +795,12 @@ GError *error = NULL; GSocket *socket; GObject *source_object; + AcceptSocketAsyncData *data = g_task_get_task_data (task); + + /* Don’t call g_task_return_*() multiple times if we have multiple incoming + * connections in the same #GMainContext iteration. */ + if (data->returned_yet) + return G_SOURCE_REMOVE; socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error); if (socket) @@ -798,8 +817,10 @@ g_task_return_error (task, error); } + data->returned_yet = TRUE; g_object_unref (task); - return FALSE; + + return G_SOURCE_REMOVE; } /** @@ -824,8 +845,8 @@ gpointer user_data) { GTask *task; - GList *sources; GError *error = NULL; + AcceptSocketAsyncData *data = NULL; task = g_task_new (listener, cancellable, callback, user_data); g_task_set_source_tag (task, g_socket_listener_accept_socket_async); @@ -837,12 +858,15 @@ return; } - sources = add_sources (listener, + data = g_new0 (AcceptSocketAsyncData, 1); + data->returned_yet = FALSE; + data->sources = add_sources (listener, accept_ready, task, cancellable, g_main_context_get_thread_default ()); - g_task_set_task_data (task, sources, (GDestroyNotify) free_sources); + g_task_set_task_data (task, g_steal_pointer (&data), + (GDestroyNotify) accept_socket_async_data_free); } /** diff -Nru glib2.0-2.59.2/gio/gtask.c glib2.0-2.59.3/gio/gtask.c --- glib2.0-2.59.2/gio/gtask.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gtask.c 2019-03-04 09:01:42.000000000 +0000 @@ -1,6 +1,6 @@ /* GIO - GLib Input, Output and Streaming Library * - * Copyright 2011 Red Hat, Inc. + * Copyright 2011-2018 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1260,9 +1260,18 @@ */ if (g_source_get_time (source) > task->creation_time) { - g_task_return_now (task); - g_object_unref (task); - return; + /* Finally, if the task has been cancelled, we shouldn't + * return synchronously from inside the + * GCancellable::cancelled handler. It's easier to run + * another iteration of the main loop than tracking how the + * cancellation was handled. + */ + if (!g_cancellable_is_cancelled (task->cancellable)) + { + g_task_return_now (task); + g_object_unref (task); + return; + } } } diff -Nru glib2.0-2.59.2/gio/gwin32volumemonitor.c glib2.0-2.59.3/gio/gwin32volumemonitor.c --- glib2.0-2.59.2/gio/gwin32volumemonitor.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/gwin32volumemonitor.c 2019-03-04 09:01:42.000000000 +0000 @@ -111,7 +111,7 @@ { DWORD drives; gchar drive[4] = "A:\\"; - GList *list = NULL; + GQueue queue = G_QUEUE_INIT; drives = get_viewable_logical_drives (); @@ -121,13 +121,13 @@ while (drives && drive[0] <= 'Z') { if (drives & 1) - { - list = g_list_prepend (list, _g_win32_mount_new (volume_monitor, drive, NULL)); - } + g_queue_push_tail (&queue, _g_win32_mount_new (volume_monitor, drive, NULL)); + drives >>= 1; drive[0]++; } - return list; + + return g_steal_pointer (&queue.head); } /* actually 'mounting' volumes is out of GIOs business on win32, so no volumes are delivered either */ diff -Nru glib2.0-2.59.2/gio/meson.build glib2.0-2.59.3/gio/meson.build --- glib2.0-2.59.2/gio/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -1,6 +1,7 @@ gio_c_args = [ '-DG_LOG_DOMAIN="GLib-GIO"', '-DGIO_COMPILATION', + '-DGIO_LIBDIR="@0@"'.format(glib_libdir), '-DGIO_MODULE_DIR="@0@"'.format(glib_giomodulesdir), ] @@ -828,7 +829,7 @@ 'schemasdir=' + join_paths('${datadir}', schemas_subdir), 'bindir=' + join_paths('${prefix}', get_option('bindir')), 'giomoduledir=' + giomodulesdir, - 'glib_compile_schemas=' + join_paths('${bindir}', 'glib-compile-schemas'), + 'glib_compile_schemas=' + join_paths('${libdir}', 'glib-2.0', 'glib-compile-schemas'), 'glib_compile_resources=' + join_paths('${bindir}', 'glib-compile-resources'), 'gdbus_codegen=' + join_paths('${bindir}', 'gdbus-codegen')], version : glib_version, diff -Nru glib2.0-2.59.2/gio/tests/autoptr.c glib2.0-2.59.3/gio/tests/autoptr.c --- glib2.0-2.59.2/gio/tests/autoptr.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/autoptr.c 2019-03-04 09:01:42.000000000 +0000 @@ -8,7 +8,7 @@ g_autofree gchar *path = g_file_get_path (p); g_autofree gchar *istr = g_inet_address_to_string (a); - g_assert_cmpstr (path, ==, "/blah"); + g_assert_cmpstr (path, ==, G_DIR_SEPARATOR_S "blah"); g_assert_cmpstr (istr, ==, "127.0.0.1"); } diff -Nru glib2.0-2.59.2/gio/tests/de/LC_MESSAGES/meson.build glib2.0-2.59.3/gio/tests/de/LC_MESSAGES/meson.build --- glib2.0-2.59.2/gio/tests/de/LC_MESSAGES/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/de/LC_MESSAGES/meson.build 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -# Doing this in a subdir, so we get it in the right build de/LC_MESSAGES subdir -# at least in cases where the build directory layout is mirrored. -test_mo = custom_target('test.mo', - input : ['../../de.po'], - output : ['test.mo'], - command : [msgfmt, '-o', '@OUTPUT@', '@INPUT@']) - -test_mo_dir = meson.current_build_dir() diff -Nru glib2.0-2.59.2/gio/tests/gdbus-threading.c glib2.0-2.59.3/gio/tests/gdbus-threading.c --- glib2.0-2.59.2/gio/tests/gdbus-threading.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/gdbus-threading.c 2019-03-04 09:01:42.000000000 +0000 @@ -499,6 +499,12 @@ guint unref_wins = 0; guint get_wins = 0; + if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) + { + g_test_skip ("Not reliable (glib#1515)"); + return; + } + if (g_test_thorough ()) n = 100000; else diff -Nru glib2.0-2.59.2/gio/tests/.gitignore glib2.0-2.59.3/gio/tests/.gitignore --- glib2.0-2.59.2/gio/tests/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ -actions -appinfo -appinfo-test -appmonitor -apps -async-close-output-stream -async-splice-output-stream -autoptr -basic-application -buffered-input-stream -buffered-output-stream -cancellable -connectable -contenttype -contexts -converter-stream -credentials -data-input-stream -data-output-stream -dbus-appinfo -dbus-launch -de/ -defaultvalue -desktop-app-info -echo-server -file -fileattributematcher -filter-cat -filter-streams -gapplication -gapplication-example-actions -gapplication-example-cmdline -gapplication-example-cmdline2 -gapplication-example-cmdline3 -gapplication-example-dbushooks -gapplication-example-menu -gapplication-example-open -gdbus-addresses -gdbus-auth -gdbus-bz627724 -gdbus-close-pending -gdbus-connection -gdbus-connection-flush -gdbus-connection-flush-helper -gdbus-connection-loss -gdbus-connection-slow -gdbus-daemon -gdbus-error -gdbus-example-export -gdbus-example-objectmanager-client -gdbus-example-objectmanager-server -gdbus-example-own-name -gdbus-example-peer -gdbus-example-proxy-subclass -gdbus-example-server -gdbus-example-subtree -gdbus-example-unix-fd-client -gdbus-example-watch-name -gdbus-example-watch-proxy -gdbus-exit-on-close -gdbus-export -gdbus-introspection -gdbus-message -gdbus-names -gdbus-non-socket -gdbus-overflow -gdbus-peer -gdbus-peer-object-manager -gdbus-proxy -gdbus-proxy-threads -gdbus-proxy-well-known-name -gdbus-serialization -gdbus-test-codegen -gdbus-test-codegen-generated* -gdbus-test-codegen-old -gdbus-test-fixture -gdbus-testserver -gdbus-threading -gdbus-unix-addresses -glistmodel -gio-du -giomodule -giotypefuncs.inc -gnotification -gsubprocess -gsubprocess-testprog -g-file -g-file-info -g-icon -gmenumodel -gschemas.compiled -gsettings -gsettings.store -httpd -icons -inet-address -io-stream -live-g-file -memory-input-stream -memory-output-stream -mimeapps -monitor -network-address -network-monitor -org.gtk.test.enums.xml -org.gtk.test.gschema.xml -permission -pollable -plugin_resources.c -proxy -proxy-test -readwrite -resolver -resources -send-data -services/org.gtk.GDBus.Examples.ObjectManager.service -simple-async-result -simple-proxy -sleepy-stream -stream-rw_all -socket -socket-address -socket-client -socket-listener -socket-service -socket-server -srvtarget -task -test-generated.txt -test.gresource -test.mo -test_resources.c -test_resources2.c -test_resources2.h -testfilemonitor -thumbnail-verification -tls-certificate -tls-database -tls-interaction -unix-fd -unix-streams -vfs -volumemonitor -xgen-gio -xgen-giosrc.c -gresource-big-test.txt diff -Nru glib2.0-2.59.2/gio/tests/gsettings.c glib2.0-2.59.3/gio/tests/gsettings.c --- glib2.0-2.59.2/gio/tests/gsettings.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/gsettings.c 2019-03-04 09:01:42.000000000 +0000 @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include #define G_SETTINGS_ENABLE_BACKEND @@ -53,10 +55,10 @@ "delay-apply", &delay_apply, NULL); g_assert_cmpstr (str, ==, "org.gtk.test"); - g_assert (b != NULL); + g_assert_nonnull (b); g_assert_cmpstr (path, ==, "/tests/"); - g_assert (!has_unapplied); - g_assert (!delay_apply); + g_assert_false (has_unapplied); + g_assert_false (delay_apply); g_free (str); g_object_unref (b); g_free (path); @@ -114,7 +116,7 @@ settings = g_settings_new ("org.gtk.test"); value = g_settings_get_value (settings, "no_such_key"); - g_assert (value == NULL); + g_assert_null (value); g_object_unref (settings); return; @@ -139,7 +141,7 @@ settings = g_settings_new ("no.such.schema"); - g_assert (settings == NULL); + g_assert_null (settings); return; } g_test_trap_subprocess (NULL, 0, 0); @@ -168,7 +170,7 @@ g_settings_get (settings, "greeting", "o", &str); g_test_assert_expected_messages (); - g_assert (str == NULL); + g_assert_null (str); g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*expects type 's'*"); @@ -358,28 +360,28 @@ g_settings_get (settings, "test-array", "ai", &iter); g_assert_cmpint (g_variant_iter_n_children (iter), ==, 6); - g_assert (g_variant_iter_next (iter, "i", &i1)); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); g_assert_cmpint (i1, ==, 0); - g_assert (g_variant_iter_next (iter, "i", &i1)); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); g_assert_cmpint (i1, ==, 1); - g_assert (g_variant_iter_next (iter, "i", &i1)); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); g_assert_cmpint (i1, ==, 2); - g_assert (g_variant_iter_next (iter, "i", &i1)); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); g_assert_cmpint (i1, ==, 3); - g_assert (g_variant_iter_next (iter, "i", &i1)); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); g_assert_cmpint (i1, ==, 4); - g_assert (g_variant_iter_next (iter, "i", &i1)); + g_assert_true (g_variant_iter_next (iter, "i", &i1)); g_assert_cmpint (i1, ==, 5); - g_assert (!g_variant_iter_next (iter, "i", &i1)); + g_assert_false (g_variant_iter_next (iter, "i", &i1)); g_variant_iter_free (iter); g_settings_get (settings, "test-dict", "a{sau}", &iter); g_assert_cmpint (g_variant_iter_n_children (iter), ==, 2); - g_assert (g_variant_iter_next (iter, "{&s@au}", &s, &v)); + g_assert_true (g_variant_iter_next (iter, "{&s@au}", &s, &v)); g_assert_cmpstr (s, ==, "AC"); g_assert_cmpstr ((char *)g_variant_get_type (v), ==, "au"); g_variant_unref (v); - g_assert (g_variant_iter_next (iter, "{&s@au}", &s, &v)); + g_assert_true (g_variant_iter_next (iter, "{&s@au}", &s, &v)); g_assert_cmpstr (s, ==, "IV"); g_assert_cmpstr ((char *)g_variant_get_type (v), ==, "au"); g_variant_unref (v); @@ -420,14 +422,14 @@ changed_cb_called = FALSE; g_settings_set (settings, "greeting", "s", "new greeting"); - g_assert (changed_cb_called); + g_assert_true (changed_cb_called); settings2 = g_settings_new ("org.gtk.test"); changed_cb_called = FALSE; g_settings_set (settings2, "greeting", "s", "hi"); - g_assert (changed_cb_called); + g_assert_true (changed_cb_called); g_object_unref (settings2); g_object_unref (settings); @@ -479,11 +481,11 @@ g_settings_set (settings, "greeting", "s", "greetings from test_delay_apply"); - g_assert (changed_cb_called); - g_assert (!changed_cb_called2); + g_assert_true (changed_cb_called); + g_assert_false (changed_cb_called2); writable = g_settings_is_writable (settings, "greeting"); - g_assert (writable); + g_assert_true (writable); g_settings_get (settings, "greeting", "s", &str); g_assert_cmpstr (str, ==, "greetings from test_delay_apply"); @@ -500,16 +502,16 @@ g_free (str); str = NULL; - g_assert (g_settings_get_has_unapplied (settings)); - g_assert (!g_settings_get_has_unapplied (settings2)); + g_assert_true (g_settings_get_has_unapplied (settings)); + g_assert_false (g_settings_get_has_unapplied (settings2)); changed_cb_called = FALSE; changed_cb_called2 = FALSE; g_settings_apply (settings); - g_assert (!changed_cb_called); - g_assert (changed_cb_called2); + g_assert_false (changed_cb_called); + g_assert_true (changed_cb_called2); g_settings_get (settings, "greeting", "s", &str); g_assert_cmpstr (str, ==, "greetings from test_delay_apply"); @@ -521,8 +523,8 @@ g_free (str); str = NULL; - g_assert (!g_settings_get_has_unapplied (settings)); - g_assert (!g_settings_get_has_unapplied (settings2)); + g_assert_false (g_settings_get_has_unapplied (settings)); + g_assert_false (g_settings_get_has_unapplied (settings2)); g_settings_reset (settings, "greeting"); g_settings_apply (settings); @@ -568,11 +570,11 @@ g_free (str); str = NULL; - g_assert (g_settings_get_has_unapplied (settings)); + g_assert_true (g_settings_get_has_unapplied (settings)); g_settings_revert (settings); - g_assert (!g_settings_get_has_unapplied (settings)); + g_assert_false (g_settings_get_has_unapplied (settings)); g_settings_get (settings, "greeting", "s", &str); g_assert_cmpstr (str, ==, "top o' the morning"); @@ -603,13 +605,13 @@ settings = g_settings_new ("org.gtk.test"); g_settings_delay (settings); g_object_get (settings, "delay-apply", &delay, NULL); - g_assert (delay); + g_assert_true (delay); child = g_settings_get_child (settings, "basic-types"); - g_assert (child != NULL); + g_assert_nonnull (child); g_object_get (child, "delay-apply", &delay, NULL); - g_assert (!delay); + g_assert_false (delay); g_settings_get (child, "test-byte", "y", &byte); g_assert_cmpuint (byte, ==, 36); @@ -634,10 +636,10 @@ g_assert_cmpint (n_keys, ==, 2); - g_assert ((keys[0] == g_quark_from_static_string ("greeting") && - keys[1] == g_quark_from_static_string ("farewell")) || - (keys[1] == g_quark_from_static_string ("greeting") && - keys[0] == g_quark_from_static_string ("farewell"))); + g_assert_true ((keys[0] == g_quark_from_static_string ("greeting") && + keys[1] == g_quark_from_static_string ("farewell")) || + (keys[1] == g_quark_from_static_string ("greeting") && + keys[0] == g_quark_from_static_string ("farewell"))); g_settings_get (settings, "greeting", "s", &str); g_assert_cmpstr (str, ==, "greetings from test_atomic"); @@ -1297,7 +1299,7 @@ g_free (s); g_settings_set_strv (settings, "strv", NULL); g_object_get (obj, "strv", &strv, NULL); - g_assert (strv != NULL); + g_assert_nonnull (strv); g_assert_cmpint (g_strv_length (strv), ==, 0); g_strfreev (strv); @@ -1401,14 +1403,14 @@ g_settings_bind_writable (settings, "int", obj, "bool", FALSE); g_object_get (obj, "bool", &b, NULL); - g_assert (b); + g_assert_true (b); g_settings_unbind (obj, "bool"); g_settings_bind_writable (settings, "int", obj, "bool", TRUE); g_object_get (obj, "bool", &b, NULL); - g_assert (!b); + g_assert_false (b); g_object_unref (obj); g_object_unref (settings); @@ -1724,7 +1726,7 @@ g_free (str); writable = g_settings_is_writable (settings, "greeting"); - g_assert (writable); + g_assert_true (writable); g_settings_set (settings, "greeting", "s", "see if this works"); str = g_settings_get_string (settings, "greeting"); @@ -1736,7 +1738,7 @@ g_settings_apply (settings); keyfile = g_key_file_new (); - g_assert (g_key_file_load_from_file (keyfile, "keyfile/gsettings.store", 0, NULL)); + g_assert_true (g_key_file_load_from_file (keyfile, "keyfile/gsettings.store", 0, NULL)); str = g_key_file_get_string (keyfile, "tests", "greeting", NULL); g_assert_cmpstr (str, ==, "'see if this works'"); @@ -1750,10 +1752,10 @@ g_settings_reset (settings, "greeting"); g_settings_apply (settings); keyfile = g_key_file_new (); - g_assert (g_key_file_load_from_file (keyfile, "keyfile/gsettings.store", 0, NULL)); + g_assert_true (g_key_file_load_from_file (keyfile, "keyfile/gsettings.store", 0, NULL)); str = g_key_file_get_string (keyfile, "tests", "greeting", NULL); - g_assert (str == NULL); + g_assert_null (str); called = FALSE; g_signal_connect (settings, "changed::greeting", G_CALLBACK (key_changed_cb), &called); @@ -1789,16 +1791,23 @@ g_settings_set (settings, "farewell", "s", "cheerio"); - called = FALSE; - g_signal_connect (settings, "writable-changed::greeting", G_CALLBACK (key_changed_cb), &called); - - g_chmod ("keyfile", 0500); - while (!called) - g_main_context_iteration (NULL, FALSE); - g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); + /* When executing as root, changing the mode of the keyfile will have + * no effect on the writability of the settings. + */ + if (geteuid () != 0) + { + called = FALSE; + g_signal_connect (settings, "writable-changed::greeting", + G_CALLBACK (key_changed_cb), &called); + + g_chmod ("keyfile", 0500); + while (!called) + g_main_context_iteration (NULL, FALSE); + g_signal_handlers_disconnect_by_func (settings, key_changed_cb, &called); - writable = g_settings_is_writable (settings, "greeting"); - g_assert (!writable); + writable = g_settings_is_writable (settings, "greeting"); + g_assert_false (writable); + } g_key_file_free (keyfile); g_free (data); @@ -1827,7 +1836,7 @@ settings = g_settings_new ("org.gtk.test"); child = g_settings_get_child (settings, "basic-types"); - g_assert (child != NULL); + g_assert_nonnull (child); g_settings_get (child, "test-byte", "y", &byte); g_assert_cmpint (byte, ==, 36); @@ -1860,7 +1869,7 @@ builder = g_string_new (NULL); strinfo_builder_append_item (builder, "foo", 1); strinfo_builder_append_item (builder, "bar", 2); - g_assert (strinfo_builder_append_alias (builder, "baz", "bar")); + g_assert_true (strinfo_builder_append_alias (builder, "baz", "bar")); g_assert_cmpmem (builder->str, builder->len, strinfo, length * 4); g_string_free (builder, TRUE); } @@ -1874,22 +1883,22 @@ g_assert_cmpstr (strinfo_string_from_alias (strinfo, length, "quux"), ==, NULL); - g_assert (strinfo_enum_from_string (strinfo, length, "foo", &result)); + g_assert_true (strinfo_enum_from_string (strinfo, length, "foo", &result)); g_assert_cmpint (result, ==, 1); - g_assert (strinfo_enum_from_string (strinfo, length, "bar", &result)); + g_assert_true (strinfo_enum_from_string (strinfo, length, "bar", &result)); g_assert_cmpint (result, ==, 2); - g_assert (!strinfo_enum_from_string (strinfo, length, "baz", &result)); - g_assert (!strinfo_enum_from_string (strinfo, length, "quux", &result)); + g_assert_false (strinfo_enum_from_string (strinfo, length, "baz", &result)); + g_assert_false (strinfo_enum_from_string (strinfo, length, "quux", &result)); g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 0), ==, NULL); g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 1), ==, "foo"); g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 2), ==, "bar"); g_assert_cmpstr (strinfo_string_from_enum (strinfo, length, 3), ==, NULL); - g_assert (strinfo_is_string_valid (strinfo, length, "foo")); - g_assert (strinfo_is_string_valid (strinfo, length, "bar")); - g_assert (!strinfo_is_string_valid (strinfo, length, "baz")); - g_assert (!strinfo_is_string_valid (strinfo, length, "quux")); + g_assert_true (strinfo_is_string_valid (strinfo, length, "foo")); + g_assert_true (strinfo_is_string_valid (strinfo, length, "bar")); + g_assert_false (strinfo_is_string_valid (strinfo, length, "baz")); + g_assert_false (strinfo_is_string_valid (strinfo, length, "quux")); } static void @@ -2152,13 +2161,13 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS value = g_variant_new_int32 (1); - g_assert (!g_settings_range_check (settings, "val", value)); + g_assert_false (g_settings_range_check (settings, "val", value)); g_variant_unref (value); value = g_variant_new_int32 (33); - g_assert (g_settings_range_check (settings, "val", value)); + g_assert_true (g_settings_range_check (settings, "val", value)); g_variant_unref (value); value = g_variant_new_int32 (45); - g_assert (!g_settings_range_check (settings, "val", value)); + g_assert_false (g_settings_range_check (settings, "val", value)); g_variant_unref (value); G_GNUC_END_IGNORE_DEPRECATIONS @@ -2224,8 +2233,8 @@ children = g_settings_list_children (settings); keys = g_settings_schema_list_keys (schema); - g_assert (strv_set_equal (children, "basic-types", "complex-types", "localized", NULL)); - g_assert (strv_set_equal (keys, "greeting", "farewell", NULL)); + g_assert_true (strv_set_equal (children, "basic-types", "complex-types", "localized", NULL)); + g_assert_true (strv_set_equal (keys, "greeting", "farewell", NULL)); g_strfreev (children); g_strfreev (keys); @@ -2245,26 +2254,26 @@ schemas = g_settings_list_schemas (); G_GNUC_END_IGNORE_DEPRECATIONS - g_assert (strv_set_equal ((gchar **)relocs, - "org.gtk.test.no-path", - "org.gtk.test.extends.base", - "org.gtk.test.extends.extended", - NULL)); - - g_assert (strv_set_equal ((gchar **)schemas, - "org.gtk.test", - "org.gtk.test.basic-types", - "org.gtk.test.complex-types", - "org.gtk.test.localized", - "org.gtk.test.binding", - "org.gtk.test.enums", - "org.gtk.test.enums.direct", - "org.gtk.test.range", - "org.gtk.test.range.direct", - "org.gtk.test.mapped", - "org.gtk.test.descriptions", - "org.gtk.test.per-desktop", - NULL)); + g_assert_true (strv_set_equal ((gchar **)relocs, + "org.gtk.test.no-path", + "org.gtk.test.extends.base", + "org.gtk.test.extends.extended", + NULL)); + + g_assert_true (strv_set_equal ((gchar **)schemas, + "org.gtk.test", + "org.gtk.test.basic-types", + "org.gtk.test.complex-types", + "org.gtk.test.localized", + "org.gtk.test.binding", + "org.gtk.test.enums", + "org.gtk.test.enums.direct", + "org.gtk.test.range", + "org.gtk.test.range.direct", + "org.gtk.test.mapped", + "org.gtk.test.descriptions", + "org.gtk.test.per-desktop", + NULL)); } static gboolean @@ -2294,7 +2303,7 @@ } else { - g_assert (value == NULL); + g_assert_null (value); *result = g_variant_new_int32 (5); return TRUE; } @@ -2366,7 +2375,7 @@ /* make sure it fails properly */ parent = g_settings_schema_source_get_default (); source = g_settings_schema_source_new_from_directory ("/path/that/does/not/exist", parent, TRUE, &error); - g_assert (source == NULL); + g_assert_null (source); g_assert_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT); g_clear_error (&error); @@ -2385,60 +2394,60 @@ /* create a source with the parent */ source = g_settings_schema_source_new_from_directory ("schema-source", parent, TRUE, &error); g_assert_no_error (error); - g_assert (source != NULL); + g_assert_nonnull (source); /* check recursive lookups are working */ schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE); - g_assert (schema != NULL); + g_assert_nonnull (schema); g_settings_schema_unref (schema); /* check recursive lookups for non-existent schemas */ schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", TRUE); - g_assert (schema == NULL); + g_assert_null (schema); /* check non-recursive for schema that only exists in lower layers */ schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE); - g_assert (schema == NULL); + g_assert_null (schema); /* check non-recursive lookup for non-existent */ schema = g_settings_schema_source_lookup (source, "org.gtk.doesnotexist", FALSE); - g_assert (schema == NULL); + g_assert_null (schema); /* check non-recursive for schema that exists in toplevel */ schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE); - g_assert (schema != NULL); + g_assert_nonnull (schema); g_settings_schema_unref (schema); /* check recursive for schema that exists in toplevel */ schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE); - g_assert (schema != NULL); + g_assert_nonnull (schema); /* try to use it for something */ settings = g_settings_new_full (schema, backend, g_settings_schema_get_path (schema)); g_settings_schema_unref (schema); enabled = FALSE; g_settings_get (settings, "enabled", "b", &enabled); - g_assert (enabled); + g_assert_true (enabled); g_object_unref (settings); g_settings_schema_source_unref (source); /* try again, but with no parent */ source = g_settings_schema_source_new_from_directory ("schema-source", NULL, FALSE, NULL); - g_assert (source != NULL); + g_assert_nonnull (source); /* should not find it this time, even if recursive... */ schema = g_settings_schema_source_lookup (source, "org.gtk.test", FALSE); - g_assert (schema == NULL); + g_assert_null (schema); schema = g_settings_schema_source_lookup (source, "org.gtk.test", TRUE); - g_assert (schema == NULL); + g_assert_null (schema); /* should still find our own... */ schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", TRUE); - g_assert (schema != NULL); + g_assert_nonnull (schema); g_settings_schema_unref (schema); schema = g_settings_schema_source_lookup (source, "org.gtk.schemasourcecheck", FALSE); - g_assert (schema != NULL); + g_assert_nonnull (schema); g_settings_schema_unref (schema); g_settings_schema_source_unref (source); @@ -2451,14 +2460,14 @@ gchar **keys; GSettingsSchemaSource *src = g_settings_schema_source_get_default (); GSettingsSchema *schema = g_settings_schema_source_lookup (src, "org.gtk.test", TRUE); - g_assert (schema != NULL); + g_assert_nonnull (schema); keys = g_settings_schema_list_keys (schema); - g_assert (strv_set_equal ((gchar **)keys, - "greeting", - "farewell", - NULL)); + g_assert_true (strv_set_equal ((gchar **)keys, + "greeting", + "farewell", + NULL)); g_strfreev (keys); g_settings_schema_unref (schema); @@ -2488,27 +2497,27 @@ c1 = c2 = c3 = FALSE; g_settings_set_string (settings, "test-string", "hello world"); check_and_free (g_action_get_state (string), "'hello world'"); - g_assert (c1 && c2 && !c3); + g_assert_true (c1 && c2 && !c3); c1 = c2 = c3 = FALSE; g_action_activate (string, g_variant_new_string ("hihi")); check_and_free (g_settings_get_value (settings, "test-string"), "'hihi'"); - g_assert (c1 && c2 && !c3); + g_assert_true (c1 && c2 && !c3); c1 = c2 = c3 = FALSE; g_action_change_state (string, g_variant_new_string ("kthxbye")); check_and_free (g_settings_get_value (settings, "test-string"), "'kthxbye'"); - g_assert (c1 && c2 && !c3); + g_assert_true (c1 && c2 && !c3); c1 = c2 = c3 = FALSE; g_action_change_state (toggle, g_variant_new_boolean (TRUE)); - g_assert (g_settings_get_boolean (settings, "test-boolean")); - g_assert (c1 && !c2 && c3); + g_assert_true (g_settings_get_boolean (settings, "test-boolean")); + g_assert_true (c1 && !c2 && c3); c1 = c2 = c3 = FALSE; g_action_activate (toggle, NULL); - g_assert (!g_settings_get_boolean (settings, "test-boolean")); - g_assert (c1 && !c2 && c3); + g_assert_false (g_settings_get_boolean (settings, "test-boolean")); + g_assert_true (c1 && !c2 && c3); g_object_get (string, "name", &name, @@ -2519,9 +2528,9 @@ NULL); g_assert_cmpstr (name, ==, "test-string"); - g_assert (g_variant_type_equal (param_type, G_VARIANT_TYPE_STRING)); - g_assert (enabled); - g_assert (g_variant_type_equal (state_type, G_VARIANT_TYPE_STRING)); + g_assert_true (g_variant_type_equal (param_type, G_VARIANT_TYPE_STRING)); + g_assert_true (enabled); + g_assert_true (g_variant_type_equal (state_type, G_VARIANT_TYPE_STRING)); g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "kthxbye"); g_free (name); @@ -2558,7 +2567,7 @@ g_free (str); writable = g_settings_is_writable (settings, "greeting"); - g_assert (!writable); + g_assert_false (writable); g_settings_reset (settings, "greeting"); @@ -2579,7 +2588,7 @@ GSettingsBackend *backend; backend = g_memory_settings_backend_new (); - g_assert (G_IS_SETTINGS_BACKEND (backend)); + g_assert_true (G_IS_SETTINGS_BACKEND (backend)); g_object_unref (backend); } @@ -2634,7 +2643,7 @@ g_settings_schema_unref (schema); g_settings_schema_key_ref (key); - g_assert (g_variant_type_equal (g_settings_schema_key_get_value_type (key), G_VARIANT_TYPE_STRING)); + g_assert_true (g_variant_type_equal (g_settings_schema_key_get_value_type (key), G_VARIANT_TYPE_STRING)); v = g_settings_schema_key_get_default_value (key); str = g_variant_get_string (v, NULL); @@ -2772,7 +2781,7 @@ settings = g_settings_new_with_path ("org.gtk.test.extends.extended", "/test/extendes/"); g_object_get (settings, "settings-schema", &schema, NULL); keys = g_settings_schema_list_keys (schema); - g_assert (strv_set_equal (keys, "int32", "string", "another-int32", NULL)); + g_assert_true (strv_set_equal (keys, "int32", "string", "another-int32", NULL)); g_strfreev (keys); g_object_unref (settings); g_settings_schema_unref (schema); @@ -2818,37 +2827,37 @@ g_remove ("org.gtk.test.enums.xml"); /* #GLIB_MKENUMS is defined in meson.build */ - g_assert (g_spawn_command_line_sync (GLIB_MKENUMS " " - "--template " SRCDIR "/enums.xml.template " - SRCDIR "/testenum.h", - &enums, NULL, &result, NULL)); - g_assert (result == 0); - g_assert (g_file_set_contents ("org.gtk.test.enums.xml", enums, -1, NULL)); + g_assert_true (g_spawn_command_line_sync (GLIB_MKENUMS " " + "--template " SRCDIR "/enums.xml.template " + SRCDIR "/testenum.h", + &enums, NULL, &result, NULL)); + g_assert_cmpint (result, ==, 0); + g_assert_true (g_file_set_contents ("org.gtk.test.enums.xml", enums, -1, NULL)); g_free (enums); - g_assert (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.xml.orig", &schema_text, NULL, NULL)); - g_assert (g_file_set_contents ("org.gtk.test.gschema.xml", schema_text, -1, NULL)); + g_assert_true (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.xml.orig", &schema_text, NULL, NULL)); + g_assert_true (g_file_set_contents ("org.gtk.test.gschema.xml", schema_text, -1, NULL)); g_free (schema_text); - g_assert (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.override.orig", &override_text, NULL, NULL)); - g_assert (g_file_set_contents ("org.gtk.test.gschema.override", override_text, -1, NULL)); + g_assert_true (g_file_get_contents (SRCDIR "/org.gtk.test.gschema.override.orig", &override_text, NULL, NULL)); + g_assert_true (g_file_set_contents ("org.gtk.test.gschema.override", override_text, -1, NULL)); g_free (override_text); g_remove ("gschemas.compiled"); /* #GLIB_COMPILE_SCHEMAS is defined in meson.build */ - g_assert (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=. " - "--schema-file=org.gtk.test.enums.xml " - "--schema-file=org.gtk.test.gschema.xml " - "--override-file=org.gtk.test.gschema.override", - NULL, NULL, &result, NULL)); - g_assert (result == 0); + g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=. " + "--schema-file=org.gtk.test.enums.xml " + "--schema-file=org.gtk.test.gschema.xml " + "--override-file=org.gtk.test.gschema.override", + NULL, NULL, &result, NULL)); + g_assert_cmpint (result, ==, 0); g_remove ("schema-source/gschemas.compiled"); g_mkdir ("schema-source", 0777); - g_assert (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=schema-source " - "--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml", - NULL, NULL, &result, NULL)); - g_assert (result == 0); + g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=schema-source " + "--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml", + NULL, NULL, &result, NULL)); + g_assert_cmpint (result, ==, 0); g_remove ("schema-source-corrupt/gschemas.compiled"); g_mkdir ("schema-source-corrupt", 0777); diff -Nru glib2.0-2.59.2/gio/tests/gsubprocess.c glib2.0-2.59.3/gio/tests/gsubprocess.c --- glib2.0-2.59.2/gio/tests/gsubprocess.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/gsubprocess.c 2019-03-04 09:01:42.000000000 +0000 @@ -8,12 +8,20 @@ #include #endif +/* We write 2^1 + 2^2 ... + 2^10 or 2047 copies of "Hello World!\n" + * ultimately + */ +#define TOTAL_HELLOS 2047 +#define HELLO_WORLD "hello world!\n" + #ifdef G_OS_WIN32 #define LINEEND "\r\n" #define EXEEXT ".exe" +#define SPLICELEN (TOTAL_HELLOS * (strlen (HELLO_WORLD) + 1)) /* because \r */ #else #define LINEEND "\n" #define EXEEXT +#define SPLICELEN (TOTAL_HELLOS * strlen (HELLO_WORLD)) #endif static GPtrArray * @@ -557,10 +565,7 @@ { TestMultiSpliceData *data = user_data; - /* We write 2^1 + 2^2 ... + 2^10 or 2047 copies of "Hello World!\n" - * ultimately - */ - if (data->counter >= 2047 || data->caught_error) + if (data->counter >= TOTAL_HELLOS || data->caught_error) { if (!g_output_stream_close (data->first_stdin, NULL, &data->error)) data->caught_error = TRUE; @@ -577,8 +582,8 @@ for (i = 0; i < data->counter; i++) { gsize bytes_written; - if (!g_output_stream_write_all (data->first_stdin, "hello world!\n", - strlen ("hello world!\n"), &bytes_written, + if (!g_output_stream_write_all (data->first_stdin, HELLO_WORLD, + strlen (HELLO_WORLD), &bytes_written, NULL, &data->error)) { data->caught_error = TRUE; @@ -684,7 +689,7 @@ g_assert (!data.caught_error); g_assert_no_error (data.error); - g_assert_cmpint (g_memory_output_stream_get_data_size ((GMemoryOutputStream*)membuf), ==, 26611); + g_assert_cmpint (g_memory_output_stream_get_data_size ((GMemoryOutputStream*)membuf), ==, SPLICELEN); g_main_loop_unref (data.loop); g_object_unref (membuf); @@ -732,7 +737,7 @@ else stdout_data = g_bytes_get_data (stdout_bytes, &stdout_len); - g_assert_cmpmem (stdout_data, stdout_len, "# hello world\n", 14); + g_assert_cmpmem (stdout_data, stdout_len, "# hello world" LINEEND, 13 + strlen (LINEEND)); } else { @@ -834,7 +839,7 @@ if (flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE) { stdout_data = g_bytes_get_data (stdout_bytes, &stdout_len); - g_assert_cmpmem (stdout_data, stdout_len, "# hello world\n", 14); + g_assert_cmpmem (stdout_data, stdout_len, "# hello world" LINEEND, 13 + strlen (LINEEND)); } else g_assert_null (stdout_bytes); @@ -1110,7 +1115,7 @@ g_assert_no_error (error); if (flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE) - g_assert_cmpstr (stdout_buf, ==, "# hello world\n"); + g_assert_cmpstr (stdout_buf, ==, "# hello world" LINEEND); else g_assert_null (stdout_buf); if (flags & G_SUBPROCESS_FLAGS_STDERR_PIPE) @@ -1358,9 +1363,10 @@ GPtrArray *args; GInputStream *stdout_stream; gchar *result; - gchar *envp[] = { "ONE=1", "TWO=1", "THREE=3", "FOUR=1", NULL }; + gchar *envp[] = { NULL, "ONE=1", "TWO=1", "THREE=3", "FOUR=1", NULL }; gchar **split; + envp[0] = g_strdup_printf ("PATH=%s", g_getenv ("PATH")); args = get_test_subprocess_args ("env", NULL); launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE); g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE); @@ -1374,11 +1380,12 @@ proc = g_subprocess_launcher_spawn (launcher, error, args->pdata[0], "env", NULL); g_ptr_array_free (args, TRUE); g_assert_no_error (local_error); + g_free (envp[0]); stdout_stream = g_subprocess_get_stdout_pipe (proc); result = splice_to_string (stdout_stream, error); - split = g_strsplit (result, "\n", -1); + split = g_strsplit (result, LINEEND, -1); g_assert_cmpstr (g_environ_getenv (split, "ONE"), ==, "1"); g_assert_cmpstr (g_environ_getenv (split, "TWO"), ==, "2"); g_assert_cmpstr (g_environ_getenv (split, "THREE"), ==, "3"); @@ -1425,7 +1432,7 @@ stdout_stream = g_subprocess_get_stdout_pipe (proc); result = splice_to_string (stdout_stream, error); - split = g_strsplit (result, "\n", -1); + split = g_strsplit (result, LINEEND, -1); g_assert_null (g_environ_getenv (split, "TEST_ENV_INHERIT1")); g_assert_cmpstr (g_environ_getenv (split, "TEST_ENV_INHERIT2"), ==, "2"); g_assert_cmpstr (g_environ_getenv (split, "TWO"), ==, "2"); @@ -1447,11 +1454,15 @@ GInputStream *stdout_stream; gchar *result; const char *basename; + gchar *tmp_lineend; + const gchar *tmp_lineend_basename; args = get_test_subprocess_args ("cwd", NULL); launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE); g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE); - g_subprocess_launcher_set_cwd (launcher, "/tmp"); + g_subprocess_launcher_set_cwd (launcher, g_get_tmp_dir ()); + tmp_lineend = g_strdup_printf ("%s%s", g_get_tmp_dir (), LINEEND); + tmp_lineend_basename = g_strrstr (tmp_lineend, G_DIR_SEPARATOR_S); proc = g_subprocess_launcher_spawnv (launcher, (const char * const *)args->pdata, error); g_ptr_array_free (args, TRUE); @@ -1461,9 +1472,10 @@ result = splice_to_string (stdout_stream, error); - basename = g_strrstr (result, "/"); + basename = g_strrstr (result, G_DIR_SEPARATOR_S); g_assert (basename != NULL); - g_assert_cmpstr (basename, ==, "/tmp" LINEEND); + g_assert_cmpstr (basename, ==, tmp_lineend_basename); + g_free (tmp_lineend); g_free (result); g_object_unref (proc); @@ -1719,7 +1731,7 @@ g_subprocess_communicate_utf8 (proc, NULL, NULL, &out, NULL, &error); g_assert_no_error (error); - g_assert_cmpstr (out, ==, "C=D\nE=F\n"); + g_assert_cmpstr (out, ==, "C=D" LINEEND "E=F" LINEEND); g_free (out); g_object_unref (proc); diff -Nru glib2.0-2.59.2/gio/tests/meson.build glib2.0-2.59.3/gio/tests/meson.build --- glib2.0-2.59.2/gio/tests/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -55,7 +55,7 @@ 'memory-output-stream' : {}, 'monitor' : {}, 'mount-operation' : {}, - 'network-address' : {'extra_sources': ['mock-resolver.c'], 'suite': ['flaky']}, + 'network-address' : {'extra_sources': ['mock-resolver.c']}, 'network-monitor' : {}, 'network-monitor-race' : {}, 'permission' : {}, @@ -140,11 +140,16 @@ 'slow-connect-preload.c', name_prefix : '', dependencies: cc.find_library('dl'), + install_dir : installed_tests_execdir, + install: installed_tests_enabled, ) ], 'env' : { 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(meson.current_build_dir()) }, + 'installed_tests_env' : { + 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(installed_tests_execdir), + }, 'suite': ['flaky'], }, 'gschema-compile' : {'install' : false}, @@ -428,6 +433,7 @@ 'appinfo-test-static.desktop', 'file.c', 'org.gtk.test.dbusappinfo.desktop', + 'test1.overlay', install_dir : installed_tests_execdir, ) install_subdir('x-content', install_dir : installed_tests_execdir) @@ -592,11 +598,21 @@ source = extra_args.get('source', test_name + '.c') extra_sources = extra_args.get('extra_sources', []) install = installed_tests_enabled and extra_args.get('install', true) + installed_tests_env = extra_args.get('installed_tests_env', {}) if install test_conf = configuration_data() test_conf.set('installed_tests_dir', installed_tests_execdir) test_conf.set('program', test_name) + test_env_override = '' + if installed_tests_env != {} + envs = [] + foreach var, value : installed_tests_env + envs += '@0@=@1@'.format(var, value) + endforeach + test_env_override = '@0@ @1@ '.format(env_program.path(), ' '.join(envs)) + endif + test_conf.set('env', test_env_override) configure_file( input: installed_tests_template_tap, output: test_name + '.test', diff -Nru glib2.0-2.59.2/gio/tests/monitor.c glib2.0-2.59.3/gio/tests/monitor.c --- glib2.0-2.59.2/gio/tests/monitor.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/monitor.c 2019-03-04 09:01:42.000000000 +0000 @@ -214,7 +214,9 @@ { g_test_init (&argc, &argv, NULL); +#ifdef __linux__ g_test_add ("/monitor/directory", Fixture, NULL, setup, test_directory_monitor, teardown); +#endif return g_test_run (); } diff -Nru glib2.0-2.59.2/gio/tests/network-address.c glib2.0-2.59.3/gio/tests/network-address.c --- glib2.0-2.59.2/gio/tests/network-address.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/network-address.c 2019-03-04 09:01:42.000000000 +0000 @@ -271,6 +271,7 @@ static void test_scope_id (GSocketConnectable *addr) { +#ifndef G_OS_WIN32 GSocketAddressEnumerator *addr_enum; GSocketAddress *saddr; GInetSocketAddress *isaddr; @@ -300,6 +301,9 @@ g_assert (saddr == NULL); g_object_unref (addr_enum); +#else + g_test_skip ("winsock2 getaddrinfo() can’t understand scope IDs"); +#endif } static void @@ -622,13 +626,16 @@ g_main_loop_unref (fixture->loop); } +static const guint FAST_DELAY_LESS_THAN_TIMEOUT = 25; +static const guint SLOW_DELAY_MORE_THAN_TIMEOUT = 100; + static void test_happy_eyeballs_basic (HappyEyeballsFixture *fixture, gconstpointer user_data) { AsyncData data = { 0 }; - data.delay_ms = 10; + data.delay_ms = FAST_DELAY_LESS_THAN_TIMEOUT; data.loop = fixture->loop; /* This just tests in the common case it gets all results */ @@ -645,15 +652,15 @@ { AsyncData data = { 0 }; - /* If ipv4 dns response is a bit slow we just don't get them */ + /* If ipv4 dns response is a bit slow we still get everything */ data.loop = fixture->loop; - mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, 25); + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); g_main_loop_run (fixture->loop); - assert_list_matches_expected (data.addrs, fixture->input_ipv6_results); + assert_list_matches_expected (data.addrs, fixture->input_all_results); } static void @@ -665,7 +672,7 @@ /* If ipv6 is a bit slow it waits for them */ data.loop = fixture->loop; - mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, 25); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); g_main_loop_run (fixture->loop); @@ -679,15 +686,15 @@ { AsyncData data = { 0 }; - /* If ipv6 is very slow we don't get them */ + /* If ipv6 is very slow we still get everything */ data.loop = fixture->loop; - mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, 200); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, SLOW_DELAY_MORE_THAN_TIMEOUT); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); g_main_loop_run (fixture->loop); - assert_list_matches_expected (data.addrs, fixture->input_ipv4_results); + assert_list_matches_expected (data.addrs, fixture->input_all_results); } static void @@ -700,8 +707,8 @@ * take long enough. */ data.loop = fixture->loop; - data.delay_ms = 500; - mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, 200); + data.delay_ms = SLOW_DELAY_MORE_THAN_TIMEOUT * 2; + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, SLOW_DELAY_MORE_THAN_TIMEOUT); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); g_main_loop_run (fixture->loop); @@ -710,17 +717,18 @@ } static void -test_happy_eyeballs_ipv6_error (HappyEyeballsFixture *fixture, - gconstpointer user_data) +test_happy_eyeballs_ipv6_error_ipv4_first (HappyEyeballsFixture *fixture, + gconstpointer user_data) { AsyncData data = { 0 }; GError *ipv6_error; - /* If ipv6 fails we still get ipv4. */ + /* If ipv6 fails, ensuring that ipv4 finishes before ipv6 errors, we still get ipv4. */ data.loop = fixture->loop; ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); g_main_loop_run (fixture->loop); @@ -731,17 +739,62 @@ } static void -test_happy_eyeballs_ipv4_error (HappyEyeballsFixture *fixture, - gconstpointer user_data) +test_happy_eyeballs_ipv6_error_ipv6_first (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv6_error; + + /* If ipv6 fails, ensuring that ipv6 errors before ipv4 finishes, we still get ipv4. */ + + data.loop = fixture->loop; + ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); + mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_ipv4_results); + + g_error_free (ipv6_error); +} + +static void +test_happy_eyeballs_ipv4_error_ipv4_first (HappyEyeballsFixture *fixture, + gconstpointer user_data) +{ + AsyncData data = { 0 }; + GError *ipv4_error; + + /* If ipv4 fails, ensuring that ipv4 errors before ipv6 finishes, we still get ipv6. */ + + data.loop = fixture->loop; + ipv4_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv4 Broken"); + mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); + + g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); + g_main_loop_run (fixture->loop); + + assert_list_matches_expected (data.addrs, fixture->input_ipv6_results); + + g_error_free (ipv4_error); +} + +static void +test_happy_eyeballs_ipv4_error_ipv6_first (HappyEyeballsFixture *fixture, + gconstpointer user_data) { AsyncData data = { 0 }; GError *ipv4_error; - /* If ipv4 fails we still get ipv6. */ + /* If ipv4 fails, ensuring that ipv6 finishes before ipv4 errors, we still get ipv6. */ data.loop = fixture->loop; ipv4_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv4 Broken"); mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); g_main_loop_run (fixture->loop); @@ -792,7 +845,7 @@ ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); - mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, 25); + mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); @@ -820,7 +873,7 @@ mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); - mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, 25); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, FAST_DELAY_LESS_THAN_TIMEOUT); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); g_main_loop_run (fixture->loop); @@ -847,7 +900,7 @@ mock_resolver_set_ipv4_error (fixture->mock_resolver, ipv4_error); mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); - mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, 200); + mock_resolver_set_ipv6_delay_ms (fixture->mock_resolver, SLOW_DELAY_MORE_THAN_TIMEOUT); g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); g_main_loop_run (fixture->loop); @@ -913,10 +966,14 @@ happy_eyeballs_setup, test_happy_eyeballs_very_slow_ipv6, happy_eyeballs_teardown); g_test_add ("/network-address/happy-eyeballs/slow-connection-and-ipv4", HappyEyeballsFixture, NULL, happy_eyeballs_setup, test_happy_eyeballs_slow_connection_and_ipv4, happy_eyeballs_teardown); - g_test_add ("/network-address/happy-eyeballs/ipv6-error", HappyEyeballsFixture, NULL, - happy_eyeballs_setup, test_happy_eyeballs_ipv6_error, happy_eyeballs_teardown); - g_test_add ("/network-address/happy-eyeballs/ipv4-error", HappyEyeballsFixture, NULL, - happy_eyeballs_setup, test_happy_eyeballs_ipv4_error, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv6-error-ipv4-first", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv6_error_ipv4_first, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv6-error-ipv6-first", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv6_error_ipv6_first, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv4-error-ipv6-first", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv4_error_ipv6_first, happy_eyeballs_teardown); + g_test_add ("/network-address/happy-eyeballs/ipv4-error-ipv4-first", HappyEyeballsFixture, NULL, + happy_eyeballs_setup, test_happy_eyeballs_ipv4_error_ipv4_first, happy_eyeballs_teardown); g_test_add ("/network-address/happy-eyeballs/both-error", HappyEyeballsFixture, NULL, happy_eyeballs_setup, test_happy_eyeballs_both_error, happy_eyeballs_teardown); g_test_add ("/network-address/happy-eyeballs/both-error-delays-1", HappyEyeballsFixture, NULL, diff -Nru glib2.0-2.59.2/gio/tests/socket.c glib2.0-2.59.3/gio/tests/socket.c --- glib2.0-2.59.2/gio/tests/socket.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/socket.c 2019-03-04 09:01:42.000000000 +0000 @@ -1111,6 +1111,14 @@ gint64 start_time; gint poll_duration; +#if defined(__arm__) + if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) + { + g_test_skip ("Not reliable on older ARM hardware"); + return; + } +#endif + data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error); if (error != NULL) { diff -Nru glib2.0-2.59.2/gio/tests/socket-service.c glib2.0-2.59.3/gio/tests/socket-service.c --- glib2.0-2.59.2/gio/tests/socket-service.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/socket-service.c 2019-03-04 09:01:42.000000000 +0000 @@ -139,6 +139,12 @@ GObject *source_object, gpointer user_data) { + GMainLoop *loop = user_data; + + /* Since the connection attempt has come through to be handled, stop the main + * thread waiting for it; this causes the #GSocketService to be stopped. */ + g_main_loop_quit (loop); + /* Block until the main thread has dropped its ref to @service, so that we * will drop the final ref from this thread. */ @@ -158,7 +164,6 @@ GAsyncResult *result, gpointer user_data) { - GMainLoop *loop = user_data; GSocketConnection *conn; GError *error = NULL; @@ -166,7 +171,6 @@ g_assert_no_error (error); g_object_unref (conn); - g_main_loop_quit (loop); } static void @@ -195,9 +199,8 @@ g_assert_no_error (error); g_object_unref (addr); - g_signal_connect (service, "run", G_CALLBACK (connection_cb), NULL); - loop = g_main_loop_new (NULL, FALSE); + g_signal_connect (service, "run", G_CALLBACK (connection_cb), loop); client = g_socket_client_new (); g_socket_client_connect_async (client, @@ -222,6 +225,11 @@ g_main_context_iteration (NULL, TRUE); while (G_OBJECT (service)->ref_count > 3); + /* Wait some more iterations, as #GTask results are deferred to the next + * #GMainContext iteration, and propagation of a #GTask result takes an + * additional ref on the source object. */ + g_main_context_iteration (NULL, FALSE); + /* Drop our ref, then unlock the mutex and wait for the service to be * finalized. (Without the fix for 712570 it would hang forever here.) */ diff -Nru glib2.0-2.59.2/gio/tests/task.c glib2.0-2.59.3/gio/tests/task.c --- glib2.0-2.59.2/gio/tests/task.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/tests/task.c 2019-03-04 09:01:42.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright 2012 Red Hat, Inc. + * Copyright 2012-2019 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -654,6 +654,151 @@ g_main_loop_quit (loop); } +/* test_asynchronous_cancellation: cancelled tasks are returned + * asynchronously, i.e. not from inside the GCancellable::cancelled + * handler. + * + * The test is set up further below in test_asynchronous_cancellation. + */ + +/* asynchronous_cancellation_callback represents the callback that the + * caller of a typical asynchronous API would have passed. See + * test_asynchronous_cancellation. + */ +static void +asynchronous_cancellation_callback (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + guint run_task_id; + + g_assert_null (object); + g_assert_true (g_task_is_valid (result, object)); + g_assert_true (g_async_result_get_user_data (result) == user_data); + g_assert_true (g_task_had_error (G_TASK (result))); + g_assert_false (g_task_get_completed (G_TASK (result))); + + run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (G_TASK (result))); + g_assert_cmpuint (run_task_id, ==, 0); + + g_task_propagate_boolean (G_TASK (result), &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_clear_error (&error); + + g_assert_true (g_task_had_error (G_TASK (result))); + + g_main_loop_quit (loop); +} + +/* asynchronous_cancellation_cancel_task represents a user cancelling + * the ongoing operation. To make it somewhat realistic it is delayed + * by 50ms via a timeout GSource. See test_asynchronous_cancellation. + */ +static gboolean +asynchronous_cancellation_cancel_task (gpointer user_data) +{ + GCancellable *cancellable; + GTask *task = G_TASK (user_data); + + cancellable = g_task_get_cancellable (task); + g_assert_true (G_IS_CANCELLABLE (cancellable)); + + g_cancellable_cancel (cancellable); + g_assert_false (g_task_get_completed (task)); + + return G_SOURCE_REMOVE; +} + +/* asynchronous_cancellation_cancelled is the GCancellable::cancelled + * handler that's used by the asynchronous implementation for + * cancelling itself. + */ +static void +asynchronous_cancellation_cancelled (GCancellable *cancellable, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + guint run_task_id; + + g_assert_true (cancellable == g_task_get_cancellable (task)); + + run_task_id = GPOINTER_TO_UINT (g_task_get_task_data (task)); + g_assert_cmpuint (run_task_id, !=, 0); + + g_source_remove (run_task_id); + g_task_set_task_data (task, GUINT_TO_POINTER (0), NULL); + + g_task_return_boolean (task, FALSE); + g_assert_false (g_task_get_completed (task)); +} + +/* asynchronous_cancellation_run_task represents the actual + * asynchronous work being done in an idle GSource as was mentioned + * above. This is effectively meant to be an infinite loop so that + * the only way to break out of it is via cancellation. + */ +static gboolean +asynchronous_cancellation_run_task (gpointer user_data) +{ + GCancellable *cancellable; + GTask *task = G_TASK (user_data); + + cancellable = g_task_get_cancellable (task); + g_assert_true (G_IS_CANCELLABLE (cancellable)); + g_assert_false (g_cancellable_is_cancelled (cancellable)); + + return G_SOURCE_CONTINUE; +} + +/* Test that cancellation is always asynchronous. The completion callback for + * a #GTask must not be called from inside the cancellation handler. + * + * The body of the loop inside test_asynchronous_cancellation + * represents what would have been a typical asynchronous API call, + * and its implementation. They are fused together without an API + * boundary. The actual work done by this asynchronous API is + * represented by an idle GSource. + */ +static void +test_asynchronous_cancellation (void) +{ + guint i; + + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1608"); + + /* Run a few times to shake out any timing issues between the + * cancellation and task sources. + */ + for (i = 0; i < 5; i++) + { + GCancellable *cancellable; + GTask *task; + gboolean notification_emitted = FALSE; + guint run_task_id; + + cancellable = g_cancellable_new (); + + task = g_task_new (NULL, cancellable, asynchronous_cancellation_callback, NULL); + g_cancellable_connect (cancellable, (GCallback) asynchronous_cancellation_cancelled, task, NULL); + g_signal_connect (task, "notify::completed", (GCallback) completed_cb, ¬ification_emitted); + + run_task_id = g_idle_add (asynchronous_cancellation_run_task, task); + g_source_set_name_by_id (run_task_id, "[test_asynchronous_cancellation] run_task"); + g_task_set_task_data (task, GUINT_TO_POINTER (run_task_id), NULL); + + g_timeout_add (50, asynchronous_cancellation_cancel_task, task); + + g_main_loop_run (loop); + + g_assert_true (g_task_get_completed (task)); + g_assert_true (notification_emitted); + + g_object_unref (cancellable); + g_object_unref (task); + } +} + /* test_check_cancellable: cancellation overrides return value */ enum { @@ -2186,6 +2331,7 @@ g_test_add_func ("/gtask/report-error", test_report_error); g_test_add_func ("/gtask/priority", test_priority); g_test_add_func ("/gtask/name", test_name); + g_test_add_func ("/gtask/asynchronous-cancellation", test_asynchronous_cancellation); g_test_add_func ("/gtask/check-cancellable", test_check_cancellable); g_test_add_func ("/gtask/return-if-cancelled", test_return_if_cancelled); g_test_add_func ("/gtask/run-in-thread", test_run_in_thread); diff -Nru glib2.0-2.59.2/gio/win32/gwinhttpvfs.c glib2.0-2.59.3/gio/win32/gwinhttpvfs.c --- glib2.0-2.59.2/gio/win32/gwinhttpvfs.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/win32/gwinhttpvfs.c 2019-03-04 09:01:42.000000000 +0000 @@ -173,7 +173,7 @@ return _g_winhttp_file_new (winhttp_vfs, uri); /* For other URIs fallback to the wrapped GVfs */ - return g_vfs_parse_name (winhttp_vfs->wrapped_vfs, uri); + return g_vfs_get_file_for_uri (winhttp_vfs->wrapped_vfs, uri); } static const gchar * const * diff -Nru glib2.0-2.59.2/gio/xdgmime/.gitignore glib2.0-2.59.3/gio/xdgmime/.gitignore --- glib2.0-2.59.2/gio/xdgmime/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gio/xdgmime/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -test-mime diff -Nru glib2.0-2.59.2/glib/.gitignore glib2.0-2.59.3/glib/.gitignore --- glib2.0-2.59.2/glib/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ -glibconfig.h -glibconfig-stamp - -gtester -libglib-gdb.py -gspawn-win32-helper-console.c -gspawn-win64-helper-console.c -gspawn-win64-helper.c -glib_probes.h -glib-public-headers.txt diff -Nru glib2.0-2.59.2/glib/gkeyfile.c glib2.0-2.59.3/glib/gkeyfile.c --- glib2.0-2.59.2/glib/gkeyfile.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/gkeyfile.c 2019-03-04 09:01:42.000000000 +0000 @@ -511,6 +511,7 @@ GKeyFileFlags flags; gchar **locales; + gchar *gettext_domain; volatile gint ref_count; }; @@ -636,6 +637,7 @@ key_file->list_separator = ';'; key_file->flags = 0; key_file->locales = g_strdupv ((gchar **)g_get_language_names ()); + key_file->gettext_domain = NULL; } static void @@ -655,6 +657,12 @@ key_file->parse_buffer = NULL; } + if (key_file->gettext_domain) + { + g_free (key_file->gettext_domain); + key_file->gettext_domain = NULL; + } + tmp = key_file->groups; while (tmp != NULL) { @@ -874,6 +882,21 @@ return FALSE; } + key_file->gettext_domain = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, + NULL); + if (!key_file->gettext_domain) + key_file->gettext_domain = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + "X-Ubuntu-Gettext-Domain", + NULL); + if (!key_file->gettext_domain) + key_file->gettext_domain = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + "X-Debian-Gettext-Domain", + NULL); + return TRUE; } @@ -930,6 +953,21 @@ return FALSE; } + key_file->gettext_domain = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, + NULL); + if (!key_file->gettext_domain) + key_file->gettext_domain = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + "X-Ubuntu-Gettext-Domain", + NULL); + if (!key_file->gettext_domain) + key_file->gettext_domain = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + "X-Debian-Gettext-Domain", + NULL); + return TRUE; } @@ -2213,6 +2251,8 @@ GError *key_file_error; gchar **languages; gboolean free_languages = FALSE; + gboolean try_gettext = FALSE; + const gchar *msg_locale; gint i; g_return_val_if_fail (key_file != NULL, NULL); @@ -2234,6 +2274,25 @@ free_languages = FALSE; } + /* we're only interested in gettext translation if we don't have a + * translation in the .desktop file itself and if the key is one of the keys + * we know we want to translate: Name, GenericName, Comment, Keywords. + * Blindly doing this for all keys can give strange result for the icons, + * since the Icon is a locale string in the spec, eg. We also only get + * translation in the mo file if the requested locale is the LC_MESSAGES one. + * Ideally, we should do more and change LC_MESSAGES to use the requested + * locale, but there's no guarantee it's installed on the system and it might + * have some side-effects. Since this is a corner case, let's ignore it. */ + msg_locale = setlocale (LC_MESSAGES, NULL); + try_gettext = msg_locale && key_file->gettext_domain && + (strcmp (group_name, G_KEY_FILE_DESKTOP_GROUP) == 0 || + g_str_has_prefix (group_name, G_KEY_FILE_DESKTOP_ACTION_GROUP_PREFIX)) && + (strcmp (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0 || + strcmp (key, G_KEY_FILE_DESKTOP_KEY_FULLNAME) == 0 || + strcmp (key, G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME) == 0 || + strcmp (key, G_KEY_FILE_DESKTOP_KEY_KEYWORDS) == 0 || + strcmp (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0); + for (i = 0; languages[i]; i++) { candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); @@ -2250,6 +2309,39 @@ translated_value = NULL; } + /* Fallback to gettext */ + if (try_gettext && !translated_value) + { + gchar *orig_value = g_key_file_get_string (key_file, group_name, key, NULL); + + if (orig_value) + { + gboolean codeset_set; + const gchar *translated; + gboolean has_gettext; + + codeset_set = bind_textdomain_codeset (key_file->gettext_domain, "UTF-8") != NULL; + translated = NULL; + + translated = g_dgettext (key_file->gettext_domain, + orig_value); + has_gettext = translated != orig_value; + + g_free (orig_value); + + if (has_gettext) + { + if (codeset_set) + translated_value = g_strdup (translated); + else + translated_value = g_locale_to_utf8 (translated, + -1, NULL, NULL, NULL); + } + else + translated_value = NULL; + } + } + /* Fallback to untranslated key */ if (!translated_value) diff -Nru glib2.0-2.59.2/glib/gkeyfile.h glib2.0-2.59.3/glib/gkeyfile.h --- glib2.0-2.59.2/glib/gkeyfile.h 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/gkeyfile.h 2019-03-04 09:01:42.000000000 +0000 @@ -298,6 +298,7 @@ /* Defines for handling freedesktop.org Desktop files */ #define G_KEY_FILE_DESKTOP_GROUP "Desktop Entry" +#define G_KEY_FILE_DESKTOP_ACTION_GROUP_PREFIX "Desktop Action" #define G_KEY_FILE_DESKTOP_KEY_TYPE "Type" #define G_KEY_FILE_DESKTOP_KEY_VERSION "Version" @@ -320,6 +321,9 @@ #define G_KEY_FILE_DESKTOP_KEY_URL "URL" #define G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE "DBusActivatable" #define G_KEY_FILE_DESKTOP_KEY_ACTIONS "Actions" +#define G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN "X-GNOME-Gettext-Domain" +#define G_KEY_FILE_DESKTOP_KEY_FULLNAME "X-GNOME-FullName" +#define G_KEY_FILE_DESKTOP_KEY_KEYWORDS "Keywords" #define G_KEY_FILE_DESKTOP_TYPE_APPLICATION "Application" #define G_KEY_FILE_DESKTOP_TYPE_LINK "Link" diff -Nru glib2.0-2.59.2/glib/gmacros.h glib2.0-2.59.3/glib/gmacros.h --- glib2.0-2.59.2/glib/gmacros.h 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/gmacros.h 2019-03-04 09:01:42.000000000 +0000 @@ -304,10 +304,10 @@ #endif /* Provide a string identifying the current function, non-concatenatable */ -#if defined (__GNUC__) && defined (__cplusplus) -#define G_STRFUNC ((const char*) (__PRETTY_FUNCTION__)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#if defined (__func__) #define G_STRFUNC ((const char*) (__func__)) +#elif defined (__GNUC__) && defined (__cplusplus) +#define G_STRFUNC ((const char*) (__PRETTY_FUNCTION__)) #elif defined (__GNUC__) || (defined(_MSC_VER) && (_MSC_VER > 1300)) #define G_STRFUNC ((const char*) (__FUNCTION__)) #else diff -Nru glib2.0-2.59.2/glib/gosxutils.m glib2.0-2.59.3/glib/gosxutils.m --- glib2.0-2.59.2/glib/gosxutils.m 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/glib/gosxutils.m 2019-03-04 09:01:42.000000000 +0000 @@ -0,0 +1,58 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2018-2019 Patrick Griffis, James Westman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + */ + +#include "config.h" + +#ifndef HAVE_COCOA +#error "Can only build gutils-macos.m on MacOS" +#endif + +#include +#include "gutils.h" +#include "gstrfuncs.h" + +static gchar * +find_folder (NSSearchPathDirectory type) +{ + gchar *filename; + NSString *path; + NSArray *paths; + + paths = NSSearchPathForDirectoriesInDomains (type, NSUserDomainMask, YES); + path = [paths firstObject]; + if (path == nil) + { + return NULL; + } + + filename = g_strdup ([path UTF8String]); + + return filename; +} + +void +load_user_special_dirs_macos(gchar **table) +{ + table[G_USER_DIRECTORY_DESKTOP] = find_folder (NSDesktopDirectory); + table[G_USER_DIRECTORY_DOCUMENTS] = find_folder (NSDocumentDirectory); + table[G_USER_DIRECTORY_DOWNLOAD] = find_folder (NSDownloadsDirectory); + table[G_USER_DIRECTORY_MUSIC] = find_folder (NSMusicDirectory); + table[G_USER_DIRECTORY_PICTURES] = find_folder (NSPicturesDirectory); + table[G_USER_DIRECTORY_PUBLIC_SHARE] = find_folder (NSSharedPublicDirectory); + table[G_USER_DIRECTORY_TEMPLATES] = NULL; + table[G_USER_DIRECTORY_VIDEOS] = find_folder (NSMoviesDirectory); +} \ No newline at end of file diff -Nru glib2.0-2.59.2/glib/gspawn.c glib2.0-2.59.3/glib/gspawn.c --- glib2.0-2.59.2/glib/gspawn.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/gspawn.c 2019-03-04 09:01:42.000000000 +0000 @@ -633,7 +633,7 @@ * a command line, and the C runtime startup code does a corresponding * reconstruction of an argument vector from the command line, to be * passed to main(). Complications arise when you have argument vector - * elements that contain spaces of double quotes. The spawn*() functions + * elements that contain spaces or double quotes. The `spawn*()` functions * don't do any quoting or escaping, but on the other hand the startup * code does do unquoting and unescaping in order to enable receiving * arguments with embedded spaces or double quotes. To work around this diff -Nru glib2.0-2.59.2/glib/gstring.c glib2.0-2.59.3/glib/gstring.c --- glib2.0-2.59.2/glib/gstring.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/gstring.c 2019-03-04 09:01:42.000000000 +0000 @@ -407,16 +407,18 @@ * @pos: position in @string where insertion should * happen, or -1 for at the end * @val: bytes to insert - * @len: number of bytes of @val to insert + * @len: number of bytes of @val to insert, or -1 for all of @val * * Inserts @len bytes of @val into @string at @pos. - * Because @len is provided, @val may contain embedded - * nuls and need not be nul-terminated. If @pos is -1, - * bytes are inserted at the end of the string. - * - * Since this function does not stop at nul bytes, it is - * the caller's responsibility to ensure that @val has at - * least @len addressable bytes. + * + * If @len is positive, @val may contain embedded nuls and need + * not be nul-terminated. It is the caller's responsibility to + * ensure that @val has at least @len addressable bytes. + * + * If @len is negative, @val must be nul-terminated and @len + * is considered to request the entire string length. + * + * If @pos is -1, bytes are inserted at the end of the string. * * Returns: (transfer none): @string */ @@ -600,15 +602,17 @@ * g_string_append_len: * @string: a #GString * @val: bytes to append - * @len: number of bytes of @val to use + * @len: number of bytes of @val to use, or -1 for all of @val + * + * Appends @len bytes of @val to @string. + * + * If @len is positive, @val may contain embedded nuls and need + * not be nul-terminated. It is the caller's responsibility to + * ensure that @val has at least @len addressable bytes. * - * Appends @len bytes of @val to @string. Because @len is - * provided, @val may contain embedded nuls and need not - * be nul-terminated. - * - * Since this function does not stop at nul bytes, it is - * the caller's responsibility to ensure that @val has at - * least @len addressable bytes. + * If @len is negative, @val must be nul-terminated and @len + * is considered to request the entire string length. This + * makes g_string_append_len() equivalent to g_string_append(). * * Returns: (transfer none): @string */ @@ -680,15 +684,17 @@ * g_string_prepend_len: * @string: a #GString * @val: bytes to prepend - * @len: number of bytes in @val to prepend + * @len: number of bytes in @val to prepend, or -1 for all of @val * * Prepends @len bytes of @val to @string. - * Because @len is provided, @val may contain - * embedded nuls and need not be nul-terminated. * - * Since this function does not stop at nul bytes, - * it is the caller's responsibility to ensure that - * @val has at least @len addressable bytes. + * If @len is positive, @val may contain embedded nuls and need + * not be nul-terminated. It is the caller's responsibility to + * ensure that @val has at least @len addressable bytes. + * + * If @len is negative, @val must be nul-terminated and @len + * is considered to request the entire string length. This + * makes g_string_prepend_len() equivalent to g_string_prepend(). * * Returns: (transfer none): @string */ diff -Nru glib2.0-2.59.2/glib/gutils.c glib2.0-2.59.3/glib/gutils.c --- glib2.0-2.59.2/glib/gutils.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/gutils.c 2019-03-04 09:01:42.000000000 +0000 @@ -120,10 +120,6 @@ # include #endif -#ifdef HAVE_CARBON -#include -#endif - #ifdef HAVE_CODESET #include #endif @@ -801,7 +797,9 @@ gchar *home_dir; /* We first check HOME and use it if it is set */ - home_dir = g_strdup (g_getenv ("HOME")); + home_dir = g_strdup (g_getenv ("G_HOME")); + if (!home_dir) + home_dir = g_strdup (g_getenv ("HOME")); #ifdef G_OS_WIN32 /* Only believe HOME if it is an absolute path and exists. @@ -889,6 +887,12 @@ * should either directly check the `HOME` environment variable yourself * or unset it before calling any functions in GLib. * + * When the pre-2.36 behaviour was in effect, Debian provided the + * G_HOME environment variable for testing and development + * purposes. This is now unnecessary as HOME can be used + * directly, but is retained for compatibility. It is deprecated and will be + * removed in a future release. + * * Returns: (type filename): the current user's home directory */ const gchar * @@ -1519,56 +1523,15 @@ return user_runtime_dir; } -#ifdef HAVE_CARBON - -static gchar * -find_folder (OSType type) -{ - gchar *filename = NULL; - FSRef found; - - if (FSFindFolder (kUserDomain, type, kDontCreateFolder, &found) == noErr) - { - CFURLRef url = CFURLCreateFromFSRef (kCFAllocatorSystemDefault, &found); - - if (url) - { - CFStringRef path = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle); +#ifdef HAVE_COCOA - if (path) - { - filename = g_strdup (CFStringGetCStringPtr (path, kCFStringEncodingUTF8)); - - if (! filename) - { - filename = g_new0 (gchar, CFStringGetLength (path) * 3 + 1); - - CFStringGetCString (path, filename, - CFStringGetLength (path) * 3 + 1, - kCFStringEncodingUTF8); - } - - CFRelease (path); - } - - CFRelease (url); - } - } - - return filename; -} +/* Implemented in gutils-macos.m */ +void load_user_special_dirs_macos (gchar **table); static void load_user_special_dirs (void) { - g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = find_folder (kDesktopFolderType); - g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = find_folder (kDocumentsFolderType); - g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = find_folder (kDesktopFolderType); /* XXX correct ? */ - g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = find_folder (kMusicDocumentsFolderType); - g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = find_folder (kPictureDocumentsFolderType); - g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = NULL; - g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = NULL; - g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = find_folder (kMovieDocumentsFolderType); + load_user_special_dirs_macos (g_user_special_dirs); } #elif defined(G_OS_WIN32) diff -Nru glib2.0-2.59.2/glib/gvariant-parser.c glib2.0-2.59.3/glib/gvariant-parser.c --- glib2.0-2.59.2/glib/gvariant-parser.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/gvariant-parser.c 2019-03-04 09:01:42.000000000 +0000 @@ -1921,6 +1921,8 @@ case 'n': if (abs_val - negative > G_MAXINT16) return number_overflow (ast, type, error); + if (negative && abs_val > G_MAXINT16) + return g_variant_new_int16 (G_MININT16); return g_variant_new_int16 (negative ? -((gint16) abs_val) : abs_val); case 'q': @@ -1931,6 +1933,8 @@ case 'i': if (abs_val - negative > G_MAXINT32) return number_overflow (ast, type, error); + if (negative && abs_val > G_MAXINT32) + return g_variant_new_int32 (G_MININT32); return g_variant_new_int32 (negative ? -((gint32) abs_val) : abs_val); case 'u': @@ -1941,6 +1945,8 @@ case 'x': if (abs_val - negative > G_MAXINT64) return number_overflow (ast, type, error); + if (negative && abs_val > G_MAXINT64) + return g_variant_new_int64 (G_MININT64); return g_variant_new_int64 (negative ? -((gint64) abs_val) : abs_val); case 't': @@ -1951,6 +1957,8 @@ case 'h': if (abs_val - negative > G_MAXINT32) return number_overflow (ast, type, error); + if (negative && abs_val > G_MAXINT32) + return g_variant_new_handle (G_MININT32); return g_variant_new_handle (negative ? -((gint32) abs_val) : abs_val); default: diff -Nru glib2.0-2.59.2/glib/libcharset/.gitignore glib2.0-2.59.3/glib/libcharset/.gitignore --- glib2.0-2.59.2/glib/libcharset/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/libcharset/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -charset.alias -ref-add.sed -ref-del.sed diff -Nru glib2.0-2.59.2/glib/meson.build glib2.0-2.59.3/glib/meson.build --- glib2.0-2.59.2/glib/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -230,6 +230,10 @@ platform_deps = [] endif +if host_system == 'darwin' + glib_sources += files('gosxutils.m') +endif + glib_sources += files('gthread-@0@.c'.format(threads_implementation)) if enable_dtrace @@ -254,6 +258,7 @@ pcre_objects = [libpcre.extract_all_objects()] endif +glib_c_args = ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre_static_args + glib_hidden_visibility_args libglib = library('glib-2.0', glib_dtrace_obj, glib_dtrace_hdr, sources : [deprecated_sources, glib_sources], @@ -266,7 +271,8 @@ link_args : [noseh_link_args, glib_link_flags, win32_ldflags], include_directories : configinc, dependencies : pcre_deps + [thread_dep, libintl, librt] + libiconv + platform_deps, - c_args : ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre_static_args + glib_hidden_visibility_args + c_args : glib_c_args, + objc_args : glib_c_args, ) libglib_dep = declare_dependency( diff -Nru glib2.0-2.59.2/glib/tests/.gitignore glib2.0-2.59.3/glib/tests/.gitignore --- glib2.0-2.59.2/glib/tests/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -1bit-emufutex -1bit-mutex -642026 -642026-ec -array-test -asyncqueue -atomic -autoptr -base64 -bitlock -bookmarkfile -bytes -cache -checksum -collate -cond -convert -dataset -date -dir -environment -error -fileutils -gdatetime -guuid -gvariant -gwakeup -gwakeup-fallback -hash -hmac -hook -hostutils -include -keyfile -list -logging -mainloop -malloc -mappedfile -markup -markup-collect -markup-escape -markup-parse -markup-subparser -mem-overflow -mutex -node -once -option-argv0 -option-context -overflow -overflow-fallback -pattern -private -protocol -queue -rand -rec-mutex -regex -rwlock -scannerapi -search-utils -sequence -shell -slice -slist -sort -spawn-multithreaded -spawn-singlethread -strfuncs -string -testing -test-printf -test-spawn-echo -thread -timeout -timer -tmpsample.xml -tree -unicode -unix -unix-multithreaded -unix-nothreads -uri -utf8-misc -utf8-performance -utf8-pointer -utf8-validate -utils diff -Nru glib2.0-2.59.2/glib/tests/gvariant.c glib2.0-2.59.3/glib/tests/gvariant.c --- glib2.0-2.59.2/glib/tests/gvariant.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/gvariant.c 2019-03-04 09:01:42.000000000 +0000 @@ -4097,6 +4097,38 @@ } } +/* Test that parsing GVariant text format integers works at the boundaries of + * those integer types. We’re especially interested in the handling of the most + * negative numbers, since those can’t be represented in sign + absolute value + * form. */ +static void +test_parser_integer_bounds (void) +{ + GVariant *value = NULL; + GError *local_error = NULL; + +#define test_bound(TYPE, type, text, expected_value) \ + value = g_variant_parse (G_VARIANT_TYPE_##TYPE, text, NULL, NULL, &local_error); \ + g_assert_no_error (local_error); \ + g_assert_nonnull (value); \ + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_##TYPE)); \ + g_assert_cmpint (g_variant_get_##type (value), ==, expected_value); \ + g_variant_unref (value) + + test_bound (BYTE, byte, "0", 0); + test_bound (BYTE, byte, "255", G_MAXUINT8); + test_bound (INT16, int16, "-32768", G_MININT16); + test_bound (INT16, int16, "32767", G_MAXINT16); + test_bound (INT32, int32, "-2147483648", G_MININT32); + test_bound (INT32, int32, "2147483647", G_MAXINT32); + test_bound (INT64, int64, "-9223372036854775808", G_MININT64); + test_bound (INT64, int64, "9223372036854775807", G_MAXINT64); + test_bound (HANDLE, handle, "-2147483648", G_MININT32); + test_bound (HANDLE, handle, "2147483647", G_MAXINT32); + +#undef test_bound +} + static void test_parse_bad_format_char (void) { @@ -5068,6 +5100,7 @@ g_test_add_func ("/gvariant/hashing", test_hashing); g_test_add_func ("/gvariant/byteswap", test_gv_byteswap); g_test_add_func ("/gvariant/parser", test_parses); + g_test_add_func ("/gvariant/parser/integer-bounds", test_parser_integer_bounds); g_test_add_func ("/gvariant/parse-failures", test_parse_failures); g_test_add_func ("/gvariant/parse-positional", test_parse_positional); g_test_add_func ("/gvariant/parse/subprocess/bad-format-char", test_parse_bad_format_char); diff -Nru glib2.0-2.59.2/glib/tests/gwakeuptest.c glib2.0-2.59.3/glib/tests/gwakeuptest.c --- glib2.0-2.59.2/glib/tests/gwakeuptest.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/gwakeuptest.c 2019-03-04 09:01:42.000000000 +0000 @@ -89,6 +89,9 @@ #define NUM_TOKENS 5 #define TOKEN_TTL 100000 +static gint num_threads = NUM_THREADS; +static gint token_ttl = TOKEN_TTL; + static struct context contexts[NUM_THREADS]; static GThread *threads[NUM_THREADS]; static GWakeup *last_token_wakeup; @@ -158,7 +161,7 @@ struct context *ctx; gint next_ctx; - next_ctx = g_test_rand_int_range (0, NUM_THREADS); + next_ctx = g_test_rand_int_range (0, num_threads); ctx = &contexts[next_ctx]; token->owner = ctx; token->ttl--; @@ -213,6 +216,12 @@ { gint i; + if (!g_test_slow ()) + { + num_threads = NUM_THREADS / 10; + token_ttl = TOKEN_TTL / 10; + } + /* make sure we don't block forever */ alarm (60); @@ -230,7 +239,7 @@ last_token_wakeup = g_wakeup_new (); /* create contexts, assign to threads */ - for (i = 0; i < NUM_THREADS; i++) + for (i = 0; i < num_threads; i++) { context_init (&contexts[i]); threads[i] = g_thread_new ("test", thread_func, &contexts[i]); @@ -238,13 +247,13 @@ /* dispatch tokens */ for (i = 0; i < NUM_TOKENS; i++) - dispatch_token (token_new (TOKEN_TTL)); + dispatch_token (token_new (token_ttl)); /* wait until all tokens are gone */ wait_for_signaled (last_token_wakeup); /* ask threads to quit, join them, cleanup */ - for (i = 0; i < NUM_THREADS; i++) + for (i = 0; i < num_threads; i++) { context_quit (&contexts[i]); g_thread_join (threads[i]); diff -Nru glib2.0-2.59.2/glib/tests/mainloop.c glib2.0-2.59.3/glib/tests/mainloop.c --- glib2.0-2.59.2/glib/tests/mainloop.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/mainloop.c 2019-03-04 09:01:42.000000000 +0000 @@ -168,6 +168,14 @@ GMainLoop *loop; GSource *source; +#if defined(__arm__) + if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) + { + g_test_skip ("Not reliable on older ARM hardware"); + return; + } +#endif + a = b = c = 0; ctx = g_main_context_new (); @@ -451,6 +459,14 @@ GMainLoop *loop; GSource *parent, *child_b, *child_c, *end; +#if defined(__arm__) + if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) + { + g_test_skip ("Not reliable on older ARM hardware"); + return; + } +#endif + ctx = g_main_context_new (); loop = g_main_loop_new (ctx, FALSE); @@ -529,6 +545,14 @@ GMainLoop *loop; GSource *parent, *child_b, *child_c, *end; +#if defined(__arm__) + if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) + { + g_test_skip ("Not reliable on older ARM hardware"); + return; + } +#endif + ctx = g_main_context_new (); loop = g_main_loop_new (ctx, FALSE); diff -Nru glib2.0-2.59.2/glib/tests/meson.build glib2.0-2.59.3/glib/tests/meson.build --- glib2.0-2.59.2/glib/tests/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -183,6 +183,7 @@ test_conf = configuration_data() test_conf.set('installed_tests_dir', installed_tests_execdir) test_conf.set('program', test_name) + test_conf.set('env', '') configure_file( input: installed_tests_template_tap, output: test_name + '.test', diff -Nru glib2.0-2.59.2/glib/tests/protocol.c glib2.0-2.59.3/glib/tests/protocol.c --- glib2.0-2.59.2/glib/tests/protocol.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/protocol.c 2019-03-04 09:01:42.000000000 +0000 @@ -162,7 +162,11 @@ tlb = g_test_log_buffer_new (); loop = g_main_loop_new (NULL, FALSE); +#ifdef G_OS_WIN32 + channel = g_io_channel_win32_new_fd (pipes[0]); +#else channel = g_io_channel_unix_new (pipes[0]); +#endif g_io_channel_set_close_on_unref (channel, TRUE); g_io_channel_set_encoding (channel, NULL, NULL); g_io_channel_set_buffered (channel, FALSE); @@ -285,7 +289,11 @@ tlb = g_test_log_buffer_new (); loop = g_main_loop_new (NULL, FALSE); +#ifdef G_OS_WIN32 + channel = g_io_channel_win32_new_fd (pipes[0]); +#else channel = g_io_channel_unix_new (pipes[0]); +#endif g_io_channel_set_close_on_unref (channel, TRUE); g_io_channel_set_encoding (channel, NULL, NULL); g_io_channel_set_buffered (channel, FALSE); diff -Nru glib2.0-2.59.2/glib/tests/testing-helper.c glib2.0-2.59.3/glib/tests/testing-helper.c --- glib2.0-2.59.2/glib/tests/testing-helper.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/testing-helper.c 2019-03-04 09:01:42.000000000 +0000 @@ -17,6 +17,11 @@ */ #include +#ifdef G_OS_WIN32 +#include +#include +#include +#endif static void test_pass (void) @@ -47,6 +52,14 @@ { char *argv1; +#ifdef G_OS_WIN32 + /* Windows opens std streams in text mode, with \r\n EOLs. + * Sometimes it's easier to force a switch to binary mode than + * to account for extra \r in testcases. + */ + setmode (fileno (stdout), O_BINARY); +#endif + g_return_val_if_fail (argc > 1, 1); argv1 = argv[1]; diff -Nru glib2.0-2.59.2/glib/tests/thread.c glib2.0-2.59.3/glib/tests/thread.c --- glib2.0-2.59.2/glib/tests/thread.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/thread.c 2019-03-04 09:01:42.000000000 +0000 @@ -147,8 +147,11 @@ getrlimit (RLIMIT_NPROC, &nl); nl.rlim_cur = 1; - if ((ret = prlimit (getpid (), RLIMIT_NPROC, &nl, &ol)) != 0) - g_error ("prlimit failed: %s", g_strerror (errno)); + if ((ret = prlimit (getpid(), RLIMIT_NPROC, &nl, &ol)) != 0) + { + g_debug ("prlimit failed: %s\n", g_strerror (errno)); + return; + } error = NULL; thread = g_thread_try_new ("a", thread1_func, NULL, &error); diff -Nru glib2.0-2.59.2/glib/tests/timeout.c glib2.0-2.59.3/glib/tests/timeout.c --- glib2.0-2.59.2/glib/tests/timeout.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/timeout.c 2019-03-04 09:01:42.000000000 +0000 @@ -175,6 +175,15 @@ static void test_rounding (void) { + +#if defined(__arm__) + if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) + { + g_test_skip ("Not reliable on older ARM hardware"); + return; + } +#endif + loop = g_main_loop_new (NULL, FALSE); last_time = g_get_monotonic_time (); diff -Nru glib2.0-2.59.2/glib/tests/timer.c glib2.0-2.59.3/glib/tests/timer.c --- glib2.0-2.59.2/glib/tests/timer.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/glib/tests/timer.c 2019-03-04 09:01:42.000000000 +0000 @@ -27,9 +27,15 @@ test_timer_basic (void) { GTimer *timer; - gdouble elapsed; + volatile gdouble elapsed; gulong micros; + if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") == NULL) + { + g_test_skip ("Not reliable due to floating-point rounding (glib#820)"); + return; + } + timer = g_timer_new (); elapsed = g_timer_elapsed (timer, µs); @@ -44,7 +50,7 @@ test_timer_stop (void) { GTimer *timer; - gdouble elapsed, elapsed2; + volatile gdouble elapsed, elapsed2; timer = g_timer_new (); diff -Nru glib2.0-2.59.2/gmodule/.gitignore glib2.0-2.59.3/gmodule/.gitignore --- glib2.0-2.59.2/gmodule/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gmodule/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -gmoduleconf.h diff -Nru glib2.0-2.59.2/gobject/.gitignore glib2.0-2.59.3/gobject/.gitignore --- glib2.0-2.59.2/gobject/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gobject/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -glib-genmarshal -glib-mkenums -gmarshal.strings -gobject-query -testgobject -libgobject-gdb.py -gobject_probes.h -gobject-public-headers.txt diff -Nru glib2.0-2.59.2/gobject/tests/.gitignore glib2.0-2.59.3/gobject/tests/.gitignore --- glib2.0-2.59.2/gobject/tests/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gobject/tests/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -binding -boxed -closure -dynamictests -enums -ifaceproperties -object -param -properties -qdata -reference -signal-handler -signals -threadtests -type -value -private -marshalers.[ch] diff -Nru glib2.0-2.59.2/gobject/tests/meson.build glib2.0-2.59.3/gobject/tests/meson.build --- glib2.0-2.59.2/gobject/tests/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/gobject/tests/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -77,6 +77,7 @@ test_conf = configuration_data() test_conf.set('installed_tests_dir', installed_tests_execdir) test_conf.set('program', test_name) + test_conf.set('env', '') configure_file( input: installed_tests_template_tap, output: test_name + '.test', diff -Nru glib2.0-2.59.2/meson.build glib2.0-2.59.3/meson.build --- glib2.0-2.59.2/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -1,5 +1,5 @@ project('glib', 'c', 'cpp', - version : '2.59.2', + version : '2.59.3', meson_version : '>= 0.48.0', default_options : [ 'buildtype=debugoptimized', @@ -1893,6 +1893,9 @@ have_bash = find_program('bash', required : false).found() # For completion scripts have_sh = find_program('sh', required : false).found() # For glib-gettextize +# Some installed tests require a custom environment +env_program = find_program('env', required: installed_tests_enabled) + # FIXME: How to detect Solaris? https://github.com/mesonbuild/meson/issues/1578 if host_system == 'sunos' glib_conf.set('_XOPEN_SOURCE_EXTENDED', 1) diff -Nru glib2.0-2.59.2/NEWS glib2.0-2.59.3/NEWS --- glib2.0-2.59.2/NEWS 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/NEWS 2019-03-04 09:01:41.000000000 +0000 @@ -1,3 +1,52 @@ +Overview of changes in GLib 2.59.3 +================================== + +* Fix support for g_get_user_special_dir() on macOS, including support for the Downloads directory (#1048) + +* Ensure that cancelling a GTask cannot cause its callback to be called synchronously (in the same call chain as the original *_async() call) (#1608) + +* Further fixes to the Happy Eyeballs (RFC 8305) implementation (#1644, #1680) + +* Various fixes for installation of installed tests (thanks to Iain Lane) (!649, !651) + +* Various fixes for tests when run on Windows (thanks to LRN) (!665, !667) + +* Bugs fixed: + - #535 gmacros: Try to use the standard __func__ first in G_STRFUNC + - #875 gio-gvfs on Windows: Don't mishandle other non-native URIs in gwinhttpvfs.c + - #1048 "Desktop" shortcut appears twice in file chooser sidebar on OSX + - #1608 Cancellation might not be asynchronous under certain circumstances + - #1644 network-address test failure in CI: IPv6 Broken (g-io-error-quark, 24) + - #1680 Regression: g_socket_client_connect_to_host_async() sometimes gets "Connection refused" when connecting to localhost + - #1686 gdbus-peer test is sometimes timing out + - !613 Use win32 io channel on windows for the protocol test + - !634 Win32: gio/gsocket.c: Set WSAEWOULDBLOCK on G_POLLABLE_RETURN_WOULD_BLOCK + - !638 gvariant-parser: Fix parsing of G_MININT* values in GVariant text format + - !640 tests: Tag socket-service test as ‘flaky’ + - !641 Minor typo fixes to GSpawn documentation + - !645 gsocketlistener: Fix multiple returns of GTask when accepting sockets + - !647 gsocketclient: Ensure task is always returned on cancel + - !648 gio/tests/task: Run the worker indefinitely until it's cancelled + - !649 gio tests: Install test1.overlay file when building installed tests + - !650 gstring: fully document semantics of @len for g_string_insert_len + - !651 tests: Install the slow-connect-preload.so library and use it + - !667 GSubprocess fixes for W32 test suite + - !668 tests: Mark gdbus-peer test as flaky + - !669 GWin32VolumeMonitor: Sort the volumes correctly + - !670 gpollableoutputstream: Fix the description of the interface + - !672 Fix some tests when running as root + +* Translation updates: + - Catalan + - Danish + - French + - Indonesian + - Kazakh + - Portuguese (Brazil) + - Slovenian + - Turkish + + Overview of changes in GLib 2.59.2 ================================== diff -Nru glib2.0-2.59.2/.pc/0001-timer-test-use-volatile-for-locals.patch/glib/tests/timer.c glib2.0-2.59.3/.pc/0001-timer-test-use-volatile-for-locals.patch/glib/tests/timer.c --- glib2.0-2.59.2/.pc/0001-timer-test-use-volatile-for-locals.patch/glib/tests/timer.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/0001-timer-test-use-volatile-for-locals.patch/glib/tests/timer.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,291 @@ +/* Unit tests for GTimer + * Copyright (C) 2013 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Matthias Clasen + */ + +#include "glib.h" + +static void +test_timer_basic (void) +{ + GTimer *timer; + gdouble elapsed; + gulong micros; + + timer = g_timer_new (); + + elapsed = g_timer_elapsed (timer, µs); + + g_assert_cmpfloat (elapsed, <, 1.0); + g_assert_cmpuint (micros, ==, ((guint64)(elapsed * 1e6)) % 1000000); + + g_timer_destroy (timer); +} + +static void +test_timer_stop (void) +{ + GTimer *timer; + gdouble elapsed, elapsed2; + + timer = g_timer_new (); + + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_usleep (100); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, ==, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timer_continue (void) +{ + GTimer *timer; + gdouble elapsed, elapsed2; + + timer = g_timer_new (); + g_usleep (100); + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_timer_continue (timer); + g_usleep (100); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, <, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timer_reset (void) +{ + GTimer *timer; + gdouble elapsed, elapsed2; + + timer = g_timer_new (); + g_usleep (100); + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_timer_reset (timer); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, >, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timeval_add (void) +{ + GTimeVal time = { 1, 0 }; + + g_time_val_add (&time, 10); + + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 10); + + g_time_val_add (&time, -500); + g_assert_cmpint (time.tv_sec, ==, 0); + g_assert_cmpint (time.tv_usec, ==, G_USEC_PER_SEC - 490); + + g_time_val_add (&time, 1000); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 510); + + g_time_val_add (&time, 0); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 510); + + g_time_val_add (&time, -210); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 300); +} + +typedef struct { + gboolean success; + const gchar *in; + GTimeVal val; +} TimeValParseTest; + +static void +test_timeval_from_iso8601 (void) +{ + gchar *old_tz = g_strdup (g_getenv ("TZ")); + TimeValParseTest tests[] = { + { TRUE, "1990-11-01T10:21:17Z", { 657454877, 0 } }, + { TRUE, "19901101T102117Z", { 657454877, 0 } }, + { TRUE, "19901101T102117+5", { 657454577, 0 } }, + { TRUE, "19901101T102117+3:15", { 657443177, 0 } }, + { TRUE, " 1990-11-01T10:21:17Z ", { 657454877, 0 } }, + { TRUE, "1970-01-01T00:00:17.12Z", { 17, 120000 } }, + { TRUE, "1970-01-01T00:00:17.1234Z", { 17, 123400 } }, + { TRUE, "1970-01-01T00:00:17.123456Z", { 17, 123456 } }, + { TRUE, "1980-02-22T12:36:00+02:00", { 320063760, 0 } }, + { FALSE, " ", { 0, 0 } }, + { FALSE, "x", { 0, 0 } }, + { FALSE, "123x", { 0, 0 } }, + { FALSE, "2001-10+x", { 0, 0 } }, + { FALSE, "1980-02-22T", { 0, 0 } }, + { FALSE, "2001-10-08Tx", { 0, 0 } }, + { FALSE, "2001-10-08T10:11x", { 0, 0 } }, + { FALSE, "Wed Dec 19 17:20:20 GMT 2007", { 0, 0 } }, + { FALSE, "1980-02-22T10:36:00Zulu", { 0, 0 } }, + { FALSE, "2T0+819855292164632335", { 0, 0 } }, + { TRUE, "2018-08-03T14:08:05.446178377+01:00", { 1533301685, 446178 } }, + { FALSE, "2147483648-08-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-13-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-00-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-00T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-32T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T24:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:60:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:63.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:05.446178377+100:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:05.446178377+01:60", { 0, 0 } }, + { TRUE, "20180803T140805.446178377+0100", { 1533301685, 446178 } }, + { FALSE, "21474836480803T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20181303T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180003T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180800T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180832T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T240805.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T146005.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T140863.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T140805.446178377+10000", { 0, 0 } }, + { FALSE, "20180803T140805.446178377+0160", { 0, 0 } }, + { TRUE, "+1980-02-22T12:36:00+02:00", { 320063760, 0 } }, + { FALSE, "-0005-01-01T00:00:00Z", { 0, 0 } }, + { FALSE, "2018-08-06", { 0, 0 } }, + { FALSE, "2018-08-06 13:51:00Z", { 0, 0 } }, + { TRUE, "20180803T140805,446178377+0100", { 1533301685, 446178 } }, + { TRUE, "2018-08-03T14:08:05.446178377-01:00", { 1533308885, 446178 } }, + { FALSE, "2018-08-03T14:08:05.446178377 01:00", { 0, 0 } }, + { TRUE, "1990-11-01T10:21:17", { 657454877, 0 } }, + { TRUE, "1990-11-01T10:21:17 ", { 657454877, 0 } }, + }; + GTimeVal out; + gboolean success; + gint i; + + /* Always run in UTC so the comparisons of parsed values are valid. */ + if (!g_setenv ("TZ", "UTC", TRUE)) + { + g_test_skip ("Failed to set TZ=UTC"); + return; + } + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + out.tv_sec = 0; + out.tv_usec = 0; + success = g_time_val_from_iso8601 (tests[i].in, &out); + g_assert (success == tests[i].success); + if (tests[i].success) + { + g_assert_cmpint (out.tv_sec, ==, tests[i].val.tv_sec); + g_assert_cmpint (out.tv_usec, ==, tests[i].val.tv_usec); + } + } + + if (old_tz != NULL) + g_assert_true (g_setenv ("TZ", old_tz, TRUE)); + else + g_unsetenv ("TZ"); + + g_free (old_tz); +} + +typedef struct { + GTimeVal val; + const gchar *expected; +} TimeValFormatTest; + +static void +test_timeval_to_iso8601 (void) +{ + TimeValFormatTest tests[] = { + { { 657454877, 0 }, "1990-11-01T10:21:17Z" }, + { { 17, 123400 }, "1970-01-01T00:00:17.123400Z" } + }; + gint i; + gchar *out; + GTimeVal val; + gboolean ret; + + g_unsetenv ("TZ"); + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + out = g_time_val_to_iso8601 (&(tests[i].val)); + g_assert_cmpstr (out, ==, tests[i].expected); + + ret = g_time_val_from_iso8601 (out, &val); + g_assert (ret); + g_assert_cmpint (val.tv_sec, ==, tests[i].val.tv_sec); + g_assert_cmpint (val.tv_usec, ==, tests[i].val.tv_usec); + g_free (out); + } +} + +/* Test error handling for g_time_val_to_iso8601() on dates which are too large. */ +static void +test_timeval_to_iso8601_overflow (void) +{ + GTimeVal val; + gchar *out = NULL; + + if ((glong) G_MAXINT == G_MAXLONG) + { + g_test_skip ("G_MAXINT == G_MAXLONG - we can't make g_time_val_to_iso8601() overflow."); + return; + } + + g_unsetenv ("TZ"); + + val.tv_sec = G_MAXLONG; + val.tv_usec = G_USEC_PER_SEC - 1; + + out = g_time_val_to_iso8601 (&val); + g_assert_null (out); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/timer/basic", test_timer_basic); + g_test_add_func ("/timer/stop", test_timer_stop); + g_test_add_func ("/timer/continue", test_timer_continue); + g_test_add_func ("/timer/reset", test_timer_reset); + g_test_add_func ("/timeval/add", test_timeval_add); + g_test_add_func ("/timeval/from-iso8601", test_timeval_from_iso8601); + g_test_add_func ("/timeval/to-iso8601", test_timeval_to_iso8601); + g_test_add_func ("/timeval/to-iso8601/overflow", test_timeval_to_iso8601_overflow); + + return g_test_run (); +} diff -Nru glib2.0-2.59.2/.pc/01_gettext-desktopfiles.patch/glib/gkeyfile.c glib2.0-2.59.3/.pc/01_gettext-desktopfiles.patch/glib/gkeyfile.c --- glib2.0-2.59.2/.pc/01_gettext-desktopfiles.patch/glib/gkeyfile.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/01_gettext-desktopfiles.patch/glib/gkeyfile.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,4642 @@ +/* gkeyfile.c - key file parser + * + * Copyright 2004 Red Hat, Inc. + * Copyright 2009-2010 Collabora Ltd. + * Copyright 2009 Nokia Corporation + * + * Written by Ray Strode + * Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + */ + +#include "config.h" + +#include "gkeyfile.h" +#include "gutils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include + +#undef fstat +#define fstat(a,b) _fstati64(a,b) +#undef stat +#define stat _stati64 + +#ifndef S_ISREG +#define S_ISREG(mode) ((mode)&_S_IFREG) +#endif + +#endif /* G_OS_WIN23 */ + +#include "gconvert.h" +#include "gdataset.h" +#include "gerror.h" +#include "gfileutils.h" +#include "ghash.h" +#include "glibintl.h" +#include "glist.h" +#include "gslist.h" +#include "gmem.h" +#include "gmessages.h" +#include "gstdio.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "gutils.h" + + +/** + * SECTION:keyfile + * @title: Key-value file parser + * @short_description: parses .ini-like config files + * + * #GKeyFile lets you parse, edit or create files containing groups of + * key-value pairs, which we call "key files" for lack of a better name. + * Several freedesktop.org specifications use key files now, e.g the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec) + * and the + * [Icon Theme Specification](http://freedesktop.org/Standards/icon-theme-spec). + * + * The syntax of key files is described in detail in the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec), + * here is a quick summary: Key files + * consists of groups of key-value pairs, interspersed with comments. + * + * |[ + * # this is just an example + * # there can be comments before the first group + * + * [First Group] + * + * Name=Key File Example\tthis value shows\nescaping + * + * # localized strings are stored in multiple key-value pairs + * Welcome=Hello + * Welcome[de]=Hallo + * Welcome[fr_FR]=Bonjour + * Welcome[it]=Ciao + * Welcome[be@latin]=Hello + * + * [Another Group] + * + * Numbers=2;20;-200;0 + * + * Booleans=true;false;true;true + * ]| + * + * Lines beginning with a '#' and blank lines are considered comments. + * + * Groups are started by a header line containing the group name enclosed + * in '[' and ']', and ended implicitly by the start of the next group or + * the end of the file. Each key-value pair must be contained in a group. + * + * Key-value pairs generally have the form `key=value`, with the + * exception of localized strings, which have the form + * `key[locale]=value`, with a locale identifier of the + * form `lang_COUNTRY@MODIFIER` where `COUNTRY` and `MODIFIER` + * are optional. + * Space before and after the '=' character are ignored. Newline, tab, + * carriage return and backslash characters in value are escaped as \n, + * \t, \r, and \\\\, respectively. To preserve leading spaces in values, + * these can also be escaped as \s. + * + * Key files can store strings (possibly with localized variants), integers, + * booleans and lists of these. Lists are separated by a separator character, + * typically ';' or ','. To use the list separator character in a value in + * a list, it has to be escaped by prefixing it with a backslash. + * + * This syntax is obviously inspired by the .ini files commonly met + * on Windows, but there are some important differences: + * + * - .ini files use the ';' character to begin comments, + * key files use the '#' character. + * + * - Key files do not allow for ungrouped keys meaning only + * comments can precede the first group. + * + * - Key files are always encoded in UTF-8. + * + * - Key and Group names are case-sensitive. For example, a group called + * [GROUP] is a different from [group]. + * + * - .ini files don't have a strongly typed boolean entry type, + * they only have GetProfileInt(). In key files, only + * true and false (in lower case) are allowed. + * + * Note that in contrast to the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec), + * groups in key files may contain the same + * key multiple times; the last entry wins. Key files may also contain + * multiple groups with the same name; they are merged together. + * Another difference is that keys and group names in key files are not + * restricted to ASCII characters. + * + * Here is an example of loading a key file and reading a value: + * |[ + * g_autoptr(GError) error = NULL; + * g_autoptr(GKeyFile) key_file = g_key_file_new (); + * + * if (!g_key_file_load_from_file (key_file, "key-file.ini", flags, &error)) + * { + * if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + * g_warning ("Error loading key file: %s", error->message); + * return; + * } + * + * g_autofree gchar *val = g_key_file_get_string (key_file, "Group Name", "SomeKey", &error); + * if (val == NULL && + * !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) + * { + * g_warning ("Error finding key in key file: %s", error->message); + * return; + * } + * else if (val == NULL) + * { + * // Fall back to a default value. + * val = g_strdup ("default-value"); + * } + * ]| + * + * Here is an example of creating and saving a key file: + * |[ + * g_autoptr(GKeyFile) key_file = g_key_file_new (); + * const gchar *val = …; + * g_autoptr(GError) error = NULL; + * + * g_key_file_set_string (key_file, "Group Name", "SomeKey", val); + * + * // Save as a file. + * if (!g_key_file_save_to_file (key_file, "key-file.ini", &error)) + * { + * g_warning ("Error saving key file: %s", error->message); + * return; + * } + * + * // Or store to a GBytes for use elsewhere. + * gsize data_len; + * g_autofree guint8 *data = (guint8 *) g_key_file_to_data (key_file, &data_len, &error); + * if (data == NULL) + * { + * g_warning ("Error saving key file: %s", error->message); + * return; + * } + * g_autoptr(GBytes) bytes = g_bytes_new_take (g_steal_pointer (&data), data_len); + * ]| + */ + +/** + * G_KEY_FILE_ERROR: + * + * Error domain for key file parsing. Errors in this domain will + * be from the #GKeyFileError enumeration. + * + * See #GError for information on error domains. + */ + +/** + * GKeyFileError: + * @G_KEY_FILE_ERROR_UNKNOWN_ENCODING: the text being parsed was in + * an unknown encoding + * @G_KEY_FILE_ERROR_PARSE: document was ill-formed + * @G_KEY_FILE_ERROR_NOT_FOUND: the file was not found + * @G_KEY_FILE_ERROR_KEY_NOT_FOUND: a requested key was not found + * @G_KEY_FILE_ERROR_GROUP_NOT_FOUND: a requested group was not found + * @G_KEY_FILE_ERROR_INVALID_VALUE: a value could not be parsed + * + * Error codes returned by key file parsing. + */ + +/** + * GKeyFileFlags: + * @G_KEY_FILE_NONE: No flags, default behaviour + * @G_KEY_FILE_KEEP_COMMENTS: Use this flag if you plan to write the + * (possibly modified) contents of the key file back to a file; + * otherwise all comments will be lost when the key file is + * written back. + * @G_KEY_FILE_KEEP_TRANSLATIONS: Use this flag if you plan to write the + * (possibly modified) contents of the key file back to a file; + * otherwise only the translations for the current language will be + * written back. + * + * Flags which influence the parsing. + */ + +/** + * G_KEY_FILE_DESKTOP_GROUP: + * + * The name of the main group of a desktop entry file, as defined in the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec). + * Consult the specification for more + * details about the meanings of the keys below. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TYPE: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the type of the desktop entry. Usually + * #G_KEY_FILE_DESKTOP_TYPE_APPLICATION, + * #G_KEY_FILE_DESKTOP_TYPE_LINK, or + * #G_KEY_FILE_DESKTOP_TYPE_DIRECTORY. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_VERSION: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the version of the Desktop Entry Specification used for + * the desktop entry file. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NAME: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the specific name of the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the generic name of the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the desktop entry should be shown in menus. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_COMMENT: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the tooltip for the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_ICON: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the name of the icon to be displayed for the desktop + * entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_HIDDEN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the desktop entry has been deleted by the user. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of + * strings identifying the environments that should display the + * desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of + * strings identifying the environments that should not display the + * desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TRY_EXEC: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the file name of a binary on disk used to determine if the + * program is actually installed. It is only valid for desktop entries + * with the `Application` type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_EXEC: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the command line to execute. It is only valid for desktop + * entries with the `Application` type. + * + * Since: 2.14 + */ + + /** + * G_KEY_FILE_DESKTOP_KEY_PATH: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * containing the working directory to run the program in. It is only + * valid for desktop entries with the `Application` type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TERMINAL: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the program should be run in a terminal window. + * It is only valid for desktop entries with the + * `Application` type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_MIME_TYPE: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list + * of strings giving the MIME types supported by this desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_CATEGORIES: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list + * of strings giving the categories in which the desktop entry + * should be shown in a menu. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the application supports the + * [Startup Notification Protocol Specification](http://www.freedesktop.org/Standards/startup-notification-spec). + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is string + * identifying the WM class or name hint of a window that the application + * will create, which can be used to emulate Startup Notification with + * older applications. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_URL: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the URL to access. It is only valid for desktop entries + * with the `Link` type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean set to true + * if the application is D-Bus activatable. + * + * Since: 2.38 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_ACTIONS: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string list + * giving the available application actions. + * + * Since: 2.38 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_APPLICATION: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing applications. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_LINK: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing links to documents. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_DIRECTORY: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing directories. + * + * Since: 2.14 + */ + +typedef struct _GKeyFileGroup GKeyFileGroup; + +/** + * GKeyFile: + * + * The GKeyFile struct contains only private data + * and should not be accessed directly. + */ +struct _GKeyFile +{ + GList *groups; + GHashTable *group_hash; + + GKeyFileGroup *start_group; + GKeyFileGroup *current_group; + + GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */ + + gchar list_separator; + + GKeyFileFlags flags; + + gchar **locales; + + volatile gint ref_count; +}; + +typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair; + +struct _GKeyFileGroup +{ + const gchar *name; /* NULL for above first group (which will be comments) */ + + GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */ + + GList *key_value_pairs; + + /* Used in parallel with key_value_pairs for + * increased lookup performance + */ + GHashTable *lookup_map; +}; + +struct _GKeyFileKeyValuePair +{ + gchar *key; /* NULL for comments */ + gchar *value; +}; + +static gint find_file_in_data_dirs (const gchar *file, + const gchar **data_dirs, + gchar **output_file, + GError **error); +static gboolean g_key_file_load_from_fd (GKeyFile *key_file, + gint fd, + GKeyFileFlags flags, + GError **error); +static GList *g_key_file_lookup_group_node (GKeyFile *key_file, + const gchar *group_name); +static GKeyFileGroup *g_key_file_lookup_group (GKeyFile *key_file, + const gchar *group_name); + +static GList *g_key_file_lookup_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key); +static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key); + +static void g_key_file_remove_group_node (GKeyFile *key_file, + GList *group_node); +static void g_key_file_remove_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + GList *pair_node); + +static void g_key_file_add_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + GKeyFileKeyValuePair *pair); +static void g_key_file_add_key (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key, + const gchar *value); +static void g_key_file_add_group (GKeyFile *key_file, + const gchar *group_name); +static gboolean g_key_file_is_group_name (const gchar *name); +static gboolean g_key_file_is_key_name (const gchar *name); +static void g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair); +static gboolean g_key_file_line_is_comment (const gchar *line); +static gboolean g_key_file_line_is_group (const gchar *line); +static gboolean g_key_file_line_is_key_value_pair (const gchar *line); +static gchar *g_key_file_parse_value_as_string (GKeyFile *key_file, + const gchar *value, + GSList **separators, + GError **error); +static gchar *g_key_file_parse_string_as_value (GKeyFile *key_file, + const gchar *string, + gboolean escape_separator); +static gint g_key_file_parse_value_as_integer (GKeyFile *key_file, + const gchar *value, + GError **error); +static gchar *g_key_file_parse_integer_as_value (GKeyFile *key_file, + gint value); +static gdouble g_key_file_parse_value_as_double (GKeyFile *key_file, + const gchar *value, + GError **error); +static gboolean g_key_file_parse_value_as_boolean (GKeyFile *key_file, + const gchar *value, + GError **error); +static gchar *g_key_file_parse_boolean_as_value (GKeyFile *key_file, + gboolean value); +static gchar *g_key_file_parse_value_as_comment (GKeyFile *key_file, + const gchar *value, + gboolean is_final_line); +static gchar *g_key_file_parse_comment_as_value (GKeyFile *key_file, + const gchar *comment); +static void g_key_file_parse_key_value_pair (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static void g_key_file_parse_comment (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static void g_key_file_parse_group (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static gchar *key_get_locale (const gchar *key); +static void g_key_file_parse_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GError **error); +static void g_key_file_flush_parse_buffer (GKeyFile *key_file, + GError **error); + +G_DEFINE_QUARK (g-key-file-error-quark, g_key_file_error) + +static void +g_key_file_init (GKeyFile *key_file) +{ + key_file->current_group = g_slice_new0 (GKeyFileGroup); + key_file->groups = g_list_prepend (NULL, key_file->current_group); + key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal); + key_file->start_group = NULL; + key_file->parse_buffer = g_string_sized_new (128); + key_file->list_separator = ';'; + key_file->flags = 0; + key_file->locales = g_strdupv ((gchar **)g_get_language_names ()); +} + +static void +g_key_file_clear (GKeyFile *key_file) +{ + GList *tmp, *group_node; + + if (key_file->locales) + { + g_strfreev (key_file->locales); + key_file->locales = NULL; + } + + if (key_file->parse_buffer) + { + g_string_free (key_file->parse_buffer, TRUE); + key_file->parse_buffer = NULL; + } + + tmp = key_file->groups; + while (tmp != NULL) + { + group_node = tmp; + tmp = tmp->next; + g_key_file_remove_group_node (key_file, group_node); + } + + if (key_file->group_hash != NULL) + { + g_hash_table_destroy (key_file->group_hash); + key_file->group_hash = NULL; + } + + g_warn_if_fail (key_file->groups == NULL); +} + + +/** + * g_key_file_new: + * + * Creates a new empty #GKeyFile object. Use + * g_key_file_load_from_file(), g_key_file_load_from_data(), + * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to + * read an existing key file. + * + * Returns: (transfer full): an empty #GKeyFile. + * + * Since: 2.6 + **/ +GKeyFile * +g_key_file_new (void) +{ + GKeyFile *key_file; + + key_file = g_slice_new0 (GKeyFile); + key_file->ref_count = 1; + g_key_file_init (key_file); + + return key_file; +} + +/** + * g_key_file_set_list_separator: + * @key_file: a #GKeyFile + * @separator: the separator + * + * Sets the character which is used to separate + * values in lists. Typically ';' or ',' are used + * as separators. The default list separator is ';'. + * + * Since: 2.6 + */ +void +g_key_file_set_list_separator (GKeyFile *key_file, + gchar separator) +{ + g_return_if_fail (key_file != NULL); + + key_file->list_separator = separator; +} + + +/* Iterates through all the directories in *dirs trying to + * open file. When it successfully locates and opens a file it + * returns the file descriptor to the open file. It also + * outputs the absolute path of the file in output_file. + */ +static gint +find_file_in_data_dirs (const gchar *file, + const gchar **dirs, + gchar **output_file, + GError **error) +{ + const gchar **data_dirs, *data_dir; + gchar *path; + gint fd; + + path = NULL; + fd = -1; + + if (dirs == NULL) + return fd; + + data_dirs = dirs; + + while (data_dirs && (data_dir = *data_dirs) && fd == -1) + { + gchar *candidate_file, *sub_dir; + + candidate_file = (gchar *) file; + sub_dir = g_strdup (""); + while (candidate_file != NULL && fd == -1) + { + gchar *p; + + path = g_build_filename (data_dir, sub_dir, + candidate_file, NULL); + + fd = g_open (path, O_RDONLY, 0); + + if (fd == -1) + { + g_free (path); + path = NULL; + } + + candidate_file = strchr (candidate_file, '-'); + + if (candidate_file == NULL) + break; + + candidate_file++; + + g_free (sub_dir); + sub_dir = g_strndup (file, candidate_file - file - 1); + + for (p = sub_dir; *p != '\0'; p++) + { + if (*p == '-') + *p = G_DIR_SEPARATOR; + } + } + g_free (sub_dir); + data_dirs++; + } + + if (fd == -1) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_NOT_FOUND, + _("Valid key file could not be " + "found in search dirs")); + } + + if (output_file != NULL && fd != -1) + *output_file = g_strdup (path); + + g_free (path); + + return fd; +} + +static gboolean +g_key_file_load_from_fd (GKeyFile *key_file, + gint fd, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gssize bytes_read; + struct stat stat_buf; + gchar read_buf[4096]; + gchar list_separator; + + if (fstat (fd, &stat_buf) < 0) + { + int errsv = errno; + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errsv), + g_strerror (errsv)); + return FALSE; + } + + if (!S_ISREG (stat_buf.st_mode)) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Not a regular file")); + return FALSE; + } + + list_separator = key_file->list_separator; + g_key_file_clear (key_file); + g_key_file_init (key_file); + key_file->list_separator = list_separator; + key_file->flags = flags; + + do + { + int errsv; + + bytes_read = read (fd, read_buf, 4096); + errsv = errno; + + if (bytes_read == 0) /* End of File */ + break; + + if (bytes_read < 0) + { + if (errsv == EINTR || errsv == EAGAIN) + continue; + + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errsv), + g_strerror (errsv)); + return FALSE; + } + + g_key_file_parse_data (key_file, + read_buf, bytes_read, + &key_file_error); + } + while (!key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + g_key_file_flush_parse_buffer (key_file, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + return TRUE; +} + +/** + * g_key_file_load_from_file: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): the path of a filename to load, in the GLib filename encoding + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * Loads a key file into an empty #GKeyFile structure. + * + * If the OS returns an error when opening or reading the file, a + * %G_FILE_ERROR is returned. If there is a problem parsing the file, a + * %G_KEY_FILE_ERROR is returned. + * + * This function will never return a %G_KEY_FILE_ERROR_NOT_FOUND error. If the + * @file is not found, %G_FILE_ERROR_NOENT is returned. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_file (GKeyFile *key_file, + const gchar *file, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gint fd; + int errsv; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (file != NULL, FALSE); + + fd = g_open (file, O_RDONLY, 0); + errsv = errno; + + if (fd == -1) + { + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errsv), + g_strerror (errsv)); + return FALSE; + } + + g_key_file_load_from_fd (key_file, fd, flags, &key_file_error); + close (fd); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + return TRUE; +} + +/** + * g_key_file_load_from_data: + * @key_file: an empty #GKeyFile struct + * @data: key file loaded in memory + * @length: the length of @data in bytes (or (gsize)-1 if data is nul-terminated) + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * Loads a key file from memory into an empty #GKeyFile structure. + * If the object cannot be created then %error is set to a #GKeyFileError. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gchar list_separator; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (data != NULL || length == 0, FALSE); + + if (length == (gsize)-1) + length = strlen (data); + + list_separator = key_file->list_separator; + g_key_file_clear (key_file); + g_key_file_init (key_file); + key_file->list_separator = list_separator; + key_file->flags = flags; + + g_key_file_parse_data (key_file, data, length, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + g_key_file_flush_parse_buffer (key_file, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + return TRUE; +} + +/** + * g_key_file_load_from_bytes: + * @key_file: an empty #GKeyFile struct + * @bytes: a #GBytes + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * Loads a key file from the data in @bytes into an empty #GKeyFile structure. + * If the object cannot be created then %error is set to a #GKeyFileError. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.50 + **/ +gboolean +g_key_file_load_from_bytes (GKeyFile *key_file, + GBytes *bytes, + GKeyFileFlags flags, + GError **error) +{ + const guchar *data; + gsize size; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (bytes != NULL, FALSE); + + data = g_bytes_get_data (bytes, &size); + return g_key_file_load_from_data (key_file, (const gchar *) data, size, flags, error); +} + +/** + * g_key_file_load_from_dirs: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): a relative path to a filename to open and parse + * @search_dirs: (array zero-terminated=1) (element-type filename): %NULL-terminated array of directories to search + * @full_path: (out) (type filename) (optional): return location for a string containing the full path + * of the file, or %NULL + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * This function looks for a key file named @file in the paths + * specified in @search_dirs, loads the file into @key_file and + * returns the file's full path in @full_path. + * + * If the file could not be found in any of the @search_dirs, + * %G_KEY_FILE_ERROR_NOT_FOUND is returned. If + * the file is found but the OS returns an error when opening or reading the + * file, a %G_FILE_ERROR is returned. If there is a problem parsing the file, a + * %G_KEY_FILE_ERROR is returned. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.14 + **/ +gboolean +g_key_file_load_from_dirs (GKeyFile *key_file, + const gchar *file, + const gchar **search_dirs, + gchar **full_path, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + const gchar **data_dirs; + gchar *output_path; + gint fd; + gboolean found_file; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (!g_path_is_absolute (file), FALSE); + g_return_val_if_fail (search_dirs != NULL, FALSE); + + found_file = FALSE; + data_dirs = search_dirs; + output_path = NULL; + while (*data_dirs != NULL && !found_file) + { + g_free (output_path); + output_path = NULL; + + fd = find_file_in_data_dirs (file, data_dirs, &output_path, + &key_file_error); + + if (fd == -1) + { + if (key_file_error) + g_propagate_error (error, key_file_error); + break; + } + + found_file = g_key_file_load_from_fd (key_file, fd, flags, + &key_file_error); + close (fd); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + break; + } + } + + if (found_file && full_path) + *full_path = output_path; + else + g_free (output_path); + + return found_file; +} + +/** + * g_key_file_load_from_data_dirs: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): a relative path to a filename to open and parse + * @full_path: (out) (type filename) (optional): return location for a string containing the full path + * of the file, or %NULL + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * This function looks for a key file named @file in the paths + * returned from g_get_user_data_dir() and g_get_system_data_dirs(), + * loads the file into @key_file and returns the file's full path in + * @full_path. If the file could not be loaded then an %error is + * set to either a #GFileError or #GKeyFileError. + * + * Returns: %TRUE if a key file could be loaded, %FALSE othewise + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_data_dirs (GKeyFile *key_file, + const gchar *file, + gchar **full_path, + GKeyFileFlags flags, + GError **error) +{ + gchar **all_data_dirs; + const gchar * user_data_dir; + const gchar * const * system_data_dirs; + gsize i, j; + gboolean found_file; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (!g_path_is_absolute (file), FALSE); + + user_data_dir = g_get_user_data_dir (); + system_data_dirs = g_get_system_data_dirs (); + all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2); + + i = 0; + all_data_dirs[i++] = g_strdup (user_data_dir); + + j = 0; + while (system_data_dirs[j] != NULL) + all_data_dirs[i++] = g_strdup (system_data_dirs[j++]); + all_data_dirs[i] = NULL; + + found_file = g_key_file_load_from_dirs (key_file, + file, + (const gchar **)all_data_dirs, + full_path, + flags, + error); + + g_strfreev (all_data_dirs); + + return found_file; +} + +/** + * g_key_file_ref: (skip) + * @key_file: a #GKeyFile + * + * Increases the reference count of @key_file. + * + * Returns: the same @key_file. + * + * Since: 2.32 + **/ +GKeyFile * +g_key_file_ref (GKeyFile *key_file) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + g_atomic_int_inc (&key_file->ref_count); + + return key_file; +} + +/** + * g_key_file_free: (skip) + * @key_file: a #GKeyFile + * + * Clears all keys and groups from @key_file, and decreases the + * reference count by 1. If the reference count reaches zero, + * frees the key file and all its allocated memory. + * + * Since: 2.6 + **/ +void +g_key_file_free (GKeyFile *key_file) +{ + g_return_if_fail (key_file != NULL); + + g_key_file_clear (key_file); + + if (g_atomic_int_dec_and_test (&key_file->ref_count)) + g_slice_free (GKeyFile, key_file); + else + g_key_file_init (key_file); +} + +/** + * g_key_file_unref: + * @key_file: a #GKeyFile + * + * Decreases the reference count of @key_file by 1. If the reference count + * reaches zero, frees the key file and all its allocated memory. + * + * Since: 2.32 + **/ +void +g_key_file_unref (GKeyFile *key_file) +{ + g_return_if_fail (key_file != NULL); + + if (g_atomic_int_dec_and_test (&key_file->ref_count)) + { + g_key_file_clear (key_file); + g_slice_free (GKeyFile, key_file); + } +} + +/* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns + * true for locales that match those in g_get_language_names(). + */ +static gboolean +g_key_file_locale_is_interesting (GKeyFile *key_file, + const gchar *locale) +{ + gsize i; + + if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS) + return TRUE; + + for (i = 0; key_file->locales[i] != NULL; i++) + { + if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0) + return TRUE; + } + + return FALSE; +} + +static void +g_key_file_parse_line (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + GError *parse_error = NULL; + gchar *line_start; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (line != NULL); + + line_start = (gchar *) line; + while (g_ascii_isspace (*line_start)) + line_start++; + + if (g_key_file_line_is_comment (line_start)) + g_key_file_parse_comment (key_file, line, length, &parse_error); + else if (g_key_file_line_is_group (line_start)) + g_key_file_parse_group (key_file, line_start, + length - (line_start - line), + &parse_error); + else if (g_key_file_line_is_key_value_pair (line_start)) + g_key_file_parse_key_value_pair (key_file, line_start, + length - (line_start - line), + &parse_error); + else + { + gchar *line_utf8 = g_utf8_make_valid (line, length); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Key file contains line “%s” which is not " + "a key-value pair, group, or comment"), + line_utf8); + g_free (line_utf8); + + return; + } + + if (parse_error) + g_propagate_error (error, parse_error); +} + +static void +g_key_file_parse_comment (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + GKeyFileKeyValuePair *pair; + + if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS)) + return; + + g_warn_if_fail (key_file->current_group != NULL); + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_strndup (line, length); + + key_file->current_group->key_value_pairs = + g_list_prepend (key_file->current_group->key_value_pairs, pair); +} + +static void +g_key_file_parse_group (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + gchar *group_name; + const gchar *group_name_start, *group_name_end; + + /* advance past opening '[' + */ + group_name_start = line + 1; + group_name_end = line + length - 1; + + while (*group_name_end != ']') + group_name_end--; + + group_name = g_strndup (group_name_start, + group_name_end - group_name_start); + + if (!g_key_file_is_group_name (group_name)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Invalid group name: %s"), group_name); + g_free (group_name); + return; + } + + g_key_file_add_group (key_file, group_name); + g_free (group_name); +} + +static void +g_key_file_parse_key_value_pair (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + gchar *key, *value, *key_end, *value_start, *locale; + gsize key_len, value_len; + + if (key_file->current_group == NULL || key_file->current_group->name == NULL) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not start with a group")); + return; + } + + key_end = value_start = strchr (line, '='); + + g_warn_if_fail (key_end != NULL); + + key_end--; + value_start++; + + /* Pull the key name from the line (chomping trailing whitespace) + */ + while (g_ascii_isspace (*key_end)) + key_end--; + + key_len = key_end - line + 2; + + g_warn_if_fail (key_len <= length); + + key = g_strndup (line, key_len - 1); + + if (!g_key_file_is_key_name (key)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Invalid key name: %s"), key); + g_free (key); + return; + } + + /* Pull the value from the line (chugging leading whitespace) + */ + while (g_ascii_isspace (*value_start)) + value_start++; + + value_len = line + length - value_start + 1; + + value = g_strndup (value_start, value_len); + + g_warn_if_fail (key_file->start_group != NULL); + + if (key_file->current_group + && key_file->current_group->name + && strcmp (key_file->start_group->name, + key_file->current_group->name) == 0 + && strcmp (key, "Encoding") == 0) + { + if (g_ascii_strcasecmp (value, "UTF-8") != 0) + { + gchar *value_utf8 = g_utf8_make_valid (value, value_len); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains unsupported " + "encoding “%s”"), value_utf8); + g_free (value_utf8); + + g_free (key); + g_free (value); + return; + } + } + + /* Is this key a translation? If so, is it one that we care about? + */ + locale = key_get_locale (key); + + if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale)) + { + GKeyFileKeyValuePair *pair; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = key; + pair->value = value; + + g_key_file_add_key_value_pair (key_file, key_file->current_group, pair); + } + else + { + g_free (key); + g_free (value); + } + + g_free (locale); +} + +static gchar * +key_get_locale (const gchar *key) +{ + gchar *locale; + + locale = g_strrstr (key, "["); + + if (locale && strlen (locale) <= 2) + locale = NULL; + + if (locale) + locale = g_strndup (locale + 1, strlen (locale) - 2); + + return locale; +} + +static void +g_key_file_parse_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GError **error) +{ + GError *parse_error; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (data != NULL || length == 0); + + parse_error = NULL; + + i = 0; + while (i < length) + { + if (data[i] == '\n') + { + if (key_file->parse_buffer->len > 0 + && (key_file->parse_buffer->str[key_file->parse_buffer->len - 1] + == '\r')) + g_string_erase (key_file->parse_buffer, + key_file->parse_buffer->len - 1, + 1); + + /* When a newline is encountered flush the parse buffer so that the + * line can be parsed. Note that completely blank lines won't show + * up in the parse buffer, so they get parsed directly. + */ + if (key_file->parse_buffer->len > 0) + g_key_file_flush_parse_buffer (key_file, &parse_error); + else + g_key_file_parse_comment (key_file, "", 1, &parse_error); + + if (parse_error) + { + g_propagate_error (error, parse_error); + return; + } + i++; + } + else + { + const gchar *start_of_line; + const gchar *end_of_line; + gsize line_length; + + start_of_line = data + i; + end_of_line = memchr (start_of_line, '\n', length - i); + + if (end_of_line == NULL) + end_of_line = data + length; + + line_length = end_of_line - start_of_line; + + g_string_append_len (key_file->parse_buffer, start_of_line, line_length); + i += line_length; + } + } +} + +static void +g_key_file_flush_parse_buffer (GKeyFile *key_file, + GError **error) +{ + GError *file_error = NULL; + + g_return_if_fail (key_file != NULL); + + file_error = NULL; + + if (key_file->parse_buffer->len > 0) + { + g_key_file_parse_line (key_file, key_file->parse_buffer->str, + key_file->parse_buffer->len, + &file_error); + g_string_erase (key_file->parse_buffer, 0, -1); + + if (file_error) + { + g_propagate_error (error, file_error); + return; + } + } +} + +/** + * g_key_file_to_data: + * @key_file: a #GKeyFile + * @length: (out) (optional): return location for the length of the + * returned string, or %NULL + * @error: return location for a #GError, or %NULL + * + * This function outputs @key_file as a string. + * + * Note that this function never reports an error, + * so it is safe to pass %NULL as @error. + * + * Returns: a newly allocated string holding + * the contents of the #GKeyFile + * + * Since: 2.6 + **/ +gchar * +g_key_file_to_data (GKeyFile *key_file, + gsize *length, + GError **error) +{ + GString *data_string; + GList *group_node, *key_file_node; + + g_return_val_if_fail (key_file != NULL, NULL); + + data_string = g_string_new (NULL); + + for (group_node = g_list_last (key_file->groups); + group_node != NULL; + group_node = group_node->prev) + { + GKeyFileGroup *group; + + group = (GKeyFileGroup *) group_node->data; + + /* separate groups by at least an empty line */ + if (data_string->len >= 2 && + data_string->str[data_string->len - 2] != '\n') + g_string_append_c (data_string, '\n'); + + if (group->comment != NULL) + g_string_append_printf (data_string, "%s\n", group->comment->value); + + if (group->name != NULL) + g_string_append_printf (data_string, "[%s]\n", group->name); + + for (key_file_node = g_list_last (group->key_value_pairs); + key_file_node != NULL; + key_file_node = key_file_node->prev) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) key_file_node->data; + + if (pair->key != NULL) + g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value); + else + g_string_append_printf (data_string, "%s\n", pair->value); + } + } + + if (length) + *length = data_string->len; + + return g_string_free (data_string, FALSE); +} + +/** + * g_key_file_get_keys: + * @key_file: a #GKeyFile + * @group_name: a group name + * @length: (out) (optional): return location for the number of keys returned, or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns all keys for the group name @group_name. The array of + * returned keys will be %NULL-terminated, so @length may + * optionally be %NULL. In the event that the @group_name cannot + * be found, %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Returns: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_keys (GKeyFile *key_file, + const gchar *group_name, + gsize *length, + GError **error) +{ + GKeyFileGroup *group; + GList *tmp; + gchar **keys; + gsize i, num_keys; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + return NULL; + } + + num_keys = 0; + for (tmp = group->key_value_pairs; tmp; tmp = tmp->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key) + num_keys++; + } + + keys = g_new (gchar *, num_keys + 1); + + i = num_keys - 1; + for (tmp = group->key_value_pairs; tmp; tmp = tmp->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key) + { + keys[i] = g_strdup (pair->key); + i--; + } + } + + keys[num_keys] = NULL; + + if (length) + *length = num_keys; + + return keys; +} + +/** + * g_key_file_get_start_group: + * @key_file: a #GKeyFile + * + * Returns the name of the start group of the file. + * + * Returns: The start group of the key file. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_start_group (GKeyFile *key_file) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + if (key_file->start_group) + return g_strdup (key_file->start_group->name); + + return NULL; +} + +/** + * g_key_file_get_groups: + * @key_file: a #GKeyFile + * @length: (out) (optional): return location for the number of returned groups, or %NULL + * + * Returns all groups in the key file loaded with @key_file. + * The array of returned groups will be %NULL-terminated, so + * @length may optionally be %NULL. + * + * Returns: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * Since: 2.6 + **/ +gchar ** +g_key_file_get_groups (GKeyFile *key_file, + gsize *length) +{ + GList *group_node; + gchar **groups; + gsize i, num_groups; + + g_return_val_if_fail (key_file != NULL, NULL); + + num_groups = g_list_length (key_file->groups); + + g_return_val_if_fail (num_groups > 0, NULL); + + group_node = g_list_last (key_file->groups); + + g_return_val_if_fail (((GKeyFileGroup *) group_node->data)->name == NULL, NULL); + + /* Only need num_groups instead of num_groups + 1 + * because the first group of the file (last in the + * list) is always the comment group at the top, + * which we skip + */ + groups = g_new (gchar *, num_groups); + + + i = 0; + for (group_node = group_node->prev; + group_node != NULL; + group_node = group_node->prev) + { + GKeyFileGroup *group; + + group = (GKeyFileGroup *) group_node->data; + + g_warn_if_fail (group->name != NULL); + + groups[i++] = g_strdup (group->name); + } + groups[i] = NULL; + + if (length) + *length = i; + + return groups; +} + +static void +set_not_found_key_error (const char *group_name, + const char *key, + GError **error) +{ + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND, + _("Key file does not have key “%s” in group “%s”"), + key, group_name); +} + +/** + * g_key_file_get_value: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError, or %NULL + * + * Returns the raw value associated with @key under @group_name. + * Use g_key_file_get_string() to retrieve an unescaped UTF-8 string. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * + * Returns: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + gchar *value = NULL; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + return NULL; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (pair) + value = g_strdup (pair->value); + else + set_not_found_key_error (group_name, key, error); + + return value; +} + +/** + * g_key_file_set_value: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: a string + * + * Associates a new value with @key under @group_name. + * + * If @key cannot be found then it is created. If @group_name cannot + * be found then it is created. To set an UTF-8 string which may contain + * characters that need escaping (such as newlines or spaces), use + * g_key_file_set_string(). + * + * Since: 2.6 + **/ +void +g_key_file_set_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *value) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (g_key_file_is_group_name (group_name)); + g_return_if_fail (g_key_file_is_key_name (key)); + g_return_if_fail (value != NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_key_file_add_group (key_file, group_name); + group = (GKeyFileGroup *) key_file->groups->data; + + g_key_file_add_key (key_file, group, key, value); + } + else + { + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (!pair) + g_key_file_add_key (key_file, group, key, value); + else + { + g_free (pair->value); + pair->value = g_strdup (value); + } + } +} + +/** + * g_key_file_get_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError, or %NULL + * + * Returns the string value associated with @key under @group_name. + * Unlike g_key_file_get_value(), this function handles escape sequences + * like \s. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Returns: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *value, *string_value; + GError *key_file_error; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return NULL; + } + + if (!g_utf8_validate (value, -1, NULL)) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains key “%s” with value “%s” " + "which is not UTF-8"), key, value_utf8); + g_free (value_utf8); + g_free (value); + + return NULL; + } + + string_value = g_key_file_parse_value_as_string (key_file, value, NULL, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return string_value; +} + +/** + * g_key_file_set_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @string: a string + * + * Associates a new string value with @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name cannot be found then it is created. + * Unlike g_key_file_set_value(), this function handles characters + * that need escaping, such as newlines. + * + * Since: 2.6 + **/ +void +g_key_file_set_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *string) +{ + gchar *value; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (string != NULL); + + value = g_key_file_parse_string_as_value (key_file, string, FALSE); + g_key_file_set_value (key_file, group_name, key, value); + g_free (value); +} + +/** + * g_key_file_get_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out) (optional): return location for the number of returned strings, or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns the values associated with @key under @group_name. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Returns: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): + * a %NULL-terminated string array or %NULL if the specified + * key cannot be found. The array should be freed with g_strfreev(). + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar *value, *string_value, **values; + gint i, len; + GSList *p, *pieces = NULL; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return NULL; + } + + if (!g_utf8_validate (value, -1, NULL)) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains key “%s” with value “%s” " + "which is not UTF-8"), key, value_utf8); + g_free (value_utf8); + g_free (value); + + return NULL; + } + + string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error); + g_free (value); + g_free (string_value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + + g_slist_free_full (pieces, g_free); + return NULL; + } + + len = g_slist_length (pieces); + values = g_new (gchar *, len + 1); + for (p = pieces, i = 0; p; p = p->next) + values[i++] = p->data; + values[len] = NULL; + + g_slist_free (pieces); + + if (length) + *length = len; + + return values; +} + +/** + * g_key_file_set_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array zero-terminated=1 length=length) (element-type utf8): an array of string values + * @length: number of string values in @list + * + * Associates a list of string values for @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar * const list[], + gsize length) +{ + GString *value_list; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL || length == 0); + + value_list = g_string_sized_new (length * 128); + for (i = 0; i < length && list[i] != NULL; i++) + { + gchar *value; + + value = g_key_file_parse_string_as_value (key_file, list[i], TRUE); + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, value_list->str); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_set_locale_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: a locale identifier + * @string: a string + * + * Associates a string value for @key and @locale under @group_name. + * If the translation for @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar *string) +{ + gchar *full_key, *value; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (locale != NULL); + g_return_if_fail (string != NULL); + + value = g_key_file_parse_string_as_value (key_file, string, FALSE); + full_key = g_strdup_printf ("%s[%s]", key, locale); + g_key_file_set_value (key_file, group_name, full_key, value); + g_free (full_key); + g_free (value); +} + +/** + * g_key_file_get_locale_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: (nullable): a locale identifier or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns the value associated with @key under @group_name + * translated in the given @locale if available. If @locale is + * %NULL then the current locale is assumed. + * + * If @locale is to be non-%NULL, or if the current locale will change over + * the lifetime of the #GKeyFile, it must be loaded with + * %G_KEY_FILE_KEEP_TRANSLATIONS in order to load strings for all locales. + * + * If @key cannot be found then %NULL is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated + * with @key cannot be interpreted or no suitable translation can + * be found then the untranslated value is returned. + * + * Returns: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + GError **error) +{ + gchar *candidate_key, *translated_value; + GError *key_file_error; + gchar **languages; + gboolean free_languages = FALSE; + gint i; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + candidate_key = NULL; + translated_value = NULL; + key_file_error = NULL; + + if (locale) + { + languages = g_get_locale_variants (locale); + free_languages = TRUE; + } + else + { + languages = (gchar **) g_get_language_names (); + free_languages = FALSE; + } + + for (i = 0; languages[i]; i++) + { + candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); + + translated_value = g_key_file_get_string (key_file, + group_name, + candidate_key, NULL); + g_free (candidate_key); + + if (translated_value) + break; + + g_free (translated_value); + translated_value = NULL; + } + + /* Fallback to untranslated key + */ + if (!translated_value) + { + translated_value = g_key_file_get_string (key_file, group_name, key, + &key_file_error); + + if (!translated_value) + g_propagate_error (error, key_file_error); + } + + if (free_languages) + g_strfreev (languages); + + return translated_value; +} + +/** + * g_key_file_get_locale_for_key: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: (nullable): a locale identifier or %NULL + * + * Returns the actual locale which the result of + * g_key_file_get_locale_string() or g_key_file_get_locale_string_list() + * came from. + * + * If calling g_key_file_get_locale_string() or + * g_key_file_get_locale_string_list() with exactly the same @key_file, + * @group_name, @key and @locale, the result of those functions will + * have originally been tagged with the locale that is the result of + * this function. + * + * Returns: (nullable): the locale from the file, or %NULL if the key was not + * found or the entry in the file was was untranslated + * + * Since: 2.56 + */ +gchar * +g_key_file_get_locale_for_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale) +{ + gchar **languages_allocated = NULL; + const gchar * const *languages; + gchar *result = NULL; + gsize i; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (locale != NULL) + { + languages_allocated = g_get_locale_variants (locale); + languages = (const gchar * const *) languages_allocated; + } + else + languages = g_get_language_names (); + + for (i = 0; languages[i] != NULL; i++) + { + gchar *candidate_key, *translated_value; + + candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); + translated_value = g_key_file_get_string (key_file, group_name, candidate_key, NULL); + g_free (translated_value); + g_free (candidate_key); + + if (translated_value != NULL) + break; + } + + result = g_strdup (languages[i]); + + g_strfreev (languages_allocated); + + return result; +} + +/** + * g_key_file_get_locale_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: (nullable): a locale identifier or %NULL + * @length: (out) (optional): return location for the number of returned strings or %NULL + * @error: return location for a #GError or %NULL + * + * Returns the values associated with @key under @group_name + * translated in the given @locale if available. If @locale is + * %NULL then the current locale is assumed. + * + * If @locale is to be non-%NULL, or if the current locale will change over + * the lifetime of the #GKeyFile, it must be loaded with + * %G_KEY_FILE_KEEP_TRANSLATIONS in order to load strings for all locales. + * + * If @key cannot be found then %NULL is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated + * with @key cannot be interpreted or no suitable translations + * can be found then the untranslated values are returned. The + * returned array is %NULL-terminated, so @length may optionally + * be %NULL. + * + * Returns: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): a newly allocated %NULL-terminated string array + * or %NULL if the key isn't found. The string array should be freed + * with g_strfreev(). + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + gsize *length, + GError **error) +{ + GError *key_file_error; + gchar **values, *value; + char list_separator[2]; + gsize len; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + key_file_error = NULL; + + value = g_key_file_get_locale_string (key_file, group_name, + key, locale, + &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!value) + { + if (length) + *length = 0; + return NULL; + } + + len = strlen (value); + if (value[len - 1] == key_file->list_separator) + value[len - 1] = '\0'; + + list_separator[0] = key_file->list_separator; + list_separator[1] = '\0'; + values = g_strsplit (value, list_separator, 0); + + g_free (value); + + if (length) + *length = g_strv_length (values); + + return values; +} + +/** + * g_key_file_set_locale_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: a locale identifier + * @list: (array zero-terminated=1 length=length): a %NULL-terminated array of locale string values + * @length: the length of @list + * + * Associates a list of string values for @key and @locale under + * @group_name. If the translation for @key cannot be found then + * it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar * const list[], + gsize length) +{ + GString *value_list; + gchar *full_key; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (locale != NULL); + g_return_if_fail (length != 0); + + value_list = g_string_sized_new (length * 128); + for (i = 0; i < length && list[i] != NULL; i++) + { + gchar *value; + + value = g_key_file_parse_string_as_value (key_file, list[i], TRUE); + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + full_key = g_strdup_printf ("%s[%s]", key, locale); + g_key_file_set_value (key_file, group_name, full_key, value_list->str); + g_free (full_key); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_get_boolean: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a + * boolean. + * + * If @key cannot be found then %FALSE is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value + * associated with @key cannot be interpreted as a boolean then %FALSE + * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: the value associated with the key as a boolean, + * or %FALSE if the key was not found or could not be parsed. + * + * Since: 2.6 + **/ +gboolean +g_key_file_get_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error = NULL; + gchar *value; + gboolean bool_value; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (!value) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + bool_value = g_key_file_parse_value_as_boolean (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return bool_value; +} + +/** + * g_key_file_set_boolean: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: %TRUE or %FALSE + * + * Associates a new boolean value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_key_file_parse_boolean_as_value (key_file, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_boolean_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of booleans returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * booleans. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as booleans then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: (array length=length) (element-type gboolean) (transfer container): + * the values associated with the key as a list of booleans, or %NULL if the + * key was not found or could not be parsed. The returned list of booleans + * should be freed with g_free() when no longer needed. + * + * Since: 2.6 + **/ +gboolean * +g_key_file_get_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error; + gchar **values; + gboolean *bool_values; + gsize i, num_bools; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + key_file_error = NULL; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_bools, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + bool_values = g_new (gboolean, num_bools); + + for (i = 0; i < num_bools; i++) + { + bool_values[i] = g_key_file_parse_value_as_boolean (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (bool_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_bools; + + return bool_values; +} + +/** + * g_key_file_set_boolean_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of boolean values + * @length: length of @list + * + * Associates a list of boolean values with @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name is %NULL, the start_group is used. + * + * Since: 2.6 + **/ +void +g_key_file_set_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean list[], + gsize length) +{ + GString *value_list; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + value_list = g_string_sized_new (length * 8); + for (i = 0; i < length; i++) + { + gchar *value; + + value = g_key_file_parse_boolean_as_value (key_file, list[i]); + + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, value_list->str); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_get_integer: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as an + * integer. + * + * If @key cannot be found then 0 is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated + * with @key cannot be interpreted as an integer, or is out of range + * for a #gint, then 0 is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: the value associated with the key as an integer, or + * 0 if the key was not found or could not be parsed. + * + * Since: 2.6 + **/ +gint +g_key_file_get_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error; + gchar *value; + gint int_value; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return 0; + } + + int_value = g_key_file_parse_value_as_integer (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” in group “%s” " + "which has a value that cannot be interpreted."), + key, group_name); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return int_value; +} + +/** + * g_key_file_set_integer: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_key_file_parse_integer_as_value (key_file, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_int64: + * @key_file: a non-%NULL #GKeyFile + * @group_name: a non-%NULL group name + * @key: a non-%NULL key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a signed + * 64-bit integer. This is similar to g_key_file_get_integer() but can return + * 64-bit results without truncation. + * + * Returns: the value associated with the key as a signed 64-bit integer, or + * 0 if the key was not found or could not be parsed. + * + * Since: 2.26 + */ +gint64 +g_key_file_get_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *s, *end; + gint64 v; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + s = g_key_file_get_value (key_file, group_name, key, error); + + if (s == NULL) + return 0; + + v = g_ascii_strtoll (s, &end, 10); + + if (*s == '\0' || *end != '\0') + { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key “%s” in group “%s” has value “%s” " + "where %s was expected"), + key, group_name, s, "int64"); + g_free (s); + return 0; + } + + g_free (s); + return v; +} + +/** + * g_key_file_set_int64: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.26 + **/ +void +g_key_file_set_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint64 value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_strdup_printf ("%" G_GINT64_FORMAT, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_uint64: + * @key_file: a non-%NULL #GKeyFile + * @group_name: a non-%NULL group name + * @key: a non-%NULL key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as an unsigned + * 64-bit integer. This is similar to g_key_file_get_integer() but can return + * large positive results without truncation. + * + * Returns: the value associated with the key as an unsigned 64-bit integer, + * or 0 if the key was not found or could not be parsed. + * + * Since: 2.26 + */ +guint64 +g_key_file_get_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *s, *end; + guint64 v; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + s = g_key_file_get_value (key_file, group_name, key, error); + + if (s == NULL) + return 0; + + v = g_ascii_strtoull (s, &end, 10); + + if (*s == '\0' || *end != '\0') + { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key “%s” in group “%s” has value “%s” " + "where %s was expected"), + key, group_name, s, "uint64"); + g_free (s); + return 0; + } + + g_free (s); + return v; +} + +/** + * g_key_file_set_uint64: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.26 + **/ +void +g_key_file_set_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + guint64 value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_strdup_printf ("%" G_GUINT64_FORMAT, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_integer_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of integers returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * integers. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as integers, or are out of range for + * #gint, then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: (array length=length) (element-type gint) (transfer container): + * the values associated with the key as a list of integers, or %NULL if + * the key was not found or could not be parsed. The returned list of + * integers should be freed with g_free() when no longer needed. + * + * Since: 2.6 + **/ +gint * +g_key_file_get_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar **values; + gint *int_values; + gsize i, num_ints; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_ints, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + int_values = g_new (gint, num_ints); + + for (i = 0; i < num_ints; i++) + { + int_values[i] = g_key_file_parse_value_as_integer (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (int_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_ints; + + return int_values; +} + +/** + * g_key_file_set_integer_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of integer values + * @length: number of integer values in @list + * + * Associates a list of integer values with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint list[], + gsize length) +{ + GString *values; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + values = g_string_sized_new (length * 16); + for (i = 0; i < length; i++) + { + gchar *value; + + value = g_key_file_parse_integer_as_value (key_file, list[i]); + + g_string_append (values, value); + g_string_append_c (values, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, values->str); + g_string_free (values, TRUE); +} + +/** + * g_key_file_get_double: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a + * double. If @group_name is %NULL, the start_group is used. + * + * If @key cannot be found then 0.0 is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated + * with @key cannot be interpreted as a double then 0.0 is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: the value associated with the key as a double, or + * 0.0 if the key was not found or could not be parsed. + * + * Since: 2.12 + **/ +gdouble +g_key_file_get_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error; + gchar *value; + gdouble double_value; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return 0; + } + + double_value = g_key_file_parse_value_as_double (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” in group “%s” " + "which has a value that cannot be interpreted."), + key, group_name); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return double_value; +} + +/** + * g_key_file_set_double: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an double value + * + * Associates a new double value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.12 + **/ +void +g_key_file_set_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble value) +{ + gchar result[G_ASCII_DTOSTR_BUF_SIZE]; + + g_return_if_fail (key_file != NULL); + + g_ascii_dtostr (result, sizeof (result), value); + g_key_file_set_value (key_file, group_name, key, result); +} + +/** + * g_key_file_get_double_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of doubles returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * doubles. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as doubles then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: (array length=length) (element-type gdouble) (transfer container): + * the values associated with the key as a list of doubles, or %NULL if the + * key was not found or could not be parsed. The returned list of doubles + * should be freed with g_free() when no longer needed. + * + * Since: 2.12 + **/ +gdouble * +g_key_file_get_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar **values; + gdouble *double_values; + gsize i, num_doubles; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_doubles, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + double_values = g_new (gdouble, num_doubles); + + for (i = 0; i < num_doubles; i++) + { + double_values[i] = g_key_file_parse_value_as_double (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (double_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_doubles; + + return double_values; +} + +/** + * g_key_file_set_double_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of double values + * @length: number of double values in @list + * + * Associates a list of double values with @key under + * @group_name. If @key cannot be found then it is created. + * + * Since: 2.12 + **/ +void +g_key_file_set_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble list[], + gsize length) +{ + GString *values; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + values = g_string_sized_new (length * 16); + for (i = 0; i < length; i++) + { + gchar result[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_dtostr( result, sizeof (result), list[i] ); + + g_string_append (values, result); + g_string_append_c (values, key_file->list_separator); + } + + g_key_file_set_value (key_file, group_name, key, values->str); + g_string_free (values, TRUE); +} + +static gboolean +g_key_file_set_key_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *comment, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + GList *key_node, *comment_node, *tmp; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name ? group_name : "(null)"); + + return FALSE; + } + + /* First find the key the comments are supposed to be + * associated with + */ + key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key); + + if (key_node == NULL) + { + set_not_found_key_error (group->name, key, error); + return FALSE; + } + + /* Then find all the comments already associated with the + * key and free them + */ + tmp = key_node->next; + while (tmp != NULL) + { + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key != NULL) + break; + + comment_node = tmp; + tmp = tmp->next; + g_key_file_remove_key_value_pair_node (key_file, group, + comment_node); + } + + if (comment == NULL) + return TRUE; + + /* Now we can add our new comment + */ + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); + + key_node = g_list_insert (key_node, pair, 1); + + return TRUE; +} + +static gboolean +g_key_file_set_group_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *comment, + GError **error) +{ + GKeyFileGroup *group; + + g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE); + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name ? group_name : "(null)"); + + return FALSE; + } + + /* First remove any existing comment + */ + if (group->comment) + { + g_key_file_key_value_pair_free (group->comment); + group->comment = NULL; + } + + if (comment == NULL) + return TRUE; + + /* Now we can add our new comment + */ + group->comment = g_slice_new (GKeyFileKeyValuePair); + group->comment->key = NULL; + group->comment->value = g_key_file_parse_comment_as_value (key_file, comment); + + return TRUE; +} + +static gboolean +g_key_file_set_top_comment (GKeyFile *key_file, + const gchar *comment, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + /* The last group in the list should be the top (comments only) + * group in the file + */ + g_warn_if_fail (key_file->groups != NULL); + group_node = g_list_last (key_file->groups); + group = (GKeyFileGroup *) group_node->data; + g_warn_if_fail (group->name == NULL); + + /* Note all keys must be comments at the top of + * the file, so we can just free it all. + */ + g_list_free_full (group->key_value_pairs, (GDestroyNotify) g_key_file_key_value_pair_free); + group->key_value_pairs = NULL; + + if (comment == NULL) + return TRUE; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); + + group->key_value_pairs = + g_list_prepend (group->key_value_pairs, pair); + + return TRUE; +} + +/** + * g_key_file_set_comment: + * @key_file: a #GKeyFile + * @group_name: (nullable): a group name, or %NULL + * @key: (nullable): a key + * @comment: a comment + * @error: return location for a #GError + * + * Places a comment above @key from @group_name. + * + * If @key is %NULL then @comment will be written above @group_name. + * If both @key and @group_name are %NULL, then @comment will be + * written above the first group in the file. + * + * Note that this function prepends a '#' comment marker to + * each line of @comment. + * + * Returns: %TRUE if the comment was written, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_set_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *comment, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + + if (group_name != NULL && key != NULL) + { + if (!g_key_file_set_key_comment (key_file, group_name, key, comment, error)) + return FALSE; + } + else if (group_name != NULL) + { + if (!g_key_file_set_group_comment (key_file, group_name, comment, error)) + return FALSE; + } + else + { + if (!g_key_file_set_top_comment (key_file, comment, error)) + return FALSE; + } + + return TRUE; +} + +static gchar * +g_key_file_get_key_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + GList *key_node, *tmp; + GString *string; + gchar *comment; + + g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL); + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name ? group_name : "(null)"); + + return NULL; + } + + /* First find the key the comments are supposed to be + * associated with + */ + key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key); + + if (key_node == NULL) + { + set_not_found_key_error (group->name, key, error); + return NULL; + } + + string = NULL; + + /* Then find all the comments already associated with the + * key and concatentate them. + */ + tmp = key_node->next; + if (!key_node->next) + return NULL; + + pair = (GKeyFileKeyValuePair *) tmp->data; + if (pair->key != NULL) + return NULL; + + while (tmp->next) + { + pair = (GKeyFileKeyValuePair *) tmp->next->data; + + if (pair->key != NULL) + break; + + tmp = tmp->next; + } + + while (tmp != key_node) + { + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (string == NULL) + string = g_string_sized_new (512); + + comment = g_key_file_parse_value_as_comment (key_file, pair->value, + (tmp->prev == key_node)); + g_string_append (string, comment); + g_free (comment); + + tmp = tmp->prev; + } + + if (string != NULL) + { + comment = string->str; + g_string_free (string, FALSE); + } + else + comment = NULL; + + return comment; +} + +static gchar * +get_group_comment (GKeyFile *key_file, + GKeyFileGroup *group, + GError **error) +{ + GString *string; + GList *tmp; + gchar *comment; + + string = NULL; + + tmp = group->key_value_pairs; + while (tmp) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key != NULL) + { + tmp = tmp->prev; + break; + } + + if (tmp->next == NULL) + break; + + tmp = tmp->next; + } + + while (tmp != NULL) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (string == NULL) + string = g_string_sized_new (512); + + comment = g_key_file_parse_value_as_comment (key_file, pair->value, + (tmp->prev == NULL)); + g_string_append (string, comment); + g_free (comment); + + tmp = tmp->prev; + } + + if (string != NULL) + return g_string_free (string, FALSE); + + return NULL; +} + +static gchar * +g_key_file_get_group_comment (GKeyFile *key_file, + const gchar *group_name, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name ? group_name : "(null)"); + + return NULL; + } + + if (group->comment) + return g_strdup (group->comment->value); + + group_node = g_key_file_lookup_group_node (key_file, group_name); + group_node = group_node->next; + group = (GKeyFileGroup *)group_node->data; + return get_group_comment (key_file, group, error); +} + +static gchar * +g_key_file_get_top_comment (GKeyFile *key_file, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + + /* The last group in the list should be the top (comments only) + * group in the file + */ + g_warn_if_fail (key_file->groups != NULL); + group_node = g_list_last (key_file->groups); + group = (GKeyFileGroup *) group_node->data; + g_warn_if_fail (group->name == NULL); + + return get_group_comment (key_file, group, error); +} + +/** + * g_key_file_get_comment: + * @key_file: a #GKeyFile + * @group_name: (nullable): a group name, or %NULL + * @key: a key + * @error: return location for a #GError + * + * Retrieves a comment above @key from @group_name. + * If @key is %NULL then @comment will be read from above + * @group_name. If both @key and @group_name are %NULL, then + * @comment will be read from above the first group in the file. + * + * Note that the returned string does not include the '#' comment markers, + * but does include any whitespace after them (on each line). It includes + * the line breaks between lines, but does not include the final line break. + * + * Returns: a comment that should be freed with g_free() + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + if (group_name != NULL && key != NULL) + return g_key_file_get_key_comment (key_file, group_name, key, error); + else if (group_name != NULL) + return g_key_file_get_group_comment (key_file, group_name, error); + else + return g_key_file_get_top_comment (key_file, error); +} + +/** + * g_key_file_remove_comment: + * @key_file: a #GKeyFile + * @group_name: (nullable): a group name, or %NULL + * @key: (nullable): a key + * @error: return location for a #GError + * + * Removes a comment above @key from @group_name. + * If @key is %NULL then @comment will be removed above @group_name. + * If both @key and @group_name are %NULL, then @comment will + * be removed above the first group in the file. + * + * Returns: %TRUE if the comment was removed, %FALSE otherwise + * + * Since: 2.6 + **/ + +gboolean +g_key_file_remove_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + + if (group_name != NULL && key != NULL) + return g_key_file_set_key_comment (key_file, group_name, key, NULL, error); + else if (group_name != NULL) + return g_key_file_set_group_comment (key_file, group_name, NULL, error); + else + return g_key_file_set_top_comment (key_file, NULL, error); +} + +/** + * g_key_file_has_group: + * @key_file: a #GKeyFile + * @group_name: a group name + * + * Looks whether the key file has the group @group_name. + * + * Returns: %TRUE if @group_name is a part of @key_file, %FALSE + * otherwise. + * Since: 2.6 + **/ +gboolean +g_key_file_has_group (GKeyFile *key_file, + const gchar *group_name) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + + return g_key_file_lookup_group (key_file, group_name) != NULL; +} + +/* This code remains from a historical attempt to add a new public API + * which respects the GError rules. + */ +static gboolean +g_key_file_has_key_full (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean *has_key, + GError **error) +{ + GKeyFileKeyValuePair *pair; + GKeyFileGroup *group; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + + return FALSE; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (has_key) + *has_key = pair != NULL; + return TRUE; +} + +/** + * g_key_file_has_key: (skip) + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key name + * @error: return location for a #GError + * + * Looks whether the key file has the key @key in the group + * @group_name. + * + * Note that this function does not follow the rules for #GError strictly; + * the return value both carries meaning and signals an error. To use + * this function, you must pass a #GError pointer in @error, and check + * whether it is not %NULL to see if an error occurred. + * + * Language bindings should use g_key_file_get_value() to test whether + * or not a key exists. + * + * Returns: %TRUE if @key is a part of @group_name, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_has_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *temp_error = NULL; + gboolean has_key; + + if (g_key_file_has_key_full (key_file, group_name, key, &has_key, &temp_error)) + { + return has_key; + } + else + { + g_propagate_error (error, temp_error); + return FALSE; + } +} + +static void +g_key_file_add_group (GKeyFile *key_file, + const gchar *group_name) +{ + GKeyFileGroup *group; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (g_key_file_is_group_name (group_name)); + + group = g_key_file_lookup_group (key_file, group_name); + if (group != NULL) + { + key_file->current_group = group; + return; + } + + group = g_slice_new0 (GKeyFileGroup); + group->name = g_strdup (group_name); + group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal); + key_file->groups = g_list_prepend (key_file->groups, group); + key_file->current_group = group; + + if (key_file->start_group == NULL) + key_file->start_group = group; + + g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group); +} + +static void +g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair) +{ + if (pair != NULL) + { + g_free (pair->key); + g_free (pair->value); + g_slice_free (GKeyFileKeyValuePair, pair); + } +} + +/* Be careful not to call this function on a node with data in the + * lookup map without removing it from the lookup map, first. + * + * Some current cases where this warning is not a concern are + * when: + * - the node being removed is a comment node + * - the entire lookup map is getting destroyed soon after + * anyway. + */ +static void +g_key_file_remove_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + GList *pair_node) +{ + + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) pair_node->data; + + group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node); + + g_warn_if_fail (pair->value != NULL); + + g_key_file_key_value_pair_free (pair); + + g_list_free_1 (pair_node); +} + +static void +g_key_file_remove_group_node (GKeyFile *key_file, + GList *group_node) +{ + GKeyFileGroup *group; + GList *tmp; + + group = (GKeyFileGroup *) group_node->data; + + if (group->name) + g_hash_table_remove (key_file->group_hash, group->name); + + /* If the current group gets deleted make the current group the last + * added group. + */ + if (key_file->current_group == group) + { + /* groups should always contain at least the top comment group, + * unless g_key_file_clear has been called + */ + if (key_file->groups) + key_file->current_group = (GKeyFileGroup *) key_file->groups->data; + else + key_file->current_group = NULL; + } + + /* If the start group gets deleted make the start group the first + * added group. + */ + if (key_file->start_group == group) + { + tmp = g_list_last (key_file->groups); + while (tmp != NULL) + { + if (tmp != group_node && + ((GKeyFileGroup *) tmp->data)->name != NULL) + break; + + tmp = tmp->prev; + } + + if (tmp) + key_file->start_group = (GKeyFileGroup *) tmp->data; + else + key_file->start_group = NULL; + } + + key_file->groups = g_list_remove_link (key_file->groups, group_node); + + tmp = group->key_value_pairs; + while (tmp != NULL) + { + GList *pair_node; + + pair_node = tmp; + tmp = tmp->next; + g_key_file_remove_key_value_pair_node (key_file, group, pair_node); + } + + g_warn_if_fail (group->key_value_pairs == NULL); + + if (group->comment) + { + g_key_file_key_value_pair_free (group->comment); + group->comment = NULL; + } + + if (group->lookup_map) + { + g_hash_table_destroy (group->lookup_map); + group->lookup_map = NULL; + } + + g_free ((gchar *) group->name); + g_slice_free (GKeyFileGroup, group); + g_list_free_1 (group_node); +} + +/** + * g_key_file_remove_group: + * @key_file: a #GKeyFile + * @group_name: a group name + * @error: return location for a #GError or %NULL + * + * Removes the specified group, @group_name, + * from the key file. + * + * Returns: %TRUE if the group was removed, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_remove_group (GKeyFile *key_file, + const gchar *group_name, + GError **error) +{ + GList *group_node; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + + group_node = g_key_file_lookup_group_node (key_file, group_name); + + if (!group_node) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + return FALSE; + } + + g_key_file_remove_group_node (key_file, group_node); + + return TRUE; +} + +static void +g_key_file_add_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + GKeyFileKeyValuePair *pair) +{ + g_hash_table_replace (group->lookup_map, pair->key, pair); + group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair); +} + +static void +g_key_file_add_key (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key, + const gchar *value) +{ + GKeyFileKeyValuePair *pair; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = g_strdup (key); + pair->value = g_strdup (value); + + g_key_file_add_key_value_pair (key_file, group, pair); +} + +/** + * g_key_file_remove_key: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key name to remove + * @error: return location for a #GError or %NULL + * + * Removes @key in @group_name from the key file. + * + * Returns: %TRUE if the key was removed, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_remove_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + pair = NULL; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + return FALSE; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (!pair) + { + set_not_found_key_error (group->name, key, error); + return FALSE; + } + + group->key_value_pairs = g_list_remove (group->key_value_pairs, pair); + g_hash_table_remove (group->lookup_map, pair->key); + g_key_file_key_value_pair_free (pair); + + return TRUE; +} + +static GList * +g_key_file_lookup_group_node (GKeyFile *key_file, + const gchar *group_name) +{ + GKeyFileGroup *group; + GList *tmp; + + for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next) + { + group = (GKeyFileGroup *) tmp->data; + + if (group && group->name && strcmp (group->name, group_name) == 0) + break; + } + + return tmp; +} + +static GKeyFileGroup * +g_key_file_lookup_group (GKeyFile *key_file, + const gchar *group_name) +{ + return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name); +} + +static GList * +g_key_file_lookup_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key) +{ + GList *key_node; + + for (key_node = group->key_value_pairs; + key_node != NULL; + key_node = key_node->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) key_node->data; + + if (pair->key && strcmp (pair->key, key) == 0) + break; + } + + return key_node; +} + +static GKeyFileKeyValuePair * +g_key_file_lookup_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key) +{ + return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key); +} + +/* Lines starting with # or consisting entirely of whitespace are merely + * recorded, not parsed. This function assumes all leading whitespace + * has been stripped. + */ +static gboolean +g_key_file_line_is_comment (const gchar *line) +{ + return (*line == '#' || *line == '\0' || *line == '\n'); +} + +static gboolean +g_key_file_is_group_name (const gchar *name) +{ + gchar *p, *q; + + if (name == NULL) + return FALSE; + + p = q = (gchar *) name; + while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q)) + q = g_utf8_find_next_char (q, NULL); + + if (*q != '\0' || q == p) + return FALSE; + + return TRUE; +} + +static gboolean +g_key_file_is_key_name (const gchar *name) +{ + gchar *p, *q; + + if (name == NULL) + return FALSE; + + p = q = (gchar *) name; + /* We accept a little more than the desktop entry spec says, + * since gnome-vfs uses mime-types as keys in its cache. + */ + while (*q && *q != '=' && *q != '[' && *q != ']') + q = g_utf8_find_next_char (q, NULL); + + /* No empty keys, please */ + if (q == p) + return FALSE; + + /* We accept spaces in the middle of keys to not break + * existing apps, but we don't tolerate initial or final + * spaces, which would lead to silent corruption when + * rereading the file. + */ + if (*p == ' ' || q[-1] == ' ') + return FALSE; + + if (*q == '[') + { + q++; + while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@')) + q = g_utf8_find_next_char (q, NULL); + + if (*q != ']') + return FALSE; + + q++; + } + + if (*q != '\0') + return FALSE; + + return TRUE; +} + +/* A group in a key file is made up of a starting '[' followed by one + * or more letters making up the group name followed by ']'. + */ +static gboolean +g_key_file_line_is_group (const gchar *line) +{ + gchar *p; + + p = (gchar *) line; + if (*p != '[') + return FALSE; + + p++; + + while (*p && *p != ']') + p = g_utf8_find_next_char (p, NULL); + + if (*p != ']') + return FALSE; + + /* silently accept whitespace after the ] */ + p = g_utf8_find_next_char (p, NULL); + while (*p == ' ' || *p == '\t') + p = g_utf8_find_next_char (p, NULL); + + if (*p) + return FALSE; + + return TRUE; +} + +static gboolean +g_key_file_line_is_key_value_pair (const gchar *line) +{ + gchar *p; + + p = (gchar *) g_utf8_strchr (line, -1, '='); + + if (!p) + return FALSE; + + /* Key must be non-empty + */ + if (*p == line[0]) + return FALSE; + + return TRUE; +} + +static gchar * +g_key_file_parse_value_as_string (GKeyFile *key_file, + const gchar *value, + GSList **pieces, + GError **error) +{ + gchar *string_value, *p, *q0, *q; + + string_value = g_new (gchar, strlen (value) + 1); + + p = (gchar *) value; + q0 = q = string_value; + while (*p) + { + if (*p == '\\') + { + p++; + + switch (*p) + { + case 's': + *q = ' '; + break; + + case 'n': + *q = '\n'; + break; + + case 't': + *q = '\t'; + break; + + case 'r': + *q = '\r'; + break; + + case '\\': + *q = '\\'; + break; + + case '\0': + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains escape character " + "at end of line")); + break; + + default: + if (pieces && *p == key_file->list_separator) + *q = key_file->list_separator; + else + { + *q++ = '\\'; + *q = *p; + + if (*error == NULL) + { + gchar sequence[3]; + + sequence[0] = '\\'; + sequence[1] = *p; + sequence[2] = '\0'; + + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains invalid escape " + "sequence “%s”"), sequence); + } + } + break; + } + } + else + { + *q = *p; + if (pieces && (*p == key_file->list_separator)) + { + *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0)); + q0 = q + 1; + } + } + + if (*p == '\0') + break; + + q++; + p++; + } + + *q = '\0'; + if (pieces) + { + if (q0 < q) + *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0)); + *pieces = g_slist_reverse (*pieces); + } + + return string_value; +} + +static gchar * +g_key_file_parse_string_as_value (GKeyFile *key_file, + const gchar *string, + gboolean escape_separator) +{ + gchar *value, *p, *q; + gsize length; + gboolean parsing_leading_space; + + length = strlen (string) + 1; + + /* Worst case would be that every character needs to be escaped. + * In other words every character turns to two characters + */ + value = g_new (gchar, 2 * length); + + p = (gchar *) string; + q = value; + parsing_leading_space = TRUE; + while (p < (string + length - 1)) + { + gchar escaped_character[3] = { '\\', 0, 0 }; + + switch (*p) + { + case ' ': + if (parsing_leading_space) + { + escaped_character[1] = 's'; + strcpy (q, escaped_character); + q += 2; + } + else + { + *q = *p; + q++; + } + break; + case '\t': + if (parsing_leading_space) + { + escaped_character[1] = 't'; + strcpy (q, escaped_character); + q += 2; + } + else + { + *q = *p; + q++; + } + break; + case '\n': + escaped_character[1] = 'n'; + strcpy (q, escaped_character); + q += 2; + break; + case '\r': + escaped_character[1] = 'r'; + strcpy (q, escaped_character); + q += 2; + break; + case '\\': + escaped_character[1] = '\\'; + strcpy (q, escaped_character); + q += 2; + parsing_leading_space = FALSE; + break; + default: + if (escape_separator && *p == key_file->list_separator) + { + escaped_character[1] = key_file->list_separator; + strcpy (q, escaped_character); + q += 2; + parsing_leading_space = TRUE; + } + else + { + *q = *p; + q++; + parsing_leading_space = FALSE; + } + break; + } + p++; + } + *q = '\0'; + + return value; +} + +static gint +g_key_file_parse_value_as_integer (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *eof_int; + glong long_value; + gint int_value; + int errsv; + + errno = 0; + long_value = strtol (value, &eof_int, 10); + errsv = errno; + + if (*value == '\0' || (*eof_int != '\0' && !g_ascii_isspace(*eof_int))) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value “%s” cannot be interpreted " + "as a number."), value_utf8); + g_free (value_utf8); + + return 0; + } + + int_value = long_value; + if (int_value != long_value || errsv == ERANGE) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Integer value “%s” out of range"), + value_utf8); + g_free (value_utf8); + + return 0; + } + + return int_value; +} + +static gchar * +g_key_file_parse_integer_as_value (GKeyFile *key_file, + gint value) + +{ + return g_strdup_printf ("%d", value); +} + +static gdouble +g_key_file_parse_value_as_double (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *end_of_valid_d; + gdouble double_value = 0; + + double_value = g_ascii_strtod (value, &end_of_valid_d); + + if (*end_of_valid_d != '\0' || end_of_valid_d == value) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value “%s” cannot be interpreted " + "as a float number."), + value_utf8); + g_free (value_utf8); + + double_value = 0; + } + + return double_value; +} + +static gint +strcmp_sized (const gchar *s1, size_t len1, const gchar *s2) +{ + size_t len2 = strlen (s2); + return strncmp (s1, s2, MAX (len1, len2)); +} + +static gboolean +g_key_file_parse_value_as_boolean (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *value_utf8; + gint i, length = 0; + + /* Count the number of non-whitespace characters */ + for (i = 0; value[i]; i++) + if (!g_ascii_isspace (value[i])) + length = i + 1; + + if (strcmp_sized (value, length, "true") == 0 || strcmp_sized (value, length, "1") == 0) + return TRUE; + else if (strcmp_sized (value, length, "false") == 0 || strcmp_sized (value, length, "0") == 0) + return FALSE; + + value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value “%s” cannot be interpreted " + "as a boolean."), value_utf8); + g_free (value_utf8); + + return FALSE; +} + +static gchar * +g_key_file_parse_boolean_as_value (GKeyFile *key_file, + gboolean value) +{ + if (value) + return g_strdup ("true"); + else + return g_strdup ("false"); +} + +static gchar * +g_key_file_parse_value_as_comment (GKeyFile *key_file, + const gchar *value, + gboolean is_final_line) +{ + GString *string; + gchar **lines; + gsize i; + + string = g_string_sized_new (512); + + lines = g_strsplit (value, "\n", 0); + + for (i = 0; lines[i] != NULL; i++) + { + const gchar *line = lines[i]; + + if (i != 0) + g_string_append_c (string, '\n'); + + if (line[0] == '#') + line++; + g_string_append (string, line); + } + g_strfreev (lines); + + /* This function gets called once per line of a comment, but we don’t want + * to add a trailing newline. */ + if (!is_final_line) + g_string_append_c (string, '\n'); + + return g_string_free (string, FALSE); +} + +static gchar * +g_key_file_parse_comment_as_value (GKeyFile *key_file, + const gchar *comment) +{ + GString *string; + gchar **lines; + gsize i; + + string = g_string_sized_new (512); + + lines = g_strsplit (comment, "\n", 0); + + for (i = 0; lines[i] != NULL; i++) + g_string_append_printf (string, "#%s%s", lines[i], + lines[i + 1] == NULL? "" : "\n"); + g_strfreev (lines); + + return g_string_free (string, FALSE); +} + +/** + * g_key_file_save_to_file: + * @key_file: a #GKeyFile + * @filename: the name of the file to write to + * @error: a pointer to a %NULL #GError, or %NULL + * + * Writes the contents of @key_file to @filename using + * g_file_set_contents(). + * + * This function can fail for any of the reasons that + * g_file_set_contents() may fail. + * + * Returns: %TRUE if successful, else %FALSE with @error set + * + * Since: 2.40 + */ +gboolean +g_key_file_save_to_file (GKeyFile *key_file, + const gchar *filename, + GError **error) +{ + gchar *contents; + gboolean success; + gsize length; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + contents = g_key_file_to_data (key_file, &length, NULL); + g_assert (contents != NULL); + + success = g_file_set_contents (filename, contents, length, error); + g_free (contents); + + return success; +} diff -Nru glib2.0-2.59.2/.pc/01_gettext-desktopfiles.patch/glib/gkeyfile.h glib2.0-2.59.3/.pc/01_gettext-desktopfiles.patch/glib/gkeyfile.h --- glib2.0-2.59.2/.pc/01_gettext-desktopfiles.patch/glib/gkeyfile.h 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/01_gettext-desktopfiles.patch/glib/gkeyfile.h 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,330 @@ +/* gkeyfile.h - desktop entry file parser + * + * Copyright 2004 Red Hat, Inc. + * + * Ray Strode + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + */ + +#ifndef __G_KEY_FILE_H__ +#define __G_KEY_FILE_H__ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +typedef enum +{ + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + G_KEY_FILE_ERROR_PARSE, + G_KEY_FILE_ERROR_NOT_FOUND, + G_KEY_FILE_ERROR_KEY_NOT_FOUND, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + G_KEY_FILE_ERROR_INVALID_VALUE +} GKeyFileError; + +#define G_KEY_FILE_ERROR g_key_file_error_quark() + +GLIB_AVAILABLE_IN_ALL +GQuark g_key_file_error_quark (void); + +typedef struct _GKeyFile GKeyFile; + +typedef enum +{ + G_KEY_FILE_NONE = 0, + G_KEY_FILE_KEEP_COMMENTS = 1 << 0, + G_KEY_FILE_KEEP_TRANSLATIONS = 1 << 1 +} GKeyFileFlags; + +GLIB_AVAILABLE_IN_ALL +GKeyFile *g_key_file_new (void); +GLIB_AVAILABLE_IN_ALL +GKeyFile *g_key_file_ref (GKeyFile *key_file); +GLIB_AVAILABLE_IN_ALL +void g_key_file_unref (GKeyFile *key_file); +GLIB_AVAILABLE_IN_ALL +void g_key_file_free (GKeyFile *key_file); +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_list_separator (GKeyFile *key_file, + gchar separator); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_load_from_file (GKeyFile *key_file, + const gchar *file, + GKeyFileFlags flags, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_load_from_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GKeyFileFlags flags, + GError **error); +GLIB_AVAILABLE_IN_2_50 +gboolean g_key_file_load_from_bytes (GKeyFile *key_file, + GBytes *bytes, + GKeyFileFlags flags, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_load_from_dirs (GKeyFile *key_file, + const gchar *file, + const gchar **search_dirs, + gchar **full_path, + GKeyFileFlags flags, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_load_from_data_dirs (GKeyFile *key_file, + const gchar *file, + gchar **full_path, + GKeyFileFlags flags, + GError **error); +GLIB_AVAILABLE_IN_ALL +gchar *g_key_file_to_data (GKeyFile *key_file, + gsize *length, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_2_40 +gboolean g_key_file_save_to_file (GKeyFile *key_file, + const gchar *filename, + GError **error); +GLIB_AVAILABLE_IN_ALL +gchar *g_key_file_get_start_group (GKeyFile *key_file) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +gchar **g_key_file_get_groups (GKeyFile *key_file, + gsize *length); +GLIB_AVAILABLE_IN_ALL +gchar **g_key_file_get_keys (GKeyFile *key_file, + const gchar *group_name, + gsize *length, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_has_group (GKeyFile *key_file, + const gchar *group_name); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_has_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +GLIB_AVAILABLE_IN_ALL +gchar *g_key_file_get_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *value); +GLIB_AVAILABLE_IN_ALL +gchar *g_key_file_get_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *string); +GLIB_AVAILABLE_IN_ALL +gchar *g_key_file_get_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_2_56 +gchar *g_key_file_get_locale_for_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar *string); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_get_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean value); +GLIB_AVAILABLE_IN_ALL +gint g_key_file_get_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint value); +GLIB_AVAILABLE_IN_ALL +gint64 g_key_file_get_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint64 value); +GLIB_AVAILABLE_IN_ALL +guint64 g_key_file_get_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + guint64 value); +GLIB_AVAILABLE_IN_ALL +gdouble g_key_file_get_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble value); +GLIB_AVAILABLE_IN_ALL +gchar **g_key_file_get_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar * const list[], + gsize length); +GLIB_AVAILABLE_IN_ALL +gchar **g_key_file_get_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + gsize *length, + GError **error); +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar * const list[], + gsize length); +GLIB_AVAILABLE_IN_ALL +gboolean *g_key_file_get_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean list[], + gsize length); +GLIB_AVAILABLE_IN_ALL +gint *g_key_file_get_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble list[], + gsize length); +GLIB_AVAILABLE_IN_ALL +gdouble *g_key_file_get_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) G_GNUC_MALLOC; +GLIB_AVAILABLE_IN_ALL +void g_key_file_set_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint list[], + gsize length); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_set_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *comment, + GError **error); +GLIB_AVAILABLE_IN_ALL +gchar *g_key_file_get_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) G_GNUC_MALLOC; + +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_remove_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_remove_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +GLIB_AVAILABLE_IN_ALL +gboolean g_key_file_remove_group (GKeyFile *key_file, + const gchar *group_name, + GError **error); + +/* Defines for handling freedesktop.org Desktop files */ +#define G_KEY_FILE_DESKTOP_GROUP "Desktop Entry" + +#define G_KEY_FILE_DESKTOP_KEY_TYPE "Type" +#define G_KEY_FILE_DESKTOP_KEY_VERSION "Version" +#define G_KEY_FILE_DESKTOP_KEY_NAME "Name" +#define G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME "GenericName" +#define G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY "NoDisplay" +#define G_KEY_FILE_DESKTOP_KEY_COMMENT "Comment" +#define G_KEY_FILE_DESKTOP_KEY_ICON "Icon" +#define G_KEY_FILE_DESKTOP_KEY_HIDDEN "Hidden" +#define G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN "OnlyShowIn" +#define G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN "NotShowIn" +#define G_KEY_FILE_DESKTOP_KEY_TRY_EXEC "TryExec" +#define G_KEY_FILE_DESKTOP_KEY_EXEC "Exec" +#define G_KEY_FILE_DESKTOP_KEY_PATH "Path" +#define G_KEY_FILE_DESKTOP_KEY_TERMINAL "Terminal" +#define G_KEY_FILE_DESKTOP_KEY_MIME_TYPE "MimeType" +#define G_KEY_FILE_DESKTOP_KEY_CATEGORIES "Categories" +#define G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY "StartupNotify" +#define G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS "StartupWMClass" +#define G_KEY_FILE_DESKTOP_KEY_URL "URL" +#define G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE "DBusActivatable" +#define G_KEY_FILE_DESKTOP_KEY_ACTIONS "Actions" + +#define G_KEY_FILE_DESKTOP_TYPE_APPLICATION "Application" +#define G_KEY_FILE_DESKTOP_TYPE_LINK "Link" +#define G_KEY_FILE_DESKTOP_TYPE_DIRECTORY "Directory" + +G_END_DECLS + +#endif /* __G_KEY_FILE_H__ */ diff -Nru glib2.0-2.59.2/.pc/81-skip-monitor-test-on-non-linux.patch/gio/tests/monitor.c glib2.0-2.59.3/.pc/81-skip-monitor-test-on-non-linux.patch/gio/tests/monitor.c --- glib2.0-2.59.2/.pc/81-skip-monitor-test-on-non-linux.patch/gio/tests/monitor.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/81-skip-monitor-test-on-non-linux.patch/gio/tests/monitor.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,220 @@ +#include +#include + +typedef struct +{ + gchar *tmp_dir; +} Fixture; + +static void +setup (Fixture *fixture, + gconstpointer user_data) +{ + GError *error = NULL; + + fixture->tmp_dir = g_dir_make_tmp ("gio-test-file-monitor_XXXXXX", &error); + g_assert_no_error (error); + + g_test_message ("Using temporary directory: %s", fixture->tmp_dir); +} + +static void +teardown (Fixture *fixture, + gconstpointer user_data) +{ + g_assert_cmpint (g_rmdir (fixture->tmp_dir), ==, 0); + g_clear_pointer (&fixture->tmp_dir, g_free); +} + +typedef struct { + GFile *file; + GOutputStream *stream; + GMainLoop *loop; + gint state; +} MonitorData; + +static gboolean +create_file_idle (gpointer data) +{ + MonitorData *d = data; + GError *error = NULL; + + g_assert (d->state == 0); + + d->stream = (GOutputStream*)g_file_create (d->file, 0, NULL, &error); + g_assert_no_error (error); + + d->state = 1; + + return G_SOURCE_REMOVE; +} + +static gboolean +write_file_idle (gpointer data) +{ + MonitorData *d = data; + GError *error = NULL; + + g_assert (d->state == 2); + + g_output_stream_write (d->stream, "abcd", 4, NULL, &error); + g_assert_no_error (error); + g_object_unref (d->stream); + d->stream = NULL; + + d->state = 3; + + + return G_SOURCE_REMOVE; +} + +static gboolean +delete_file_idle (gpointer data) +{ + MonitorData *d = data; + GError *error = NULL; + + g_assert (d->state == 4); + + g_file_delete (d->file, NULL, &error); + g_assert_no_error (error); + + d->state = 5; + + return G_SOURCE_REMOVE; +} + +static gboolean +stop_loop_idle (gpointer data) +{ + MonitorData *d = data; + + g_assert (d->state == 6); + + if (d->loop) + g_main_loop_quit (d->loop); + + return G_SOURCE_REMOVE; +} + +static void +changed_cb (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event, + gpointer data) +{ + MonitorData *d = data; + + switch (d->state) + { + case 1: + g_assert (event == G_FILE_MONITOR_EVENT_CREATED); + d->state = 2; + g_idle_add (write_file_idle, data); + break; + case 3: + g_assert (event == G_FILE_MONITOR_EVENT_CHANGED || + event == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT); + if (event == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) + { + d->state = 4; + g_idle_add (delete_file_idle, data); + } + break; + case 5: + g_assert (event == G_FILE_MONITOR_EVENT_DELETED); + d->state = 6; + g_idle_add (stop_loop_idle, data); + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +file_changed_cb (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event, + gpointer data) +{ + gint *state = data; + + switch (*state) + { + case 0: + g_assert (event == G_FILE_MONITOR_EVENT_CREATED); + *state = 1; + break; + case 1: + g_assert (event == G_FILE_MONITOR_EVENT_CHANGED || + event == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT); + if (event == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) + *state = 2; + break; + case 2: + g_assert (event == G_FILE_MONITOR_EVENT_DELETED); + *state = 3; + break; + default: + g_assert_not_reached (); + break; + } +} + +static void +test_directory_monitor (Fixture *fixture, + gconstpointer user_data) +{ + GFile *file; + GFile *child; + GFileMonitor *dir_monitor; + GFileMonitor *file_monitor; + GError *error = NULL; + MonitorData data; + gint state; + GMainLoop *loop; + + file = g_file_new_for_path (fixture->tmp_dir); + dir_monitor = g_file_monitor_directory (file, 0, NULL, &error); + g_assert_no_error (error); + + child = g_file_get_child (file, "test-file"); + file_monitor = g_file_monitor_file (child, 0, NULL, &error); + g_assert_no_error (error); + + loop = g_main_loop_new (NULL, FALSE); + + g_signal_connect (dir_monitor, "changed", G_CALLBACK (changed_cb), &data); + g_signal_connect (file_monitor, "changed", G_CALLBACK (file_changed_cb), &state); + + data.loop = loop; + data.file = child; + data.state = 0; + state = 0; + + g_idle_add (create_file_idle, &data); + + g_main_loop_run (loop); + + g_assert_cmpint (data.state, ==, 6); + g_assert_cmpint (state, ==, 3); + + g_main_loop_unref (loop); + g_object_unref (dir_monitor); + g_object_unref (file_monitor); + g_object_unref (child); + g_object_unref (file); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add ("/monitor/directory", Fixture, NULL, setup, test_directory_monitor, teardown); + + return g_test_run (); +} diff -Nru glib2.0-2.59.2/.pc/applied-patches glib2.0-2.59.3/.pc/applied-patches --- glib2.0-2.59.2/.pc/applied-patches 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/applied-patches 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,18 @@ +flaky-socket-service-test/tests-Fix-flaky-socket-service-test-caused-by-GTask-sched.patch +flaky-socket-service-test/tests-Fix-unlikely-race-in-socket-service-test.patch +flaky-socket-service-test/tests-Unmark-socket-service-test-as-flaky.patch +01_gettext-desktopfiles.patch +81-skip-monitor-test-on-non-linux.patch +0001-timer-test-use-volatile-for-locals.patch +gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch +debian/02_gettext-desktopfiles-ubuntu.patch +debian/03_disble_glib_compile_schemas_warning.patch +debian/04_homedir_env.patch +debian/06_thread_test_ignore_prctl_fail.patch +debian/61_glib-compile-binaries-path.patch +debian/90_gio-modules-multiarch-compat.patch +debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch +debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch +debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch +debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch +debian/Skip-unreliable-test_threaded_singleton-by-default.patch diff -Nru glib2.0-2.59.2/.pc/debian/02_gettext-desktopfiles-ubuntu.patch/glib/gkeyfile.c glib2.0-2.59.3/.pc/debian/02_gettext-desktopfiles-ubuntu.patch/glib/gkeyfile.c --- glib2.0-2.59.2/.pc/debian/02_gettext-desktopfiles-ubuntu.patch/glib/gkeyfile.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/02_gettext-desktopfiles-ubuntu.patch/glib/gkeyfile.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,4714 @@ +/* gkeyfile.c - key file parser + * + * Copyright 2004 Red Hat, Inc. + * Copyright 2009-2010 Collabora Ltd. + * Copyright 2009 Nokia Corporation + * + * Written by Ray Strode + * Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + */ + +#include "config.h" + +#include "gkeyfile.h" +#include "gutils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef G_OS_UNIX +#include +#endif +#ifdef G_OS_WIN32 +#include + +#undef fstat +#define fstat(a,b) _fstati64(a,b) +#undef stat +#define stat _stati64 + +#ifndef S_ISREG +#define S_ISREG(mode) ((mode)&_S_IFREG) +#endif + +#endif /* G_OS_WIN23 */ + +#include "gconvert.h" +#include "gdataset.h" +#include "gerror.h" +#include "gfileutils.h" +#include "ghash.h" +#include "glibintl.h" +#include "glist.h" +#include "gslist.h" +#include "gmem.h" +#include "gmessages.h" +#include "gstdio.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "gutils.h" + + +/** + * SECTION:keyfile + * @title: Key-value file parser + * @short_description: parses .ini-like config files + * + * #GKeyFile lets you parse, edit or create files containing groups of + * key-value pairs, which we call "key files" for lack of a better name. + * Several freedesktop.org specifications use key files now, e.g the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec) + * and the + * [Icon Theme Specification](http://freedesktop.org/Standards/icon-theme-spec). + * + * The syntax of key files is described in detail in the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec), + * here is a quick summary: Key files + * consists of groups of key-value pairs, interspersed with comments. + * + * |[ + * # this is just an example + * # there can be comments before the first group + * + * [First Group] + * + * Name=Key File Example\tthis value shows\nescaping + * + * # localized strings are stored in multiple key-value pairs + * Welcome=Hello + * Welcome[de]=Hallo + * Welcome[fr_FR]=Bonjour + * Welcome[it]=Ciao + * Welcome[be@latin]=Hello + * + * [Another Group] + * + * Numbers=2;20;-200;0 + * + * Booleans=true;false;true;true + * ]| + * + * Lines beginning with a '#' and blank lines are considered comments. + * + * Groups are started by a header line containing the group name enclosed + * in '[' and ']', and ended implicitly by the start of the next group or + * the end of the file. Each key-value pair must be contained in a group. + * + * Key-value pairs generally have the form `key=value`, with the + * exception of localized strings, which have the form + * `key[locale]=value`, with a locale identifier of the + * form `lang_COUNTRY@MODIFIER` where `COUNTRY` and `MODIFIER` + * are optional. + * Space before and after the '=' character are ignored. Newline, tab, + * carriage return and backslash characters in value are escaped as \n, + * \t, \r, and \\\\, respectively. To preserve leading spaces in values, + * these can also be escaped as \s. + * + * Key files can store strings (possibly with localized variants), integers, + * booleans and lists of these. Lists are separated by a separator character, + * typically ';' or ','. To use the list separator character in a value in + * a list, it has to be escaped by prefixing it with a backslash. + * + * This syntax is obviously inspired by the .ini files commonly met + * on Windows, but there are some important differences: + * + * - .ini files use the ';' character to begin comments, + * key files use the '#' character. + * + * - Key files do not allow for ungrouped keys meaning only + * comments can precede the first group. + * + * - Key files are always encoded in UTF-8. + * + * - Key and Group names are case-sensitive. For example, a group called + * [GROUP] is a different from [group]. + * + * - .ini files don't have a strongly typed boolean entry type, + * they only have GetProfileInt(). In key files, only + * true and false (in lower case) are allowed. + * + * Note that in contrast to the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec), + * groups in key files may contain the same + * key multiple times; the last entry wins. Key files may also contain + * multiple groups with the same name; they are merged together. + * Another difference is that keys and group names in key files are not + * restricted to ASCII characters. + * + * Here is an example of loading a key file and reading a value: + * |[ + * g_autoptr(GError) error = NULL; + * g_autoptr(GKeyFile) key_file = g_key_file_new (); + * + * if (!g_key_file_load_from_file (key_file, "key-file.ini", flags, &error)) + * { + * if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + * g_warning ("Error loading key file: %s", error->message); + * return; + * } + * + * g_autofree gchar *val = g_key_file_get_string (key_file, "Group Name", "SomeKey", &error); + * if (val == NULL && + * !g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) + * { + * g_warning ("Error finding key in key file: %s", error->message); + * return; + * } + * else if (val == NULL) + * { + * // Fall back to a default value. + * val = g_strdup ("default-value"); + * } + * ]| + * + * Here is an example of creating and saving a key file: + * |[ + * g_autoptr(GKeyFile) key_file = g_key_file_new (); + * const gchar *val = …; + * g_autoptr(GError) error = NULL; + * + * g_key_file_set_string (key_file, "Group Name", "SomeKey", val); + * + * // Save as a file. + * if (!g_key_file_save_to_file (key_file, "key-file.ini", &error)) + * { + * g_warning ("Error saving key file: %s", error->message); + * return; + * } + * + * // Or store to a GBytes for use elsewhere. + * gsize data_len; + * g_autofree guint8 *data = (guint8 *) g_key_file_to_data (key_file, &data_len, &error); + * if (data == NULL) + * { + * g_warning ("Error saving key file: %s", error->message); + * return; + * } + * g_autoptr(GBytes) bytes = g_bytes_new_take (g_steal_pointer (&data), data_len); + * ]| + */ + +/** + * G_KEY_FILE_ERROR: + * + * Error domain for key file parsing. Errors in this domain will + * be from the #GKeyFileError enumeration. + * + * See #GError for information on error domains. + */ + +/** + * GKeyFileError: + * @G_KEY_FILE_ERROR_UNKNOWN_ENCODING: the text being parsed was in + * an unknown encoding + * @G_KEY_FILE_ERROR_PARSE: document was ill-formed + * @G_KEY_FILE_ERROR_NOT_FOUND: the file was not found + * @G_KEY_FILE_ERROR_KEY_NOT_FOUND: a requested key was not found + * @G_KEY_FILE_ERROR_GROUP_NOT_FOUND: a requested group was not found + * @G_KEY_FILE_ERROR_INVALID_VALUE: a value could not be parsed + * + * Error codes returned by key file parsing. + */ + +/** + * GKeyFileFlags: + * @G_KEY_FILE_NONE: No flags, default behaviour + * @G_KEY_FILE_KEEP_COMMENTS: Use this flag if you plan to write the + * (possibly modified) contents of the key file back to a file; + * otherwise all comments will be lost when the key file is + * written back. + * @G_KEY_FILE_KEEP_TRANSLATIONS: Use this flag if you plan to write the + * (possibly modified) contents of the key file back to a file; + * otherwise only the translations for the current language will be + * written back. + * + * Flags which influence the parsing. + */ + +/** + * G_KEY_FILE_DESKTOP_GROUP: + * + * The name of the main group of a desktop entry file, as defined in the + * [Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec). + * Consult the specification for more + * details about the meanings of the keys below. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TYPE: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the type of the desktop entry. Usually + * #G_KEY_FILE_DESKTOP_TYPE_APPLICATION, + * #G_KEY_FILE_DESKTOP_TYPE_LINK, or + * #G_KEY_FILE_DESKTOP_TYPE_DIRECTORY. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_VERSION: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the version of the Desktop Entry Specification used for + * the desktop entry file. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NAME: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the specific name of the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the generic name of the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the desktop entry should be shown in menus. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_COMMENT: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the tooltip for the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_ICON: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the name of the icon to be displayed for the desktop + * entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_HIDDEN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the desktop entry has been deleted by the user. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of + * strings identifying the environments that should display the + * desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of + * strings identifying the environments that should not display the + * desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TRY_EXEC: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the file name of a binary on disk used to determine if the + * program is actually installed. It is only valid for desktop entries + * with the `Application` type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_EXEC: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the command line to execute. It is only valid for desktop + * entries with the `Application` type. + * + * Since: 2.14 + */ + + /** + * G_KEY_FILE_DESKTOP_KEY_PATH: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * containing the working directory to run the program in. It is only + * valid for desktop entries with the `Application` type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TERMINAL: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the program should be run in a terminal window. + * It is only valid for desktop entries with the + * `Application` type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_MIME_TYPE: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list + * of strings giving the MIME types supported by this desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_CATEGORIES: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list + * of strings giving the categories in which the desktop entry + * should be shown in a menu. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the application supports the + * [Startup Notification Protocol Specification](http://www.freedesktop.org/Standards/startup-notification-spec). + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is string + * identifying the WM class or name hint of a window that the application + * will create, which can be used to emulate Startup Notification with + * older applications. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_URL: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the URL to access. It is only valid for desktop entries + * with the `Link` type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean set to true + * if the application is D-Bus activatable. + * + * Since: 2.38 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_ACTIONS: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string list + * giving the available application actions. + * + * Since: 2.38 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_APPLICATION: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing applications. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_LINK: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing links to documents. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_DIRECTORY: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing directories. + * + * Since: 2.14 + */ + +typedef struct _GKeyFileGroup GKeyFileGroup; + +/** + * GKeyFile: + * + * The GKeyFile struct contains only private data + * and should not be accessed directly. + */ +struct _GKeyFile +{ + GList *groups; + GHashTable *group_hash; + + GKeyFileGroup *start_group; + GKeyFileGroup *current_group; + + GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */ + + gchar list_separator; + + GKeyFileFlags flags; + + gchar **locales; + gchar *gettext_domain; + + volatile gint ref_count; +}; + +typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair; + +struct _GKeyFileGroup +{ + const gchar *name; /* NULL for above first group (which will be comments) */ + + GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */ + + GList *key_value_pairs; + + /* Used in parallel with key_value_pairs for + * increased lookup performance + */ + GHashTable *lookup_map; +}; + +struct _GKeyFileKeyValuePair +{ + gchar *key; /* NULL for comments */ + gchar *value; +}; + +static gint find_file_in_data_dirs (const gchar *file, + const gchar **data_dirs, + gchar **output_file, + GError **error); +static gboolean g_key_file_load_from_fd (GKeyFile *key_file, + gint fd, + GKeyFileFlags flags, + GError **error); +static GList *g_key_file_lookup_group_node (GKeyFile *key_file, + const gchar *group_name); +static GKeyFileGroup *g_key_file_lookup_group (GKeyFile *key_file, + const gchar *group_name); + +static GList *g_key_file_lookup_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key); +static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key); + +static void g_key_file_remove_group_node (GKeyFile *key_file, + GList *group_node); +static void g_key_file_remove_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + GList *pair_node); + +static void g_key_file_add_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + GKeyFileKeyValuePair *pair); +static void g_key_file_add_key (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key, + const gchar *value); +static void g_key_file_add_group (GKeyFile *key_file, + const gchar *group_name); +static gboolean g_key_file_is_group_name (const gchar *name); +static gboolean g_key_file_is_key_name (const gchar *name); +static void g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair); +static gboolean g_key_file_line_is_comment (const gchar *line); +static gboolean g_key_file_line_is_group (const gchar *line); +static gboolean g_key_file_line_is_key_value_pair (const gchar *line); +static gchar *g_key_file_parse_value_as_string (GKeyFile *key_file, + const gchar *value, + GSList **separators, + GError **error); +static gchar *g_key_file_parse_string_as_value (GKeyFile *key_file, + const gchar *string, + gboolean escape_separator); +static gint g_key_file_parse_value_as_integer (GKeyFile *key_file, + const gchar *value, + GError **error); +static gchar *g_key_file_parse_integer_as_value (GKeyFile *key_file, + gint value); +static gdouble g_key_file_parse_value_as_double (GKeyFile *key_file, + const gchar *value, + GError **error); +static gboolean g_key_file_parse_value_as_boolean (GKeyFile *key_file, + const gchar *value, + GError **error); +static gchar *g_key_file_parse_boolean_as_value (GKeyFile *key_file, + gboolean value); +static gchar *g_key_file_parse_value_as_comment (GKeyFile *key_file, + const gchar *value, + gboolean is_final_line); +static gchar *g_key_file_parse_comment_as_value (GKeyFile *key_file, + const gchar *comment); +static void g_key_file_parse_key_value_pair (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static void g_key_file_parse_comment (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static void g_key_file_parse_group (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static gchar *key_get_locale (const gchar *key); +static void g_key_file_parse_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GError **error); +static void g_key_file_flush_parse_buffer (GKeyFile *key_file, + GError **error); + +G_DEFINE_QUARK (g-key-file-error-quark, g_key_file_error) + +static void +g_key_file_init (GKeyFile *key_file) +{ + key_file->current_group = g_slice_new0 (GKeyFileGroup); + key_file->groups = g_list_prepend (NULL, key_file->current_group); + key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal); + key_file->start_group = NULL; + key_file->parse_buffer = g_string_sized_new (128); + key_file->list_separator = ';'; + key_file->flags = 0; + key_file->locales = g_strdupv ((gchar **)g_get_language_names ()); + key_file->gettext_domain = NULL; +} + +static void +g_key_file_clear (GKeyFile *key_file) +{ + GList *tmp, *group_node; + + if (key_file->locales) + { + g_strfreev (key_file->locales); + key_file->locales = NULL; + } + + if (key_file->parse_buffer) + { + g_string_free (key_file->parse_buffer, TRUE); + key_file->parse_buffer = NULL; + } + + if (key_file->gettext_domain) + { + g_free (key_file->gettext_domain); + key_file->gettext_domain = NULL; + } + + tmp = key_file->groups; + while (tmp != NULL) + { + group_node = tmp; + tmp = tmp->next; + g_key_file_remove_group_node (key_file, group_node); + } + + if (key_file->group_hash != NULL) + { + g_hash_table_destroy (key_file->group_hash); + key_file->group_hash = NULL; + } + + g_warn_if_fail (key_file->groups == NULL); +} + + +/** + * g_key_file_new: + * + * Creates a new empty #GKeyFile object. Use + * g_key_file_load_from_file(), g_key_file_load_from_data(), + * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to + * read an existing key file. + * + * Returns: (transfer full): an empty #GKeyFile. + * + * Since: 2.6 + **/ +GKeyFile * +g_key_file_new (void) +{ + GKeyFile *key_file; + + key_file = g_slice_new0 (GKeyFile); + key_file->ref_count = 1; + g_key_file_init (key_file); + + return key_file; +} + +/** + * g_key_file_set_list_separator: + * @key_file: a #GKeyFile + * @separator: the separator + * + * Sets the character which is used to separate + * values in lists. Typically ';' or ',' are used + * as separators. The default list separator is ';'. + * + * Since: 2.6 + */ +void +g_key_file_set_list_separator (GKeyFile *key_file, + gchar separator) +{ + g_return_if_fail (key_file != NULL); + + key_file->list_separator = separator; +} + + +/* Iterates through all the directories in *dirs trying to + * open file. When it successfully locates and opens a file it + * returns the file descriptor to the open file. It also + * outputs the absolute path of the file in output_file. + */ +static gint +find_file_in_data_dirs (const gchar *file, + const gchar **dirs, + gchar **output_file, + GError **error) +{ + const gchar **data_dirs, *data_dir; + gchar *path; + gint fd; + + path = NULL; + fd = -1; + + if (dirs == NULL) + return fd; + + data_dirs = dirs; + + while (data_dirs && (data_dir = *data_dirs) && fd == -1) + { + gchar *candidate_file, *sub_dir; + + candidate_file = (gchar *) file; + sub_dir = g_strdup (""); + while (candidate_file != NULL && fd == -1) + { + gchar *p; + + path = g_build_filename (data_dir, sub_dir, + candidate_file, NULL); + + fd = g_open (path, O_RDONLY, 0); + + if (fd == -1) + { + g_free (path); + path = NULL; + } + + candidate_file = strchr (candidate_file, '-'); + + if (candidate_file == NULL) + break; + + candidate_file++; + + g_free (sub_dir); + sub_dir = g_strndup (file, candidate_file - file - 1); + + for (p = sub_dir; *p != '\0'; p++) + { + if (*p == '-') + *p = G_DIR_SEPARATOR; + } + } + g_free (sub_dir); + data_dirs++; + } + + if (fd == -1) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_NOT_FOUND, + _("Valid key file could not be " + "found in search dirs")); + } + + if (output_file != NULL && fd != -1) + *output_file = g_strdup (path); + + g_free (path); + + return fd; +} + +static gboolean +g_key_file_load_from_fd (GKeyFile *key_file, + gint fd, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gssize bytes_read; + struct stat stat_buf; + gchar read_buf[4096]; + gchar list_separator; + + if (fstat (fd, &stat_buf) < 0) + { + int errsv = errno; + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errsv), + g_strerror (errsv)); + return FALSE; + } + + if (!S_ISREG (stat_buf.st_mode)) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Not a regular file")); + return FALSE; + } + + list_separator = key_file->list_separator; + g_key_file_clear (key_file); + g_key_file_init (key_file); + key_file->list_separator = list_separator; + key_file->flags = flags; + + do + { + int errsv; + + bytes_read = read (fd, read_buf, 4096); + errsv = errno; + + if (bytes_read == 0) /* End of File */ + break; + + if (bytes_read < 0) + { + if (errsv == EINTR || errsv == EAGAIN) + continue; + + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errsv), + g_strerror (errsv)); + return FALSE; + } + + g_key_file_parse_data (key_file, + read_buf, bytes_read, + &key_file_error); + } + while (!key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + g_key_file_flush_parse_buffer (key_file, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + key_file->gettext_domain = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, + NULL); + + return TRUE; +} + +/** + * g_key_file_load_from_file: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): the path of a filename to load, in the GLib filename encoding + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * Loads a key file into an empty #GKeyFile structure. + * + * If the OS returns an error when opening or reading the file, a + * %G_FILE_ERROR is returned. If there is a problem parsing the file, a + * %G_KEY_FILE_ERROR is returned. + * + * This function will never return a %G_KEY_FILE_ERROR_NOT_FOUND error. If the + * @file is not found, %G_FILE_ERROR_NOENT is returned. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_file (GKeyFile *key_file, + const gchar *file, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gint fd; + int errsv; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (file != NULL, FALSE); + + fd = g_open (file, O_RDONLY, 0); + errsv = errno; + + if (fd == -1) + { + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errsv), + g_strerror (errsv)); + return FALSE; + } + + g_key_file_load_from_fd (key_file, fd, flags, &key_file_error); + close (fd); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + key_file->gettext_domain = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_GETTEXT_DOMAIN, + NULL); + + return TRUE; +} + +/** + * g_key_file_load_from_data: + * @key_file: an empty #GKeyFile struct + * @data: key file loaded in memory + * @length: the length of @data in bytes (or (gsize)-1 if data is nul-terminated) + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * Loads a key file from memory into an empty #GKeyFile structure. + * If the object cannot be created then %error is set to a #GKeyFileError. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gchar list_separator; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (data != NULL || length == 0, FALSE); + + if (length == (gsize)-1) + length = strlen (data); + + list_separator = key_file->list_separator; + g_key_file_clear (key_file); + g_key_file_init (key_file); + key_file->list_separator = list_separator; + key_file->flags = flags; + + g_key_file_parse_data (key_file, data, length, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + g_key_file_flush_parse_buffer (key_file, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + return TRUE; +} + +/** + * g_key_file_load_from_bytes: + * @key_file: an empty #GKeyFile struct + * @bytes: a #GBytes + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * Loads a key file from the data in @bytes into an empty #GKeyFile structure. + * If the object cannot be created then %error is set to a #GKeyFileError. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.50 + **/ +gboolean +g_key_file_load_from_bytes (GKeyFile *key_file, + GBytes *bytes, + GKeyFileFlags flags, + GError **error) +{ + const guchar *data; + gsize size; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (bytes != NULL, FALSE); + + data = g_bytes_get_data (bytes, &size); + return g_key_file_load_from_data (key_file, (const gchar *) data, size, flags, error); +} + +/** + * g_key_file_load_from_dirs: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): a relative path to a filename to open and parse + * @search_dirs: (array zero-terminated=1) (element-type filename): %NULL-terminated array of directories to search + * @full_path: (out) (type filename) (optional): return location for a string containing the full path + * of the file, or %NULL + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * This function looks for a key file named @file in the paths + * specified in @search_dirs, loads the file into @key_file and + * returns the file's full path in @full_path. + * + * If the file could not be found in any of the @search_dirs, + * %G_KEY_FILE_ERROR_NOT_FOUND is returned. If + * the file is found but the OS returns an error when opening or reading the + * file, a %G_FILE_ERROR is returned. If there is a problem parsing the file, a + * %G_KEY_FILE_ERROR is returned. + * + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.14 + **/ +gboolean +g_key_file_load_from_dirs (GKeyFile *key_file, + const gchar *file, + const gchar **search_dirs, + gchar **full_path, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + const gchar **data_dirs; + gchar *output_path; + gint fd; + gboolean found_file; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (!g_path_is_absolute (file), FALSE); + g_return_val_if_fail (search_dirs != NULL, FALSE); + + found_file = FALSE; + data_dirs = search_dirs; + output_path = NULL; + while (*data_dirs != NULL && !found_file) + { + g_free (output_path); + output_path = NULL; + + fd = find_file_in_data_dirs (file, data_dirs, &output_path, + &key_file_error); + + if (fd == -1) + { + if (key_file_error) + g_propagate_error (error, key_file_error); + break; + } + + found_file = g_key_file_load_from_fd (key_file, fd, flags, + &key_file_error); + close (fd); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + break; + } + } + + if (found_file && full_path) + *full_path = output_path; + else + g_free (output_path); + + return found_file; +} + +/** + * g_key_file_load_from_data_dirs: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): a relative path to a filename to open and parse + * @full_path: (out) (type filename) (optional): return location for a string containing the full path + * of the file, or %NULL + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * This function looks for a key file named @file in the paths + * returned from g_get_user_data_dir() and g_get_system_data_dirs(), + * loads the file into @key_file and returns the file's full path in + * @full_path. If the file could not be loaded then an %error is + * set to either a #GFileError or #GKeyFileError. + * + * Returns: %TRUE if a key file could be loaded, %FALSE othewise + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_data_dirs (GKeyFile *key_file, + const gchar *file, + gchar **full_path, + GKeyFileFlags flags, + GError **error) +{ + gchar **all_data_dirs; + const gchar * user_data_dir; + const gchar * const * system_data_dirs; + gsize i, j; + gboolean found_file; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (!g_path_is_absolute (file), FALSE); + + user_data_dir = g_get_user_data_dir (); + system_data_dirs = g_get_system_data_dirs (); + all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2); + + i = 0; + all_data_dirs[i++] = g_strdup (user_data_dir); + + j = 0; + while (system_data_dirs[j] != NULL) + all_data_dirs[i++] = g_strdup (system_data_dirs[j++]); + all_data_dirs[i] = NULL; + + found_file = g_key_file_load_from_dirs (key_file, + file, + (const gchar **)all_data_dirs, + full_path, + flags, + error); + + g_strfreev (all_data_dirs); + + return found_file; +} + +/** + * g_key_file_ref: (skip) + * @key_file: a #GKeyFile + * + * Increases the reference count of @key_file. + * + * Returns: the same @key_file. + * + * Since: 2.32 + **/ +GKeyFile * +g_key_file_ref (GKeyFile *key_file) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + g_atomic_int_inc (&key_file->ref_count); + + return key_file; +} + +/** + * g_key_file_free: (skip) + * @key_file: a #GKeyFile + * + * Clears all keys and groups from @key_file, and decreases the + * reference count by 1. If the reference count reaches zero, + * frees the key file and all its allocated memory. + * + * Since: 2.6 + **/ +void +g_key_file_free (GKeyFile *key_file) +{ + g_return_if_fail (key_file != NULL); + + g_key_file_clear (key_file); + + if (g_atomic_int_dec_and_test (&key_file->ref_count)) + g_slice_free (GKeyFile, key_file); + else + g_key_file_init (key_file); +} + +/** + * g_key_file_unref: + * @key_file: a #GKeyFile + * + * Decreases the reference count of @key_file by 1. If the reference count + * reaches zero, frees the key file and all its allocated memory. + * + * Since: 2.32 + **/ +void +g_key_file_unref (GKeyFile *key_file) +{ + g_return_if_fail (key_file != NULL); + + if (g_atomic_int_dec_and_test (&key_file->ref_count)) + { + g_key_file_clear (key_file); + g_slice_free (GKeyFile, key_file); + } +} + +/* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns + * true for locales that match those in g_get_language_names(). + */ +static gboolean +g_key_file_locale_is_interesting (GKeyFile *key_file, + const gchar *locale) +{ + gsize i; + + if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS) + return TRUE; + + for (i = 0; key_file->locales[i] != NULL; i++) + { + if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0) + return TRUE; + } + + return FALSE; +} + +static void +g_key_file_parse_line (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + GError *parse_error = NULL; + gchar *line_start; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (line != NULL); + + line_start = (gchar *) line; + while (g_ascii_isspace (*line_start)) + line_start++; + + if (g_key_file_line_is_comment (line_start)) + g_key_file_parse_comment (key_file, line, length, &parse_error); + else if (g_key_file_line_is_group (line_start)) + g_key_file_parse_group (key_file, line_start, + length - (line_start - line), + &parse_error); + else if (g_key_file_line_is_key_value_pair (line_start)) + g_key_file_parse_key_value_pair (key_file, line_start, + length - (line_start - line), + &parse_error); + else + { + gchar *line_utf8 = g_utf8_make_valid (line, length); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Key file contains line “%s” which is not " + "a key-value pair, group, or comment"), + line_utf8); + g_free (line_utf8); + + return; + } + + if (parse_error) + g_propagate_error (error, parse_error); +} + +static void +g_key_file_parse_comment (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + GKeyFileKeyValuePair *pair; + + if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS)) + return; + + g_warn_if_fail (key_file->current_group != NULL); + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_strndup (line, length); + + key_file->current_group->key_value_pairs = + g_list_prepend (key_file->current_group->key_value_pairs, pair); +} + +static void +g_key_file_parse_group (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + gchar *group_name; + const gchar *group_name_start, *group_name_end; + + /* advance past opening '[' + */ + group_name_start = line + 1; + group_name_end = line + length - 1; + + while (*group_name_end != ']') + group_name_end--; + + group_name = g_strndup (group_name_start, + group_name_end - group_name_start); + + if (!g_key_file_is_group_name (group_name)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Invalid group name: %s"), group_name); + g_free (group_name); + return; + } + + g_key_file_add_group (key_file, group_name); + g_free (group_name); +} + +static void +g_key_file_parse_key_value_pair (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + gchar *key, *value, *key_end, *value_start, *locale; + gsize key_len, value_len; + + if (key_file->current_group == NULL || key_file->current_group->name == NULL) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not start with a group")); + return; + } + + key_end = value_start = strchr (line, '='); + + g_warn_if_fail (key_end != NULL); + + key_end--; + value_start++; + + /* Pull the key name from the line (chomping trailing whitespace) + */ + while (g_ascii_isspace (*key_end)) + key_end--; + + key_len = key_end - line + 2; + + g_warn_if_fail (key_len <= length); + + key = g_strndup (line, key_len - 1); + + if (!g_key_file_is_key_name (key)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Invalid key name: %s"), key); + g_free (key); + return; + } + + /* Pull the value from the line (chugging leading whitespace) + */ + while (g_ascii_isspace (*value_start)) + value_start++; + + value_len = line + length - value_start + 1; + + value = g_strndup (value_start, value_len); + + g_warn_if_fail (key_file->start_group != NULL); + + if (key_file->current_group + && key_file->current_group->name + && strcmp (key_file->start_group->name, + key_file->current_group->name) == 0 + && strcmp (key, "Encoding") == 0) + { + if (g_ascii_strcasecmp (value, "UTF-8") != 0) + { + gchar *value_utf8 = g_utf8_make_valid (value, value_len); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains unsupported " + "encoding “%s”"), value_utf8); + g_free (value_utf8); + + g_free (key); + g_free (value); + return; + } + } + + /* Is this key a translation? If so, is it one that we care about? + */ + locale = key_get_locale (key); + + if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale)) + { + GKeyFileKeyValuePair *pair; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = key; + pair->value = value; + + g_key_file_add_key_value_pair (key_file, key_file->current_group, pair); + } + else + { + g_free (key); + g_free (value); + } + + g_free (locale); +} + +static gchar * +key_get_locale (const gchar *key) +{ + gchar *locale; + + locale = g_strrstr (key, "["); + + if (locale && strlen (locale) <= 2) + locale = NULL; + + if (locale) + locale = g_strndup (locale + 1, strlen (locale) - 2); + + return locale; +} + +static void +g_key_file_parse_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GError **error) +{ + GError *parse_error; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (data != NULL || length == 0); + + parse_error = NULL; + + i = 0; + while (i < length) + { + if (data[i] == '\n') + { + if (key_file->parse_buffer->len > 0 + && (key_file->parse_buffer->str[key_file->parse_buffer->len - 1] + == '\r')) + g_string_erase (key_file->parse_buffer, + key_file->parse_buffer->len - 1, + 1); + + /* When a newline is encountered flush the parse buffer so that the + * line can be parsed. Note that completely blank lines won't show + * up in the parse buffer, so they get parsed directly. + */ + if (key_file->parse_buffer->len > 0) + g_key_file_flush_parse_buffer (key_file, &parse_error); + else + g_key_file_parse_comment (key_file, "", 1, &parse_error); + + if (parse_error) + { + g_propagate_error (error, parse_error); + return; + } + i++; + } + else + { + const gchar *start_of_line; + const gchar *end_of_line; + gsize line_length; + + start_of_line = data + i; + end_of_line = memchr (start_of_line, '\n', length - i); + + if (end_of_line == NULL) + end_of_line = data + length; + + line_length = end_of_line - start_of_line; + + g_string_append_len (key_file->parse_buffer, start_of_line, line_length); + i += line_length; + } + } +} + +static void +g_key_file_flush_parse_buffer (GKeyFile *key_file, + GError **error) +{ + GError *file_error = NULL; + + g_return_if_fail (key_file != NULL); + + file_error = NULL; + + if (key_file->parse_buffer->len > 0) + { + g_key_file_parse_line (key_file, key_file->parse_buffer->str, + key_file->parse_buffer->len, + &file_error); + g_string_erase (key_file->parse_buffer, 0, -1); + + if (file_error) + { + g_propagate_error (error, file_error); + return; + } + } +} + +/** + * g_key_file_to_data: + * @key_file: a #GKeyFile + * @length: (out) (optional): return location for the length of the + * returned string, or %NULL + * @error: return location for a #GError, or %NULL + * + * This function outputs @key_file as a string. + * + * Note that this function never reports an error, + * so it is safe to pass %NULL as @error. + * + * Returns: a newly allocated string holding + * the contents of the #GKeyFile + * + * Since: 2.6 + **/ +gchar * +g_key_file_to_data (GKeyFile *key_file, + gsize *length, + GError **error) +{ + GString *data_string; + GList *group_node, *key_file_node; + + g_return_val_if_fail (key_file != NULL, NULL); + + data_string = g_string_new (NULL); + + for (group_node = g_list_last (key_file->groups); + group_node != NULL; + group_node = group_node->prev) + { + GKeyFileGroup *group; + + group = (GKeyFileGroup *) group_node->data; + + /* separate groups by at least an empty line */ + if (data_string->len >= 2 && + data_string->str[data_string->len - 2] != '\n') + g_string_append_c (data_string, '\n'); + + if (group->comment != NULL) + g_string_append_printf (data_string, "%s\n", group->comment->value); + + if (group->name != NULL) + g_string_append_printf (data_string, "[%s]\n", group->name); + + for (key_file_node = g_list_last (group->key_value_pairs); + key_file_node != NULL; + key_file_node = key_file_node->prev) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) key_file_node->data; + + if (pair->key != NULL) + g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value); + else + g_string_append_printf (data_string, "%s\n", pair->value); + } + } + + if (length) + *length = data_string->len; + + return g_string_free (data_string, FALSE); +} + +/** + * g_key_file_get_keys: + * @key_file: a #GKeyFile + * @group_name: a group name + * @length: (out) (optional): return location for the number of keys returned, or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns all keys for the group name @group_name. The array of + * returned keys will be %NULL-terminated, so @length may + * optionally be %NULL. In the event that the @group_name cannot + * be found, %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Returns: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_keys (GKeyFile *key_file, + const gchar *group_name, + gsize *length, + GError **error) +{ + GKeyFileGroup *group; + GList *tmp; + gchar **keys; + gsize i, num_keys; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + return NULL; + } + + num_keys = 0; + for (tmp = group->key_value_pairs; tmp; tmp = tmp->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key) + num_keys++; + } + + keys = g_new (gchar *, num_keys + 1); + + i = num_keys - 1; + for (tmp = group->key_value_pairs; tmp; tmp = tmp->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key) + { + keys[i] = g_strdup (pair->key); + i--; + } + } + + keys[num_keys] = NULL; + + if (length) + *length = num_keys; + + return keys; +} + +/** + * g_key_file_get_start_group: + * @key_file: a #GKeyFile + * + * Returns the name of the start group of the file. + * + * Returns: The start group of the key file. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_start_group (GKeyFile *key_file) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + if (key_file->start_group) + return g_strdup (key_file->start_group->name); + + return NULL; +} + +/** + * g_key_file_get_groups: + * @key_file: a #GKeyFile + * @length: (out) (optional): return location for the number of returned groups, or %NULL + * + * Returns all groups in the key file loaded with @key_file. + * The array of returned groups will be %NULL-terminated, so + * @length may optionally be %NULL. + * + * Returns: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * Since: 2.6 + **/ +gchar ** +g_key_file_get_groups (GKeyFile *key_file, + gsize *length) +{ + GList *group_node; + gchar **groups; + gsize i, num_groups; + + g_return_val_if_fail (key_file != NULL, NULL); + + num_groups = g_list_length (key_file->groups); + + g_return_val_if_fail (num_groups > 0, NULL); + + group_node = g_list_last (key_file->groups); + + g_return_val_if_fail (((GKeyFileGroup *) group_node->data)->name == NULL, NULL); + + /* Only need num_groups instead of num_groups + 1 + * because the first group of the file (last in the + * list) is always the comment group at the top, + * which we skip + */ + groups = g_new (gchar *, num_groups); + + + i = 0; + for (group_node = group_node->prev; + group_node != NULL; + group_node = group_node->prev) + { + GKeyFileGroup *group; + + group = (GKeyFileGroup *) group_node->data; + + g_warn_if_fail (group->name != NULL); + + groups[i++] = g_strdup (group->name); + } + groups[i] = NULL; + + if (length) + *length = i; + + return groups; +} + +static void +set_not_found_key_error (const char *group_name, + const char *key, + GError **error) +{ + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND, + _("Key file does not have key “%s” in group “%s”"), + key, group_name); +} + +/** + * g_key_file_get_value: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError, or %NULL + * + * Returns the raw value associated with @key under @group_name. + * Use g_key_file_get_string() to retrieve an unescaped UTF-8 string. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * + * Returns: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + gchar *value = NULL; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + return NULL; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (pair) + value = g_strdup (pair->value); + else + set_not_found_key_error (group_name, key, error); + + return value; +} + +/** + * g_key_file_set_value: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: a string + * + * Associates a new value with @key under @group_name. + * + * If @key cannot be found then it is created. If @group_name cannot + * be found then it is created. To set an UTF-8 string which may contain + * characters that need escaping (such as newlines or spaces), use + * g_key_file_set_string(). + * + * Since: 2.6 + **/ +void +g_key_file_set_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *value) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (g_key_file_is_group_name (group_name)); + g_return_if_fail (g_key_file_is_key_name (key)); + g_return_if_fail (value != NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_key_file_add_group (key_file, group_name); + group = (GKeyFileGroup *) key_file->groups->data; + + g_key_file_add_key (key_file, group, key, value); + } + else + { + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (!pair) + g_key_file_add_key (key_file, group, key, value); + else + { + g_free (pair->value); + pair->value = g_strdup (value); + } + } +} + +/** + * g_key_file_get_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError, or %NULL + * + * Returns the string value associated with @key under @group_name. + * Unlike g_key_file_get_value(), this function handles escape sequences + * like \s. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Returns: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *value, *string_value; + GError *key_file_error; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return NULL; + } + + if (!g_utf8_validate (value, -1, NULL)) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains key “%s” with value “%s” " + "which is not UTF-8"), key, value_utf8); + g_free (value_utf8); + g_free (value); + + return NULL; + } + + string_value = g_key_file_parse_value_as_string (key_file, value, NULL, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return string_value; +} + +/** + * g_key_file_set_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @string: a string + * + * Associates a new string value with @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name cannot be found then it is created. + * Unlike g_key_file_set_value(), this function handles characters + * that need escaping, such as newlines. + * + * Since: 2.6 + **/ +void +g_key_file_set_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *string) +{ + gchar *value; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (string != NULL); + + value = g_key_file_parse_string_as_value (key_file, string, FALSE); + g_key_file_set_value (key_file, group_name, key, value); + g_free (value); +} + +/** + * g_key_file_get_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out) (optional): return location for the number of returned strings, or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns the values associated with @key under @group_name. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Returns: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): + * a %NULL-terminated string array or %NULL if the specified + * key cannot be found. The array should be freed with g_strfreev(). + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar *value, *string_value, **values; + gint i, len; + GSList *p, *pieces = NULL; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return NULL; + } + + if (!g_utf8_validate (value, -1, NULL)) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains key “%s” with value “%s” " + "which is not UTF-8"), key, value_utf8); + g_free (value_utf8); + g_free (value); + + return NULL; + } + + string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error); + g_free (value); + g_free (string_value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + + g_slist_free_full (pieces, g_free); + return NULL; + } + + len = g_slist_length (pieces); + values = g_new (gchar *, len + 1); + for (p = pieces, i = 0; p; p = p->next) + values[i++] = p->data; + values[len] = NULL; + + g_slist_free (pieces); + + if (length) + *length = len; + + return values; +} + +/** + * g_key_file_set_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array zero-terminated=1 length=length) (element-type utf8): an array of string values + * @length: number of string values in @list + * + * Associates a list of string values for @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar * const list[], + gsize length) +{ + GString *value_list; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL || length == 0); + + value_list = g_string_sized_new (length * 128); + for (i = 0; i < length && list[i] != NULL; i++) + { + gchar *value; + + value = g_key_file_parse_string_as_value (key_file, list[i], TRUE); + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, value_list->str); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_set_locale_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: a locale identifier + * @string: a string + * + * Associates a string value for @key and @locale under @group_name. + * If the translation for @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar *string) +{ + gchar *full_key, *value; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (locale != NULL); + g_return_if_fail (string != NULL); + + value = g_key_file_parse_string_as_value (key_file, string, FALSE); + full_key = g_strdup_printf ("%s[%s]", key, locale); + g_key_file_set_value (key_file, group_name, full_key, value); + g_free (full_key); + g_free (value); +} + +/** + * g_key_file_get_locale_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: (nullable): a locale identifier or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns the value associated with @key under @group_name + * translated in the given @locale if available. If @locale is + * %NULL then the current locale is assumed. + * + * If @locale is to be non-%NULL, or if the current locale will change over + * the lifetime of the #GKeyFile, it must be loaded with + * %G_KEY_FILE_KEEP_TRANSLATIONS in order to load strings for all locales. + * + * If @key cannot be found then %NULL is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated + * with @key cannot be interpreted or no suitable translation can + * be found then the untranslated value is returned. + * + * Returns: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + GError **error) +{ + gchar *candidate_key, *translated_value; + GError *key_file_error; + gchar **languages; + gboolean free_languages = FALSE; + gboolean try_gettext = FALSE; + const gchar *msg_locale; + gint i; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + candidate_key = NULL; + translated_value = NULL; + key_file_error = NULL; + + if (locale) + { + languages = g_get_locale_variants (locale); + free_languages = TRUE; + } + else + { + languages = (gchar **) g_get_language_names (); + free_languages = FALSE; + } + + /* we're only interested in gettext translation if we don't have a + * translation in the .desktop file itself and if the key is one of the keys + * we know we want to translate: Name, GenericName, Comment, Keywords. + * Blindly doing this for all keys can give strange result for the icons, + * since the Icon is a locale string in the spec, eg. We also only get + * translation in the mo file if the requested locale is the LC_MESSAGES one. + * Ideally, we should do more and change LC_MESSAGES to use the requested + * locale, but there's no guarantee it's installed on the system and it might + * have some side-effects. Since this is a corner case, let's ignore it. */ + msg_locale = setlocale (LC_MESSAGES, NULL); + try_gettext = msg_locale && key_file->gettext_domain && + (strcmp (group_name, G_KEY_FILE_DESKTOP_GROUP) == 0 || + g_str_has_prefix (group_name, G_KEY_FILE_DESKTOP_ACTION_GROUP_PREFIX)) && + (strcmp (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0 || + strcmp (key, G_KEY_FILE_DESKTOP_KEY_FULLNAME) == 0 || + strcmp (key, G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME) == 0 || + strcmp (key, G_KEY_FILE_DESKTOP_KEY_KEYWORDS) == 0 || + strcmp (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0); + + for (i = 0; languages[i]; i++) + { + candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); + + translated_value = g_key_file_get_string (key_file, + group_name, + candidate_key, NULL); + g_free (candidate_key); + + if (translated_value) + break; + + g_free (translated_value); + translated_value = NULL; + } + + /* Fallback to gettext */ + if (try_gettext && !translated_value) + { + gchar *orig_value = g_key_file_get_string (key_file, group_name, key, NULL); + + if (orig_value) + { + gboolean codeset_set; + const gchar *translated; + gboolean has_gettext; + + codeset_set = bind_textdomain_codeset (key_file->gettext_domain, "UTF-8") != NULL; + translated = NULL; + + translated = g_dgettext (key_file->gettext_domain, + orig_value); + has_gettext = translated != orig_value; + + g_free (orig_value); + + if (has_gettext) + { + if (codeset_set) + translated_value = g_strdup (translated); + else + translated_value = g_locale_to_utf8 (translated, + -1, NULL, NULL, NULL); + } + else + translated_value = NULL; + } + } + + /* Fallback to untranslated key + */ + if (!translated_value) + { + translated_value = g_key_file_get_string (key_file, group_name, key, + &key_file_error); + + if (!translated_value) + g_propagate_error (error, key_file_error); + } + + if (free_languages) + g_strfreev (languages); + + return translated_value; +} + +/** + * g_key_file_get_locale_for_key: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: (nullable): a locale identifier or %NULL + * + * Returns the actual locale which the result of + * g_key_file_get_locale_string() or g_key_file_get_locale_string_list() + * came from. + * + * If calling g_key_file_get_locale_string() or + * g_key_file_get_locale_string_list() with exactly the same @key_file, + * @group_name, @key and @locale, the result of those functions will + * have originally been tagged with the locale that is the result of + * this function. + * + * Returns: (nullable): the locale from the file, or %NULL if the key was not + * found or the entry in the file was was untranslated + * + * Since: 2.56 + */ +gchar * +g_key_file_get_locale_for_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale) +{ + gchar **languages_allocated = NULL; + const gchar * const *languages; + gchar *result = NULL; + gsize i; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (locale != NULL) + { + languages_allocated = g_get_locale_variants (locale); + languages = (const gchar * const *) languages_allocated; + } + else + languages = g_get_language_names (); + + for (i = 0; languages[i] != NULL; i++) + { + gchar *candidate_key, *translated_value; + + candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); + translated_value = g_key_file_get_string (key_file, group_name, candidate_key, NULL); + g_free (translated_value); + g_free (candidate_key); + + if (translated_value != NULL) + break; + } + + result = g_strdup (languages[i]); + + g_strfreev (languages_allocated); + + return result; +} + +/** + * g_key_file_get_locale_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: (nullable): a locale identifier or %NULL + * @length: (out) (optional): return location for the number of returned strings or %NULL + * @error: return location for a #GError or %NULL + * + * Returns the values associated with @key under @group_name + * translated in the given @locale if available. If @locale is + * %NULL then the current locale is assumed. + * + * If @locale is to be non-%NULL, or if the current locale will change over + * the lifetime of the #GKeyFile, it must be loaded with + * %G_KEY_FILE_KEEP_TRANSLATIONS in order to load strings for all locales. + * + * If @key cannot be found then %NULL is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated + * with @key cannot be interpreted or no suitable translations + * can be found then the untranslated values are returned. The + * returned array is %NULL-terminated, so @length may optionally + * be %NULL. + * + * Returns: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): a newly allocated %NULL-terminated string array + * or %NULL if the key isn't found. The string array should be freed + * with g_strfreev(). + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + gsize *length, + GError **error) +{ + GError *key_file_error; + gchar **values, *value; + char list_separator[2]; + gsize len; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + key_file_error = NULL; + + value = g_key_file_get_locale_string (key_file, group_name, + key, locale, + &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!value) + { + if (length) + *length = 0; + return NULL; + } + + len = strlen (value); + if (value[len - 1] == key_file->list_separator) + value[len - 1] = '\0'; + + list_separator[0] = key_file->list_separator; + list_separator[1] = '\0'; + values = g_strsplit (value, list_separator, 0); + + g_free (value); + + if (length) + *length = g_strv_length (values); + + return values; +} + +/** + * g_key_file_set_locale_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: a locale identifier + * @list: (array zero-terminated=1 length=length): a %NULL-terminated array of locale string values + * @length: the length of @list + * + * Associates a list of string values for @key and @locale under + * @group_name. If the translation for @key cannot be found then + * it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar * const list[], + gsize length) +{ + GString *value_list; + gchar *full_key; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (locale != NULL); + g_return_if_fail (length != 0); + + value_list = g_string_sized_new (length * 128); + for (i = 0; i < length && list[i] != NULL; i++) + { + gchar *value; + + value = g_key_file_parse_string_as_value (key_file, list[i], TRUE); + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + full_key = g_strdup_printf ("%s[%s]", key, locale); + g_key_file_set_value (key_file, group_name, full_key, value_list->str); + g_free (full_key); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_get_boolean: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a + * boolean. + * + * If @key cannot be found then %FALSE is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value + * associated with @key cannot be interpreted as a boolean then %FALSE + * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: the value associated with the key as a boolean, + * or %FALSE if the key was not found or could not be parsed. + * + * Since: 2.6 + **/ +gboolean +g_key_file_get_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error = NULL; + gchar *value; + gboolean bool_value; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (!value) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + bool_value = g_key_file_parse_value_as_boolean (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return bool_value; +} + +/** + * g_key_file_set_boolean: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: %TRUE or %FALSE + * + * Associates a new boolean value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_key_file_parse_boolean_as_value (key_file, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_boolean_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of booleans returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * booleans. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as booleans then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: (array length=length) (element-type gboolean) (transfer container): + * the values associated with the key as a list of booleans, or %NULL if the + * key was not found or could not be parsed. The returned list of booleans + * should be freed with g_free() when no longer needed. + * + * Since: 2.6 + **/ +gboolean * +g_key_file_get_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error; + gchar **values; + gboolean *bool_values; + gsize i, num_bools; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + key_file_error = NULL; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_bools, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + bool_values = g_new (gboolean, num_bools); + + for (i = 0; i < num_bools; i++) + { + bool_values[i] = g_key_file_parse_value_as_boolean (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (bool_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_bools; + + return bool_values; +} + +/** + * g_key_file_set_boolean_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of boolean values + * @length: length of @list + * + * Associates a list of boolean values with @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name is %NULL, the start_group is used. + * + * Since: 2.6 + **/ +void +g_key_file_set_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean list[], + gsize length) +{ + GString *value_list; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + value_list = g_string_sized_new (length * 8); + for (i = 0; i < length; i++) + { + gchar *value; + + value = g_key_file_parse_boolean_as_value (key_file, list[i]); + + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, value_list->str); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_get_integer: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as an + * integer. + * + * If @key cannot be found then 0 is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated + * with @key cannot be interpreted as an integer, or is out of range + * for a #gint, then 0 is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: the value associated with the key as an integer, or + * 0 if the key was not found or could not be parsed. + * + * Since: 2.6 + **/ +gint +g_key_file_get_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error; + gchar *value; + gint int_value; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return 0; + } + + int_value = g_key_file_parse_value_as_integer (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” in group “%s” " + "which has a value that cannot be interpreted."), + key, group_name); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return int_value; +} + +/** + * g_key_file_set_integer: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_key_file_parse_integer_as_value (key_file, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_int64: + * @key_file: a non-%NULL #GKeyFile + * @group_name: a non-%NULL group name + * @key: a non-%NULL key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a signed + * 64-bit integer. This is similar to g_key_file_get_integer() but can return + * 64-bit results without truncation. + * + * Returns: the value associated with the key as a signed 64-bit integer, or + * 0 if the key was not found or could not be parsed. + * + * Since: 2.26 + */ +gint64 +g_key_file_get_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *s, *end; + gint64 v; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + s = g_key_file_get_value (key_file, group_name, key, error); + + if (s == NULL) + return 0; + + v = g_ascii_strtoll (s, &end, 10); + + if (*s == '\0' || *end != '\0') + { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key “%s” in group “%s” has value “%s” " + "where %s was expected"), + key, group_name, s, "int64"); + g_free (s); + return 0; + } + + g_free (s); + return v; +} + +/** + * g_key_file_set_int64: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.26 + **/ +void +g_key_file_set_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint64 value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_strdup_printf ("%" G_GINT64_FORMAT, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_uint64: + * @key_file: a non-%NULL #GKeyFile + * @group_name: a non-%NULL group name + * @key: a non-%NULL key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as an unsigned + * 64-bit integer. This is similar to g_key_file_get_integer() but can return + * large positive results without truncation. + * + * Returns: the value associated with the key as an unsigned 64-bit integer, + * or 0 if the key was not found or could not be parsed. + * + * Since: 2.26 + */ +guint64 +g_key_file_get_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *s, *end; + guint64 v; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + s = g_key_file_get_value (key_file, group_name, key, error); + + if (s == NULL) + return 0; + + v = g_ascii_strtoull (s, &end, 10); + + if (*s == '\0' || *end != '\0') + { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key “%s” in group “%s” has value “%s” " + "where %s was expected"), + key, group_name, s, "uint64"); + g_free (s); + return 0; + } + + g_free (s); + return v; +} + +/** + * g_key_file_set_uint64: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.26 + **/ +void +g_key_file_set_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + guint64 value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_strdup_printf ("%" G_GUINT64_FORMAT, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_integer_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of integers returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * integers. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as integers, or are out of range for + * #gint, then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: (array length=length) (element-type gint) (transfer container): + * the values associated with the key as a list of integers, or %NULL if + * the key was not found or could not be parsed. The returned list of + * integers should be freed with g_free() when no longer needed. + * + * Since: 2.6 + **/ +gint * +g_key_file_get_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar **values; + gint *int_values; + gsize i, num_ints; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_ints, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + int_values = g_new (gint, num_ints); + + for (i = 0; i < num_ints; i++) + { + int_values[i] = g_key_file_parse_value_as_integer (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (int_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_ints; + + return int_values; +} + +/** + * g_key_file_set_integer_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of integer values + * @length: number of integer values in @list + * + * Associates a list of integer values with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint list[], + gsize length) +{ + GString *values; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + values = g_string_sized_new (length * 16); + for (i = 0; i < length; i++) + { + gchar *value; + + value = g_key_file_parse_integer_as_value (key_file, list[i]); + + g_string_append (values, value); + g_string_append_c (values, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, values->str); + g_string_free (values, TRUE); +} + +/** + * g_key_file_get_double: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a + * double. If @group_name is %NULL, the start_group is used. + * + * If @key cannot be found then 0.0 is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated + * with @key cannot be interpreted as a double then 0.0 is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: the value associated with the key as a double, or + * 0.0 if the key was not found or could not be parsed. + * + * Since: 2.12 + **/ +gdouble +g_key_file_get_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error; + gchar *value; + gdouble double_value; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return 0; + } + + double_value = g_key_file_parse_value_as_double (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key “%s” in group “%s” " + "which has a value that cannot be interpreted."), + key, group_name); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return double_value; +} + +/** + * g_key_file_set_double: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an double value + * + * Associates a new double value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.12 + **/ +void +g_key_file_set_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble value) +{ + gchar result[G_ASCII_DTOSTR_BUF_SIZE]; + + g_return_if_fail (key_file != NULL); + + g_ascii_dtostr (result, sizeof (result), value); + g_key_file_set_value (key_file, group_name, key, result); +} + +/** + * g_key_file_get_double_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of doubles returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * doubles. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as doubles then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Returns: (array length=length) (element-type gdouble) (transfer container): + * the values associated with the key as a list of doubles, or %NULL if the + * key was not found or could not be parsed. The returned list of doubles + * should be freed with g_free() when no longer needed. + * + * Since: 2.12 + **/ +gdouble * +g_key_file_get_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar **values; + gdouble *double_values; + gsize i, num_doubles; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_doubles, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + double_values = g_new (gdouble, num_doubles); + + for (i = 0; i < num_doubles; i++) + { + double_values[i] = g_key_file_parse_value_as_double (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (double_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_doubles; + + return double_values; +} + +/** + * g_key_file_set_double_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of double values + * @length: number of double values in @list + * + * Associates a list of double values with @key under + * @group_name. If @key cannot be found then it is created. + * + * Since: 2.12 + **/ +void +g_key_file_set_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble list[], + gsize length) +{ + GString *values; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + values = g_string_sized_new (length * 16); + for (i = 0; i < length; i++) + { + gchar result[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_dtostr( result, sizeof (result), list[i] ); + + g_string_append (values, result); + g_string_append_c (values, key_file->list_separator); + } + + g_key_file_set_value (key_file, group_name, key, values->str); + g_string_free (values, TRUE); +} + +static gboolean +g_key_file_set_key_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *comment, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + GList *key_node, *comment_node, *tmp; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name ? group_name : "(null)"); + + return FALSE; + } + + /* First find the key the comments are supposed to be + * associated with + */ + key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key); + + if (key_node == NULL) + { + set_not_found_key_error (group->name, key, error); + return FALSE; + } + + /* Then find all the comments already associated with the + * key and free them + */ + tmp = key_node->next; + while (tmp != NULL) + { + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key != NULL) + break; + + comment_node = tmp; + tmp = tmp->next; + g_key_file_remove_key_value_pair_node (key_file, group, + comment_node); + } + + if (comment == NULL) + return TRUE; + + /* Now we can add our new comment + */ + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); + + key_node = g_list_insert (key_node, pair, 1); + + return TRUE; +} + +static gboolean +g_key_file_set_group_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *comment, + GError **error) +{ + GKeyFileGroup *group; + + g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE); + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name ? group_name : "(null)"); + + return FALSE; + } + + /* First remove any existing comment + */ + if (group->comment) + { + g_key_file_key_value_pair_free (group->comment); + group->comment = NULL; + } + + if (comment == NULL) + return TRUE; + + /* Now we can add our new comment + */ + group->comment = g_slice_new (GKeyFileKeyValuePair); + group->comment->key = NULL; + group->comment->value = g_key_file_parse_comment_as_value (key_file, comment); + + return TRUE; +} + +static gboolean +g_key_file_set_top_comment (GKeyFile *key_file, + const gchar *comment, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + /* The last group in the list should be the top (comments only) + * group in the file + */ + g_warn_if_fail (key_file->groups != NULL); + group_node = g_list_last (key_file->groups); + group = (GKeyFileGroup *) group_node->data; + g_warn_if_fail (group->name == NULL); + + /* Note all keys must be comments at the top of + * the file, so we can just free it all. + */ + g_list_free_full (group->key_value_pairs, (GDestroyNotify) g_key_file_key_value_pair_free); + group->key_value_pairs = NULL; + + if (comment == NULL) + return TRUE; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); + + group->key_value_pairs = + g_list_prepend (group->key_value_pairs, pair); + + return TRUE; +} + +/** + * g_key_file_set_comment: + * @key_file: a #GKeyFile + * @group_name: (nullable): a group name, or %NULL + * @key: (nullable): a key + * @comment: a comment + * @error: return location for a #GError + * + * Places a comment above @key from @group_name. + * + * If @key is %NULL then @comment will be written above @group_name. + * If both @key and @group_name are %NULL, then @comment will be + * written above the first group in the file. + * + * Note that this function prepends a '#' comment marker to + * each line of @comment. + * + * Returns: %TRUE if the comment was written, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_set_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *comment, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + + if (group_name != NULL && key != NULL) + { + if (!g_key_file_set_key_comment (key_file, group_name, key, comment, error)) + return FALSE; + } + else if (group_name != NULL) + { + if (!g_key_file_set_group_comment (key_file, group_name, comment, error)) + return FALSE; + } + else + { + if (!g_key_file_set_top_comment (key_file, comment, error)) + return FALSE; + } + + return TRUE; +} + +static gchar * +g_key_file_get_key_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + GList *key_node, *tmp; + GString *string; + gchar *comment; + + g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL); + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name ? group_name : "(null)"); + + return NULL; + } + + /* First find the key the comments are supposed to be + * associated with + */ + key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key); + + if (key_node == NULL) + { + set_not_found_key_error (group->name, key, error); + return NULL; + } + + string = NULL; + + /* Then find all the comments already associated with the + * key and concatentate them. + */ + tmp = key_node->next; + if (!key_node->next) + return NULL; + + pair = (GKeyFileKeyValuePair *) tmp->data; + if (pair->key != NULL) + return NULL; + + while (tmp->next) + { + pair = (GKeyFileKeyValuePair *) tmp->next->data; + + if (pair->key != NULL) + break; + + tmp = tmp->next; + } + + while (tmp != key_node) + { + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (string == NULL) + string = g_string_sized_new (512); + + comment = g_key_file_parse_value_as_comment (key_file, pair->value, + (tmp->prev == key_node)); + g_string_append (string, comment); + g_free (comment); + + tmp = tmp->prev; + } + + if (string != NULL) + { + comment = string->str; + g_string_free (string, FALSE); + } + else + comment = NULL; + + return comment; +} + +static gchar * +get_group_comment (GKeyFile *key_file, + GKeyFileGroup *group, + GError **error) +{ + GString *string; + GList *tmp; + gchar *comment; + + string = NULL; + + tmp = group->key_value_pairs; + while (tmp) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key != NULL) + { + tmp = tmp->prev; + break; + } + + if (tmp->next == NULL) + break; + + tmp = tmp->next; + } + + while (tmp != NULL) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (string == NULL) + string = g_string_sized_new (512); + + comment = g_key_file_parse_value_as_comment (key_file, pair->value, + (tmp->prev == NULL)); + g_string_append (string, comment); + g_free (comment); + + tmp = tmp->prev; + } + + if (string != NULL) + return g_string_free (string, FALSE); + + return NULL; +} + +static gchar * +g_key_file_get_group_comment (GKeyFile *key_file, + const gchar *group_name, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name ? group_name : "(null)"); + + return NULL; + } + + if (group->comment) + return g_strdup (group->comment->value); + + group_node = g_key_file_lookup_group_node (key_file, group_name); + group_node = group_node->next; + group = (GKeyFileGroup *)group_node->data; + return get_group_comment (key_file, group, error); +} + +static gchar * +g_key_file_get_top_comment (GKeyFile *key_file, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + + /* The last group in the list should be the top (comments only) + * group in the file + */ + g_warn_if_fail (key_file->groups != NULL); + group_node = g_list_last (key_file->groups); + group = (GKeyFileGroup *) group_node->data; + g_warn_if_fail (group->name == NULL); + + return get_group_comment (key_file, group, error); +} + +/** + * g_key_file_get_comment: + * @key_file: a #GKeyFile + * @group_name: (nullable): a group name, or %NULL + * @key: a key + * @error: return location for a #GError + * + * Retrieves a comment above @key from @group_name. + * If @key is %NULL then @comment will be read from above + * @group_name. If both @key and @group_name are %NULL, then + * @comment will be read from above the first group in the file. + * + * Note that the returned string does not include the '#' comment markers, + * but does include any whitespace after them (on each line). It includes + * the line breaks between lines, but does not include the final line break. + * + * Returns: a comment that should be freed with g_free() + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + if (group_name != NULL && key != NULL) + return g_key_file_get_key_comment (key_file, group_name, key, error); + else if (group_name != NULL) + return g_key_file_get_group_comment (key_file, group_name, error); + else + return g_key_file_get_top_comment (key_file, error); +} + +/** + * g_key_file_remove_comment: + * @key_file: a #GKeyFile + * @group_name: (nullable): a group name, or %NULL + * @key: (nullable): a key + * @error: return location for a #GError + * + * Removes a comment above @key from @group_name. + * If @key is %NULL then @comment will be removed above @group_name. + * If both @key and @group_name are %NULL, then @comment will + * be removed above the first group in the file. + * + * Returns: %TRUE if the comment was removed, %FALSE otherwise + * + * Since: 2.6 + **/ + +gboolean +g_key_file_remove_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + + if (group_name != NULL && key != NULL) + return g_key_file_set_key_comment (key_file, group_name, key, NULL, error); + else if (group_name != NULL) + return g_key_file_set_group_comment (key_file, group_name, NULL, error); + else + return g_key_file_set_top_comment (key_file, NULL, error); +} + +/** + * g_key_file_has_group: + * @key_file: a #GKeyFile + * @group_name: a group name + * + * Looks whether the key file has the group @group_name. + * + * Returns: %TRUE if @group_name is a part of @key_file, %FALSE + * otherwise. + * Since: 2.6 + **/ +gboolean +g_key_file_has_group (GKeyFile *key_file, + const gchar *group_name) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + + return g_key_file_lookup_group (key_file, group_name) != NULL; +} + +/* This code remains from a historical attempt to add a new public API + * which respects the GError rules. + */ +static gboolean +g_key_file_has_key_full (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean *has_key, + GError **error) +{ + GKeyFileKeyValuePair *pair; + GKeyFileGroup *group; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + + return FALSE; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (has_key) + *has_key = pair != NULL; + return TRUE; +} + +/** + * g_key_file_has_key: (skip) + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key name + * @error: return location for a #GError + * + * Looks whether the key file has the key @key in the group + * @group_name. + * + * Note that this function does not follow the rules for #GError strictly; + * the return value both carries meaning and signals an error. To use + * this function, you must pass a #GError pointer in @error, and check + * whether it is not %NULL to see if an error occurred. + * + * Language bindings should use g_key_file_get_value() to test whether + * or not a key exists. + * + * Returns: %TRUE if @key is a part of @group_name, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_has_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *temp_error = NULL; + gboolean has_key; + + if (g_key_file_has_key_full (key_file, group_name, key, &has_key, &temp_error)) + { + return has_key; + } + else + { + g_propagate_error (error, temp_error); + return FALSE; + } +} + +static void +g_key_file_add_group (GKeyFile *key_file, + const gchar *group_name) +{ + GKeyFileGroup *group; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (g_key_file_is_group_name (group_name)); + + group = g_key_file_lookup_group (key_file, group_name); + if (group != NULL) + { + key_file->current_group = group; + return; + } + + group = g_slice_new0 (GKeyFileGroup); + group->name = g_strdup (group_name); + group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal); + key_file->groups = g_list_prepend (key_file->groups, group); + key_file->current_group = group; + + if (key_file->start_group == NULL) + key_file->start_group = group; + + g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group); +} + +static void +g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair) +{ + if (pair != NULL) + { + g_free (pair->key); + g_free (pair->value); + g_slice_free (GKeyFileKeyValuePair, pair); + } +} + +/* Be careful not to call this function on a node with data in the + * lookup map without removing it from the lookup map, first. + * + * Some current cases where this warning is not a concern are + * when: + * - the node being removed is a comment node + * - the entire lookup map is getting destroyed soon after + * anyway. + */ +static void +g_key_file_remove_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + GList *pair_node) +{ + + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) pair_node->data; + + group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node); + + g_warn_if_fail (pair->value != NULL); + + g_key_file_key_value_pair_free (pair); + + g_list_free_1 (pair_node); +} + +static void +g_key_file_remove_group_node (GKeyFile *key_file, + GList *group_node) +{ + GKeyFileGroup *group; + GList *tmp; + + group = (GKeyFileGroup *) group_node->data; + + if (group->name) + g_hash_table_remove (key_file->group_hash, group->name); + + /* If the current group gets deleted make the current group the last + * added group. + */ + if (key_file->current_group == group) + { + /* groups should always contain at least the top comment group, + * unless g_key_file_clear has been called + */ + if (key_file->groups) + key_file->current_group = (GKeyFileGroup *) key_file->groups->data; + else + key_file->current_group = NULL; + } + + /* If the start group gets deleted make the start group the first + * added group. + */ + if (key_file->start_group == group) + { + tmp = g_list_last (key_file->groups); + while (tmp != NULL) + { + if (tmp != group_node && + ((GKeyFileGroup *) tmp->data)->name != NULL) + break; + + tmp = tmp->prev; + } + + if (tmp) + key_file->start_group = (GKeyFileGroup *) tmp->data; + else + key_file->start_group = NULL; + } + + key_file->groups = g_list_remove_link (key_file->groups, group_node); + + tmp = group->key_value_pairs; + while (tmp != NULL) + { + GList *pair_node; + + pair_node = tmp; + tmp = tmp->next; + g_key_file_remove_key_value_pair_node (key_file, group, pair_node); + } + + g_warn_if_fail (group->key_value_pairs == NULL); + + if (group->comment) + { + g_key_file_key_value_pair_free (group->comment); + group->comment = NULL; + } + + if (group->lookup_map) + { + g_hash_table_destroy (group->lookup_map); + group->lookup_map = NULL; + } + + g_free ((gchar *) group->name); + g_slice_free (GKeyFileGroup, group); + g_list_free_1 (group_node); +} + +/** + * g_key_file_remove_group: + * @key_file: a #GKeyFile + * @group_name: a group name + * @error: return location for a #GError or %NULL + * + * Removes the specified group, @group_name, + * from the key file. + * + * Returns: %TRUE if the group was removed, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_remove_group (GKeyFile *key_file, + const gchar *group_name, + GError **error) +{ + GList *group_node; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + + group_node = g_key_file_lookup_group_node (key_file, group_name); + + if (!group_node) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + return FALSE; + } + + g_key_file_remove_group_node (key_file, group_node); + + return TRUE; +} + +static void +g_key_file_add_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + GKeyFileKeyValuePair *pair) +{ + g_hash_table_replace (group->lookup_map, pair->key, pair); + group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair); +} + +static void +g_key_file_add_key (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key, + const gchar *value) +{ + GKeyFileKeyValuePair *pair; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = g_strdup (key); + pair->value = g_strdup (value); + + g_key_file_add_key_value_pair (key_file, group, pair); +} + +/** + * g_key_file_remove_key: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key name to remove + * @error: return location for a #GError or %NULL + * + * Removes @key in @group_name from the key file. + * + * Returns: %TRUE if the key was removed, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_remove_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + pair = NULL; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group “%s”"), + group_name); + return FALSE; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (!pair) + { + set_not_found_key_error (group->name, key, error); + return FALSE; + } + + group->key_value_pairs = g_list_remove (group->key_value_pairs, pair); + g_hash_table_remove (group->lookup_map, pair->key); + g_key_file_key_value_pair_free (pair); + + return TRUE; +} + +static GList * +g_key_file_lookup_group_node (GKeyFile *key_file, + const gchar *group_name) +{ + GKeyFileGroup *group; + GList *tmp; + + for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next) + { + group = (GKeyFileGroup *) tmp->data; + + if (group && group->name && strcmp (group->name, group_name) == 0) + break; + } + + return tmp; +} + +static GKeyFileGroup * +g_key_file_lookup_group (GKeyFile *key_file, + const gchar *group_name) +{ + return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name); +} + +static GList * +g_key_file_lookup_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key) +{ + GList *key_node; + + for (key_node = group->key_value_pairs; + key_node != NULL; + key_node = key_node->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) key_node->data; + + if (pair->key && strcmp (pair->key, key) == 0) + break; + } + + return key_node; +} + +static GKeyFileKeyValuePair * +g_key_file_lookup_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key) +{ + return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key); +} + +/* Lines starting with # or consisting entirely of whitespace are merely + * recorded, not parsed. This function assumes all leading whitespace + * has been stripped. + */ +static gboolean +g_key_file_line_is_comment (const gchar *line) +{ + return (*line == '#' || *line == '\0' || *line == '\n'); +} + +static gboolean +g_key_file_is_group_name (const gchar *name) +{ + gchar *p, *q; + + if (name == NULL) + return FALSE; + + p = q = (gchar *) name; + while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q)) + q = g_utf8_find_next_char (q, NULL); + + if (*q != '\0' || q == p) + return FALSE; + + return TRUE; +} + +static gboolean +g_key_file_is_key_name (const gchar *name) +{ + gchar *p, *q; + + if (name == NULL) + return FALSE; + + p = q = (gchar *) name; + /* We accept a little more than the desktop entry spec says, + * since gnome-vfs uses mime-types as keys in its cache. + */ + while (*q && *q != '=' && *q != '[' && *q != ']') + q = g_utf8_find_next_char (q, NULL); + + /* No empty keys, please */ + if (q == p) + return FALSE; + + /* We accept spaces in the middle of keys to not break + * existing apps, but we don't tolerate initial or final + * spaces, which would lead to silent corruption when + * rereading the file. + */ + if (*p == ' ' || q[-1] == ' ') + return FALSE; + + if (*q == '[') + { + q++; + while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@')) + q = g_utf8_find_next_char (q, NULL); + + if (*q != ']') + return FALSE; + + q++; + } + + if (*q != '\0') + return FALSE; + + return TRUE; +} + +/* A group in a key file is made up of a starting '[' followed by one + * or more letters making up the group name followed by ']'. + */ +static gboolean +g_key_file_line_is_group (const gchar *line) +{ + gchar *p; + + p = (gchar *) line; + if (*p != '[') + return FALSE; + + p++; + + while (*p && *p != ']') + p = g_utf8_find_next_char (p, NULL); + + if (*p != ']') + return FALSE; + + /* silently accept whitespace after the ] */ + p = g_utf8_find_next_char (p, NULL); + while (*p == ' ' || *p == '\t') + p = g_utf8_find_next_char (p, NULL); + + if (*p) + return FALSE; + + return TRUE; +} + +static gboolean +g_key_file_line_is_key_value_pair (const gchar *line) +{ + gchar *p; + + p = (gchar *) g_utf8_strchr (line, -1, '='); + + if (!p) + return FALSE; + + /* Key must be non-empty + */ + if (*p == line[0]) + return FALSE; + + return TRUE; +} + +static gchar * +g_key_file_parse_value_as_string (GKeyFile *key_file, + const gchar *value, + GSList **pieces, + GError **error) +{ + gchar *string_value, *p, *q0, *q; + + string_value = g_new (gchar, strlen (value) + 1); + + p = (gchar *) value; + q0 = q = string_value; + while (*p) + { + if (*p == '\\') + { + p++; + + switch (*p) + { + case 's': + *q = ' '; + break; + + case 'n': + *q = '\n'; + break; + + case 't': + *q = '\t'; + break; + + case 'r': + *q = '\r'; + break; + + case '\\': + *q = '\\'; + break; + + case '\0': + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains escape character " + "at end of line")); + break; + + default: + if (pieces && *p == key_file->list_separator) + *q = key_file->list_separator; + else + { + *q++ = '\\'; + *q = *p; + + if (*error == NULL) + { + gchar sequence[3]; + + sequence[0] = '\\'; + sequence[1] = *p; + sequence[2] = '\0'; + + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains invalid escape " + "sequence “%s”"), sequence); + } + } + break; + } + } + else + { + *q = *p; + if (pieces && (*p == key_file->list_separator)) + { + *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0)); + q0 = q + 1; + } + } + + if (*p == '\0') + break; + + q++; + p++; + } + + *q = '\0'; + if (pieces) + { + if (q0 < q) + *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0)); + *pieces = g_slist_reverse (*pieces); + } + + return string_value; +} + +static gchar * +g_key_file_parse_string_as_value (GKeyFile *key_file, + const gchar *string, + gboolean escape_separator) +{ + gchar *value, *p, *q; + gsize length; + gboolean parsing_leading_space; + + length = strlen (string) + 1; + + /* Worst case would be that every character needs to be escaped. + * In other words every character turns to two characters + */ + value = g_new (gchar, 2 * length); + + p = (gchar *) string; + q = value; + parsing_leading_space = TRUE; + while (p < (string + length - 1)) + { + gchar escaped_character[3] = { '\\', 0, 0 }; + + switch (*p) + { + case ' ': + if (parsing_leading_space) + { + escaped_character[1] = 's'; + strcpy (q, escaped_character); + q += 2; + } + else + { + *q = *p; + q++; + } + break; + case '\t': + if (parsing_leading_space) + { + escaped_character[1] = 't'; + strcpy (q, escaped_character); + q += 2; + } + else + { + *q = *p; + q++; + } + break; + case '\n': + escaped_character[1] = 'n'; + strcpy (q, escaped_character); + q += 2; + break; + case '\r': + escaped_character[1] = 'r'; + strcpy (q, escaped_character); + q += 2; + break; + case '\\': + escaped_character[1] = '\\'; + strcpy (q, escaped_character); + q += 2; + parsing_leading_space = FALSE; + break; + default: + if (escape_separator && *p == key_file->list_separator) + { + escaped_character[1] = key_file->list_separator; + strcpy (q, escaped_character); + q += 2; + parsing_leading_space = TRUE; + } + else + { + *q = *p; + q++; + parsing_leading_space = FALSE; + } + break; + } + p++; + } + *q = '\0'; + + return value; +} + +static gint +g_key_file_parse_value_as_integer (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *eof_int; + glong long_value; + gint int_value; + int errsv; + + errno = 0; + long_value = strtol (value, &eof_int, 10); + errsv = errno; + + if (*value == '\0' || (*eof_int != '\0' && !g_ascii_isspace(*eof_int))) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value “%s” cannot be interpreted " + "as a number."), value_utf8); + g_free (value_utf8); + + return 0; + } + + int_value = long_value; + if (int_value != long_value || errsv == ERANGE) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Integer value “%s” out of range"), + value_utf8); + g_free (value_utf8); + + return 0; + } + + return int_value; +} + +static gchar * +g_key_file_parse_integer_as_value (GKeyFile *key_file, + gint value) + +{ + return g_strdup_printf ("%d", value); +} + +static gdouble +g_key_file_parse_value_as_double (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *end_of_valid_d; + gdouble double_value = 0; + + double_value = g_ascii_strtod (value, &end_of_valid_d); + + if (*end_of_valid_d != '\0' || end_of_valid_d == value) + { + gchar *value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value “%s” cannot be interpreted " + "as a float number."), + value_utf8); + g_free (value_utf8); + + double_value = 0; + } + + return double_value; +} + +static gint +strcmp_sized (const gchar *s1, size_t len1, const gchar *s2) +{ + size_t len2 = strlen (s2); + return strncmp (s1, s2, MAX (len1, len2)); +} + +static gboolean +g_key_file_parse_value_as_boolean (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *value_utf8; + gint i, length = 0; + + /* Count the number of non-whitespace characters */ + for (i = 0; value[i]; i++) + if (!g_ascii_isspace (value[i])) + length = i + 1; + + if (strcmp_sized (value, length, "true") == 0 || strcmp_sized (value, length, "1") == 0) + return TRUE; + else if (strcmp_sized (value, length, "false") == 0 || strcmp_sized (value, length, "0") == 0) + return FALSE; + + value_utf8 = g_utf8_make_valid (value, -1); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value “%s” cannot be interpreted " + "as a boolean."), value_utf8); + g_free (value_utf8); + + return FALSE; +} + +static gchar * +g_key_file_parse_boolean_as_value (GKeyFile *key_file, + gboolean value) +{ + if (value) + return g_strdup ("true"); + else + return g_strdup ("false"); +} + +static gchar * +g_key_file_parse_value_as_comment (GKeyFile *key_file, + const gchar *value, + gboolean is_final_line) +{ + GString *string; + gchar **lines; + gsize i; + + string = g_string_sized_new (512); + + lines = g_strsplit (value, "\n", 0); + + for (i = 0; lines[i] != NULL; i++) + { + const gchar *line = lines[i]; + + if (i != 0) + g_string_append_c (string, '\n'); + + if (line[0] == '#') + line++; + g_string_append (string, line); + } + g_strfreev (lines); + + /* This function gets called once per line of a comment, but we don’t want + * to add a trailing newline. */ + if (!is_final_line) + g_string_append_c (string, '\n'); + + return g_string_free (string, FALSE); +} + +static gchar * +g_key_file_parse_comment_as_value (GKeyFile *key_file, + const gchar *comment) +{ + GString *string; + gchar **lines; + gsize i; + + string = g_string_sized_new (512); + + lines = g_strsplit (comment, "\n", 0); + + for (i = 0; lines[i] != NULL; i++) + g_string_append_printf (string, "#%s%s", lines[i], + lines[i + 1] == NULL? "" : "\n"); + g_strfreev (lines); + + return g_string_free (string, FALSE); +} + +/** + * g_key_file_save_to_file: + * @key_file: a #GKeyFile + * @filename: the name of the file to write to + * @error: a pointer to a %NULL #GError, or %NULL + * + * Writes the contents of @key_file to @filename using + * g_file_set_contents(). + * + * This function can fail for any of the reasons that + * g_file_set_contents() may fail. + * + * Returns: %TRUE if successful, else %FALSE with @error set + * + * Since: 2.40 + */ +gboolean +g_key_file_save_to_file (GKeyFile *key_file, + const gchar *filename, + GError **error) +{ + gchar *contents; + gboolean success; + gsize length; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + contents = g_key_file_to_data (key_file, &length, NULL); + g_assert (contents != NULL); + + success = g_file_set_contents (filename, contents, length, error); + g_free (contents); + + return success; +} diff -Nru glib2.0-2.59.2/.pc/debian/03_disble_glib_compile_schemas_warning.patch/gio/glib-compile-schemas.c glib2.0-2.59.3/.pc/debian/03_disble_glib_compile_schemas_warning.patch/gio/glib-compile-schemas.c --- glib2.0-2.59.2/.pc/debian/03_disble_glib_compile_schemas_warning.patch/gio/glib-compile-schemas.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/03_disble_glib_compile_schemas_warning.patch/gio/glib-compile-schemas.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,2301 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + * + * Author: Ryan Lortie + */ + +/* Prologue {{{1 */ +#include "config.h" + +#include +#include + +#include +#include +#include + +#include "gvdb/gvdb-builder.h" +#include "strinfo.c" + +#ifdef G_OS_WIN32 +#include "glib/glib-private.h" +#endif + +static void +strip_string (GString *string) +{ + gint i; + + for (i = 0; g_ascii_isspace (string->str[i]); i++); + g_string_erase (string, 0, i); + + if (string->len > 0) + { + /* len > 0, so there must be at least one non-whitespace character */ + for (i = string->len - 1; g_ascii_isspace (string->str[i]); i--); + g_string_truncate (string, i + 1); + } +} + +/* Handling of {{{1 */ +typedef struct +{ + GString *strinfo; + + gboolean is_flags; +} EnumState; + +static void +enum_state_free (gpointer data) +{ + EnumState *state = data; + + g_string_free (state->strinfo, TRUE); + g_slice_free (EnumState, state); +} + +static EnumState * +enum_state_new (gboolean is_flags) +{ + EnumState *state; + + state = g_slice_new (EnumState); + state->strinfo = g_string_new (NULL); + state->is_flags = is_flags; + + return state; +} + +static void +enum_state_add_value (EnumState *state, + const gchar *nick, + const gchar *valuestr, + GError **error) +{ + gint64 value; + gchar *end; + + if (nick[0] == '\0' || nick[1] == '\0') + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("nick must be a minimum of 2 characters")); + return; + } + + value = g_ascii_strtoll (valuestr, &end, 0); + if (*end || (state->is_flags ? + (value > G_MAXUINT32 || value < 0) : + (value > G_MAXINT32 || value < G_MININT32))) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid numeric value")); + return; + } + + if (strinfo_builder_contains (state->strinfo, nick)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), nick); + return; + } + + if (strinfo_builder_contains_value (state->strinfo, value)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("value='%s' already specified"), valuestr); + return; + } + + /* Silently drop the null case if it is mentioned. + * It is properly denoted with an empty array. + */ + if (state->is_flags && value == 0) + return; + + if (state->is_flags && (value & (value - 1))) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("flags values must have at most 1 bit set")); + return; + } + + /* Since we reject exact duplicates of value='' and we only allow one + * bit to be set, it's not possible to have overlaps. + * + * If we loosen the one-bit-set restriction we need an overlap check. + */ + + strinfo_builder_append_item (state->strinfo, nick, value); +} + +static void +enum_state_end (EnumState **state_ptr, + GError **error) +{ + EnumState *state; + + state = *state_ptr; + *state_ptr = NULL; + + if (state->strinfo->len == 0) + g_set_error (error, + G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> must contain at least one "), + state->is_flags ? "flags" : "enum"); +} + +/* Handling of {{{1 */ +typedef struct +{ + /* for , @child_schema will be set. + * for , everything else will be set. + */ + gchar *child_schema; + + + GVariantType *type; + gboolean have_gettext_domain; + + gchar l10n; + gchar *l10n_context; + GString *unparsed_default_value; + GVariant *default_value; + + GVariantDict *desktop_overrides; + + GString *strinfo; + gboolean is_enum; + gboolean is_flags; + + GVariant *minimum; + GVariant *maximum; + + gboolean has_choices; + gboolean has_aliases; + gboolean is_override; + + gboolean checked; + GVariant *serialised; + + gboolean summary_seen; + gboolean description_seen; +} KeyState; + +static KeyState * +key_state_new (const gchar *type_string, + const gchar *gettext_domain, + gboolean is_enum, + gboolean is_flags, + GString *strinfo) +{ + KeyState *state; + + state = g_slice_new0 (KeyState); + state->type = g_variant_type_new (type_string); + state->have_gettext_domain = gettext_domain != NULL; + state->is_enum = is_enum; + state->is_flags = is_flags; + state->summary_seen = FALSE; + state->description_seen = FALSE; + + if (strinfo) + state->strinfo = g_string_new_len (strinfo->str, strinfo->len); + else + state->strinfo = g_string_new (NULL); + + return state; +} + +static KeyState * +key_state_override (KeyState *state, + const gchar *gettext_domain) +{ + KeyState *copy; + + copy = g_slice_new0 (KeyState); + copy->type = g_variant_type_copy (state->type); + copy->have_gettext_domain = gettext_domain != NULL; + copy->strinfo = g_string_new_len (state->strinfo->str, + state->strinfo->len); + copy->is_enum = state->is_enum; + copy->is_flags = state->is_flags; + copy->is_override = TRUE; + + if (state->minimum) + { + copy->minimum = g_variant_ref (state->minimum); + copy->maximum = g_variant_ref (state->maximum); + } + + return copy; +} + +static KeyState * +key_state_new_child (const gchar *child_schema) +{ + KeyState *state; + + state = g_slice_new0 (KeyState); + state->child_schema = g_strdup (child_schema); + + return state; +} + +static gboolean +is_valid_choices (GVariant *variant, + GString *strinfo) +{ + switch (g_variant_classify (variant)) + { + case G_VARIANT_CLASS_MAYBE: + case G_VARIANT_CLASS_ARRAY: + { + gboolean valid = TRUE; + GVariantIter iter; + + g_variant_iter_init (&iter, variant); + + while (valid && (variant = g_variant_iter_next_value (&iter))) + { + valid = is_valid_choices (variant, strinfo); + g_variant_unref (variant); + } + + return valid; + } + + case G_VARIANT_CLASS_STRING: + return strinfo_is_string_valid ((const guint32 *) strinfo->str, + strinfo->len / 4, + g_variant_get_string (variant, NULL)); + + default: + g_assert_not_reached (); + } +} + + +/* Gets called at or to check for + * validity of the default value so that any inconsistency is + * reported as soon as it is encountered. + */ +static void +key_state_check_range (KeyState *state, + GError **error) +{ + if (state->default_value) + { + const gchar *tag; + + tag = state->is_override ? "override" : "default"; + + if (state->minimum) + { + if (g_variant_compare (state->default_value, state->minimum) < 0 || + g_variant_compare (state->default_value, state->maximum) > 0) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> is not contained in " + "the specified range"), tag); + } + } + + else if (state->strinfo->len) + { + if (!is_valid_choices (state->default_value, state->strinfo)) + { + if (state->is_enum) + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> is not a valid member of " + "the specified enumerated type"), tag); + + else if (state->is_flags) + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> contains string not in the " + "specified flags type"), tag); + + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s> contains a string not in " + ""), tag); + } + } + } +} + +static void +key_state_set_range (KeyState *state, + const gchar *min_str, + const gchar *max_str, + GError **error) +{ + const struct { + const gchar type; + const gchar *min; + const gchar *max; + } table[] = { + { 'y', "0", "255" }, + { 'n', "-32768", "32767" }, + { 'q', "0", "65535" }, + { 'i', "-2147483648", "2147483647" }, + { 'u', "0", "4294967295" }, + { 'x', "-9223372036854775808", "9223372036854775807" }, + { 't', "0", "18446744073709551615" }, + { 'd', "-inf", "inf" }, + }; + gboolean type_ok = FALSE; + gint i; + + if (state->minimum) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified for this key")); + return; + } + + for (i = 0; i < G_N_ELEMENTS (table); i++) + if (*(char *) state->type == table[i].type) + { + min_str = min_str ? min_str : table[i].min; + max_str = max_str ? max_str : table[i].max; + type_ok = TRUE; + break; + } + + if (!type_ok) + { + gchar *type = g_variant_type_dup_string (state->type); + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" not allowed for keys of type “%s”"), type); + g_free (type); + return; + } + + state->minimum = g_variant_parse (state->type, min_str, NULL, NULL, error); + if (state->minimum == NULL) + return; + + state->maximum = g_variant_parse (state->type, max_str, NULL, NULL, error); + if (state->maximum == NULL) + return; + + if (g_variant_compare (state->minimum, state->maximum) > 0) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" specified minimum is greater than maximum")); + return; + } + + key_state_check_range (state, error); +} + +static GString * +key_state_start_default (KeyState *state, + const gchar *l10n, + const gchar *context, + GError **error) +{ + if (l10n != NULL) + { + if (strcmp (l10n, "messages") == 0) + state->l10n = 'm'; + + else if (strcmp (l10n, "time") == 0) + state->l10n = 't'; + + else + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("unsupported l10n category: %s"), l10n); + return NULL; + } + + if (!state->have_gettext_domain) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("l10n requested, but no " + "gettext domain given")); + return NULL; + } + + state->l10n_context = g_strdup (context); + } + + else if (context != NULL) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("translation context given for " + "value without l10n enabled")); + return NULL; + } + + return g_string_new (NULL); +} + +static void +key_state_end_default (KeyState *state, + GString **string, + GError **error) +{ + state->unparsed_default_value = *string; + *string = NULL; + + state->default_value = g_variant_parse (state->type, + state->unparsed_default_value->str, + NULL, NULL, error); + if (!state->default_value) + { + gchar *type = g_variant_type_dup_string (state->type); + g_prefix_error (error, _("Failed to parse value of type “%s”: "), type); + g_free (type); + } + + key_state_check_range (state, error); +} + +static void +key_state_start_choices (KeyState *state, + GError **error) +{ + const GVariantType *type = state->type; + + if (state->is_enum) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" cannot be specified for keys " + "tagged as having an enumerated type")); + return; + } + + if (state->has_choices) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified for this key")); + return; + } + + while (g_variant_type_is_maybe (type) || g_variant_type_is_array (type)) + type = g_variant_type_element (type); + + if (!g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) + { + gchar *type_string = g_variant_type_dup_string (state->type); + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" not allowed for keys of type “%s”"), + type_string); + g_free (type_string); + return; + } +} + +static void +key_state_add_choice (KeyState *state, + const gchar *choice, + GError **error) +{ + if (strinfo_builder_contains (state->strinfo, choice)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already given"), choice); + return; + } + + strinfo_builder_append_item (state->strinfo, choice, 0); + state->has_choices = TRUE; +} + +static void +key_state_end_choices (KeyState *state, + GError **error) +{ + if (!state->has_choices) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _(" must contain at least one ")); + return; + } + + key_state_check_range (state, error); +} + +static void +key_state_start_aliases (KeyState *state, + GError **error) +{ + if (state->has_aliases) + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified for this key")); + else if (!state->is_flags && !state->is_enum && !state->has_choices) + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" can only be specified for keys with " + "enumerated or flags types or after ")); +} + +static void +key_state_add_alias (KeyState *state, + const gchar *alias, + const gchar *target, + GError **error) +{ + if (strinfo_builder_contains (state->strinfo, alias)) + { + if (strinfo_is_string_valid ((guint32 *) state->strinfo->str, + state->strinfo->len / 4, + alias)) + { + if (state->is_enum) + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" given when “%s” is already " + "a member of the enumerated type"), alias, alias); + + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" given when " + " was already given"), + alias, alias); + } + + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), alias); + + return; + } + + if (!strinfo_builder_append_alias (state->strinfo, alias, target)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + state->is_enum ? + _("alias target “%s” is not in enumerated type") : + _("alias target “%s” is not in "), + target); + return; + } + + state->has_aliases = TRUE; +} + +static void +key_state_end_aliases (KeyState *state, + GError **error) +{ + if (!state->has_aliases) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _(" must contain at least one ")); + return; + } +} + +static gboolean +key_state_check (KeyState *state, + GError **error) +{ + if (state->checked) + return TRUE; + + return state->checked = TRUE; +} + +static GVariant * +key_state_serialise (KeyState *state) +{ + if (state->serialised == NULL) + { + if (state->child_schema) + { + state->serialised = g_variant_new_string (state->child_schema); + } + + else + { + GVariantBuilder builder; + + g_assert (key_state_check (state, NULL)); + + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + + /* default value */ + g_variant_builder_add_value (&builder, state->default_value); + + /* translation */ + if (state->l10n) + { + /* We are going to store the untranslated default for + * runtime translation according to the current locale. + * We need to strip leading and trailing whitespace from + * the string so that it's exactly the same as the one + * that ended up in the .po file for translation. + * + * We want to do this so that + * + * + * ['a', 'b', 'c'] + * + * + * ends up in the .po file like "['a', 'b', 'c']", + * omitting the extra whitespace at the start and end. + */ + strip_string (state->unparsed_default_value); + + if (state->l10n_context) + { + gint len; + + /* Contextified messages are supported by prepending + * the context, followed by '\004' to the start of the + * message string. We do that here to save GSettings + * the work later on. + */ + len = strlen (state->l10n_context); + state->l10n_context[len] = '\004'; + g_string_prepend_len (state->unparsed_default_value, + state->l10n_context, len + 1); + g_free (state->l10n_context); + state->l10n_context = NULL; + } + + g_variant_builder_add (&builder, "(y(y&s))", 'l', state->l10n, + state->unparsed_default_value->str); + g_string_free (state->unparsed_default_value, TRUE); + state->unparsed_default_value = NULL; + } + + /* choice, aliases, enums */ + if (state->strinfo->len) + { + GVariant *array; + guint32 *words; + gpointer data; + gsize size; + gint i; + + data = state->strinfo->str; + size = state->strinfo->len; + + words = data; + for (i = 0; i < size / sizeof (guint32); i++) + words[i] = GUINT32_TO_LE (words[i]); + + array = g_variant_new_from_data (G_VARIANT_TYPE ("au"), + data, size, TRUE, + g_free, data); + + g_string_free (state->strinfo, FALSE); + state->strinfo = NULL; + + g_variant_builder_add (&builder, "(y@au)", + state->is_flags ? 'f' : + state->is_enum ? 'e' : 'c', + array); + } + + /* range */ + if (state->minimum || state->maximum) + g_variant_builder_add (&builder, "(y(**))", 'r', + state->minimum, state->maximum); + + /* per-desktop overrides */ + if (state->desktop_overrides) + g_variant_builder_add (&builder, "(y@a{sv})", 'd', + g_variant_dict_end (state->desktop_overrides)); + + state->serialised = g_variant_builder_end (&builder); + } + + g_variant_ref_sink (state->serialised); + } + + return g_variant_ref (state->serialised); +} + +static void +key_state_free (gpointer data) +{ + KeyState *state = data; + + g_free (state->child_schema); + + if (state->type) + g_variant_type_free (state->type); + + g_free (state->l10n_context); + + if (state->unparsed_default_value) + g_string_free (state->unparsed_default_value, TRUE); + + if (state->default_value) + g_variant_unref (state->default_value); + + if (state->strinfo) + g_string_free (state->strinfo, TRUE); + + if (state->minimum) + g_variant_unref (state->minimum); + + if (state->maximum) + g_variant_unref (state->maximum); + + if (state->serialised) + g_variant_unref (state->serialised); + + if (state->desktop_overrides) + g_variant_dict_unref (state->desktop_overrides); + + g_slice_free (KeyState, state); +} + +/* Key name validity {{{1 */ +static gboolean allow_any_name = FALSE; + +static gboolean +is_valid_keyname (const gchar *key, + GError **error) +{ + gint i; + + if (key[0] == '\0') + { + g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Empty names are not permitted")); + return FALSE; + } + + if (allow_any_name) + return TRUE; + + if (!g_ascii_islower (key[0])) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%s”: names must begin " + "with a lowercase letter"), key); + return FALSE; + } + + for (i = 1; key[i]; i++) + { + if (key[i] != '-' && + !g_ascii_islower (key[i]) && + !g_ascii_isdigit (key[i])) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%s”: invalid character “%c”; " + "only lowercase letters, numbers and hyphen (“-”) " + "are permitted"), key, key[i]); + return FALSE; + } + + if (key[i] == '-' && key[i + 1] == '-') + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%s”: two successive hyphens (“--”) " + "are not permitted"), key); + return FALSE; + } + } + + if (key[i - 1] == '-') + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%s”: the last character may not be a " + "hyphen (“-”)"), key); + return FALSE; + } + + if (i > 1024) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid name “%s”: maximum length is 1024"), key); + return FALSE; + } + + return TRUE; +} + +/* Handling of {{{1 */ +typedef struct _SchemaState SchemaState; +struct _SchemaState +{ + SchemaState *extends; + + gchar *path; + gchar *gettext_domain; + gchar *extends_name; + gchar *list_of; + + GHashTable *keys; +}; + +static SchemaState * +schema_state_new (const gchar *path, + const gchar *gettext_domain, + SchemaState *extends, + const gchar *extends_name, + const gchar *list_of) +{ + SchemaState *state; + + state = g_slice_new (SchemaState); + state->path = g_strdup (path); + state->gettext_domain = g_strdup (gettext_domain); + state->extends = extends; + state->extends_name = g_strdup (extends_name); + state->list_of = g_strdup (list_of); + state->keys = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, key_state_free); + + return state; +} + +static void +schema_state_free (gpointer data) +{ + SchemaState *state = data; + + g_free (state->path); + g_free (state->gettext_domain); + g_free (state->extends_name); + g_free (state->list_of); + g_hash_table_unref (state->keys); + g_slice_free (SchemaState, state); +} + +static void +schema_state_add_child (SchemaState *state, + const gchar *name, + const gchar *schema, + GError **error) +{ + gchar *childname; + + if (!is_valid_keyname (name, error)) + return; + + childname = g_strconcat (name, "/", NULL); + + if (g_hash_table_lookup (state->keys, childname)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), name); + return; + } + + g_hash_table_insert (state->keys, childname, + key_state_new_child (schema)); +} + +static KeyState * +schema_state_add_key (SchemaState *state, + GHashTable *enum_table, + GHashTable *flags_table, + const gchar *name, + const gchar *type_string, + const gchar *enum_type, + const gchar *flags_type, + GError **error) +{ + SchemaState *node; + GString *strinfo; + KeyState *key; + + if (state->list_of) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Cannot add keys to a “list-of” schema")); + return NULL; + } + + if (!is_valid_keyname (name, error)) + return NULL; + + if (g_hash_table_lookup (state->keys, name)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), name); + return NULL; + } + + for (node = state; node; node = node->extends) + if (node->extends) + { + KeyState *shadow; + + shadow = g_hash_table_lookup (node->extends->keys, name); + + /* in case of make sure we report the + * location of the original , not the . + */ + if (shadow && !shadow->is_override) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" shadows in " + "; use to modify value"), + name, name, node->extends_name); + return NULL; + } + } + + if ((type_string != NULL) + (enum_type != NULL) + (flags_type != NULL) != 1) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_MISSING_ATTRIBUTE, + _("Exactly one of “type”, “enum” or “flags” must " + "be specified as an attribute to ")); + return NULL; + } + + if (type_string == NULL) /* flags or enums was specified */ + { + EnumState *enum_state; + + if (enum_type) + enum_state = g_hash_table_lookup (enum_table, enum_type); + else + enum_state = g_hash_table_lookup (flags_table, flags_type); + + + if (enum_state == NULL) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s id='%s'> not (yet) defined."), + flags_type ? "flags" : "enum", + flags_type ? flags_type : enum_type); + return NULL; + } + + type_string = flags_type ? "as" : "s"; + strinfo = enum_state->strinfo; + } + else + { + if (!g_variant_type_string_is_valid (type_string)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Invalid GVariant type string “%s”"), type_string); + return NULL; + } + + strinfo = NULL; + } + + key = key_state_new (type_string, state->gettext_domain, + enum_type != NULL, flags_type != NULL, strinfo); + g_hash_table_insert (state->keys, g_strdup (name), key); + + return key; +} + +static void +schema_state_add_override (SchemaState *state, + KeyState **key_state, + GString **string, + const gchar *key, + const gchar *l10n, + const gchar *context, + GError **error) +{ + SchemaState *parent; + KeyState *original; + + if (state->extends == NULL) + { + g_set_error_literal (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" given but schema isn’t " + "extending anything")); + return; + } + + for (parent = state->extends; parent; parent = parent->extends) + if ((original = g_hash_table_lookup (parent->keys, key))) + break; + + if (original == NULL) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("No to override"), key); + return; + } + + if (g_hash_table_lookup (state->keys, key)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), key); + return; + } + + *key_state = key_state_override (original, state->gettext_domain); + *string = key_state_start_default (*key_state, l10n, context, error); + g_hash_table_insert (state->keys, g_strdup (key), *key_state); +} + +static void +override_state_end (KeyState **key_state, + GString **string, + GError **error) +{ + key_state_end_default (*key_state, string, error); + *key_state = NULL; +} + +/* Handling of toplevel state {{{1 */ +typedef struct +{ + gboolean strict; /* TRUE if --strict was given */ + + GHashTable *schema_table; /* string -> SchemaState */ + GHashTable *flags_table; /* string -> EnumState */ + GHashTable *enum_table; /* string -> EnumState */ + + GSList *this_file_schemas; /* strings: s in this file */ + GSList *this_file_flagss; /* strings: s in this file */ + GSList *this_file_enums; /* strings: s in this file */ + + gchar *schemalist_domain; /* the gettext domain */ + + SchemaState *schema_state; /* non-NULL when inside */ + KeyState *key_state; /* non-NULL when inside */ + EnumState *enum_state; /* non-NULL when inside */ + + GString *string; /* non-NULL when accepting text */ +} ParseState; + +static gboolean +is_subclass (const gchar *class_name, + const gchar *possible_parent, + GHashTable *schema_table) +{ + SchemaState *class; + + if (strcmp (class_name, possible_parent) == 0) + return TRUE; + + class = g_hash_table_lookup (schema_table, class_name); + g_assert (class != NULL); + + return class->extends_name && + is_subclass (class->extends_name, possible_parent, schema_table); +} + +static void +parse_state_start_schema (ParseState *state, + const gchar *id, + const gchar *path, + const gchar *gettext_domain, + const gchar *extends_name, + const gchar *list_of, + GError **error) +{ + SchemaState *extends; + gchar *my_id; + + if (g_hash_table_lookup (state->schema_table, id)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" already specified"), id); + return; + } + + if (extends_name) + { + extends = g_hash_table_lookup (state->schema_table, extends_name); + + if (extends == NULL) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" extends not yet existing " + "schema “%s”"), id, extends_name); + return; + } + } + else + extends = NULL; + + if (list_of) + { + SchemaState *tmp; + + if (!(tmp = g_hash_table_lookup (state->schema_table, list_of))) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" is list of not yet existing " + "schema “%s”"), id, list_of); + return; + } + + if (tmp->path) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Cannot be a list of a schema with a path")); + return; + } + } + + if (extends) + { + if (extends->path) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Cannot extend a schema with a path")); + return; + } + + if (list_of) + { + if (extends->list_of == NULL) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" is a list, extending " + " which is not a list"), + id, extends_name); + return; + } + + if (!is_subclass (list_of, extends->list_of, state->schema_table)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _(" extends but “%s” does not " + "extend “%s”"), id, list_of, extends_name, + extends->list_of, list_of, extends->list_of); + return; + } + } + else + /* by default we are a list of the same thing that the schema + * we are extending is a list of (which might be nothing) + */ + list_of = extends->list_of; + } + + if (path && !(g_str_has_prefix (path, "/") && g_str_has_suffix (path, "/"))) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("A path, if given, must begin and end with a slash")); + return; + } + + if (path && list_of && !g_str_has_suffix (path, ":/")) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("The path of a list must end with “:/”")); + return; + } + + if (path && (g_str_has_prefix (path, "/apps/") || + g_str_has_prefix (path, "/desktop/") || + g_str_has_prefix (path, "/system/"))) + { + gchar *message = NULL; + message = g_strdup_printf (_("Warning: Schema “%s” has path “%s”. " + "Paths starting with " + "“/apps/”, “/desktop/” or “/system/” are deprecated."), + id, path); + g_printerr ("%s\n", message); + g_free (message); + } + + state->schema_state = schema_state_new (path, gettext_domain, + extends, extends_name, list_of); + + my_id = g_strdup (id); + state->this_file_schemas = g_slist_prepend (state->this_file_schemas, my_id); + g_hash_table_insert (state->schema_table, my_id, state->schema_state); +} + +static void +parse_state_start_enum (ParseState *state, + const gchar *id, + gboolean is_flags, + GError **error) +{ + GSList **list = is_flags ? &state->this_file_flagss : &state->this_file_enums; + GHashTable *table = is_flags ? state->flags_table : state->enum_table; + gchar *my_id; + + if (g_hash_table_lookup (table, id)) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("<%s id='%s'> already specified"), + is_flags ? "flags" : "enum", id); + return; + } + + state->enum_state = enum_state_new (is_flags); + + my_id = g_strdup (id); + *list = g_slist_prepend (*list, my_id); + g_hash_table_insert (table, my_id, state->enum_state); +} + +/* GMarkup Parser Functions {{{1 */ + +/* Start element {{{2 */ +static void +start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + const GSList *element_stack; + const gchar *container; + + element_stack = g_markup_parse_context_get_element_stack (context); + container = element_stack->next ? element_stack->next->data : NULL; + +#define COLLECT(first, ...) \ + g_markup_collect_attributes (element_name, \ + attribute_names, attribute_values, error, \ + first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID) +#define OPTIONAL G_MARKUP_COLLECT_OPTIONAL +#define STRDUP G_MARKUP_COLLECT_STRDUP +#define STRING G_MARKUP_COLLECT_STRING +#define NO_ATTRS() COLLECT (G_MARKUP_COLLECT_INVALID, NULL) + + /* Toplevel items {{{3 */ + if (container == NULL) + { + if (strcmp (element_name, "schemalist") == 0) + { + COLLECT (OPTIONAL | STRDUP, + "gettext-domain", + &state->schemalist_domain); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "schemalist") == 0) + { + if (strcmp (element_name, "schema") == 0) + { + const gchar *id, *path, *gettext_domain, *extends, *list_of; + if (COLLECT (STRING, "id", &id, + OPTIONAL | STRING, "path", &path, + OPTIONAL | STRING, "gettext-domain", &gettext_domain, + OPTIONAL | STRING, "extends", &extends, + OPTIONAL | STRING, "list-of", &list_of)) + parse_state_start_schema (state, id, path, + gettext_domain ? gettext_domain + : state->schemalist_domain, + extends, list_of, error); + return; + } + + else if (strcmp (element_name, "enum") == 0) + { + const gchar *id; + if (COLLECT (STRING, "id", &id)) + parse_state_start_enum (state, id, FALSE, error); + return; + } + + else if (strcmp (element_name, "flags") == 0) + { + const gchar *id; + if (COLLECT (STRING, "id", &id)) + parse_state_start_enum (state, id, TRUE, error); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "schema") == 0) + { + if (strcmp (element_name, "key") == 0) + { + const gchar *name, *type_string, *enum_type, *flags_type; + + if (COLLECT (STRING, "name", &name, + OPTIONAL | STRING, "type", &type_string, + OPTIONAL | STRING, "enum", &enum_type, + OPTIONAL | STRING, "flags", &flags_type)) + + state->key_state = schema_state_add_key (state->schema_state, + state->enum_table, + state->flags_table, + name, type_string, + enum_type, flags_type, + error); + return; + } + else if (strcmp (element_name, "child") == 0) + { + const gchar *name, *schema; + + if (COLLECT (STRING, "name", &name, STRING, "schema", &schema)) + schema_state_add_child (state->schema_state, + name, schema, error); + return; + } + else if (strcmp (element_name, "override") == 0) + { + const gchar *name, *l10n, *context; + + if (COLLECT (STRING, "name", &name, + OPTIONAL | STRING, "l10n", &l10n, + OPTIONAL | STRING, "context", &context)) + schema_state_add_override (state->schema_state, + &state->key_state, &state->string, + name, l10n, context, error); + return; + } + } + + /* children of {{{3 */ + else if (strcmp (container, "key") == 0) + { + if (strcmp (element_name, "default") == 0) + { + const gchar *l10n, *context; + if (COLLECT (STRING | OPTIONAL, "l10n", &l10n, + STRING | OPTIONAL, "context", &context)) + state->string = key_state_start_default (state->key_state, + l10n, context, error); + return; + } + + else if (strcmp (element_name, "summary") == 0) + { + if (NO_ATTRS ()) + { + if (state->key_state->summary_seen && state->strict) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Only one <%s> element allowed inside <%s>"), + element_name, container); + else + state->string = g_string_new (NULL); + + state->key_state->summary_seen = TRUE; + } + return; + } + + else if (strcmp (element_name, "description") == 0) + { + if (NO_ATTRS ()) + { + if (state->key_state->description_seen && state->strict) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Only one <%s> element allowed inside <%s>"), + element_name, container); + else + state->string = g_string_new (NULL); + + state->key_state->description_seen = TRUE; + } + return; + } + + else if (strcmp (element_name, "range") == 0) + { + const gchar *min, *max; + if (COLLECT (STRING | OPTIONAL, "min", &min, + STRING | OPTIONAL, "max", &max)) + key_state_set_range (state->key_state, min, max, error); + return; + } + + else if (strcmp (element_name, "choices") == 0) + { + if (NO_ATTRS ()) + key_state_start_choices (state->key_state, error); + return; + } + + else if (strcmp (element_name, "aliases") == 0) + { + if (NO_ATTRS ()) + key_state_start_aliases (state->key_state, error); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "choices") == 0) + { + if (strcmp (element_name, "choice") == 0) + { + const gchar *value; + if (COLLECT (STRING, "value", &value)) + key_state_add_choice (state->key_state, value, error); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "aliases") == 0) + { + if (strcmp (element_name, "alias") == 0) + { + const gchar *value, *target; + if (COLLECT (STRING, "value", &value, STRING, "target", &target)) + key_state_add_alias (state->key_state, value, target, error); + return; + } + } + + + /* children of {{{3 */ + else if (strcmp (container, "enum") == 0 || + strcmp (container, "flags") == 0) + { + if (strcmp (element_name, "value") == 0) + { + const gchar *nick, *valuestr; + if (COLLECT (STRING, "nick", &nick, + STRING, "value", &valuestr)) + enum_state_add_value (state->enum_state, nick, valuestr, error); + return; + } + } + /* 3}}} */ + + if (container) + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Element <%s> not allowed inside <%s>"), + element_name, container); + else + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Element <%s> not allowed at the top level"), element_name); +} +/* 2}}} */ +/* End element {{{2 */ + +static void +key_state_end (KeyState **state_ptr, + GError **error) +{ + KeyState *state; + + state = *state_ptr; + *state_ptr = NULL; + + if (state->default_value == NULL) + { + g_set_error_literal (error, + G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Element is required in ")); + return; + } +} + +static void +schema_state_end (SchemaState **state_ptr, + GError **error) +{ + *state_ptr = NULL; +} + +static void +end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + + if (strcmp (element_name, "schemalist") == 0) + { + g_free (state->schemalist_domain); + state->schemalist_domain = NULL; + } + + else if (strcmp (element_name, "enum") == 0 || + strcmp (element_name, "flags") == 0) + enum_state_end (&state->enum_state, error); + + else if (strcmp (element_name, "schema") == 0) + schema_state_end (&state->schema_state, error); + + else if (strcmp (element_name, "override") == 0) + override_state_end (&state->key_state, &state->string, error); + + else if (strcmp (element_name, "key") == 0) + key_state_end (&state->key_state, error); + + else if (strcmp (element_name, "default") == 0) + key_state_end_default (state->key_state, &state->string, error); + + else if (strcmp (element_name, "choices") == 0) + key_state_end_choices (state->key_state, error); + + else if (strcmp (element_name, "aliases") == 0) + key_state_end_aliases (state->key_state, error); + + if (state->string) + { + g_string_free (state->string, TRUE); + state->string = NULL; + } +} +/* Text {{{2 */ +static void +text (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + ParseState *state = user_data; + + if (state->string) + { + /* we are expecting a string, so store the text data. + * + * we store the data verbatim here and deal with whitespace + * later on. there are two reasons for that: + * + * 1) whitespace is handled differently depending on the tag + * type. + * + * 2) we could do leading whitespace removal by refusing to + * insert it into state->string if it's at the start, but for + * trailing whitespace, we have no idea if there is another + * text() call coming or not. + */ + g_string_append_len (state->string, text, text_len); + } + else + { + /* string is not expected: accept (and ignore) pure whitespace */ + gsize i; + + for (i = 0; i < text_len; i++) + if (!g_ascii_isspace (text[i])) + { + g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, + _("Text may not appear inside <%s>"), + g_markup_parse_context_get_element (context)); + break; + } + } +} + +/* Write to GVDB {{{1 */ +typedef struct +{ + GHashTable *table; + GvdbItem *root; +} GvdbPair; + +static void +gvdb_pair_init (GvdbPair *pair) +{ + pair->table = gvdb_hash_table_new (NULL, NULL); + pair->root = gvdb_hash_table_insert (pair->table, ""); +} + +static void +gvdb_pair_clear (GvdbPair *pair) +{ + g_hash_table_unref (pair->table); +} + +typedef struct +{ + GHashTable *schema_table; + GvdbPair root_pair; +} WriteToFileData; + +typedef struct +{ + GHashTable *schema_table; + GvdbPair pair; + gboolean l10n; +} OutputSchemaData; + +static void +output_key (gpointer key, + gpointer value, + gpointer user_data) +{ + OutputSchemaData *data; + const gchar *name; + KeyState *state; + GvdbItem *item; + GVariant *serialised = NULL; + + name = key; + state = value; + data = user_data; + + item = gvdb_hash_table_insert (data->pair.table, name); + gvdb_item_set_parent (item, data->pair.root); + serialised = key_state_serialise (state); + gvdb_item_set_value (item, serialised); + g_variant_unref (serialised); + + if (state->l10n) + data->l10n = TRUE; + + if (state->child_schema && + !g_hash_table_lookup (data->schema_table, state->child_schema)) + { + gchar *message = NULL; + message = g_strdup_printf (_("Warning: undefined reference to "), + state->child_schema); + g_printerr ("%s\n", message); + g_free (message); + } +} + +static void +output_schema (gpointer key, + gpointer value, + gpointer user_data) +{ + WriteToFileData *wtf_data = user_data; + OutputSchemaData data; + GvdbPair *root_pair; + SchemaState *state; + const gchar *id; + GvdbItem *item; + + id = key; + state = value; + root_pair = &wtf_data->root_pair; + + data.schema_table = wtf_data->schema_table; + gvdb_pair_init (&data.pair); + data.l10n = FALSE; + + item = gvdb_hash_table_insert (root_pair->table, id); + gvdb_item_set_parent (item, root_pair->root); + gvdb_item_set_hash_table (item, data.pair.table); + + g_hash_table_foreach (state->keys, output_key, &data); + + if (state->path) + gvdb_hash_table_insert_string (data.pair.table, ".path", state->path); + + if (state->extends_name) + gvdb_hash_table_insert_string (data.pair.table, ".extends", + state->extends_name); + + if (state->list_of) + gvdb_hash_table_insert_string (data.pair.table, ".list-of", + state->list_of); + + if (data.l10n) + gvdb_hash_table_insert_string (data.pair.table, + ".gettext-domain", + state->gettext_domain); + + gvdb_pair_clear (&data.pair); +} + +static gboolean +write_to_file (GHashTable *schema_table, + const gchar *filename, + GError **error) +{ + WriteToFileData data; + gboolean success; + + data.schema_table = schema_table; + + gvdb_pair_init (&data.root_pair); + + g_hash_table_foreach (schema_table, output_schema, &data); + + success = gvdb_table_write_contents (data.root_pair.table, filename, + G_BYTE_ORDER != G_LITTLE_ENDIAN, + error); + g_hash_table_unref (data.root_pair.table); + + return success; +} + +/* Parser driver {{{1 */ +static GHashTable * +parse_gschema_files (gchar **files, + gboolean strict) +{ + GMarkupParser parser = { start_element, end_element, text }; + ParseState state = { 0, }; + const gchar *filename; + GError *error = NULL; + + state.strict = strict; + + state.enum_table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, enum_state_free); + + state.flags_table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, enum_state_free); + + state.schema_table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, schema_state_free); + + while ((filename = *files++) != NULL) + { + GMarkupParseContext *context; + gchar *contents; + gsize size; + gint line, col; + + if (!g_file_get_contents (filename, &contents, &size, &error)) + { + fprintf (stderr, "%s\n", error->message); + g_clear_error (&error); + continue; + } + + context = g_markup_parse_context_new (&parser, + G_MARKUP_TREAT_CDATA_AS_TEXT | + G_MARKUP_PREFIX_ERROR_POSITION | + G_MARKUP_IGNORE_QUALIFIED, + &state, NULL); + + + if (!g_markup_parse_context_parse (context, contents, size, &error) || + !g_markup_parse_context_end_parse (context, &error)) + { + GSList *item; + + /* back out any changes from this file */ + for (item = state.this_file_schemas; item; item = item->next) + g_hash_table_remove (state.schema_table, item->data); + + for (item = state.this_file_flagss; item; item = item->next) + g_hash_table_remove (state.flags_table, item->data); + + for (item = state.this_file_enums; item; item = item->next) + g_hash_table_remove (state.enum_table, item->data); + + /* let them know */ + g_markup_parse_context_get_position (context, &line, &col); + fprintf (stderr, "%s:%d:%d %s. ", filename, line, col, error->message); + g_clear_error (&error); + + if (strict) + { + /* Translators: Do not translate "--strict". */ + fprintf (stderr, _("--strict was specified; exiting.\n")); + g_hash_table_unref (state.schema_table); + g_hash_table_unref (state.flags_table); + g_hash_table_unref (state.enum_table); + + g_free (contents); + + return NULL; + } + else + fprintf (stderr, _("This entire file has been ignored.\n")); + } + + /* cleanup */ + g_free (contents); + g_markup_parse_context_free (context); + g_slist_free (state.this_file_schemas); + g_slist_free (state.this_file_flagss); + g_slist_free (state.this_file_enums); + state.this_file_schemas = NULL; + state.this_file_flagss = NULL; + state.this_file_enums = NULL; + } + + g_hash_table_unref (state.flags_table); + g_hash_table_unref (state.enum_table); + + return state.schema_table; +} + +static gint +compare_strings (gconstpointer a, + gconstpointer b) +{ + gchar *one = *(gchar **) a; + gchar *two = *(gchar **) b; + gint cmp; + + cmp = g_str_has_suffix (two, ".enums.xml") - + g_str_has_suffix (one, ".enums.xml"); + + if (!cmp) + cmp = strcmp (one, two); + + return cmp; +} + +static gboolean +set_overrides (GHashTable *schema_table, + gchar **files, + gboolean strict) +{ + const gchar *filename; + GError *error = NULL; + + while ((filename = *files++)) + { + GKeyFile *key_file; + gchar **groups; + gint i; + + g_debug ("Processing override file '%s'", filename); + + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, filename, 0, &error)) + { + fprintf (stderr, "%s: %s. ", filename, error->message); + g_key_file_free (key_file); + g_clear_error (&error); + + if (!strict) + { + fprintf (stderr, _("Ignoring this file.\n")); + continue; + } + + fprintf (stderr, _("--strict was specified; exiting.\n")); + return FALSE; + } + + groups = g_key_file_get_groups (key_file, NULL); + + for (i = 0; groups[i]; i++) + { + const gchar *group = groups[i]; + const gchar *schema_name; + const gchar *desktop_id; + SchemaState *schema; + gchar **pieces; + gchar **keys; + gint j; + + pieces = g_strsplit (group, ":", 2); + schema_name = pieces[0]; + desktop_id = pieces[1]; + + g_debug ("Processing group '%s' (schema '%s', %s)", + group, schema_name, desktop_id ? desktop_id : "all desktops"); + + schema = g_hash_table_lookup (schema_table, schema_name); + + if (schema == NULL) + { + /* Having the schema not be installed is expected to be a + * common case. Don't even emit an error message about + * that. + */ + g_strfreev (pieces); + continue; + } + + keys = g_key_file_get_keys (key_file, group, NULL, NULL); + g_assert (keys != NULL); + + for (j = 0; keys[j]; j++) + { + const gchar *key = keys[j]; + KeyState *state; + GVariant *value; + gchar *string; + + state = g_hash_table_lookup (schema->keys, key); + + if (state == NULL) + { + fprintf (stderr, _("No such key “%s” in schema “%s” as " + "specified in override file “%s”"), + key, group, filename); + + if (!strict) + { + fprintf (stderr, _("; ignoring override for this key.\n")); + continue; + } + + fprintf (stderr, _(" and --strict was specified; exiting.\n")); + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + + if (desktop_id != NULL && state->l10n) + { + /* Let's avoid the n*m case of per-desktop localised + * default values, and just forbid it. + */ + fprintf (stderr, + _("cannot provide per-desktop overrides for localised " + "key “%s” in schema “%s” (override file “%s”)"), + key, group, filename); + + if (!strict) + { + fprintf (stderr, _("; ignoring override for this key.\n")); + continue; + } + + fprintf (stderr, _(" and --strict was specified; exiting.\n")); + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + + string = g_key_file_get_value (key_file, group, key, NULL); + g_assert (string != NULL); + + value = g_variant_parse (state->type, string, + NULL, NULL, &error); + + if (value == NULL) + { + fprintf (stderr, _("error parsing key “%s” in schema “%s” " + "as specified in override file “%s”: " + "%s."), + key, group, filename, error->message); + + g_clear_error (&error); + g_free (string); + + if (!strict) + { + fprintf (stderr, _("Ignoring override for this key.\n")); + continue; + } + + fprintf (stderr, _("--strict was specified; exiting.\n")); + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + + if (state->minimum) + { + if (g_variant_compare (value, state->minimum) < 0 || + g_variant_compare (value, state->maximum) > 0) + { + fprintf (stderr, + _("override for key “%s” in schema “%s” in " + "override file “%s” is outside the range " + "given in the schema"), + key, group, filename); + + g_variant_unref (value); + g_free (string); + + if (!strict) + { + fprintf (stderr, _("; ignoring override for this key.\n")); + continue; + } + + fprintf (stderr, _(" and --strict was specified; exiting.\n")); + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + } + + else if (state->strinfo->len) + { + if (!is_valid_choices (value, state->strinfo)) + { + fprintf (stderr, + _("override for key “%s” in schema “%s” in " + "override file “%s” is not in the list " + "of valid choices"), + key, group, filename); + + g_variant_unref (value); + g_free (string); + + if (!strict) + { + fprintf (stderr, _("; ignoring override for this key.\n")); + continue; + } + + fprintf (stderr, _(" and --strict was specified; exiting.\n")); + g_key_file_free (key_file); + g_strfreev (pieces); + g_strfreev (groups); + g_strfreev (keys); + + return FALSE; + } + } + + if (desktop_id != NULL) + { + if (state->desktop_overrides == NULL) + state->desktop_overrides = g_variant_dict_new (NULL); + + g_variant_dict_insert_value (state->desktop_overrides, desktop_id, value); + g_variant_unref (value); + } + else + { + g_variant_unref (state->default_value); + state->default_value = value; + } + + g_free (string); + } + + g_strfreev (pieces); + g_strfreev (keys); + } + + g_strfreev (groups); + g_key_file_free (key_file); + } + + return TRUE; +} + +int +main (int argc, char **argv) +{ + GError *error = NULL; + GHashTable *table = NULL; + GDir *dir = NULL; + const gchar *file; + const gchar *srcdir; + gboolean show_version_and_exit = FALSE; + gchar *targetdir = NULL; + gchar *target = NULL; + gboolean dry_run = FALSE; + gboolean strict = FALSE; + gchar **schema_files = NULL; + gchar **override_files = NULL; + GOptionContext *context = NULL; + gint retval; + GOptionEntry entries[] = { + { "version", 0, 0, G_OPTION_ARG_NONE, &show_version_and_exit, N_("Show program version and exit"), NULL }, + { "targetdir", 0, 0, G_OPTION_ARG_FILENAME, &targetdir, N_("where to store the gschemas.compiled file"), N_("DIRECTORY") }, + { "strict", 0, 0, G_OPTION_ARG_NONE, &strict, N_("Abort on any errors in schemas"), NULL }, + { "dry-run", 0, 0, G_OPTION_ARG_NONE, &dry_run, N_("Do not write the gschema.compiled file"), NULL }, + { "allow-any-name", 0, 0, G_OPTION_ARG_NONE, &allow_any_name, N_("Do not enforce key name restrictions") }, + + /* These options are only for use in the gschema-compile tests */ + { "schema-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &schema_files, NULL, NULL }, + { "override-file", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME_ARRAY, &override_files, NULL, NULL }, + { NULL } + }; + +#ifdef G_OS_WIN32 + gchar *tmp = NULL; +#endif + + setlocale (LC_ALL, ""); + textdomain (GETTEXT_PACKAGE); + +#ifdef G_OS_WIN32 + tmp = _glib_get_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, tmp); +#else + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#endif + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + + context = g_option_context_new (N_("DIRECTORY")); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_set_summary (context, + N_("Compile all GSettings schema files into a schema cache.\n" + "Schema files are required to have the extension .gschema.xml,\n" + "and the cache file is called gschemas.compiled.")); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + + if (!g_option_context_parse (context, &argc, &argv, &error)) + { + fprintf (stderr, "%s\n", error->message); + retval = 1; + goto done; + } + + if (show_version_and_exit) + { + g_print (PACKAGE_VERSION "\n"); + retval = 0; + goto done; + } + + if (!schema_files && argc != 2) + { + fprintf (stderr, _("You should give exactly one directory name\n")); + retval = 1; + goto done; + } + + srcdir = argv[1]; + + target = g_build_filename (targetdir ? targetdir : srcdir, "gschemas.compiled", NULL); + + if (!schema_files) + { + GPtrArray *overrides; + GPtrArray *files; + + files = g_ptr_array_new (); + overrides = g_ptr_array_new (); + + dir = g_dir_open (srcdir, 0, &error); + if (dir == NULL) + { + fprintf (stderr, "%s\n", error->message); + + g_ptr_array_unref (files); + g_ptr_array_unref (overrides); + + retval = 1; + goto done; + } + + while ((file = g_dir_read_name (dir)) != NULL) + { + if (g_str_has_suffix (file, ".gschema.xml") || + g_str_has_suffix (file, ".enums.xml")) + g_ptr_array_add (files, g_build_filename (srcdir, file, NULL)); + + else if (g_str_has_suffix (file, ".gschema.override")) + g_ptr_array_add (overrides, + g_build_filename (srcdir, file, NULL)); + } + + if (files->len == 0) + { + fprintf (stdout, _("No schema files found: ")); + + if (g_unlink (target)) + fprintf (stdout, _("doing nothing.\n")); + + else + fprintf (stdout, _("removed existing output file.\n")); + + g_ptr_array_unref (files); + g_ptr_array_unref (overrides); + + retval = 0; + goto done; + } + g_ptr_array_sort (files, compare_strings); + g_ptr_array_add (files, NULL); + + g_ptr_array_sort (overrides, compare_strings); + g_ptr_array_add (overrides, NULL); + + schema_files = (char **) g_ptr_array_free (files, FALSE); + override_files = (gchar **) g_ptr_array_free (overrides, FALSE); + } + + if ((table = parse_gschema_files (schema_files, strict)) == NULL) + { + retval = 1; + goto done; + } + + if (override_files != NULL && + !set_overrides (table, override_files, strict)) + { + retval = 1; + goto done; + } + + if (!dry_run && !write_to_file (table, target, &error)) + { + fprintf (stderr, "%s\n", error->message); + retval = 1; + goto done; + } + + /* Success. */ + retval = 0; + +done: + g_clear_error (&error); + g_clear_pointer (&table, g_hash_table_unref); + g_clear_pointer (&dir, g_dir_close); + g_free (targetdir); + g_free (target); + g_strfreev (schema_files); + g_strfreev (override_files); + g_option_context_free (context); + +#ifdef G_OS_WIN32 + g_free (tmp); +#endif + + return retval; +} + +/* Epilogue {{{1 */ + +/* vim:set foldmethod=marker: */ diff -Nru glib2.0-2.59.2/.pc/debian/04_homedir_env.patch/docs/reference/glib/running.xml glib2.0-2.59.3/.pc/debian/04_homedir_env.patch/docs/reference/glib/running.xml --- glib2.0-2.59.2/.pc/debian/04_homedir_env.patch/docs/reference/glib/running.xml 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/04_homedir_env.patch/docs/reference/glib/running.xml 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,348 @@ + + + + +Running GLib Applications +3 +GLib Library + + + +Running GLib Applications + +How to run and debug your GLib application + + + + +Running and debugging GLib Applications + + +Environment variables + + + The runtime behaviour of GLib applications can be influenced by a + number of environment variables. + + + + Standard variables + + + GLib reads standard environment variables like LANG, + PATH, HOME, TMPDIR, + TZ and LOGNAME. + + + + + XDG directories + + + GLib consults the environment variables XDG_DATA_HOME, + XDG_DATA_DIRS, XDG_CONFIG_HOME, + XDG_CONFIG_DIRS, XDG_CACHE_HOME and + XDG_RUNTIME_DIR for the various XDG directories. + For more information, see the XDG basedir spec. + + + + + <envar>G_FILENAME_ENCODING</envar> + + + This environment variable can be set to a comma-separated list of character + set names. GLib assumes that filenames are encoded in the first character + set from that list rather than in UTF-8. The special token "@locale" can be + used to specify the character set for the current locale. + + + + + <envar>G_BROKEN_FILENAMES</envar> + + + If this environment variable is set, GLib assumes that filenames are in + the locale encoding rather than in UTF-8. G_FILENAME_ENCODING takes + priority over G_BROKEN_FILENAMES. + + + + + <envar>G_MESSAGES_PREFIXED</envar> + + + A list of log levels for which messages should be prefixed by the + program name and PID of the application. The default is to prefix + everything except G_LOG_LEVEL_MESSAGE and + G_LOG_LEVEL_INFO. + The possible values are + error, + warning, + critical, + message, + info and + debug. + You can also use the special values + all and + help. + + + This environment variable only affects the default log handler, + g_log_default_handler(). + + + + + <envar>G_MESSAGES_DEBUG</envar> + + + A space-separated list of log domains for which informational + and debug messages should be printed. By default, these + messages are not printed. + + + You can also use the special value all. + + + This environment variable only affects the default log handler, + g_log_default_handler(). + + + + + <envar>G_DEBUG</envar> + + + This environment variable can be set to a list of debug options, + which cause GLib to print out different types of debugging information. + + + fatal-warnings + Causes GLib to abort the program at the first call + to g_warning() or g_critical(). Use of this flag is not + recommended except when debugging. + + + + fatal-criticals + Causes GLib to abort the program at the first call + to g_critical(). This flag can be useful during debugging and + testing. + + + + gc-friendly + Newly allocated memory that isn't directly initialized, + as well as memory being freed will be reset to 0. The point here is + to allow memory checkers and similar programs that use Boehm GC alike + algorithms to produce more accurate results. + + + + resident-modules + All modules loaded by GModule will be made resident. + This can be useful for tracking memory leaks in modules which are + later unloaded; but it can also hide bugs where code is accessed + after the module would have normally been unloaded. + + + + bind-now-modules + All modules loaded by GModule will bind their symbols + at load time, even when the code uses %G_MODULE_BIND_LAZY. + + + + The special value all can be used to turn on all debug options. + The special value help can be used to print all available options. + + + + + <envar>G_SLICE</envar> + + + This environment variable allows reconfiguration of the GSlice + memory allocator. + + + always-malloc + This will cause all slices allocated through + g_slice_alloc() and released by g_slice_free1() to be actually + allocated via direct calls to g_malloc() and g_free(). + This is most useful for memory checkers and similar programs that + use Boehm GC alike algorithms to produce more accurate results. + It can also be in conjunction with debugging features of the system's + malloc() implementation such as glibc's MALLOC_CHECK_=2 to debug + erroneous slice allocation code, although + debug-blocks is usually a better suited debugging + tool. + + + + debug-blocks + Using this option (present since GLib 2.13) engages + extra code which performs sanity checks on the released memory + slices. Invalid slice addresses or slice sizes will be reported and + lead to a program halt. This option is for debugging scenarios. + In particular, client packages sporting their own test suite should + always enable this option when running tests. + Global slice validation is ensured by storing size and address + information for each allocated chunk, and maintaining a global + hash table of that data. That way, multi-thread scalability is + given up, and memory consumption is increased. However, the + resulting code usually performs acceptably well, possibly better + than with comparable memory checking carried out using external + tools. + An example of a memory corruption scenario that cannot be + reproduced with G_SLICE=always-malloc, but will + be caught by G_SLICE=debug-blocks is as follows: + + void *slist = g_slist_alloc (); /* void* gives up type-safety */ + g_list_free (slist); /* corruption: sizeof (GSList) != sizeof (GList) */ + + + + + The special value all can be used to turn on all options. + The special value help can be used to print all available options. + + + + + <envar>G_RANDOM_VERSION</envar> + + + If this environment variable is set to '2.0', the outdated + pseudo-random number seeding and generation algorithms from + GLib 2.0 are used instead of the newer, better ones. You should + only set this variable if you have sequences of numbers that were + generated with Glib 2.0 that you need to reproduce exactly. + + + + + <envar>LIBCHARSET_ALIAS_DIR</envar> + + + Allows to specify a nonstandard location for the + charset.aliases file that is used by the + character set conversion routines. The default location is the + libdir specified at compilation time. + + + + + <envar>TZDIR</envar> + + + Allows to specify a nonstandard location for the timezone data files + that are used by the #GDateTime API. The default location is under + /usr/share/zoneinfo. For more information, + also look at the tzset manual page. + + + + + <envar>G_ENABLE_DIAGNOSTIC</envar> + + + If set to a non-zero value, this environment variable enables + diagnostic messages, like deprecation messages for GObject properties + and signals. + + + + + + +Locale + + +A number of interfaces in GLib depend on the current locale in which +an application is running. Therefore, most GLib-using applications should +call setlocale (LC_ALL, "") to set up the current +locale. + + + +On Windows, in a C program there are several locale concepts +that not necessarily are synchronized. On one hand, there is the +system default ANSI code-page, which determines what encoding is used +for file names handled by the C library's functions and the Win32 +API. (We are talking about the "narrow" functions here that take +character pointers, not the "wide" ones.) + + + +On the other hand, there is the C library's current locale. The +character set (code-page) used by that is not necessarily the same as +the system default ANSI code-page. Strings in this character set are +returned by functions like strftime(). + + + + + +GLib ships with a set of Python macros for the GDB debugger. These includes pretty +printers for lists, hashtables and GObject types. It also has a backtrace filter +that makes backtraces with signal emissions easier to read. + + + +To use this you need a version of GDB that supports Python scripting; anything +from 7.0 should be fine. You then need to install GLib in the same prefix as +GDB so that the Python GDB autoloaded files get installed in the right place +for GDB to pick up. + + + +General pretty printing should just happen without having to do anything special. +To get the signal emission filtered backtrace you must use the "new-backtrace" command +instead of the standard one. + + + +There is also a new command called gforeach that can be used to apply a command +on each item in a list. E.g. you can do + +gforeach i in some_list_variable: print *(GtkWidget *)l + +Which would print the contents of each widget in a list of widgets. + + + +SystemTap + + +SystemTap is a dynamic whole-system +analysis toolkit. GLib ships with a file libglib-2.0.so.*.stp which defines a +set of probe points, which you can hook into with custom SystemTap scripts. +See the files libglib-2.0.so.*.stp, libgobject-2.0.so.*.stp +and libgio-2.0.so.*.stp which +are in your shared SystemTap scripts directory. + + + + + +Memory statistics + + +g_mem_profile() will output a summary g_malloc() memory usage, if memory +profiling has been enabled by calling +g_mem_set_vtable (glib_mem_profiler_table) upon startup. + + + +If GLib has been configured with , +then g_slice_debug_tree_statistics() can be called in a debugger to +output details about the memory usage of the slice allocator. + + + + + diff -Nru glib2.0-2.59.2/.pc/debian/04_homedir_env.patch/glib/gutils.c glib2.0-2.59.3/.pc/debian/04_homedir_env.patch/glib/gutils.c --- glib2.0-2.59.2/.pc/debian/04_homedir_env.patch/glib/gutils.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/04_homedir_env.patch/glib/gutils.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,2702 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe for the unix part, FIXME: make the win32 part MT safe as well. + */ + +#include "config.h" + +#include "gutils.h" +#include "gutilsprivate.h" + +#include +#include +#include +#include +#include +#include /* For tolower() */ +#include +#include +#include +#ifdef G_OS_UNIX +#include +#include +#endif +#include +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_CRT_EXTERNS_H +#include /* for _NSGetEnviron */ +#endif +#ifdef HAVE_SYS_AUXV_H +#include +#endif + +#include "glib-init.h" +#include "glib-private.h" +#include "genviron.h" +#include "gfileutils.h" +#include "ggettext.h" +#include "ghash.h" +#include "gthread.h" +#include "gtestutils.h" +#include "gunicode.h" +#include "gstrfuncs.h" +#include "garray.h" +#include "glibintl.h" +#include "gstdio.h" + +#ifdef G_PLATFORM_WIN32 +#include "gconvert.h" +#include "gwin32.h" +#endif + + +/** + * SECTION:misc_utils + * @title: Miscellaneous Utility Functions + * @short_description: a selection of portable utility functions + * + * These are portable utility functions. + */ + +#ifdef G_PLATFORM_WIN32 +# include +# ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS +# define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2 +# define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4 +# endif +# include /* For UNLEN */ +#endif /* G_PLATFORM_WIN32 */ + +#ifdef G_OS_WIN32 +# include +# include + /* older SDK (e.g. msvc 5.0) does not have these*/ +# ifndef CSIDL_MYMUSIC +# define CSIDL_MYMUSIC 13 +# endif +# ifndef CSIDL_MYVIDEO +# define CSIDL_MYVIDEO 14 +# endif +# ifndef CSIDL_INTERNET_CACHE +# define CSIDL_INTERNET_CACHE 32 +# endif +# ifndef CSIDL_COMMON_APPDATA +# define CSIDL_COMMON_APPDATA 35 +# endif +# ifndef CSIDL_MYPICTURES +# define CSIDL_MYPICTURES 0x27 +# endif +# ifndef CSIDL_COMMON_DOCUMENTS +# define CSIDL_COMMON_DOCUMENTS 46 +# endif +# ifndef CSIDL_PROFILE +# define CSIDL_PROFILE 40 +# endif +# include +#endif + +#ifdef HAVE_CODESET +#include +#endif + +#ifdef G_PLATFORM_WIN32 + +gchar * +_glib_get_dll_directory (void) +{ + gchar *retval; + gchar *p; + wchar_t wc_fn[MAX_PATH]; + +#ifdef DLL_EXPORT + if (glib_dll == NULL) + return NULL; +#endif + + /* This code is different from that in + * g_win32_get_package_installation_directory_of_module() in that + * here we return the actual folder where the GLib DLL is. We don't + * do the check for it being in a "bin" or "lib" subfolder and then + * returning the parent of that. + * + * In a statically built GLib, glib_dll will be NULL and we will + * thus look up the application's .exe file's location. + */ + if (!GetModuleFileNameW (glib_dll, wc_fn, MAX_PATH)) + return NULL; + + retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL); + + p = strrchr (retval, G_DIR_SEPARATOR); + if (p == NULL) + { + /* Wtf? */ + return NULL; + } + *p = '\0'; + + return retval; +} + +#endif + +/** + * g_memmove: + * @dest: the destination address to copy the bytes to. + * @src: the source address to copy the bytes from. + * @len: the number of bytes to copy. + * + * Copies a block of memory @len bytes long, from @src to @dest. + * The source and destination areas may overlap. + * + * Deprecated:2.40: Just use memmove(). + */ + +#ifdef G_OS_WIN32 +#undef g_atexit +#endif + +/** + * g_atexit: + * @func: (scope async): the function to call on normal program termination. + * + * Specifies a function to be called at normal program termination. + * + * Since GLib 2.8.2, on Windows g_atexit() actually is a preprocessor + * macro that maps to a call to the atexit() function in the C + * library. This means that in case the code that calls g_atexit(), + * i.e. atexit(), is in a DLL, the function will be called when the + * DLL is detached from the program. This typically makes more sense + * than that the function is called when the GLib DLL is detached, + * which happened earlier when g_atexit() was a function in the GLib + * DLL. + * + * The behaviour of atexit() in the context of dynamically loaded + * modules is not formally specified and varies wildly. + * + * On POSIX systems, calling g_atexit() (or atexit()) in a dynamically + * loaded module which is unloaded before the program terminates might + * well cause a crash at program exit. + * + * Some POSIX systems implement atexit() like Windows, and have each + * dynamically loaded module maintain an own atexit chain that is + * called when the module is unloaded. + * + * On other POSIX systems, before a dynamically loaded module is + * unloaded, the registered atexit functions (if any) residing in that + * module are called, regardless where the code that registered them + * resided. This is presumably the most robust approach. + * + * As can be seen from the above, for portability it's best to avoid + * calling g_atexit() (or atexit()) except in the main executable of a + * program. + * + * Deprecated:2.32: It is best to avoid g_atexit(). + */ +void +g_atexit (GVoidFunc func) +{ + gint result; + int errsv; + + result = atexit ((void (*)(void)) func); + errsv = errno; + if (result) + { + g_error ("Could not register atexit() function: %s", + g_strerror (errsv)); + } +} + +/* Based on execvp() from GNU Libc. + * Some of this code is cut-and-pasted into gspawn.c + */ + +static gchar* +my_strchrnul (const gchar *str, + gchar c) +{ + gchar *p = (gchar*)str; + while (*p && (*p != c)) + ++p; + + return p; +} + +#ifdef G_OS_WIN32 + +static gchar *inner_find_program_in_path (const gchar *program); + +gchar* +g_find_program_in_path (const gchar *program) +{ + const gchar *last_dot = strrchr (program, '.'); + + if (last_dot == NULL || + strchr (last_dot, '\\') != NULL || + strchr (last_dot, '/') != NULL) + { + const gint program_length = strlen (program); + gchar *pathext = g_build_path (";", + ".exe;.cmd;.bat;.com", + g_getenv ("PATHEXT"), + NULL); + gchar *p; + gchar *decorated_program; + gchar *retval; + + p = pathext; + do + { + gchar *q = my_strchrnul (p, ';'); + + decorated_program = g_malloc (program_length + (q-p) + 1); + memcpy (decorated_program, program, program_length); + memcpy (decorated_program+program_length, p, q-p); + decorated_program [program_length + (q-p)] = '\0'; + + retval = inner_find_program_in_path (decorated_program); + g_free (decorated_program); + + if (retval != NULL) + { + g_free (pathext); + return retval; + } + p = q; + } while (*p++ != '\0'); + g_free (pathext); + return NULL; + } + else + return inner_find_program_in_path (program); +} + +#endif + +/** + * g_find_program_in_path: + * @program: (type filename): a program name in the GLib file name encoding + * + * Locates the first executable named @program in the user's path, in the + * same way that execvp() would locate it. Returns an allocated string + * with the absolute path name, or %NULL if the program is not found in + * the path. If @program is already an absolute path, returns a copy of + * @program if @program exists and is executable, and %NULL otherwise. + * + * On Windows, if @program does not have a file type suffix, tries + * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in + * the `PATHEXT` environment variable. + * + * On Windows, it looks for the file in the same way as CreateProcess() + * would. This means first in the directory where the executing + * program was loaded from, then in the current directory, then in the + * Windows 32-bit system directory, then in the Windows directory, and + * finally in the directories in the `PATH` environment variable. If + * the program is found, the return value contains the full name + * including the type suffix. + * + * Returns: (type filename): a newly-allocated string with the absolute path, + * or %NULL + **/ +#ifdef G_OS_WIN32 +static gchar * +inner_find_program_in_path (const gchar *program) +#else +gchar* +g_find_program_in_path (const gchar *program) +#endif +{ + const gchar *path, *p; + gchar *name, *freeme; +#ifdef G_OS_WIN32 + const gchar *path_copy; + gchar *filename = NULL, *appdir = NULL; + gchar *sysdir = NULL, *windir = NULL; + int n; + wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN], + wwindir[MAXPATHLEN]; +#endif + gsize len; + gsize pathlen; + + g_return_val_if_fail (program != NULL, NULL); + + /* If it is an absolute path, or a relative path including subdirectories, + * don't look in PATH. + */ + if (g_path_is_absolute (program) + || strchr (program, G_DIR_SEPARATOR) != NULL +#ifdef G_OS_WIN32 + || strchr (program, '/') != NULL +#endif + ) + { + if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) && + !g_file_test (program, G_FILE_TEST_IS_DIR)) + return g_strdup (program); + else + return NULL; + } + + path = g_getenv ("PATH"); +#if defined(G_OS_UNIX) + if (path == NULL) + { + /* There is no 'PATH' in the environment. The default + * search path in GNU libc is the current directory followed by + * the path 'confstr' returns for '_CS_PATH'. + */ + + /* In GLib we put . last, for security, and don't use the + * unportable confstr(); UNIX98 does not actually specify + * what to search if PATH is unset. POSIX may, dunno. + */ + + path = "/bin:/usr/bin:."; + } +#else + n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN); + if (n > 0 && n < MAXPATHLEN) + filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL); + + n = GetSystemDirectoryW (wsysdir, MAXPATHLEN); + if (n > 0 && n < MAXPATHLEN) + sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL); + + n = GetWindowsDirectoryW (wwindir, MAXPATHLEN); + if (n > 0 && n < MAXPATHLEN) + windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL); + + if (filename) + { + appdir = g_path_get_dirname (filename); + g_free (filename); + } + + path = g_strdup (path); + + if (windir) + { + const gchar *tem = path; + path = g_strconcat (windir, ";", path, NULL); + g_free ((gchar *) tem); + g_free (windir); + } + + if (sysdir) + { + const gchar *tem = path; + path = g_strconcat (sysdir, ";", path, NULL); + g_free ((gchar *) tem); + g_free (sysdir); + } + + { + const gchar *tem = path; + path = g_strconcat (".;", path, NULL); + g_free ((gchar *) tem); + } + + if (appdir) + { + const gchar *tem = path; + path = g_strconcat (appdir, ";", path, NULL); + g_free ((gchar *) tem); + g_free (appdir); + } + + path_copy = path; +#endif + + len = strlen (program) + 1; + pathlen = strlen (path); + freeme = name = g_malloc (pathlen + len + 1); + + /* Copy the file name at the top, including '\0' */ + memcpy (name + pathlen + 1, program, len); + name = name + pathlen; + /* And add the slash before the filename */ + *name = G_DIR_SEPARATOR; + + p = path; + do + { + char *startp; + + path = p; + p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR); + + if (p == path) + /* Two adjacent colons, or a colon at the beginning or the end + * of 'PATH' means to search the current directory. + */ + startp = name + 1; + else + startp = memcpy (name - (p - path), path, p - path); + + if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) && + !g_file_test (startp, G_FILE_TEST_IS_DIR)) + { + gchar *ret; + ret = g_strdup (startp); + g_free (freeme); +#ifdef G_OS_WIN32 + g_free ((gchar *) path_copy); +#endif + return ret; + } + } + while (*p++ != '\0'); + + g_free (freeme); +#ifdef G_OS_WIN32 + g_free ((gchar *) path_copy); +#endif + + return NULL; +} + +/* The functions below are defined this way for compatibility reasons. + * See the note in gutils.h. + */ + +/** + * g_bit_nth_lsf: + * @mask: a #gulong containing flags + * @nth_bit: the index of the bit to start the search from + * + * Find the position of the first bit set in @mask, searching + * from (but not including) @nth_bit upwards. Bits are numbered + * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63, + * usually). To start searching from the 0th bit, set @nth_bit to -1. + * + * Returns: the index of the first bit set which is higher than @nth_bit, or -1 + * if no higher bits are set + */ +gint +(g_bit_nth_lsf) (gulong mask, + gint nth_bit) +{ + return g_bit_nth_lsf_impl (mask, nth_bit); +} + +/** + * g_bit_nth_msf: + * @mask: a #gulong containing flags + * @nth_bit: the index of the bit to start the search from + * + * Find the position of the first bit set in @mask, searching + * from (but not including) @nth_bit downwards. Bits are numbered + * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63, + * usually). To start searching from the last bit, set @nth_bit to + * -1 or GLIB_SIZEOF_LONG * 8. + * + * Returns: the index of the first bit set which is lower than @nth_bit, or -1 + * if no lower bits are set + */ +gint +(g_bit_nth_msf) (gulong mask, + gint nth_bit) +{ + return g_bit_nth_msf_impl (mask, nth_bit); +} + + +/** + * g_bit_storage: + * @number: a #guint + * + * Gets the number of bits used to hold @number, + * e.g. if @number is 4, 3 bits are needed. + * + * Returns: the number of bits used to hold @number + */ +guint +(g_bit_storage) (gulong number) +{ + return g_bit_storage_impl (number); +} + +G_LOCK_DEFINE_STATIC (g_utils_global); + +typedef struct +{ + gchar *user_name; + gchar *real_name; + gchar *home_dir; +} UserDatabaseEntry; + +/* These must all be read/written with @g_utils_global held. */ +static gchar *g_user_data_dir = NULL; +static gchar **g_system_data_dirs = NULL; +static gchar *g_user_cache_dir = NULL; +static gchar *g_user_config_dir = NULL; +static gchar *g_user_runtime_dir = NULL; +static gchar **g_system_config_dirs = NULL; +static gchar **g_user_special_dirs = NULL; + +/* fifteen minutes of fame for everybody */ +#define G_USER_DIRS_EXPIRE 15 * 60 + +#ifdef G_OS_WIN32 + +static gchar * +get_special_folder (int csidl) +{ + wchar_t path[MAX_PATH+1]; + HRESULT hr; + LPITEMIDLIST pidl = NULL; + BOOL b; + gchar *retval = NULL; + + hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl); + if (hr == S_OK) + { + b = SHGetPathFromIDListW (pidl, path); + if (b) + retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL); + CoTaskMemFree (pidl); + } + return retval; +} + +static char * +get_windows_directory_root (void) +{ + wchar_t wwindowsdir[MAX_PATH]; + + if (GetWindowsDirectoryW (wwindowsdir, G_N_ELEMENTS (wwindowsdir))) + { + /* Usually X:\Windows, but in terminal server environments + * might be an UNC path, AFAIK. + */ + char *windowsdir = g_utf16_to_utf8 (wwindowsdir, -1, NULL, NULL, NULL); + char *p; + + if (windowsdir == NULL) + return g_strdup ("C:\\"); + + p = (char *) g_path_skip_root (windowsdir); + if (G_IS_DIR_SEPARATOR (p[-1]) && p[-2] != ':') + p--; + *p = '\0'; + return windowsdir; + } + else + return g_strdup ("C:\\"); +} + +#endif + +/* HOLDS: g_utils_global_lock */ +static UserDatabaseEntry * +g_get_user_database_entry (void) +{ + static UserDatabaseEntry *entry; + + if (g_once_init_enter (&entry)) + { + static UserDatabaseEntry e; + +#ifdef G_OS_UNIX + { + struct passwd *pw = NULL; + gpointer buffer = NULL; + gint error; + gchar *logname; + +# if defined (HAVE_GETPWUID_R) + struct passwd pwd; +# ifdef _SC_GETPW_R_SIZE_MAX + /* This reurns the maximum length */ + glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX); + + if (bufsize < 0) + bufsize = 64; +# else /* _SC_GETPW_R_SIZE_MAX */ + glong bufsize = 64; +# endif /* _SC_GETPW_R_SIZE_MAX */ + + logname = (gchar *) g_getenv ("LOGNAME"); + + do + { + g_free (buffer); + /* we allocate 6 extra bytes to work around a bug in + * Mac OS < 10.3. See #156446 + */ + buffer = g_malloc (bufsize + 6); + errno = 0; + + if (logname) { + error = getpwnam_r (logname, &pwd, buffer, bufsize, &pw); + if (!pw || (pw->pw_uid != getuid ())) { + /* LOGNAME is lying, fall back to looking up the uid */ + error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw); + } + } else { + error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw); + } + error = error < 0 ? errno : error; + + if (!pw) + { + /* we bail out prematurely if the user id can't be found + * (should be pretty rare case actually), or if the buffer + * should be sufficiently big and lookups are still not + * successful. + */ + if (error == 0 || error == ENOENT) + { + g_warning ("getpwuid_r(): failed due to unknown user id (%lu)", + (gulong) getuid ()); + break; + } + if (bufsize > 32 * 1024) + { + g_warning ("getpwuid_r(): failed due to: %s.", + g_strerror (error)); + break; + } + + bufsize *= 2; + } + } + while (!pw); +# endif /* HAVE_GETPWUID_R */ + + if (!pw) + { + pw = getpwuid (getuid ()); + } + if (pw) + { + e.user_name = g_strdup (pw->pw_name); + +#ifndef __BIONIC__ + if (pw->pw_gecos && *pw->pw_gecos != '\0') + { + gchar **gecos_fields; + gchar **name_parts; + + /* split the gecos field and substitute '&' */ + gecos_fields = g_strsplit (pw->pw_gecos, ",", 0); + name_parts = g_strsplit (gecos_fields[0], "&", 0); + pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]); + e.real_name = g_strjoinv (pw->pw_name, name_parts); + g_strfreev (gecos_fields); + g_strfreev (name_parts); + } +#endif + + if (!e.home_dir) + e.home_dir = g_strdup (pw->pw_dir); + } + g_free (buffer); + } + +#endif /* G_OS_UNIX */ + +#ifdef G_OS_WIN32 + { + guint len = UNLEN+1; + wchar_t buffer[UNLEN+1]; + + if (GetUserNameW (buffer, (LPDWORD) &len)) + { + e.user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL); + e.real_name = g_strdup (e.user_name); + } + } +#endif /* G_OS_WIN32 */ + + if (!e.user_name) + e.user_name = g_strdup ("somebody"); + if (!e.real_name) + e.real_name = g_strdup ("Unknown"); + + g_once_init_leave (&entry, &e); + } + + return entry; +} + +/** + * g_get_user_name: + * + * Gets the user name of the current user. The encoding of the returned + * string is system-defined. On UNIX, it might be the preferred file name + * encoding, or something else, and there is no guarantee that it is even + * consistent on a machine. On Windows, it is always UTF-8. + * + * Returns: (type filename): the user name of the current user. + */ +const gchar * +g_get_user_name (void) +{ + UserDatabaseEntry *entry; + + entry = g_get_user_database_entry (); + + return entry->user_name; +} + +/** + * g_get_real_name: + * + * Gets the real name of the user. This usually comes from the user's + * entry in the `passwd` file. The encoding of the returned string is + * system-defined. (On Windows, it is, however, always UTF-8.) If the + * real user name cannot be determined, the string "Unknown" is + * returned. + * + * Returns: (type filename): the user's real name. + */ +const gchar * +g_get_real_name (void) +{ + UserDatabaseEntry *entry; + + entry = g_get_user_database_entry (); + + return entry->real_name; +} + +/* Protected by @g_utils_global_lock. */ +static gchar *g_home_dir = NULL; /* (owned) (nullable before initialised) */ + +static gchar * +g_build_home_dir (void) +{ + gchar *home_dir; + + /* We first check HOME and use it if it is set */ + home_dir = g_strdup (g_getenv ("HOME")); + +#ifdef G_OS_WIN32 + /* Only believe HOME if it is an absolute path and exists. + * + * We only do this check on Windows for a couple of reasons. + * Historically, we only did it there because we used to ignore $HOME + * on UNIX. There are concerns about enabling it now on UNIX because + * of things like autofs. In short, if the user has a bogus value in + * $HOME then they get what they pay for... + */ + if (home_dir != NULL) + { + if (!(g_path_is_absolute (home_dir) && + g_file_test (home_dir, G_FILE_TEST_IS_DIR))) + g_clear_pointer (&home_dir, g_free); + } + + /* In case HOME is Unix-style (it happens), convert it to + * Windows style. + */ + if (home_dir != NULL) + { + gchar *p; + while ((p = strchr (home_dir, '/')) != NULL) + *p = '\\'; + } + + if (home_dir == NULL) + { + /* USERPROFILE is probably the closest equivalent to $HOME? */ + if (g_getenv ("USERPROFILE") != NULL) + home_dir = g_strdup (g_getenv ("USERPROFILE")); + } + + if (home_dir == NULL) + home_dir = get_special_folder (CSIDL_PROFILE); + + if (home_dir == NULL) + home_dir = get_windows_directory_root (); +#endif /* G_OS_WIN32 */ + + if (home_dir == NULL) + { + /* If we didn't get it from any of those methods, we will have + * to read the user database entry. + */ + UserDatabaseEntry *entry = g_get_user_database_entry (); + home_dir = g_strdup (entry->home_dir); + } + + /* If we have been denied access to /etc/passwd (for example, by an + * overly-zealous LSM), make up a junk value. The return value at this + * point is explicitly documented as ‘undefined’. */ + if (home_dir == NULL) + { + g_warning ("Could not find home directory: $HOME is not set, and " + "user database could not be read."); + home_dir = g_strdup ("/"); + } + + return g_steal_pointer (&home_dir); +} + +/** + * g_get_home_dir: + * + * Gets the current user's home directory. + * + * As with most UNIX tools, this function will return the value of the + * `HOME` environment variable if it is set to an existing absolute path + * name, falling back to the `passwd` file in the case that it is unset. + * + * If the path given in `HOME` is non-absolute, does not exist, or is + * not a directory, the result is undefined. + * + * Before version 2.36 this function would ignore the `HOME` environment + * variable, taking the value from the `passwd` database instead. This was + * changed to increase the compatibility of GLib with other programs (and + * the XDG basedir specification) and to increase testability of programs + * based on GLib (by making it easier to run them from test frameworks). + * + * If your program has a strong requirement for either the new or the + * old behaviour (and if you don't wish to increase your GLib + * dependency to ensure that the new behaviour is in effect) then you + * should either directly check the `HOME` environment variable yourself + * or unset it before calling any functions in GLib. + * + * Returns: (type filename): the current user's home directory + */ +const gchar * +g_get_home_dir (void) +{ + const gchar *home_dir; + + G_LOCK (g_utils_global); + + if (g_home_dir == NULL) + g_home_dir = g_build_home_dir (); + home_dir = g_home_dir; + + G_UNLOCK (g_utils_global); + + return home_dir; +} + +/** + * g_get_tmp_dir: + * + * Gets the directory to use for temporary files. + * + * On UNIX, this is taken from the `TMPDIR` environment variable. + * If the variable is not set, `P_tmpdir` is + * used, as defined by the system C library. Failing that, a + * hard-coded default of "/tmp" is returned. + * + * On Windows, the `TEMP` environment variable is used, with the + * root directory of the Windows installation (eg: "C:\") used + * as a default. + * + * The encoding of the returned string is system-defined. On Windows, + * it is always UTF-8. The return value is never %NULL or the empty + * string. + * + * Returns: (type filename): the directory to use for temporary files. + */ +const gchar * +g_get_tmp_dir (void) +{ + static gchar *tmp_dir; + + if (g_once_init_enter (&tmp_dir)) + { + gchar *tmp; + +#ifdef G_OS_WIN32 + tmp = g_strdup (g_getenv ("TEMP")); + + if (tmp == NULL || *tmp == '\0') + { + g_free (tmp); + tmp = get_windows_directory_root (); + } +#else /* G_OS_WIN32 */ + tmp = g_strdup (g_getenv ("TMPDIR")); + +#ifdef P_tmpdir + if (tmp == NULL || *tmp == '\0') + { + gsize k; + g_free (tmp); + tmp = g_strdup (P_tmpdir); + k = strlen (tmp); + if (k > 1 && G_IS_DIR_SEPARATOR (tmp[k - 1])) + tmp[k - 1] = '\0'; + } +#endif /* P_tmpdir */ + + if (tmp == NULL || *tmp == '\0') + { + g_free (tmp); + tmp = g_strdup ("/tmp"); + } +#endif /* !G_OS_WIN32 */ + + g_once_init_leave (&tmp_dir, tmp); + } + + return tmp_dir; +} + +/** + * g_get_host_name: + * + * Return a name for the machine. + * + * The returned name is not necessarily a fully-qualified domain name, + * or even present in DNS or some other name service at all. It need + * not even be unique on your local network or site, but usually it + * is. Callers should not rely on the return value having any specific + * properties like uniqueness for security purposes. Even if the name + * of the machine is changed while an application is running, the + * return value from this function does not change. The returned + * string is owned by GLib and should not be modified or freed. If no + * name can be determined, a default fixed string "localhost" is + * returned. + * + * The encoding of the returned string is UTF-8. + * + * Returns: the host name of the machine. + * + * Since: 2.8 + */ +const gchar * +g_get_host_name (void) +{ + static gchar *hostname; + + if (g_once_init_enter (&hostname)) + { + gboolean failed; + gchar *utmp; + +#ifndef G_OS_WIN32 + gchar *tmp = g_malloc (sizeof (gchar) * 100); + failed = (gethostname (tmp, sizeof (gchar) * 100) == -1); + if (failed) + g_clear_pointer (&tmp, g_free); + utmp = tmp; +#else + wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD size = sizeof (tmp) / sizeof (tmp[0]); + failed = (!GetComputerNameW (tmp, &size)); + if (!failed) + utmp = g_utf16_to_utf8 (tmp, size, NULL, NULL, NULL); + if (utmp == NULL) + failed = TRUE; +#endif + + g_once_init_leave (&hostname, failed ? g_strdup ("localhost") : utmp); + } + + return hostname; +} + +G_LOCK_DEFINE_STATIC (g_prgname); +static gchar *g_prgname = NULL; + +/** + * g_get_prgname: + * + * Gets the name of the program. This name should not be localized, + * in contrast to g_get_application_name(). + * + * If you are using #GApplication the program name is set in + * g_application_run(). In case of GDK or GTK+ it is set in + * gdk_init(), which is called by gtk_init() and the + * #GtkApplication::startup handler. The program name is found by + * taking the last component of @argv[0]. + * + * Returns: the name of the program. The returned string belongs + * to GLib and must not be modified or freed. + */ +const gchar* +g_get_prgname (void) +{ + gchar* retval; + + G_LOCK (g_prgname); +#ifdef G_OS_WIN32 + if (g_prgname == NULL) + { + static gboolean beenhere = FALSE; + + if (!beenhere) + { + gchar *utf8_buf = NULL; + wchar_t buf[MAX_PATH+1]; + + beenhere = TRUE; + if (GetModuleFileNameW (GetModuleHandle (NULL), + buf, G_N_ELEMENTS (buf)) > 0) + utf8_buf = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL); + + if (utf8_buf) + { + g_prgname = g_path_get_basename (utf8_buf); + g_free (utf8_buf); + } + } + } +#endif + retval = g_prgname; + G_UNLOCK (g_prgname); + + return retval; +} + +/** + * g_set_prgname: + * @prgname: the name of the program. + * + * Sets the name of the program. This name should not be localized, + * in contrast to g_set_application_name(). + * + * If you are using #GApplication the program name is set in + * g_application_run(). In case of GDK or GTK+ it is set in + * gdk_init(), which is called by gtk_init() and the + * #GtkApplication::startup handler. The program name is found by + * taking the last component of @argv[0]. + * + * Note that for thread-safety reasons this function can only be called once. + */ +void +g_set_prgname (const gchar *prgname) +{ + G_LOCK (g_prgname); + g_free (g_prgname); + g_prgname = g_strdup (prgname); + G_UNLOCK (g_prgname); +} + +G_LOCK_DEFINE_STATIC (g_application_name); +static gchar *g_application_name = NULL; + +/** + * g_get_application_name: + * + * Gets a human-readable name for the application, as set by + * g_set_application_name(). This name should be localized if + * possible, and is intended for display to the user. Contrast with + * g_get_prgname(), which gets a non-localized name. If + * g_set_application_name() has not been called, returns the result of + * g_get_prgname() (which may be %NULL if g_set_prgname() has also not + * been called). + * + * Returns: human-readable application name. may return %NULL + * + * Since: 2.2 + **/ +const gchar * +g_get_application_name (void) +{ + gchar* retval; + + G_LOCK (g_application_name); + retval = g_application_name; + G_UNLOCK (g_application_name); + + if (retval == NULL) + return g_get_prgname (); + + return retval; +} + +/** + * g_set_application_name: + * @application_name: localized name of the application + * + * Sets a human-readable name for the application. This name should be + * localized if possible, and is intended for display to the user. + * Contrast with g_set_prgname(), which sets a non-localized name. + * g_set_prgname() will be called automatically by gtk_init(), + * but g_set_application_name() will not. + * + * Note that for thread safety reasons, this function can only + * be called once. + * + * The application name will be used in contexts such as error messages, + * or when displaying an application's name in the task list. + * + * Since: 2.2 + **/ +void +g_set_application_name (const gchar *application_name) +{ + gboolean already_set = FALSE; + + G_LOCK (g_application_name); + if (g_application_name) + already_set = TRUE; + else + g_application_name = g_strdup (application_name); + G_UNLOCK (g_application_name); + + if (already_set) + g_warning ("g_set_application_name() called multiple times"); +} + +/* Set @global_str to a copy of @new_value if it’s currently unset or has a + * different value. If its current value matches @new_value, do nothing. If + * replaced, we have to leak the old value as client code could still have + * pointers to it. */ +static void +set_str_if_different (gchar **global_str, + const gchar *type, + const gchar *new_value) +{ + if (*global_str == NULL || + !g_str_equal (new_value, *global_str)) + { + g_debug ("g_set_user_dirs: Setting %s to %s", type, new_value); + + /* We have to leak the old value, as user code could be retaining pointers + * to it. */ + *global_str = g_strdup (new_value); + } +} + +static void +set_strv_if_different (gchar ***global_strv, + const gchar *type, + const gchar * const *new_value) +{ + if (*global_strv == NULL || + !g_strv_equal (new_value, (const gchar * const *) *global_strv)) + { + gchar *new_value_str = g_strjoinv (":", (gchar **) new_value); + g_debug ("g_set_user_dirs: Setting %s to %s", type, new_value_str); + g_free (new_value_str); + + /* We have to leak the old value, as user code could be retaining pointers + * to it. */ + *global_strv = g_strdupv ((gchar **) new_value); + } +} + +/* + * g_set_user_dirs: + * @first_dir_type: Type of the first directory to set + * @...: Value to set the first directory to, followed by additional type/value + * pairs, followed by %NULL + * + * Set one or more ‘user’ directories to custom values. This is intended to be + * used by test code (particularly with the %G_TEST_OPTION_ISOLATE_DIRS option) + * to override the values returned by the following functions, so that test + * code can be run without touching an installed system and user data: + * + * - g_get_home_dir() — use type `HOME`, pass a string + * - g_get_user_cache_dir() — use type `XDG_CACHE_HOME`, pass a string + * - g_get_system_config_dirs() — use type `XDG_CONFIG_DIRS`, pass a + * %NULL-terminated string array + * - g_get_user_config_dir() — use type `XDG_CONFIG_HOME`, pass a string + * - g_get_system_data_dirs() — use type `XDG_DATA_DIRS`, pass a + * %NULL-terminated string array + * - g_get_user_data_dir() — use type `XDG_DATA_HOME`, pass a string + * - g_get_user_runtime_dir() — use type `XDG_RUNTIME_DIR`, pass a string + * + * The list must be terminated with a %NULL type. All of the values must be + * non-%NULL — passing %NULL as a value won’t reset a directory. If a reference + * to a directory from the calling environment needs to be kept, copy it before + * the first call to g_set_user_dirs(). g_set_user_dirs() can be called multiple + * times. + * + * Since: 2.60 + */ +/*< private > */ +void +g_set_user_dirs (const gchar *first_dir_type, + ...) +{ + va_list args; + const gchar *dir_type; + + G_LOCK (g_utils_global); + + va_start (args, first_dir_type); + + for (dir_type = first_dir_type; dir_type != NULL; dir_type = va_arg (args, const gchar *)) + { + gconstpointer dir_value = va_arg (args, gconstpointer); + g_assert (dir_value != NULL); + + if (g_str_equal (dir_type, "HOME")) + set_str_if_different (&g_home_dir, dir_type, dir_value); + else if (g_str_equal (dir_type, "XDG_CACHE_HOME")) + set_str_if_different (&g_user_cache_dir, dir_type, dir_value); + else if (g_str_equal (dir_type, "XDG_CONFIG_DIRS")) + set_strv_if_different (&g_system_config_dirs, dir_type, dir_value); + else if (g_str_equal (dir_type, "XDG_CONFIG_HOME")) + set_str_if_different (&g_user_config_dir, dir_type, dir_value); + else if (g_str_equal (dir_type, "XDG_DATA_DIRS")) + set_strv_if_different (&g_system_data_dirs, dir_type, dir_value); + else if (g_str_equal (dir_type, "XDG_DATA_HOME")) + set_str_if_different (&g_user_data_dir, dir_type, dir_value); + else if (g_str_equal (dir_type, "XDG_RUNTIME_DIR")) + set_str_if_different (&g_user_runtime_dir, dir_type, dir_value); + else + g_assert_not_reached (); + } + + va_end (args); + + G_UNLOCK (g_utils_global); +} + +static gchar * +g_build_user_data_dir (void) +{ + gchar *data_dir = NULL; + const gchar *data_dir_env = g_getenv ("XDG_DATA_HOME"); + + if (data_dir_env && data_dir_env[0]) + data_dir = g_strdup (data_dir_env); +#ifdef G_OS_WIN32 + else + data_dir = get_special_folder (CSIDL_LOCAL_APPDATA); +#endif + if (!data_dir || !data_dir[0]) + { + gchar *home_dir = g_build_home_dir (); + data_dir = g_build_filename (home_dir, ".local", "share", NULL); + g_free (home_dir); + } + + return g_steal_pointer (&data_dir); +} + +/** + * g_get_user_data_dir: + * + * Returns a base directory in which to access application data such + * as icons that is customized for a particular user. + * + * On UNIX platforms this is determined using the mechanisms described + * in the + * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec). + * In this case the directory retrieved will be `XDG_DATA_HOME`. + * + * On Windows it follows XDG Base Directory Specification if `XDG_DATA_HOME` + * is defined. If `XDG_DATA_HOME` is undefined, the folder to use for local (as + * opposed to roaming) application data is used instead. See the + * [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata). + * Note that in this case on Windows it will be the same + * as what g_get_user_config_dir() returns. + * + * Returns: (type filename): a string owned by GLib that must not be modified + * or freed. + * Since: 2.6 + **/ +const gchar * +g_get_user_data_dir (void) +{ + const gchar *user_data_dir; + + G_LOCK (g_utils_global); + + if (g_user_data_dir == NULL) + g_user_data_dir = g_build_user_data_dir (); + user_data_dir = g_user_data_dir; + + G_UNLOCK (g_utils_global); + + return user_data_dir; +} + +static gchar * +g_build_user_config_dir (void) +{ + gchar *config_dir = NULL; + const gchar *config_dir_env = g_getenv ("XDG_CONFIG_HOME"); + + if (config_dir_env && config_dir_env[0]) + config_dir = g_strdup (config_dir_env); +#ifdef G_OS_WIN32 + else + config_dir = get_special_folder (CSIDL_LOCAL_APPDATA); +#endif + if (!config_dir || !config_dir[0]) + { + gchar *home_dir = g_build_home_dir (); + config_dir = g_build_filename (home_dir, ".config", NULL); + g_free (home_dir); + } + + return g_steal_pointer (&config_dir); +} + +/** + * g_get_user_config_dir: + * + * Returns a base directory in which to store user-specific application + * configuration information such as user preferences and settings. + * + * On UNIX platforms this is determined using the mechanisms described + * in the + * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec). + * In this case the directory retrieved will be `XDG_CONFIG_HOME`. + * + * On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_HOME` is defined. + * If `XDG_CONFIG_HOME` is undefined, the folder to use for local (as opposed + * to roaming) application data is used instead. See the + * [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata). + * Note that in this case on Windows it will be the same + * as what g_get_user_data_dir() returns. + * + * Returns: (type filename): a string owned by GLib that must not be modified + * or freed. + * Since: 2.6 + **/ +const gchar * +g_get_user_config_dir (void) +{ + const gchar *user_config_dir; + + G_LOCK (g_utils_global); + + if (g_user_config_dir == NULL) + g_user_config_dir = g_build_user_config_dir (); + user_config_dir = g_user_config_dir; + + G_UNLOCK (g_utils_global); + + return user_config_dir; +} + +static gchar * +g_build_user_cache_dir (void) +{ + gchar *cache_dir = NULL; + const gchar *cache_dir_env = g_getenv ("XDG_CACHE_HOME"); + + if (cache_dir_env && cache_dir_env[0]) + cache_dir = g_strdup (cache_dir_env); +#ifdef G_OS_WIN32 + else + cache_dir = get_special_folder (CSIDL_INTERNET_CACHE); +#endif + if (!cache_dir || !cache_dir[0]) + { + gchar *home_dir = g_build_home_dir (); + cache_dir = g_build_filename (home_dir, ".cache", NULL); + g_free (home_dir); + } + + return g_steal_pointer (&cache_dir); +} + +/** + * g_get_user_cache_dir: + * + * Returns a base directory in which to store non-essential, cached + * data specific to particular user. + * + * On UNIX platforms this is determined using the mechanisms described + * in the + * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec). + * In this case the directory retrieved will be `XDG_CACHE_HOME`. + * + * On Windows it follows XDG Base Directory Specification if `XDG_CACHE_HOME` is defined. + * If `XDG_CACHE_HOME` is undefined, the directory that serves as a common + * repository for temporary Internet files is used instead. A typical path is + * `C:\Documents and Settings\username\Local Settings\Temporary Internet Files`. + * See the [documentation for `CSIDL_INTERNET_CACHE`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_internet_cache). + * + * Returns: (type filename): a string owned by GLib that must not be modified + * or freed. + * Since: 2.6 + **/ +const gchar * +g_get_user_cache_dir (void) +{ + const gchar *user_cache_dir; + + G_LOCK (g_utils_global); + + if (g_user_cache_dir == NULL) + g_user_cache_dir = g_build_user_cache_dir (); + user_cache_dir = g_user_cache_dir; + + G_UNLOCK (g_utils_global); + + return user_cache_dir; +} + +static gchar * +g_build_user_runtime_dir (void) +{ + gchar *runtime_dir = NULL; + const gchar *runtime_dir_env = g_getenv ("XDG_RUNTIME_DIR"); + + if (runtime_dir_env && runtime_dir_env[0]) + runtime_dir = g_strdup (runtime_dir_env); + else + { + runtime_dir = g_build_user_cache_dir (); + + /* The user should be able to rely on the directory existing + * when the function returns. Probably it already does, but + * let's make sure. Just do mkdir() directly since it will be + * no more expensive than a stat() in the case that the + * directory already exists and is a lot easier. + * + * $XDG_CACHE_HOME is probably ~/.cache/ so as long as $HOME + * exists this will work. If the user changed $XDG_CACHE_HOME + * then they can make sure that it exists... + */ + (void) g_mkdir (runtime_dir, 0700); + } + + return g_steal_pointer (&runtime_dir); +} + +/** + * g_get_user_runtime_dir: + * + * Returns a directory that is unique to the current user on the local + * system. + * + * This is determined using the mechanisms described + * in the + * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec). + * This is the directory + * specified in the `XDG_RUNTIME_DIR` environment variable. + * In the case that this variable is not set, we return the value of + * g_get_user_cache_dir(), after verifying that it exists. + * + * Returns: (type filename): a string owned by GLib that must not be + * modified or freed. + * + * Since: 2.28 + **/ +const gchar * +g_get_user_runtime_dir (void) +{ + const gchar *user_runtime_dir; + + G_LOCK (g_utils_global); + + if (g_user_runtime_dir == NULL) + g_user_runtime_dir = g_build_user_runtime_dir (); + user_runtime_dir = g_user_runtime_dir; + + G_UNLOCK (g_utils_global); + + return user_runtime_dir; +} + +#ifdef HAVE_COCOA + +/* Implemented in gutils-macos.m */ +void load_user_special_dirs_macos (gchar **table); + +static void +load_user_special_dirs (void) +{ + load_user_special_dirs_macos (g_user_special_dirs); +} + +#elif defined(G_OS_WIN32) + +static void +load_user_special_dirs (void) +{ + typedef HRESULT (WINAPI *t_SHGetKnownFolderPath) (const GUID *rfid, + DWORD dwFlags, + HANDLE hToken, + PWSTR *ppszPath); + t_SHGetKnownFolderPath p_SHGetKnownFolderPath; + + static const GUID FOLDERID_Downloads = + { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; + static const GUID FOLDERID_Public = + { 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } }; + + wchar_t *wcp; + + p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandle ("shell32.dll"), + "SHGetKnownFolderPath"); + + g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY); + g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (CSIDL_PERSONAL); + + if (p_SHGetKnownFolderPath == NULL) + { + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); + } + else + { + wcp = NULL; + (*p_SHGetKnownFolderPath) (&FOLDERID_Downloads, 0, NULL, &wcp); + if (wcp) + { + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL); + if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL) + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); + CoTaskMemFree (wcp); + } + else + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); + } + + g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (CSIDL_MYMUSIC); + g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (CSIDL_MYPICTURES); + + if (p_SHGetKnownFolderPath == NULL) + { + /* XXX */ + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); + } + else + { + wcp = NULL; + (*p_SHGetKnownFolderPath) (&FOLDERID_Public, 0, NULL, &wcp); + if (wcp) + { + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL); + if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL) + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); + CoTaskMemFree (wcp); + } + else + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); + } + + g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (CSIDL_TEMPLATES); + g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (CSIDL_MYVIDEO); +} + +#else /* default is unix */ + +/* adapted from xdg-user-dir-lookup.c + * + * Copyright (C) 2007 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +static void +load_user_special_dirs (void) +{ + gchar *config_dir = NULL; + gchar *config_file; + gchar *data; + gchar **lines; + gint n_lines, i; + + config_dir = g_build_user_config_dir (); + config_file = g_build_filename (config_dir, + "user-dirs.dirs", + NULL); + g_free (config_dir); + + if (!g_file_get_contents (config_file, &data, NULL, NULL)) + { + g_free (config_file); + return; + } + + lines = g_strsplit (data, "\n", -1); + n_lines = g_strv_length (lines); + g_free (data); + + for (i = 0; i < n_lines; i++) + { + gchar *buffer = lines[i]; + gchar *d, *p; + gint len; + gboolean is_relative = FALSE; + GUserDirectory directory; + + /* Remove newline at end */ + len = strlen (buffer); + if (len > 0 && buffer[len - 1] == '\n') + buffer[len - 1] = 0; + + p = buffer; + while (*p == ' ' || *p == '\t') + p++; + + if (strncmp (p, "XDG_DESKTOP_DIR", strlen ("XDG_DESKTOP_DIR")) == 0) + { + directory = G_USER_DIRECTORY_DESKTOP; + p += strlen ("XDG_DESKTOP_DIR"); + } + else if (strncmp (p, "XDG_DOCUMENTS_DIR", strlen ("XDG_DOCUMENTS_DIR")) == 0) + { + directory = G_USER_DIRECTORY_DOCUMENTS; + p += strlen ("XDG_DOCUMENTS_DIR"); + } + else if (strncmp (p, "XDG_DOWNLOAD_DIR", strlen ("XDG_DOWNLOAD_DIR")) == 0) + { + directory = G_USER_DIRECTORY_DOWNLOAD; + p += strlen ("XDG_DOWNLOAD_DIR"); + } + else if (strncmp (p, "XDG_MUSIC_DIR", strlen ("XDG_MUSIC_DIR")) == 0) + { + directory = G_USER_DIRECTORY_MUSIC; + p += strlen ("XDG_MUSIC_DIR"); + } + else if (strncmp (p, "XDG_PICTURES_DIR", strlen ("XDG_PICTURES_DIR")) == 0) + { + directory = G_USER_DIRECTORY_PICTURES; + p += strlen ("XDG_PICTURES_DIR"); + } + else if (strncmp (p, "XDG_PUBLICSHARE_DIR", strlen ("XDG_PUBLICSHARE_DIR")) == 0) + { + directory = G_USER_DIRECTORY_PUBLIC_SHARE; + p += strlen ("XDG_PUBLICSHARE_DIR"); + } + else if (strncmp (p, "XDG_TEMPLATES_DIR", strlen ("XDG_TEMPLATES_DIR")) == 0) + { + directory = G_USER_DIRECTORY_TEMPLATES; + p += strlen ("XDG_TEMPLATES_DIR"); + } + else if (strncmp (p, "XDG_VIDEOS_DIR", strlen ("XDG_VIDEOS_DIR")) == 0) + { + directory = G_USER_DIRECTORY_VIDEOS; + p += strlen ("XDG_VIDEOS_DIR"); + } + else + continue; + + while (*p == ' ' || *p == '\t') + p++; + + if (*p != '=') + continue; + p++; + + while (*p == ' ' || *p == '\t') + p++; + + if (*p != '"') + continue; + p++; + + if (strncmp (p, "$HOME", 5) == 0) + { + p += 5; + is_relative = TRUE; + } + else if (*p != '/') + continue; + + d = strrchr (p, '"'); + if (!d) + continue; + *d = 0; + + d = p; + + /* remove trailing slashes */ + len = strlen (d); + if (d[len - 1] == '/') + d[len - 1] = 0; + + if (is_relative) + { + gchar *home_dir = g_build_home_dir (); + g_user_special_dirs[directory] = g_build_filename (home_dir, d, NULL); + g_free (home_dir); + } + else + g_user_special_dirs[directory] = g_strdup (d); + } + + g_strfreev (lines); + g_free (config_file); +} + +#endif /* platform-specific load_user_special_dirs implementations */ + + +/** + * g_reload_user_special_dirs_cache: + * + * Resets the cache used for g_get_user_special_dir(), so + * that the latest on-disk version is used. Call this only + * if you just changed the data on disk yourself. + * + * Due to thread safety issues this may cause leaking of strings + * that were previously returned from g_get_user_special_dir() + * that can't be freed. We ensure to only leak the data for + * the directories that actually changed value though. + * + * Since: 2.22 + */ +void +g_reload_user_special_dirs_cache (void) +{ + int i; + + G_LOCK (g_utils_global); + + if (g_user_special_dirs != NULL) + { + /* save a copy of the pointer, to check if some memory can be preserved */ + char **old_g_user_special_dirs = g_user_special_dirs; + char *old_val; + + /* recreate and reload our cache */ + g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES); + load_user_special_dirs (); + + /* only leak changed directories */ + for (i = 0; i < G_USER_N_DIRECTORIES; i++) + { + old_val = old_g_user_special_dirs[i]; + if (g_user_special_dirs[i] == NULL) + { + g_user_special_dirs[i] = old_val; + } + else if (g_strcmp0 (old_val, g_user_special_dirs[i]) == 0) + { + /* don't leak */ + g_free (g_user_special_dirs[i]); + g_user_special_dirs[i] = old_val; + } + else + g_free (old_val); + } + + /* free the old array */ + g_free (old_g_user_special_dirs); + } + + G_UNLOCK (g_utils_global); +} + +/** + * g_get_user_special_dir: + * @directory: the logical id of special directory + * + * Returns the full path of a special directory using its logical id. + * + * On UNIX this is done using the XDG special user directories. + * For compatibility with existing practise, %G_USER_DIRECTORY_DESKTOP + * falls back to `$HOME/Desktop` when XDG special user directories have + * not been set up. + * + * Depending on the platform, the user might be able to change the path + * of the special directory without requiring the session to restart; GLib + * will not reflect any change once the special directories are loaded. + * + * Returns: (type filename): the path to the specified special directory, or + * %NULL if the logical id was not found. The returned string is owned by + * GLib and should not be modified or freed. + * + * Since: 2.14 + */ +const gchar * +g_get_user_special_dir (GUserDirectory directory) +{ + const gchar *user_special_dir; + + g_return_val_if_fail (directory >= G_USER_DIRECTORY_DESKTOP && + directory < G_USER_N_DIRECTORIES, NULL); + + G_LOCK (g_utils_global); + + if (G_UNLIKELY (g_user_special_dirs == NULL)) + { + g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES); + + load_user_special_dirs (); + + /* Special-case desktop for historical compatibility */ + if (g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] == NULL) + { + gchar *home_dir = g_build_home_dir (); + g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = g_build_filename (home_dir, "Desktop", NULL); + g_free (home_dir); + } + } + user_special_dir = g_user_special_dirs[directory]; + + G_UNLOCK (g_utils_global); + + return user_special_dir; +} + +#ifdef G_OS_WIN32 + +#undef g_get_system_data_dirs + +static HMODULE +get_module_for_address (gconstpointer address) +{ + /* Holds the g_utils_global lock */ + + static gboolean beenhere = FALSE; + typedef BOOL (WINAPI *t_GetModuleHandleExA) (DWORD, LPCTSTR, HMODULE *); + static t_GetModuleHandleExA p_GetModuleHandleExA = NULL; + HMODULE hmodule = NULL; + + if (!address) + return NULL; + + if (!beenhere) + { + p_GetModuleHandleExA = + (t_GetModuleHandleExA) GetProcAddress (GetModuleHandle ("kernel32.dll"), + "GetModuleHandleExA"); + beenhere = TRUE; + } + + if (p_GetModuleHandleExA == NULL || + !(*p_GetModuleHandleExA) (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + address, &hmodule)) + { + MEMORY_BASIC_INFORMATION mbi; + VirtualQuery (address, &mbi, sizeof (mbi)); + hmodule = (HMODULE) mbi.AllocationBase; + } + + return hmodule; +} + +static gchar * +get_module_share_dir (gconstpointer address) +{ + HMODULE hmodule; + gchar *filename; + gchar *retval; + + hmodule = get_module_for_address (address); + if (hmodule == NULL) + return NULL; + + filename = g_win32_get_package_installation_directory_of_module (hmodule); + retval = g_build_filename (filename, "share", NULL); + g_free (filename); + + return retval; +} + +static const gchar * const * +g_win32_get_system_data_dirs_for_module_real (void (*address_of_function)(void)) +{ + GArray *data_dirs; + HMODULE hmodule; + static GHashTable *per_module_data_dirs = NULL; + gchar **retval; + gchar *p; + gchar *exe_root; + + hmodule = NULL; + if (address_of_function) + { + G_LOCK (g_utils_global); + hmodule = get_module_for_address (address_of_function); + if (hmodule != NULL) + { + if (per_module_data_dirs == NULL) + per_module_data_dirs = g_hash_table_new (NULL, NULL); + else + { + retval = g_hash_table_lookup (per_module_data_dirs, hmodule); + + if (retval != NULL) + { + G_UNLOCK (g_utils_global); + return (const gchar * const *) retval; + } + } + } + } + + data_dirs = g_array_new (TRUE, TRUE, sizeof (char *)); + + /* Documents and Settings\All Users\Application Data */ + p = get_special_folder (CSIDL_COMMON_APPDATA); + if (p) + g_array_append_val (data_dirs, p); + + /* Documents and Settings\All Users\Documents */ + p = get_special_folder (CSIDL_COMMON_DOCUMENTS); + if (p) + g_array_append_val (data_dirs, p); + + /* Using the above subfolders of Documents and Settings perhaps + * makes sense from a Windows perspective. + * + * But looking at the actual use cases of this function in GTK+ + * and GNOME software, what we really want is the "share" + * subdirectory of the installation directory for the package + * our caller is a part of. + * + * The address_of_function parameter, if non-NULL, points to a + * function in the calling module. Use that to determine that + * module's installation folder, and use its "share" subfolder. + * + * Additionally, also use the "share" subfolder of the installation + * locations of GLib and the .exe file being run. + * + * To guard against none of the above being what is really wanted, + * callers of this function should have Win32-specific code to look + * up their installation folder themselves, and handle a subfolder + * "share" of it in the same way as the folders returned from this + * function. + */ + + p = get_module_share_dir (address_of_function); + if (p) + g_array_append_val (data_dirs, p); + + if (glib_dll != NULL) + { + gchar *glib_root = g_win32_get_package_installation_directory_of_module (glib_dll); + p = g_build_filename (glib_root, "share", NULL); + if (p) + g_array_append_val (data_dirs, p); + g_free (glib_root); + } + + exe_root = g_win32_get_package_installation_directory_of_module (NULL); + p = g_build_filename (exe_root, "share", NULL); + if (p) + g_array_append_val (data_dirs, p); + g_free (exe_root); + + retval = (gchar **) g_array_free (data_dirs, FALSE); + + if (address_of_function) + { + if (hmodule != NULL) + g_hash_table_insert (per_module_data_dirs, hmodule, retval); + G_UNLOCK (g_utils_global); + } + + return (const gchar * const *) retval; +} + +const gchar * const * +g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void)) +{ + gboolean should_call_g_get_system_data_dirs; + + should_call_g_get_system_data_dirs = TRUE; + /* These checks are the same as the ones that g_build_system_data_dirs() does. + * Please keep them in sync. + */ + G_LOCK (g_utils_global); + + if (!g_system_data_dirs) + { + const gchar *data_dirs = g_getenv ("XDG_DATA_DIRS"); + + if (!data_dirs || !data_dirs[0]) + should_call_g_get_system_data_dirs = FALSE; + } + + G_UNLOCK (g_utils_global); + + /* There is a subtle difference between g_win32_get_system_data_dirs_for_module (NULL), + * which is what GLib code can normally call, + * and g_win32_get_system_data_dirs_for_module (&_g_win32_get_system_data_dirs), + * which is what the inline function used by non-GLib code calls. + * The former gets prefix relative to currently-running executable, + * the latter - relative to the module that calls _g_win32_get_system_data_dirs() + * (disguised as g_get_system_data_dirs()), which could be an executable or + * a DLL that is located somewhere else. + * This is why that inline function in gutils.h exists, and why we can't just + * call g_get_system_data_dirs() from there - because we need to get the address + * local to the non-GLib caller-module. + */ + + /* + * g_get_system_data_dirs() will fall back to calling + * g_win32_get_system_data_dirs_for_module_real(NULL) if XDG_DATA_DIRS is NULL + * or an empty string. The checks above ensure that we do not call it in such + * cases and use the address_of_function that we've been given by the inline function. + * The reason we're calling g_get_system_data_dirs /at all/ is to give + * XDG_DATA_DIRS precedence (if it is set). + */ + if (should_call_g_get_system_data_dirs) + return g_get_system_data_dirs (); + + return g_win32_get_system_data_dirs_for_module_real (address_of_function); +} + +#endif + +static gchar ** +g_build_system_data_dirs (void) +{ + gchar **data_dir_vector = NULL; + gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS"); + + /* These checks are the same as the ones that g_win32_get_system_data_dirs_for_module() + * does. Please keep them in sync. + */ +#ifndef G_OS_WIN32 + if (!data_dirs || !data_dirs[0]) + data_dirs = "/usr/local/share/:/usr/share/"; + + data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0); +#else + if (!data_dirs || !data_dirs[0]) + data_dir_vector = g_strdupv ((gchar **) g_win32_get_system_data_dirs_for_module_real (NULL)); + else + data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0); +#endif + + return g_steal_pointer (&data_dir_vector); +} + +/** + * g_get_system_data_dirs: + * + * Returns an ordered list of base directories in which to access + * system-wide application data. + * + * On UNIX platforms this is determined using the mechanisms described + * in the + * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec) + * In this case the list of directories retrieved will be `XDG_DATA_DIRS`. + * + * On Windows it follows XDG Base Directory Specification if `XDG_DATA_DIRS` is defined. + * If `XDG_DATA_DIRS` is undefined, + * the first elements in the list are the Application Data + * and Documents folders for All Users. (These can be determined only + * on Windows 2000 or later and are not present in the list on other + * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and + * CSIDL_COMMON_DOCUMENTS. + * + * Then follows the "share" subfolder in the installation folder for + * the package containing the DLL that calls this function, if it can + * be determined. + * + * Finally the list contains the "share" subfolder in the installation + * folder for GLib, and in the installation folder for the package the + * application's .exe file belongs to. + * + * The installation folders above are determined by looking up the + * folder where the module (DLL or EXE) in question is located. If the + * folder's name is "bin", its parent is used, otherwise the folder + * itself. + * + * Note that on Windows the returned list can vary depending on where + * this function is called. + * + * Returns: (array zero-terminated=1) (element-type filename) (transfer none): + * a %NULL-terminated array of strings owned by GLib that must not be + * modified or freed. + * + * Since: 2.6 + **/ +const gchar * const * +g_get_system_data_dirs (void) +{ + const gchar * const *system_data_dirs; + + G_LOCK (g_utils_global); + + if (g_system_data_dirs == NULL) + g_system_data_dirs = g_build_system_data_dirs (); + system_data_dirs = (const gchar * const *) g_system_data_dirs; + + G_UNLOCK (g_utils_global); + + return system_data_dirs; +} + +static gchar ** +g_build_system_config_dirs (void) +{ + gchar **conf_dir_vector = NULL; + const gchar *conf_dirs = g_getenv ("XDG_CONFIG_DIRS"); +#ifdef G_OS_WIN32 + if (conf_dirs) + { + conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0); + } + else + { + gchar *special_conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA); + + if (special_conf_dirs) + conf_dir_vector = g_strsplit (special_conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0); + else + /* Return empty list */ + conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0); + + g_free (special_conf_dirs); + } +#else + if (!conf_dirs || !conf_dirs[0]) + conf_dirs = "/etc/xdg"; + + conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0); +#endif + + return g_steal_pointer (&conf_dir_vector); +} + +/** + * g_get_system_config_dirs: + * + * Returns an ordered list of base directories in which to access + * system-wide configuration information. + * + * On UNIX platforms this is determined using the mechanisms described + * in the + * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec). + * In this case the list of directories retrieved will be `XDG_CONFIG_DIRS`. + * + * On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_DIRS` is defined. + * If `XDG_CONFIG_DIRS` is undefined, the directory that contains application + * data for all users is used instead. A typical path is + * `C:\Documents and Settings\All Users\Application Data`. + * This folder is used for application data + * that is not user specific. For example, an application can store + * a spell-check dictionary, a database of clip art, or a log file in the + * CSIDL_COMMON_APPDATA folder. This information will not roam and is available + * to anyone using the computer. + * + * Returns: (array zero-terminated=1) (element-type filename) (transfer none): + * a %NULL-terminated array of strings owned by GLib that must not be + * modified or freed. + * + * Since: 2.6 + **/ +const gchar * const * +g_get_system_config_dirs (void) +{ + const gchar * const *system_config_dirs; + + G_LOCK (g_utils_global); + + if (g_system_config_dirs == NULL) + g_system_config_dirs = g_build_system_config_dirs (); + system_config_dirs = (const gchar * const *) g_system_config_dirs; + + G_UNLOCK (g_utils_global); + + return system_config_dirs; +} + +/** + * g_nullify_pointer: + * @nullify_location: (not nullable): the memory address of the pointer. + * + * Set the pointer at the specified location to %NULL. + **/ +void +g_nullify_pointer (gpointer *nullify_location) +{ + g_return_if_fail (nullify_location != NULL); + + *nullify_location = NULL; +} + +#define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000)) +#define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR) +#define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR) +#define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR) +#define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR) +#define EXABYTE_FACTOR (PETABYTE_FACTOR * KILOBYTE_FACTOR) + +#define KIBIBYTE_FACTOR (G_GOFFSET_CONSTANT (1024)) +#define MEBIBYTE_FACTOR (KIBIBYTE_FACTOR * KIBIBYTE_FACTOR) +#define GIBIBYTE_FACTOR (MEBIBYTE_FACTOR * KIBIBYTE_FACTOR) +#define TEBIBYTE_FACTOR (GIBIBYTE_FACTOR * KIBIBYTE_FACTOR) +#define PEBIBYTE_FACTOR (TEBIBYTE_FACTOR * KIBIBYTE_FACTOR) +#define EXBIBYTE_FACTOR (PEBIBYTE_FACTOR * KIBIBYTE_FACTOR) + +/** + * g_format_size: + * @size: a size in bytes + * + * Formats a size (for example the size of a file) into a human readable + * string. Sizes are rounded to the nearest size prefix (kB, MB, GB) + * and are displayed rounded to the nearest tenth. E.g. the file size + * 3292528 bytes will be converted into the string "3.2 MB". The returned string + * is UTF-8, and may use a non-breaking space to separate the number and units, + * to ensure they aren’t separated when line wrapped. + * + * The prefix units base is 1000 (i.e. 1 kB is 1000 bytes). + * + * This string should be freed with g_free() when not needed any longer. + * + * See g_format_size_full() for more options about how the size might be + * formatted. + * + * Returns: a newly-allocated formatted string containing a human readable + * file size + * + * Since: 2.30 + */ +gchar * +g_format_size (guint64 size) +{ + return g_format_size_full (size, G_FORMAT_SIZE_DEFAULT); +} + +/** + * GFormatSizeFlags: + * @G_FORMAT_SIZE_DEFAULT: behave the same as g_format_size() + * @G_FORMAT_SIZE_LONG_FORMAT: include the exact number of bytes as part + * of the returned string. For example, "45.6 kB (45,612 bytes)". + * @G_FORMAT_SIZE_IEC_UNITS: use IEC (base 1024) units with "KiB"-style + * suffixes. IEC units should only be used for reporting things with + * a strong "power of 2" basis, like RAM sizes or RAID stripe sizes. + * Network and storage sizes should be reported in the normal SI units. + * @G_FORMAT_SIZE_BITS: set the size as a quantity in bits, rather than + * bytes, and return units in bits. For example, ‘Mb’ rather than ‘MB’. + * + * Flags to modify the format of the string returned by g_format_size_full(). + */ + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +/** + * g_format_size_full: + * @size: a size in bytes + * @flags: #GFormatSizeFlags to modify the output + * + * Formats a size. + * + * This function is similar to g_format_size() but allows for flags + * that modify the output. See #GFormatSizeFlags. + * + * Returns: a newly-allocated formatted string containing a human + * readable file size + * + * Since: 2.30 + */ +gchar * +g_format_size_full (guint64 size, + GFormatSizeFlags flags) +{ + struct Format + { + guint64 factor; + char string[9]; + }; + + typedef enum + { + FORMAT_BYTES, + FORMAT_BYTES_IEC, + FORMAT_BITS, + FORMAT_BITS_IEC + } FormatIndex; + + const struct Format formats[4][6] = { + { + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { KILOBYTE_FACTOR, N_("%.1f kB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { MEGABYTE_FACTOR, N_("%.1f MB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { GIGABYTE_FACTOR, N_("%.1f GB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { TERABYTE_FACTOR, N_("%.1f TB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { PETABYTE_FACTOR, N_("%.1f PB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { EXABYTE_FACTOR, N_("%.1f EB") } + }, + { + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { KIBIBYTE_FACTOR, N_("%.1f KiB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { MEBIBYTE_FACTOR, N_("%.1f MiB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { GIBIBYTE_FACTOR, N_("%.1f GiB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { TEBIBYTE_FACTOR, N_("%.1f TiB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { PEBIBYTE_FACTOR, N_("%.1f PiB") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { EXBIBYTE_FACTOR, N_("%.1f EiB") } + }, + { + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { KILOBYTE_FACTOR, N_("%.1f kb") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { MEGABYTE_FACTOR, N_("%.1f Mb") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { GIGABYTE_FACTOR, N_("%.1f Gb") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { TERABYTE_FACTOR, N_("%.1f Tb") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { PETABYTE_FACTOR, N_("%.1f Pb") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { EXABYTE_FACTOR, N_("%.1f Eb") } + }, + { + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { KIBIBYTE_FACTOR, N_("%.1f Kib") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { MEBIBYTE_FACTOR, N_("%.1f Mib") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { GIBIBYTE_FACTOR, N_("%.1f Gib") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { TEBIBYTE_FACTOR, N_("%.1f Tib") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { PEBIBYTE_FACTOR, N_("%.1f Pib") }, + /* Translators: Keep the no-break space between %.1f and the unit symbol */ + { EXBIBYTE_FACTOR, N_("%.1f Eib") } + } + }; + + GString *string; + FormatIndex index; + + string = g_string_new (NULL); + + switch (flags & ~G_FORMAT_SIZE_LONG_FORMAT) + { + case G_FORMAT_SIZE_DEFAULT: + index = FORMAT_BYTES; + break; + case (G_FORMAT_SIZE_DEFAULT | G_FORMAT_SIZE_IEC_UNITS): + index = FORMAT_BYTES_IEC; + break; + case G_FORMAT_SIZE_BITS: + index = FORMAT_BITS; + break; + case (G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS): + index = FORMAT_BITS_IEC; + break; + default: + g_assert_not_reached (); + } + + + if (size < formats[index][0].factor) + { + const char * format; + + if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC) + { + format = g_dngettext (GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size); + } + else + { + format = g_dngettext (GETTEXT_PACKAGE, "%u bit", "%u bits", (guint) size); + } + + g_string_printf (string, format, (guint) size); + + flags &= ~G_FORMAT_SIZE_LONG_FORMAT; + } + else + { + const gsize n = G_N_ELEMENTS (formats[index]); + gsize i; + + /* + * Point the last format (the highest unit) by default + * and then then scan all formats, starting with the 2nd one + * because the 1st is already managed by with the plural form + */ + const struct Format * f = &formats[index][n - 1]; + + for (i = 1; i < n; i++) + { + if (size < formats[index][i].factor) + { + f = &formats[index][i - 1]; + break; + } + } + + g_string_printf (string, _(f->string), (gdouble) size / (gdouble) f->factor); + } + + if (flags & G_FORMAT_SIZE_LONG_FORMAT) + { + /* First problem: we need to use the number of bytes to decide on + * the plural form that is used for display, but the number of + * bytes potentially exceeds the size of a guint (which is what + * ngettext() takes). + * + * From a pragmatic standpoint, it seems that all known languages + * base plural forms on one or both of the following: + * + * - the lowest digits of the number + * + * - if the number if greater than some small value + * + * Here's how we fake it: Draw an arbitrary line at one thousand. + * If the number is below that, then fine. If it is above it, + * then we take the modulus of the number by one thousand (in + * order to keep the lowest digits) and add one thousand to that + * (in order to ensure that 1001 is not treated the same as 1). + */ + guint plural_form = size < 1000 ? size : size % 1000 + 1000; + + /* Second problem: we need to translate the string "%u byte/bit" and + * "%u bytes/bits" for pluralisation, but the correct number format to + * use for a gsize is different depending on which architecture + * we're on. + * + * Solution: format the number separately and use "%s bytes/bits" on + * all platforms. + */ + const gchar *translated_format; + gchar *formatted_number; + + if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC) + { + /* Translators: the %s in "%s bytes" will always be replaced by a number. */ + translated_format = g_dngettext (GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form); + } + else + { + /* Translators: the %s in "%s bits" will always be replaced by a number. */ + translated_format = g_dngettext (GETTEXT_PACKAGE, "%s bit", "%s bits", plural_form); + } + /* XXX: Windows doesn't support the "'" format modifier, so we + * must not use it there. Instead, just display the number + * without separation. Bug #655336 is open until a solution is + * found. + */ +#ifndef G_OS_WIN32 + formatted_number = g_strdup_printf ("%'"G_GUINT64_FORMAT, size); +#else + formatted_number = g_strdup_printf ("%"G_GUINT64_FORMAT, size); +#endif + + g_string_append (string, " ("); + g_string_append_printf (string, translated_format, formatted_number); + g_free (formatted_number); + g_string_append (string, ")"); + } + + return g_string_free (string, FALSE); +} + +#pragma GCC diagnostic pop + +/** + * g_format_size_for_display: + * @size: a size in bytes + * + * Formats a size (for example the size of a file) into a human + * readable string. Sizes are rounded to the nearest size prefix + * (KB, MB, GB) and are displayed rounded to the nearest tenth. + * E.g. the file size 3292528 bytes will be converted into the + * string "3.1 MB". + * + * The prefix units base is 1024 (i.e. 1 KB is 1024 bytes). + * + * This string should be freed with g_free() when not needed any longer. + * + * Returns: a newly-allocated formatted string containing a human + * readable file size + * + * Since: 2.16 + * + * Deprecated:2.30: This function is broken due to its use of SI + * suffixes to denote IEC units. Use g_format_size() instead. + */ +gchar * +g_format_size_for_display (goffset size) +{ + if (size < (goffset) KIBIBYTE_FACTOR) + return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size); + else + { + gdouble displayed_size; + + if (size < (goffset) MEBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR; + /* Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to + * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of + * compatibility. Users will not see this string unless a program is using this deprecated function. + * Please translate as literally as possible. + */ + return g_strdup_printf (_("%.1f KB"), displayed_size); + } + else if (size < (goffset) GIBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) MEBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f MB"), displayed_size); + } + else if (size < (goffset) TEBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) GIBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f GB"), displayed_size); + } + else if (size < (goffset) PEBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) TEBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f TB"), displayed_size); + } + else if (size < (goffset) EXBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) PEBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f PB"), displayed_size); + } + else + { + displayed_size = (gdouble) size / (gdouble) EXBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f EB"), displayed_size); + } + } +} + +#if defined (G_OS_WIN32) && !defined (_WIN64) + +/* Binary compatibility versions. Not for newly compiled code. */ + +_GLIB_EXTERN const gchar *g_get_user_name_utf8 (void); +_GLIB_EXTERN const gchar *g_get_real_name_utf8 (void); +_GLIB_EXTERN const gchar *g_get_home_dir_utf8 (void); +_GLIB_EXTERN const gchar *g_get_tmp_dir_utf8 (void); +_GLIB_EXTERN gchar *g_find_program_in_path_utf8 (const gchar *program); + +gchar * +g_find_program_in_path_utf8 (const gchar *program) +{ + return g_find_program_in_path (program); +} + +const gchar *g_get_user_name_utf8 (void) { return g_get_user_name (); } +const gchar *g_get_real_name_utf8 (void) { return g_get_real_name (); } +const gchar *g_get_home_dir_utf8 (void) { return g_get_home_dir (); } +const gchar *g_get_tmp_dir_utf8 (void) { return g_get_tmp_dir (); } + +#endif + +/* Private API: + * + * Returns %TRUE if the current process was executed as setuid + */ +gboolean +g_check_setuid (void) +{ +#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL) && defined(AT_SECURE) + unsigned long value; + int errsv; + + errno = 0; + value = getauxval (AT_SECURE); + errsv = errno; + if (errsv) + g_error ("getauxval () failed: %s", g_strerror (errsv)); + return value; +#elif defined(HAVE_ISSETUGID) && !defined(__BIONIC__) + /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */ + + /* Android had it in older versions but the new 64 bit ABI does not + * have it anymore, and some versions of the 32 bit ABI neither. + * https://code.google.com/p/android-developer-preview/issues/detail?id=168 + */ + return issetugid (); +#elif defined(G_OS_UNIX) + uid_t ruid, euid, suid; /* Real, effective and saved user ID's */ + gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */ + + static gsize check_setuid_initialised; + static gboolean is_setuid; + + if (g_once_init_enter (&check_setuid_initialised)) + { +#ifdef HAVE_GETRESUID + /* These aren't in the header files, so we prototype them here. + */ + int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); + int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); + + if (getresuid (&ruid, &euid, &suid) != 0 || + getresgid (&rgid, &egid, &sgid) != 0) +#endif /* HAVE_GETRESUID */ + { + suid = ruid = getuid (); + sgid = rgid = getgid (); + euid = geteuid (); + egid = getegid (); + } + + is_setuid = (ruid != euid || ruid != suid || + rgid != egid || rgid != sgid); + + g_once_init_leave (&check_setuid_initialised, 1); + } + return is_setuid; +#else + return FALSE; +#endif +} + +#ifdef G_OS_WIN32 +/** + * g_abort: + * + * A wrapper for the POSIX abort() function. + * + * On Windows it is a function that makes extra effort (including a call + * to abort()) to ensure that a debugger-catchable exception is thrown + * before the program terminates. + * + * See your C library manual for more details about abort(). + * + * Since: 2.50 + */ +void +g_abort (void) +{ + /* One call to break the debugger */ + DebugBreak (); + /* One call in case CRT does get saner about abort() behaviour */ + abort (); + /* And one call to bind them all and terminate the program for sure */ + ExitProcess (127); +} +#endif diff -Nru glib2.0-2.59.2/.pc/debian/06_thread_test_ignore_prctl_fail.patch/glib/tests/thread.c glib2.0-2.59.3/.pc/debian/06_thread_test_ignore_prctl_fail.patch/glib/tests/thread.c --- glib2.0-2.59.2/.pc/debian/06_thread_test_ignore_prctl_fail.patch/glib/tests/thread.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/06_thread_test_ignore_prctl_fail.patch/glib/tests/thread.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,211 @@ +/* Unit tests for GThread + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#include +#ifdef HAVE_SYS_PRCTL_H +#include +#endif + +#include + +#ifdef G_OS_UNIX +#include +#include +#endif + +#ifdef THREADS_POSIX +#include +#endif + +static gpointer +thread1_func (gpointer data) +{ + g_thread_exit (GINT_TO_POINTER (1)); + + g_assert_not_reached (); + + return NULL; +} + +/* test that g_thread_exit() works */ +static void +test_thread1 (void) +{ + gpointer result; + GThread *thread; + GError *error = NULL; + + thread = g_thread_try_new ("test", thread1_func, NULL, &error); + g_assert_no_error (error); + + result = g_thread_join (thread); + + g_assert_cmpint (GPOINTER_TO_INT (result), ==, 1); +} + +static gpointer +thread2_func (gpointer data) +{ + return g_thread_self (); +} + +/* test that g_thread_self() works */ +static void +test_thread2 (void) +{ + gpointer result; + GThread *thread; + + thread = g_thread_new ("test", thread2_func, NULL); + + g_assert (g_thread_self () != thread); + + result = g_thread_join (thread); + + g_assert (result == thread); +} + +static gpointer +thread3_func (gpointer data) +{ + GThread *peer = data; + gint retval; + + retval = 3; + + if (peer) + { + gpointer result; + + result = g_thread_join (peer); + + retval += GPOINTER_TO_INT (result); + } + + return GINT_TO_POINTER (retval); +} + +/* test that g_thread_join() works across peers */ +static void +test_thread3 (void) +{ + gpointer result; + GThread *thread1, *thread2, *thread3; + + thread1 = g_thread_new ("a", thread3_func, NULL); + thread2 = g_thread_new ("b", thread3_func, thread1); + thread3 = g_thread_new ("c", thread3_func, thread2); + + result = g_thread_join (thread3); + + g_assert_cmpint (GPOINTER_TO_INT(result), ==, 9); +} + +/* test that thread creation fails as expected, + * by setting RLIMIT_NPROC ridiculously low + */ +static void +test_thread4 (void) +{ +#ifdef HAVE_PRLIMIT + struct rlimit ol, nl; + GThread *thread; + GError *error; + gint ret; + + /* Linux CAP_SYS_RESOURCE overrides RLIMIT_NPROC, and probably similar + * things are true on other systems. + */ + if (getuid () == 0 || geteuid () == 0) + return; + + getrlimit (RLIMIT_NPROC, &nl); + nl.rlim_cur = 1; + + if ((ret = prlimit (getpid (), RLIMIT_NPROC, &nl, &ol)) != 0) + g_error ("prlimit failed: %s", g_strerror (errno)); + + error = NULL; + thread = g_thread_try_new ("a", thread1_func, NULL, &error); + g_assert (thread == NULL); + g_assert_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN); + g_error_free (error); + + if ((ret = prlimit (getpid (), RLIMIT_NPROC, &ol, NULL)) != 0) + g_error ("resetting RLIMIT_NPROC failed: %s", g_strerror (errno)); +#endif +} + +static void +test_thread5 (void) +{ + GThread *thread; + + thread = g_thread_new ("a", thread3_func, NULL); + g_thread_ref (thread); + g_thread_join (thread); + g_thread_unref (thread); +} + +static gpointer +thread6_func (gpointer data) +{ +#if defined (HAVE_PTHREAD_SETNAME_NP_WITH_TID) && defined (HAVE_PTHREAD_GETNAME_NP) + char name[16]; + + pthread_getname_np (pthread_self(), name, 16); + + g_assert_cmpstr (name, ==, data); +#endif + + return NULL; +} + +static void +test_thread6 (void) +{ + GThread *thread; + + thread = g_thread_new ("abc", thread6_func, "abc"); + g_thread_join (thread); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/thread/thread1", test_thread1); + g_test_add_func ("/thread/thread2", test_thread2); + g_test_add_func ("/thread/thread3", test_thread3); + g_test_add_func ("/thread/thread4", test_thread4); + g_test_add_func ("/thread/thread5", test_thread5); + g_test_add_func ("/thread/thread6", test_thread6); + + return g_test_run (); +} diff -Nru glib2.0-2.59.2/.pc/debian/61_glib-compile-binaries-path.patch/gio/meson.build glib2.0-2.59.3/.pc/debian/61_glib-compile-binaries-path.patch/gio/meson.build --- glib2.0-2.59.2/.pc/debian/61_glib-compile-binaries-path.patch/gio/meson.build 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/61_glib-compile-binaries-path.patch/gio/meson.build 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,996 @@ +gio_c_args = [ + '-DG_LOG_DOMAIN="GLib-GIO"', + '-DGIO_COMPILATION', + '-DGIO_MODULE_DIR="@0@"'.format(glib_giomodulesdir), +] + +gio_c_args += glib_hidden_visibility_args + +# FIXME: Install empty glib_giomodulesdir + +gnetworking_h_conf = configuration_data() + +gnetworking_h_wspiapi_include = '' +gnetworking_h_nameser_compat_include = '' + +if host_system == 'windows' + # in the Windows SDK and in mingw-w64 has wrappers for + # inline workarounds for getaddrinfo, getnameinfo and freeaddrinfo if + # they aren't present at run-time (on Windows 2000). + gnetworking_h_wspiapi_include = '#include ' +elif not host_system.contains('android') + # Don't check for C_IN on Android since it does not define it in public + # headers, we define it ourselves wherever necessary + if not cc.compiles('''#include + #include + int qclass = C_IN;''', + name : 'C_IN in public headers (no arpa/nameser_compat.h needed)') + if cc.compiles('''#include + #include + #include + int qclass = C_IN;''', + name : 'arpa/nameser_compat.h needed for C_IN') + gnetworking_h_nameser_compat_include = '#include ' + else + error('Could not find required includes for ARPA C_IN') + endif + endif +endif + +network_libs = [ ] +network_args = [ ] +if host_system != 'windows' + # res_query() + res_query_test = '''#include + int main (int argc, char ** argv) { + return res_query("test", 0, 0, (void *)0, 0); + }''' + res_query_test_full = '''#include + #include + #include + ''' + res_query_test + if not cc.links(res_query_test_full, name : 'res_query()') + if cc.links(res_query_test_full, args : '-lresolv', name : 'res_query() in -lresolv') + network_libs += [ cc.find_library('resolv') ] + network_args += [ '-lresolv' ] + elif cc.links(res_query_test, args : '-lbind', name : 'res_query() in -lbind') + network_libs += [ cc.find_library('bind') ] + network_args += [ '-lbind' ] + else + error('Could not find res_query()') + endif + endif + + # socket() + socket_test = '''#include + #include + int main (int argc, char ** argv) { + return socket(1, 2, 3); + }''' + if not cc.links(socket_test, name : 'socket()') + if cc.links(socket_test, args : '-lsocket', name : 'socket() in -lsocket') + network_libs += [ cc.find_library('socket') ] + network_args += [ '-lsocket' ] + else + error('Could not find socket()') + endif + endif + + # res_init() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + return res_init(); + }''', args : network_args, name : 'res_init()') + glib_conf.set('HAVE_RES_INIT', 1) + endif + + # res_nclose() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + res_nclose(&res); + return 0; + }''', args : network_args, name : 'res_nclose()') + glib_conf.set('HAVE_RES_NCLOSE', 1) + endif + + # res_ndestroy() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + res_ndestroy(&res); + return 0; + }''', args : network_args, name : 'res_ndestroy()') + glib_conf.set('HAVE_RES_NDESTROY', 1) + endif + + # res_ninit() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + return res_ninit(&res); + }''', args : network_args, name : 'res_ninit()') + glib_conf.set('HAVE_RES_NINIT', 1) + endif + + # res_nquery() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + return res_nquery(&res, "test", 0, 0, (void *)0, 0); + }''', args : network_args, name : 'res_nquery()') + glib_conf.set('HAVE_RES_NQUERY', 1) + endif + + if cc.has_type('struct ip_mreqn', prefix : '#include ') + glib_conf.set('HAVE_IP_MREQN', 1) + endif + + if cc.compiles('''#include + #include + int main (int argc, char ** argv) { + struct ifreq ifr; + ioctl(0, SIOCGIFADDR, &ifr); + return 0; + }''', + name : 'ioctl with request SIOCGIFADDR') + glib_conf.set('HAVE_SIOCGIFADDR', '/**/') + endif + +endif + +if host_system.contains('android') + # struct ip_mreq_source definition is broken on Android NDK <= r16 + # See https://bugzilla.gnome.org/show_bug.cgi?id=740791 + if not cc.compiles('''#include + int main(int argc, char ** argv) { + struct ip_mreq_source mc_req_src; + mc_req_src.imr_interface.s_addr = 0; + return 0; + }''', + name : 'ip_mreq_source.imr_interface has s_addr member') + glib_conf.set('BROKEN_IP_MREQ_SOURCE_STRUCT', 1) + endif +endif + +gnetworking_h_conf.set('WSPIAPI_INCLUDE', gnetworking_h_wspiapi_include) +gnetworking_h_conf.set('NAMESER_COMPAT_INCLUDE', gnetworking_h_nameser_compat_include) + +gnetworking_h = configure_file(input : 'gnetworking.h.in', + output : 'gnetworking.h', + install_dir : join_paths(get_option('includedir'), 'glib-2.0/gio'), + configuration : gnetworking_h_conf) + +gdbus_headers = files( + 'gdbusauthobserver.h', + 'gcredentials.h', + 'gdbusutils.h', + 'gdbuserror.h', + 'gdbusaddress.h', + 'gdbusconnection.h', + 'gdbusmessage.h', + 'gdbusnameowning.h', + 'gdbusnamewatching.h', + 'gdbusproxy.h', + 'gdbusintrospection.h', + 'gdbusmethodinvocation.h', + 'gdbusserver.h', + 'gdbusinterface.h', + 'gdbusinterfaceskeleton.h', + 'gdbusobject.h', + 'gdbusobjectskeleton.h', + 'gdbusobjectproxy.h', + 'gdbusobjectmanager.h', + 'gdbusobjectmanagerclient.h', + 'gdbusobjectmanagerserver.h', + 'gtestdbus.h', +) + +gdbus_sources = files( + 'gdbusutils.c', + 'gdbusaddress.c', + 'gdbusauthobserver.c', + 'gdbusauth.c', + 'gdbusauthmechanism.c', + 'gdbusauthmechanismanon.c', + 'gdbusauthmechanismexternal.c', + 'gdbusauthmechanismsha1.c', + 'gdbuserror.c', + 'gdbusconnection.c', + 'gdbusmessage.c', + 'gdbusnameowning.c', + 'gdbusnamewatching.c', + 'gdbusproxy.c', + 'gdbusprivate.c', + 'gdbusintrospection.c', + 'gdbusmethodinvocation.c', + 'gdbusserver.c', + 'gdbusinterface.c', + 'gdbusinterfaceskeleton.c', + 'gdbusobject.c', + 'gdbusobjectskeleton.c', + 'gdbusobjectproxy.c', + 'gdbusobjectmanager.c', + 'gdbusobjectmanagerclient.c', + 'gdbusobjectmanagerserver.c', + 'gtestdbus.c', +) + +# Generate gdbus-codegen +subdir('gdbus-2.0/codegen') + +# Generate xdp-dbus.{c,h} +xdp_dbus_generated = custom_target('xdp-dbus', + input : ['org.freedesktop.portal.Documents.xml', + 'org.freedesktop.portal.OpenURI.xml', + 'org.freedesktop.portal.ProxyResolver.xml', + 'org.freedesktop.portal.Trash.xml'], + output : ['xdp-dbus.h', 'xdp-dbus.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.freedesktop.portal.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'xdp-dbus', + '--c-namespace', 'GXdp', + '--annotate', 'org.freedesktop.portal.Documents.Add()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '--annotate', 'org.freedesktop.portal.Documents.AddNamed()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '--annotate', 'org.freedesktop.portal.Documents.AddFull()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '--annotate', 'org.freedesktop.portal.OpenURI.OpenFile()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '--annotate', 'org.freedesktop.portal.Trash.TrashFile()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '@INPUT@']) + +# Generate gdbus-generated.{c,h} +gdbus_daemon_generated = custom_target('gdbus-daemon-generated', + input : ['dbus-daemon.xml'], + output : ['gdbus-daemon-generated.h', 'gdbus-daemon-generated.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'gdbus-daemon-generated', + '--c-namespace', '_G', '@INPUT@']) + +settings_headers = files( + 'gsettingsbackend.h', + 'gsettingsschema.h', + 'gsettings.h', +) + +settings_sources = files( + 'gvdb/gvdb-reader.c', + 'gdelayedsettingsbackend.c', + 'gkeyfilesettingsbackend.c', + 'gmemorysettingsbackend.c', + 'gnullsettingsbackend.c', + 'gsettingsbackend.c', + 'gsettingsschema.c', + 'gsettings-mapping.c', + 'gsettings.c', +) + +if host_system == 'windows' + settings_sources += files('gregistrysettingsbackend.c') +endif + +application_headers = files( + 'gapplication.h', + 'gapplicationcommandline.h', + + 'gactiongroup.h', + 'gactionmap.h', + 'gsimpleactiongroup.h', + 'gremoteactiongroup.h', + 'gactiongroupexporter.h', + 'gdbusactiongroup.h', + 'gaction.h', + 'gpropertyaction.h', + 'gsimpleaction.h', + + 'gmenumodel.h', + 'gmenu.h', + 'gmenuexporter.h', + 'gdbusmenumodel.h', + 'gnotification.h', +) + +application_sources = files( + 'gapplication.c', + 'gapplicationcommandline.c', + 'gapplicationimpl-dbus.c', + + 'gactiongroup.c', + 'gactionmap.c', + 'gsimpleactiongroup.c', + 'gremoteactiongroup.c', + 'gactiongroupexporter.c', + 'gdbusactiongroup.c', + 'gaction.c', + 'gpropertyaction.c', + 'gsimpleaction.c', + + 'gmenumodel.c', + 'gmenu.c', + 'gmenuexporter.c', + 'gdbusmenumodel.c', + 'gnotification.c', + 'gnotificationbackend.c', +) + +local_sources = files( + 'ghttpproxy.c', + 'glocalfile.c', + 'glocalfileenumerator.c', + 'glocalfileinfo.c', + 'glocalfileinputstream.c', + 'glocalfilemonitor.c', + 'glocalfileoutputstream.c', + 'glocalfileiostream.c', + 'glocalvfs.c', + 'gsocks4proxy.c', + 'gsocks4aproxy.c', + 'gsocks5proxy.c', + 'thumbnail-verify.c', +) + +platform_deps = [] +internal_deps = [] +# TODO: internal_objects is a workaround for +# and +# . When we can depend +# on a meson version where those are fixed, revert the commit that +# introduced this workaround. +internal_objects = [] +appinfo_sources = [] +contenttype_sources = [] +portal_sources = [] +unix_sources = [] +win32_sources = [] + +# This is also used by tests/gdbus-daemon, so use files() to include the path +gdbus_daemon_sources = [ + files('gdbusdaemon.c'), + gdbus_daemon_generated, +] + +if host_system != 'windows' + unix_sources = files( + 'gfiledescriptorbased.c', + 'gunixconnection.c', + 'gunixcredentialsmessage.c', + 'gunixfdlist.c', + 'gunixfdmessage.c', + 'gunixmount.c', + 'gunixmounts.c', + 'gunixsocketaddress.c', + 'gunixvolume.c', + 'gunixvolumemonitor.c', + 'gunixinputstream.c', + 'gunixoutputstream.c', + 'gfdonotificationbackend.c', + 'ggtknotificationbackend.c', + ) + + portal_sources = [files( + 'gdocumentportal.c', + 'gopenuriportal.c', + 'gnetworkmonitorportal.c', + 'gproxyresolverportal.c', + 'gtrashportal.c', + 'gportalsupport.c', + 'gportalnotificationbackend.c'), + xdp_dbus_generated + ] + + gio_unix_include_headers = files( + 'gfiledescriptorbased.h', + 'gunixconnection.h', + 'gunixcredentialsmessage.h', + 'gunixmounts.h', + 'gunixfdlist.h', + 'gunixfdmessage.h', + 'gunixinputstream.h', + 'gunixoutputstream.h', + 'gunixsocketaddress.h', + ) + + if glib_have_cocoa + settings_sources += files('gnextstepsettingsbackend.m') + contenttype_sources += files('gosxcontenttype.m') + appinfo_sources += files('gosxappinfo.m') + if glib_have_os_x_9_or_later + unix_sources += files('gcocoanotificationbackend.m') + endif + else + contenttype_sources += files('gcontenttype.c') + appinfo_sources += files('gdesktopappinfo.c') + gio_unix_include_headers += files('gdesktopappinfo.h') + + executable('gio-launch-desktop', 'gio-launch-desktop.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args) + endif + + subdir('xdgmime') + internal_deps += [xdgmime_lib] + internal_objects += [xdgmime_lib.extract_all_objects()] + + install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio') + + if glib_conf.has('HAVE_NETLINK') + unix_sources += files( + 'gnetworkmonitornetlink.c', + 'gnetworkmonitornm.c', + ) + endif +else + appinfo_sources += files('gwin32appinfo.c') + contenttype_sources += files('gcontenttype-win32.c') + platform_deps += [cc.find_library('shlwapi'), + cc.find_library('dnsapi'), + iphlpapi_dep, + winsock2] + win32_sources += files( + 'gwin32registrykey.c', + 'gwin32mount.c', + 'gwin32volumemonitor.c', + 'gwin32inputstream.c', + 'gwin32outputstream.c', + 'gwin32networkmonitor.c', + 'gwin32networkmonitor.h', + 'gwin32notificationbackend.c', + ) + + gio_win_rc = configure_file( + input: 'gio.rc.in', + output: 'gio.rc', + configuration: glibconfig_conf, + ) + gio_win_res = windows.compile_resources(gio_win_rc) + win32_sources += [gio_win_res] + + gio_win32_include_headers = files( + 'gwin32inputstream.h', + 'gwin32outputstream.h', + ) + install_headers(gio_win32_include_headers, subdir : 'gio-win32-2.0/gio') +endif + +gio_sources = files( + 'gappinfo.c', + 'gasynchelper.c', + 'gasyncinitable.c', + 'gasyncresult.c', + 'gbufferedinputstream.c', + 'gbufferedoutputstream.c', + 'gbytesicon.c', + 'gcancellable.c', + 'gcharsetconverter.c', + 'gcontextspecificgroup.c', + 'gconverter.c', + 'gconverterinputstream.c', + 'gconverteroutputstream.c', + 'gcredentials.c', + 'gdatagrambased.c', + 'gdatainputstream.c', + 'gdataoutputstream.c', + 'gdrive.c', + 'gdummyfile.c', + 'gdummyproxyresolver.c', + 'gdummytlsbackend.c', + 'gemblem.c', + 'gemblemedicon.c', + 'gfile.c', + 'gfileattribute.c', + 'gfileenumerator.c', + 'gfileicon.c', + 'gfileinfo.c', + 'gfileinputstream.c', + 'gfilemonitor.c', + 'gfilenamecompleter.c', + 'gfileoutputstream.c', + 'gfileiostream.c', + 'gfilterinputstream.c', + 'gfilteroutputstream.c', + 'gicon.c', + 'ginetaddress.c', + 'ginetaddressmask.c', + 'ginetsocketaddress.c', + 'ginitable.c', + 'ginputstream.c', + 'gioerror.c', + 'giomodule.c', + 'giomodule-priv.c', + 'gioscheduler.c', + 'giostream.c', + 'gloadableicon.c', + 'gmount.c', + 'gmemoryinputstream.c', + 'gmemoryoutputstream.c', + 'gmountoperation.c', + 'gnativevolumemonitor.c', + 'gnativesocketaddress.c', + 'gnetworkaddress.c', + 'gnetworking.c', + 'gnetworkmonitor.c', + 'gnetworkmonitorbase.c', + 'gnetworkservice.c', + 'goutputstream.c', + 'gpermission.c', + 'gpollableinputstream.c', + 'gpollableoutputstream.c', + 'gpollableutils.c', + 'gpollfilemonitor.c', + 'gproxy.c', + 'gproxyaddress.c', + 'gproxyaddressenumerator.c', + 'gproxyresolver.c', + 'gresolver.c', + 'gresource.c', + 'gresourcefile.c', + 'gseekable.c', + 'gsimpleasyncresult.c', + 'gsimpleiostream.c', + 'gsimplepermission.c', + 'gsocket.c', + 'gsocketaddress.c', + 'gsocketaddressenumerator.c', + 'gsocketclient.c', + 'gsocketconnectable.c', + 'gsocketconnection.c', + 'gsocketcontrolmessage.c', + 'gsocketinputstream.c', + 'gsocketlistener.c', + 'gsocketoutputstream.c', + 'gsubprocesslauncher.c', + 'gsubprocess.c', + 'gsocketservice.c', + 'gsrvtarget.c', + 'gsimpleproxyresolver.c', + 'gtask.c', + 'gtcpconnection.c', + 'gtcpwrapperconnection.c', + 'gthreadedsocketservice.c', + 'gthemedicon.c', + 'gthreadedresolver.c', + 'gthreadedresolver.h', + 'gtlsbackend.c', + 'gtlscertificate.c', + 'gtlsclientconnection.c', + 'gtlsconnection.c', + 'gtlsdatabase.c', + 'gtlsfiledatabase.c', + 'gtlsinteraction.c', + 'gtlspassword.c', + 'gtlsserverconnection.c', + 'gdtlsconnection.c', + 'gdtlsclientconnection.c', + 'gdtlsserverconnection.c', + 'gunionvolumemonitor.c', + 'gvfs.c', + 'gvolume.c', + 'gvolumemonitor.c', + 'gzlibcompressor.c', + 'gzlibdecompressor.c', + 'glistmodel.c', + 'gliststore.c', +) + +gio_sources += appinfo_sources +gio_sources += contenttype_sources +gio_sources += gdbus_daemon_sources +gio_sources += unix_sources +gio_sources += win32_sources +gio_sources += application_sources +gio_sources += settings_sources +gio_sources += gdbus_sources +gio_sources += portal_sources +gio_sources += local_sources + +MISSING_STUFF = ''' +# This is read by gobject-introspection/misc/ and gtk-doc +gio-public-headers.txt: Makefile + '$(AM_V_GEN) echo $(gioinclude_HEADERS) $(giowin32include_HEADERS) $(giounixinclude_HEADERS) > $@.tmp && mv $@.tmp $@ + +gio.def: libgio-2.0.la + '$(AM_V_GEN) dumpbin.exe -exports .libs/libgio-2.0-0.dll | awk 'BEGIN { print "EXPORTS" } / +[[:digit:]]+ +[[:xdigit:]]+ +[[:xdigit:]]+/{ print $$4 }' > gio.def.tmp && mv gio.def.tmp gio.def + +gio-2.0.lib: libgio-2.0.la gio.def + '$(AM_V_GEN) lib.exe -machine:@LIB_EXE_MACHINE_FLAG@ -name:libgio-2.0-$(LT_CURRENT_MINUS_AGE).dll -def:$(builddir)/gio.def -out:$@ +''' + +gio_headers = files( + 'gappinfo.h', + 'gasyncinitable.h', + 'gasyncresult.h', + 'gbufferedinputstream.h', + 'gbufferedoutputstream.h', + 'gbytesicon.h', + 'gcancellable.h', + 'gcontenttype.h', + 'gcharsetconverter.h', + 'gconverter.h', + 'gconverterinputstream.h', + 'gconverteroutputstream.h', + 'gdatagrambased.h', + 'gdatainputstream.h', + 'gdataoutputstream.h', + 'gdrive.h', + 'gemblem.h', + 'gemblemedicon.h', + 'gfile.h', + 'gfileattribute.h', + 'gfileenumerator.h', + 'gfileicon.h', + 'gfileinfo.h', + 'gfileinputstream.h', + 'gfilemonitor.h', + 'gfilenamecompleter.h', + 'gfileoutputstream.h', + 'gfileiostream.h', + 'gfilterinputstream.h', + 'gfilteroutputstream.h', + 'gicon.h', + 'ginetaddress.h', + 'ginetaddressmask.h', + 'ginetsocketaddress.h', + 'ginputstream.h', + 'ginitable.h', + 'gio.h', + 'gio-autocleanups.h', + 'giotypes.h', + 'gioenums.h', + 'gioerror.h', + 'giomodule.h', + 'gioscheduler.h', + 'giostream.h', + 'gloadableicon.h', + 'gmount.h', + 'gmemoryinputstream.h', + 'gmemoryoutputstream.h', + 'gmountoperation.h', + 'gnativevolumemonitor.h', + 'gnetworkaddress.h', + 'gnetworkmonitor.h', + 'gnetworkservice.h', + 'goutputstream.h', + 'gpermission.h', + 'gpollableinputstream.h', + 'gpollableoutputstream.h', + 'gpollableutils.h', + 'gproxyaddress.h', + 'gproxy.h', + 'gproxyaddressenumerator.h', + 'gproxyresolver.h', + 'gresolver.h', + 'gresource.h', + 'gseekable.h', + 'gsimpleasyncresult.h', + 'gsimpleiostream.h', + 'gsimplepermission.h', + 'gsocket.h', + 'gsocketaddress.h', + 'gsocketaddressenumerator.h', + 'gsocketclient.h', + 'gsocketconnectable.h', + 'gsocketconnection.h', + 'gsocketcontrolmessage.h', + 'gsocketlistener.h', + 'gsocketservice.h', + 'gsrvtarget.h', + 'gsimpleproxyresolver.h', + 'gtask.h', + 'gsubprocess.h', + 'gsubprocesslauncher.h', + 'gtcpconnection.h', + 'gtcpwrapperconnection.h', + 'gthreadedsocketservice.h', + 'gthemedicon.h', + 'gtlsbackend.h', + 'gtlscertificate.h', + 'gtlsclientconnection.h', + 'gtlsconnection.h', + 'gtlsdatabase.h', + 'gtlsfiledatabase.h', + 'gtlsinteraction.h', + 'gtlspassword.h', + 'gtlsserverconnection.h', + 'gdtlsconnection.h', + 'gdtlsclientconnection.h', + 'gdtlsserverconnection.h', + 'gvfs.h', + 'gvolume.h', + 'gvolumemonitor.h', + 'gzlibcompressor.h', + 'gzlibdecompressor.h', + 'glistmodel.h', + 'gliststore.h', +) + +gio_headers += application_headers +gio_headers += settings_headers +gio_headers += gdbus_headers +install_headers(gio_headers, subdir : 'glib-2.0/gio/') + +# We can't use gnome.mkenums() because the GNOME module looks for glib-mkenums +# in PATH, which means you can't bootstrap glib with its own glib-mkenums. +gioenumtypes_h = custom_target('gioenumtypes_h', + output : 'gioenumtypes.h', + capture : true, + input : gio_headers, + install : true, + install_dir : join_paths(get_option('includedir'), 'glib-2.0/gio'), + command : [python, glib_mkenums, + '--template', files('gioenumtypes.h.template'), + '@INPUT@', gnetworking_h]) + +gioenumtypes_c = custom_target('gioenumtypes_c', + output : 'gioenumtypes.c', + capture : true, + input : gio_headers, + depends : [gioenumtypes_h], + command : [python, glib_mkenums, + '--template', files('gioenumtypes.c.template'), + '@INPUT@', gnetworking_h]) + +gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h]) + +# inotify +if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1 + subdir('inotify') + internal_deps += [ inotify_lib ] + internal_objects += [inotify_lib.extract_all_objects()] +endif + +# kevent +if have_func_kqueue and have_func_kevent + subdir('kqueue') + internal_deps += [ kqueue_lib ] + internal_objects += [kqueue_lib.extract_all_objects()] +endif + +if host_system == 'windows' + subdir('win32') + internal_deps += [ giowin32_lib ] + internal_objects += [giowin32_lib.extract_all_objects()] +endif + +if have_bash + install_data([ + 'completion/gapplication', + 'completion/gdbus', + 'completion/gio', + 'completion/gsettings', + 'completion/gresource' + ], + install_dir: join_paths(get_option('datadir'), 'bash-completion/completions')) +endif + +if enable_dtrace + gio_dtrace_obj = dtrace_obj_gen.process('gio_probes.d') + gio_dtrace_hdr = dtrace_hdr_gen.process('gio_probes.d') +else + gio_dtrace_obj = [] + gio_dtrace_hdr = [] +endif + +libgio = library('gio-2.0', + gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources, + gio_dtrace_hdr, gio_dtrace_obj, + objects : internal_objects, + version : library_version, + soversion : soversion, + darwin_versions : darwin_versions, + install : true, + include_directories : [configinc, gioinc], + # '$(gio_win32_res_ldflag)', + dependencies : [libz_dep, libdl_dep, libmount_dep, libglib_dep, + libgobject_dep, libgmodule_dep, selinux_dep, xattr_dep, + platform_deps, network_libs], + c_args : gio_c_args, + objc_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : [noseh_link_args, glib_link_flags], +) + +giomodulesdir = get_option('gio_module_dir') +if giomodulesdir == '' + giomodulesdir = join_paths('${libdir}', 'gio', 'modules') +endif + +schemas_subdir = join_paths('glib-2.0', 'schemas') + +pkg.generate(libgio, + libraries_private : [osx_ldflags], + requires : ['glib-2.0', 'gobject-2.0'], + variables : ['datadir=' + join_paths('${prefix}', get_option('datadir')), + 'schemasdir=' + join_paths('${datadir}', schemas_subdir), + 'bindir=' + join_paths('${prefix}', get_option('bindir')), + 'giomoduledir=' + giomodulesdir, + 'glib_compile_schemas=' + join_paths('${bindir}', 'glib-compile-schemas'), + 'glib_compile_resources=' + join_paths('${bindir}', 'glib-compile-resources'), + 'gdbus_codegen=' + join_paths('${bindir}', 'gdbus-codegen')], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-2.0', + name : 'GIO', + description : 'glib I/O library', +) + +if host_system == 'windows' + pkg.generate(requires : ['gobject-2.0', 'gmodule-no-export-2.0', 'gio-2.0'], + subdirs : ['gio-win32-2.0'], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-windows-2.0', + name : 'GIO Windows specific APIs', + description : 'Windows specific headers for glib I/O library', + ) +else + pkg.generate(requires : ['gobject-2.0', 'gio-2.0'], + subdirs : ['gio-unix-2.0'], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-unix-2.0', + name : 'GIO unix specific APIs', + description : 'unix specific headers for glib I/O library', + ) +endif + +libgio_dep = declare_dependency(link_with : libgio, + dependencies : [libgmodule_dep, libgobject_dep, gioenumtypes_dep], + include_directories : [gioinc]) + +if host_system == 'windows' + # Hack till https://github.com/mesonbuild/meson/issues/2324 is fixed + libgiounix_dep = dependency('', required : false) + libgiowin32_dep = libgio_dep +else + libgiowin32_dep = dependency('', required : false) + libgiounix_dep = libgio_dep +endif + +# Dependencies used by executables below +have_libelf = false +libelf = dependency('libelf', version : '>= 0.8.12', required : false) +if libelf.found() + have_libelf = true +else + # This fallback is necessary on *BSD. elfutils isn't the only libelf + # implementation, and *BSD usually includes their own libelf as a system + # library which doesn't have a corresponding .pc file. + libelf = cc.find_library('elf', required : false) + have_libelf = libelf.found() + have_libelf = have_libelf and cc.has_function('elf_begin', dependencies : libelf) + have_libelf = have_libelf and cc.has_function('elf_getshdrstrndx', dependencies : libelf) + have_libelf = have_libelf and cc.has_function('elf_getshdrnum', dependencies : libelf) + have_libelf = have_libelf and cc.has_header('libelf.h') +endif + +if have_libelf + glib_conf.set('HAVE_LIBELF', 1) +else + libelf = [] +endif + +gconstructor_as_data_h = custom_target('gconstructor_as_data.h', + input : ['data-to-c.py', files('../glib/gconstructor.h')], + output : ['gconstructor_as_data.h'], + command : [python, '@INPUT0@', '@INPUT1@', 'gconstructor_code', '@OUTPUT@']) + +# Several installed executables +gio_tool_sources = [ + 'gio-tool.c', + 'gio-tool.h', + 'gio-tool-cat.c', + 'gio-tool-copy.c', + 'gio-tool-info.c', + 'gio-tool-list.c', + 'gio-tool-mime.c', + 'gio-tool-mkdir.c', + 'gio-tool-monitor.c', + 'gio-tool-mount.c', + 'gio-tool-move.c', + 'gio-tool-open.c', + 'gio-tool-rename.c', + 'gio-tool-remove.c', + 'gio-tool-save.c', + 'gio-tool-set.c', + 'gio-tool-trash.c', + 'gio-tool-tree.c', +] + +executable('gio', gio_tool_sources, + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +executable('gresource', 'gresource-tool.c', + install : true, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libelf, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +gio_querymodules = executable('gio-querymodules', 'gio-querymodules.c', 'giomodule-priv.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +glib_compile_schemas = executable('glib-compile-schemas', + [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-schemas.c'], + install : true, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +glib_compile_resources = executable('glib-compile-resources', + [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-resources.c'], + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +executable('gsettings', 'gsettings-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) +install_data('gschema.dtd', + install_dir : join_paths(get_option('datadir'), schemas_subdir)) + +install_data(['gschema.loc', 'gschema.its'], + install_dir : join_paths(get_option('datadir'), 'gettext/its')) + +executable('gdbus', 'gdbus-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +if host_system != 'windows' and not glib_have_cocoa + executable('gapplication', 'gapplication-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) +endif + +if enable_systemtap + gio_stp = configure_file(input : 'gio.stp.in', + output : '@0@.stp'.format(libgio.full_path().split('/').get(-1)), + configuration : stp_cdata, + install_dir : tapset_install_dir, + install : true) +endif + +subdir('fam') +subdir('tests') diff -Nru glib2.0-2.59.2/.pc/debian/90_gio-modules-multiarch-compat.patch/gio/giomodule.c glib2.0-2.59.3/.pc/debian/90_gio-modules-multiarch-compat.patch/gio/giomodule.c --- glib2.0-2.59.2/.pc/debian/90_gio-modules-multiarch-compat.patch/gio/giomodule.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/90_gio-modules-multiarch-compat.patch/gio/giomodule.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,1575 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include + +#include "giomodule.h" +#include "giomodule-priv.h" +#include "glocalfilemonitor.h" +#include "gnativevolumemonitor.h" +#include "gproxyresolver.h" +#include "gproxy.h" +#include "gsettingsbackendinternal.h" +#include "ghttpproxy.h" +#include "gsocks4proxy.h" +#include "gsocks4aproxy.h" +#include "gsocks5proxy.h" +#include "gtlsbackend.h" +#include "gvfs.h" +#include "gnotificationbackend.h" +#include "ginitable.h" +#include "gnetworkmonitor.h" +#ifdef G_OS_WIN32 +#include "gregistrysettingsbackend.h" +#endif +#include + +#if defined(G_OS_UNIX) && !defined(HAVE_COCOA) +#include "gdesktopappinfo.h" +#endif +#ifdef HAVE_COCOA +#include "gosxappinfo.h" +#endif + +#ifdef HAVE_COCOA +#include +#endif + +/** + * SECTION:giomodule + * @short_description: Loadable GIO Modules + * @include: gio/gio.h + * + * Provides an interface and default functions for loading and unloading + * modules. This is used internally to make GIO extensible, but can also + * be used by others to implement module loading. + * + **/ + +/** + * SECTION:extensionpoints + * @short_description: Extension Points + * @include: gio.h + * @see_also: [Extending GIO][extending-gio] + * + * #GIOExtensionPoint provides a mechanism for modules to extend the + * functionality of the library or application that loaded it in an + * organized fashion. + * + * An extension point is identified by a name, and it may optionally + * require that any implementation must be of a certain type (or derived + * thereof). Use g_io_extension_point_register() to register an + * extension point, and g_io_extension_point_set_required_type() to + * set a required type. + * + * A module can implement an extension point by specifying the #GType + * that implements the functionality. Additionally, each implementation + * of an extension point has a name, and a priority. Use + * g_io_extension_point_implement() to implement an extension point. + * + * |[ + * GIOExtensionPoint *ep; + * + * // Register an extension point + * ep = g_io_extension_point_register ("my-extension-point"); + * g_io_extension_point_set_required_type (ep, MY_TYPE_EXAMPLE); + * ]| + * + * |[ + * // Implement an extension point + * G_DEFINE_TYPE (MyExampleImpl, my_example_impl, MY_TYPE_EXAMPLE) + * g_io_extension_point_implement ("my-extension-point", + * my_example_impl_get_type (), + * "my-example", + * 10); + * ]| + * + * It is up to the code that registered the extension point how + * it uses the implementations that have been associated with it. + * Depending on the use case, it may use all implementations, or + * only the one with the highest priority, or pick a specific + * one by name. + * + * To avoid opening all modules just to find out what extension + * points they implement, GIO makes use of a caching mechanism, + * see [gio-querymodules][gio-querymodules]. + * You are expected to run this command after installing a + * GIO module. + * + * The `GIO_EXTRA_MODULES` environment variable can be used to + * specify additional directories to automatically load modules + * from. This environment variable has the same syntax as the + * `PATH`. If two modules have the same base name in different + * directories, then the latter one will be ignored. If additional + * directories are specified GIO will load modules from the built-in + * directory last. + */ + +/** + * GIOModuleScope: + * + * Represents a scope for loading IO modules. A scope can be used for blocking + * duplicate modules, or blocking a module you don't want to load. + * + * The scope can be used with g_io_modules_load_all_in_directory_with_scope() + * or g_io_modules_scan_all_in_directory_with_scope(). + * + * Since: 2.30 + */ +struct _GIOModuleScope { + GIOModuleScopeFlags flags; + GHashTable *basenames; +}; + +/** + * g_io_module_scope_new: + * @flags: flags for the new scope + * + * Create a new scope for loading of IO modules. A scope can be used for + * blocking duplicate modules, or blocking a module you don't want to load. + * + * Specify the %G_IO_MODULE_SCOPE_BLOCK_DUPLICATES flag to block modules + * which have the same base name as a module that has already been seen + * in this scope. + * + * Returns: (transfer full): the new module scope + * + * Since: 2.30 + */ +GIOModuleScope * +g_io_module_scope_new (GIOModuleScopeFlags flags) +{ + GIOModuleScope *scope = g_new0 (GIOModuleScope, 1); + scope->flags = flags; + scope->basenames = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + return scope; +} + +/** + * g_io_module_scope_free: + * @scope: a module loading scope + * + * Free a module scope. + * + * Since: 2.30 + */ +void +g_io_module_scope_free (GIOModuleScope *scope) +{ + if (!scope) + return; + g_hash_table_destroy (scope->basenames); + g_free (scope); +} + +/** + * g_io_module_scope_block: + * @scope: a module loading scope + * @basename: the basename to block + * + * Block modules with the given @basename from being loaded when + * this scope is used with g_io_modules_scan_all_in_directory_with_scope() + * or g_io_modules_load_all_in_directory_with_scope(). + * + * Since: 2.30 + */ +void +g_io_module_scope_block (GIOModuleScope *scope, + const gchar *basename) +{ + gchar *key; + + g_return_if_fail (scope != NULL); + g_return_if_fail (basename != NULL); + + key = g_strdup (basename); + g_hash_table_add (scope->basenames, key); +} + +static gboolean +_g_io_module_scope_contains (GIOModuleScope *scope, + const gchar *basename) +{ + return g_hash_table_contains (scope->basenames, basename); +} + +struct _GIOModule { + GTypeModule parent_instance; + + gchar *filename; + GModule *library; + gboolean initialized; /* The module was loaded at least once */ + + void (* load) (GIOModule *module); + void (* unload) (GIOModule *module); +}; + +struct _GIOModuleClass +{ + GTypeModuleClass parent_class; + +}; + +static void g_io_module_finalize (GObject *object); +static gboolean g_io_module_load_module (GTypeModule *gmodule); +static void g_io_module_unload_module (GTypeModule *gmodule); + +/** + * GIOExtension: + * + * #GIOExtension is an opaque data structure and can only be accessed + * using the following functions. + */ +struct _GIOExtension { + char *name; + GType type; + gint priority; +}; + +/** + * GIOExtensionPoint: + * + * #GIOExtensionPoint is an opaque data structure and can only be accessed + * using the following functions. + */ +struct _GIOExtensionPoint { + GType required_type; + char *name; + GList *extensions; + GList *lazy_load_modules; +}; + +static GHashTable *extension_points = NULL; +G_LOCK_DEFINE_STATIC(extension_points); + +G_DEFINE_TYPE (GIOModule, g_io_module, G_TYPE_TYPE_MODULE) + +static void +g_io_module_class_init (GIOModuleClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class); + + object_class->finalize = g_io_module_finalize; + + type_module_class->load = g_io_module_load_module; + type_module_class->unload = g_io_module_unload_module; +} + +static void +g_io_module_init (GIOModule *module) +{ +} + +static void +g_io_module_finalize (GObject *object) +{ + GIOModule *module = G_IO_MODULE (object); + + g_free (module->filename); + + G_OBJECT_CLASS (g_io_module_parent_class)->finalize (object); +} + +static gboolean +load_symbols (GIOModule *module) +{ + gchar *name; + gchar *load_symname; + gchar *unload_symname; + gboolean ret; + + name = _g_io_module_extract_name (module->filename); + load_symname = g_strconcat ("g_io_", name, "_load", NULL); + unload_symname = g_strconcat ("g_io_", name, "_unload", NULL); + + ret = g_module_symbol (module->library, + load_symname, + (gpointer) &module->load) && + g_module_symbol (module->library, + unload_symname, + (gpointer) &module->unload); + + if (!ret) + { + /* Fallback to old names */ + ret = g_module_symbol (module->library, + "g_io_module_load", + (gpointer) &module->load) && + g_module_symbol (module->library, + "g_io_module_unload", + (gpointer) &module->unload); + } + + g_free (name); + g_free (load_symname); + g_free (unload_symname); + + return ret; +} + +static gboolean +g_io_module_load_module (GTypeModule *gmodule) +{ + GIOModule *module = G_IO_MODULE (gmodule); + + if (!module->filename) + { + g_warning ("GIOModule path not set"); + return FALSE; + } + + module->library = g_module_open (module->filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + + if (!module->library) + { + g_printerr ("%s\n", g_module_error ()); + return FALSE; + } + + /* Make sure that the loaded library contains the required methods */ + if (!load_symbols (module)) + { + g_printerr ("%s\n", g_module_error ()); + g_module_close (module->library); + + return FALSE; + } + + /* Initialize the loaded module */ + module->load (module); + module->initialized = TRUE; + + return TRUE; +} + +static void +g_io_module_unload_module (GTypeModule *gmodule) +{ + GIOModule *module = G_IO_MODULE (gmodule); + + module->unload (module); + + g_module_close (module->library); + module->library = NULL; + + module->load = NULL; + module->unload = NULL; +} + +/** + * g_io_module_new: + * @filename: (type filename): filename of the shared library module. + * + * Creates a new GIOModule that will load the specific + * shared library when in use. + * + * Returns: a #GIOModule from given @filename, + * or %NULL on error. + **/ +GIOModule * +g_io_module_new (const gchar *filename) +{ + GIOModule *module; + + g_return_val_if_fail (filename != NULL, NULL); + + module = g_object_new (G_IO_TYPE_MODULE, NULL); + module->filename = g_strdup (filename); + + return module; +} + +static gboolean +is_valid_module_name (const gchar *basename, + GIOModuleScope *scope) +{ + gboolean result; + +#if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN) + if (!g_str_has_prefix (basename, "lib") || + !g_str_has_suffix (basename, ".so")) + return FALSE; +#else + if (!g_str_has_suffix (basename, ".dll")) + return FALSE; +#endif + + result = TRUE; + if (scope) + { + result = _g_io_module_scope_contains (scope, basename) ? FALSE : TRUE; + if (result && (scope->flags & G_IO_MODULE_SCOPE_BLOCK_DUPLICATES)) + g_io_module_scope_block (scope, basename); + } + + return result; +} + + +/** + * g_io_modules_scan_all_in_directory_with_scope: + * @dirname: (type filename): pathname for a directory containing modules + * to scan. + * @scope: a scope to use when scanning the modules + * + * Scans all the modules in the specified directory, ensuring that + * any extension point implemented by a module is registered. + * + * This may not actually load and initialize all the types in each + * module, some modules may be lazily loaded and initialized when + * an extension point it implementes is used with e.g. + * g_io_extension_point_get_extensions() or + * g_io_extension_point_get_extension_by_name(). + * + * If you need to guarantee that all types are loaded in all the modules, + * use g_io_modules_load_all_in_directory(). + * + * Since: 2.30 + **/ +void +g_io_modules_scan_all_in_directory_with_scope (const char *dirname, + GIOModuleScope *scope) +{ + const gchar *name; + char *filename; + GDir *dir; + GStatBuf statbuf; + char *data; + time_t cache_mtime; + GHashTable *cache; + + if (!g_module_supported ()) + return; + + dir = g_dir_open (dirname, 0, NULL); + if (!dir) + return; + + filename = g_build_filename (dirname, "giomodule.cache", NULL); + + cache = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify)g_strfreev); + + cache_mtime = 0; + if (g_stat (filename, &statbuf) == 0 && + g_file_get_contents (filename, &data, NULL, NULL)) + { + char **lines; + int i; + + /* Cache mtime is the time the cache file was created, any file + * that has a ctime before this was created then and not modified + * since then (userspace can't change ctime). Its possible to change + * the ctime forward without changing the file content, by e.g. + * chmoding the file, but this is uncommon and will only cause us + * to not use the cache so will not cause bugs. + */ + cache_mtime = statbuf.st_mtime; + + lines = g_strsplit (data, "\n", -1); + g_free (data); + + for (i = 0; lines[i] != NULL; i++) + { + char *line = lines[i]; + char *file; + char *colon; + char **extension_points; + + if (line[0] == '#') + continue; + + colon = strchr (line, ':'); + if (colon == NULL || line == colon) + continue; /* Invalid line, ignore */ + + *colon = 0; /* terminate filename */ + file = g_strdup (line); + colon++; /* after colon */ + + while (g_ascii_isspace (*colon)) + colon++; + + extension_points = g_strsplit (colon, ",", -1); + g_hash_table_insert (cache, file, extension_points); + } + g_strfreev (lines); + } + + while ((name = g_dir_read_name (dir))) + { + if (is_valid_module_name (name, scope)) + { + GIOExtensionPoint *extension_point; + GIOModule *module; + gchar *path; + char **extension_points; + int i; + + path = g_build_filename (dirname, name, NULL); + module = g_io_module_new (path); + + extension_points = g_hash_table_lookup (cache, name); + if (extension_points != NULL && + g_stat (path, &statbuf) == 0 && + statbuf.st_ctime <= cache_mtime) + { + /* Lazy load/init the library when first required */ + for (i = 0; extension_points[i] != NULL; i++) + { + extension_point = + g_io_extension_point_register (extension_points[i]); + extension_point->lazy_load_modules = + g_list_prepend (extension_point->lazy_load_modules, + module); + } + } + else + { + /* Try to load and init types */ + if (g_type_module_use (G_TYPE_MODULE (module))) + g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */ + else + { /* Failure to load */ + g_printerr ("Failed to load module: %s\n", path); + g_object_unref (module); + g_free (path); + continue; + } + } + + g_free (path); + } + } + + g_dir_close (dir); + + g_hash_table_destroy (cache); + + g_free (filename); +} + +/** + * g_io_modules_scan_all_in_directory: + * @dirname: (type filename): pathname for a directory containing modules + * to scan. + * + * Scans all the modules in the specified directory, ensuring that + * any extension point implemented by a module is registered. + * + * This may not actually load and initialize all the types in each + * module, some modules may be lazily loaded and initialized when + * an extension point it implementes is used with e.g. + * g_io_extension_point_get_extensions() or + * g_io_extension_point_get_extension_by_name(). + * + * If you need to guarantee that all types are loaded in all the modules, + * use g_io_modules_load_all_in_directory(). + * + * Since: 2.24 + **/ +void +g_io_modules_scan_all_in_directory (const char *dirname) +{ + g_io_modules_scan_all_in_directory_with_scope (dirname, NULL); +} + +/** + * g_io_modules_load_all_in_directory_with_scope: + * @dirname: (type filename): pathname for a directory containing modules + * to load. + * @scope: a scope to use when scanning the modules. + * + * Loads all the modules in the specified directory. + * + * If don't require all modules to be initialized (and thus registering + * all gtypes) then you can use g_io_modules_scan_all_in_directory() + * which allows delayed/lazy loading of modules. + * + * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded + * from the directory, + * All the modules are loaded into memory, if you want to + * unload them (enabling on-demand loading) you must call + * g_type_module_unuse() on all the modules. Free the list + * with g_list_free(). + * + * Since: 2.30 + **/ +GList * +g_io_modules_load_all_in_directory_with_scope (const char *dirname, + GIOModuleScope *scope) +{ + const gchar *name; + GDir *dir; + GList *modules; + + if (!g_module_supported ()) + return NULL; + + dir = g_dir_open (dirname, 0, NULL); + if (!dir) + return NULL; + + modules = NULL; + while ((name = g_dir_read_name (dir))) + { + if (is_valid_module_name (name, scope)) + { + GIOModule *module; + gchar *path; + + path = g_build_filename (dirname, name, NULL); + module = g_io_module_new (path); + + if (!g_type_module_use (G_TYPE_MODULE (module))) + { + g_printerr ("Failed to load module: %s\n", path); + g_object_unref (module); + g_free (path); + continue; + } + + g_free (path); + + modules = g_list_prepend (modules, module); + } + } + + g_dir_close (dir); + + return modules; +} + +/** + * g_io_modules_load_all_in_directory: + * @dirname: (type filename): pathname for a directory containing modules + * to load. + * + * Loads all the modules in the specified directory. + * + * If don't require all modules to be initialized (and thus registering + * all gtypes) then you can use g_io_modules_scan_all_in_directory() + * which allows delayed/lazy loading of modules. + * + * Returns: (element-type GIOModule) (transfer full): a list of #GIOModules loaded + * from the directory, + * All the modules are loaded into memory, if you want to + * unload them (enabling on-demand loading) you must call + * g_type_module_unuse() on all the modules. Free the list + * with g_list_free(). + **/ +GList * +g_io_modules_load_all_in_directory (const char *dirname) +{ + return g_io_modules_load_all_in_directory_with_scope (dirname, NULL); +} + +static gpointer +try_class (GIOExtension *extension, + guint is_supported_offset) +{ + GType type = g_io_extension_get_type (extension); + typedef gboolean (*verify_func) (void); + gpointer class; + + class = g_type_class_ref (type); + if (!is_supported_offset || (* G_STRUCT_MEMBER(verify_func, class, is_supported_offset)) ()) + return class; + + g_type_class_unref (class); + return NULL; +} + +static void +print_help (const char *envvar, + GIOExtensionPoint *ep) +{ + g_print ("Supported arguments for %s environment variable:\n", envvar); + + if (g_io_extension_point_get_extensions (ep) == NULL) + g_print (" (none)\n"); + else + { + GList *l; + GIOExtension *extension; + int width = 0; + + for (l = g_io_extension_point_get_extensions (ep); l; l = l->next) + { + extension = l->data; + width = MAX (width, strlen (g_io_extension_get_name (extension))); + } + + for (l = g_io_extension_point_get_extensions (ep); l; l = l->next) + { + extension = l->data; + + g_print (" %*s - %d\n", width, g_io_extension_get_name (extension), g_io_extension_get_priority (extension)); + } + } +} + +/** + * _g_io_module_get_default_type: + * @extension_point: the name of an extension point + * @envvar: (nullable): the name of an environment variable to + * override the default implementation. + * @is_supported_offset: a vtable offset, or zero + * + * Retrieves the default class implementing @extension_point. + * + * If @envvar is not %NULL, and the environment variable with that + * name is set, then the implementation it specifies will be tried + * first. After that, or if @envvar is not set, all other + * implementations will be tried in order of decreasing priority. + * + * If @is_supported_offset is non-zero, then it is the offset into the + * class vtable at which there is a function that takes no arguments and + * returns a boolean. This function will be called on each candidate + * implementation to check if it is actually usable or not. + * + * The result is cached after it is generated the first time, and + * the function is thread-safe. + * + * Returns: (transfer none): the type to instantiate to implement + * @extension_point, or %G_TYPE_INVALID if there are no usable + * implementations. + */ +GType +_g_io_module_get_default_type (const gchar *extension_point, + const gchar *envvar, + guint is_supported_offset) +{ + static GRecMutex default_modules_lock; + static GHashTable *default_modules; + const char *use_this; + GList *l; + GIOExtensionPoint *ep; + GIOExtension *extension, *preferred; + gpointer impl; + + g_rec_mutex_lock (&default_modules_lock); + if (default_modules) + { + gpointer key; + + if (g_hash_table_lookup_extended (default_modules, extension_point, &key, &impl)) + { + g_rec_mutex_unlock (&default_modules_lock); + return impl ? G_OBJECT_CLASS_TYPE (impl) : G_TYPE_INVALID; + } + } + else + { + default_modules = g_hash_table_new (g_str_hash, g_str_equal); + } + + _g_io_modules_ensure_loaded (); + ep = g_io_extension_point_lookup (extension_point); + + if (!ep) + { + g_warn_if_reached (); + g_rec_mutex_unlock (&default_modules_lock); + return G_TYPE_INVALID; + } + + use_this = envvar ? g_getenv (envvar) : NULL; + if (g_strcmp0 (use_this, "help") == 0) + { + print_help (envvar, ep); + use_this = NULL; + } + + if (use_this) + { + preferred = g_io_extension_point_get_extension_by_name (ep, use_this); + if (preferred) + { + impl = try_class (preferred, is_supported_offset); + if (impl) + goto done; + } + else + g_warning ("Can't find module '%s' specified in %s", use_this, envvar); + } + else + preferred = NULL; + + for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next) + { + extension = l->data; + if (extension == preferred) + continue; + + impl = try_class (extension, is_supported_offset); + if (impl) + goto done; + } + + impl = NULL; + + done: + g_hash_table_insert (default_modules, g_strdup (extension_point), impl); + g_rec_mutex_unlock (&default_modules_lock); + + return impl ? G_OBJECT_CLASS_TYPE (impl) : G_TYPE_INVALID; +} + +static gpointer +try_implementation (const char *extension_point, + GIOExtension *extension, + GIOModuleVerifyFunc verify_func) +{ + GType type = g_io_extension_get_type (extension); + gpointer impl; + + if (g_type_is_a (type, G_TYPE_INITABLE)) + { + GError *error = NULL; + + impl = g_initable_new (type, NULL, &error, NULL); + if (impl) + return impl; + + g_debug ("Failed to initialize %s (%s) for %s: %s", + g_io_extension_get_name (extension), + g_type_name (type), + extension_point, + error ? error->message : ""); + g_clear_error (&error); + return NULL; + } + else + { + impl = g_object_new (type, NULL); + if (!verify_func || verify_func (impl)) + return impl; + + g_object_unref (impl); + return NULL; + } +} + +/** + * _g_io_module_get_default: + * @extension_point: the name of an extension point + * @envvar: (nullable): the name of an environment variable to + * override the default implementation. + * @verify_func: (nullable): a function to call to verify that + * a given implementation is usable in the current environment. + * + * Retrieves the default object implementing @extension_point. + * + * If @envvar is not %NULL, and the environment variable with that + * name is set, then the implementation it specifies will be tried + * first. After that, or if @envvar is not set, all other + * implementations will be tried in order of decreasing priority. + * + * If an extension point implementation implements #GInitable, then + * that implementation will only be used if it initializes + * successfully. Otherwise, if @verify_func is not %NULL, then it will + * be called on each candidate implementation after construction, to + * check if it is actually usable or not. + * + * The result is cached after it is generated the first time, and + * the function is thread-safe. + * + * Returns: (transfer none): an object implementing + * @extension_point, or %NULL if there are no usable + * implementations. + */ +gpointer +_g_io_module_get_default (const gchar *extension_point, + const gchar *envvar, + GIOModuleVerifyFunc verify_func) +{ + static GRecMutex default_modules_lock; + static GHashTable *default_modules; + const char *use_this; + GList *l; + GIOExtensionPoint *ep; + GIOExtension *extension = NULL, *preferred; + gpointer impl; + + g_rec_mutex_lock (&default_modules_lock); + if (default_modules) + { + gpointer key; + + if (g_hash_table_lookup_extended (default_modules, extension_point, + &key, &impl)) + { + /* Don’t debug here, since we’re returning a cached object which was + * already printed earlier. */ + g_rec_mutex_unlock (&default_modules_lock); + return impl; + } + } + else + { + default_modules = g_hash_table_new (g_str_hash, g_str_equal); + } + + _g_io_modules_ensure_loaded (); + ep = g_io_extension_point_lookup (extension_point); + + if (!ep) + { + g_debug ("%s: Failed to find extension point ‘%s’", + G_STRFUNC, extension_point); + g_warn_if_reached (); + g_rec_mutex_unlock (&default_modules_lock); + return NULL; + } + + use_this = envvar ? g_getenv (envvar) : NULL; + if (g_strcmp0 (use_this, "help") == 0) + { + print_help (envvar, ep); + use_this = NULL; + } + + if (use_this) + { + preferred = g_io_extension_point_get_extension_by_name (ep, use_this); + if (preferred) + { + impl = try_implementation (extension_point, preferred, verify_func); + extension = preferred; + if (impl) + goto done; + } + else + g_warning ("Can't find module '%s' specified in %s", use_this, envvar); + } + else + preferred = NULL; + + for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next) + { + extension = l->data; + if (extension == preferred) + continue; + + impl = try_implementation (extension_point, extension, verify_func); + if (impl) + goto done; + } + + impl = NULL; + + done: + g_hash_table_insert (default_modules, + g_strdup (extension_point), + impl ? g_object_ref (impl) : NULL); + g_rec_mutex_unlock (&default_modules_lock); + + if (impl != NULL) + { + g_assert (extension != NULL); + g_debug ("%s: Found default implementation %s (%s) for ‘%s’", + G_STRFUNC, g_io_extension_get_name (extension), + G_OBJECT_TYPE_NAME (impl), extension_point); + } + else + g_debug ("%s: Failed to find default implementation for ‘%s’", + G_STRFUNC, extension_point); + + return impl; +} + +G_LOCK_DEFINE_STATIC (registered_extensions); +G_LOCK_DEFINE_STATIC (loaded_dirs); + +extern GType g_fen_file_monitor_get_type (void); +extern GType g_inotify_file_monitor_get_type (void); +extern GType g_kqueue_file_monitor_get_type (void); +extern GType g_win32_file_monitor_get_type (void); + +extern GType _g_unix_volume_monitor_get_type (void); +extern GType _g_local_vfs_get_type (void); + +extern GType _g_win32_volume_monitor_get_type (void); +extern GType _g_winhttp_vfs_get_type (void); + +extern GType _g_dummy_proxy_resolver_get_type (void); +extern GType _g_dummy_tls_backend_get_type (void); +extern GType g_network_monitor_base_get_type (void); +#ifdef HAVE_NETLINK +extern GType _g_network_monitor_netlink_get_type (void); +extern GType _g_network_monitor_nm_get_type (void); +#endif + +#ifdef G_OS_UNIX +extern GType g_fdo_notification_backend_get_type (void); +extern GType g_gtk_notification_backend_get_type (void); +extern GType g_portal_notification_backend_get_type (void); +extern GType g_proxy_resolver_portal_get_type (void); +extern GType g_network_monitor_portal_get_type (void); +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 +extern GType g_cocoa_notification_backend_get_type (void); +#endif + +#ifdef G_PLATFORM_WIN32 +extern GType g_win32_notification_backend_get_type (void); + +#include +extern GType _g_win32_network_monitor_get_type (void); + +static HMODULE gio_dll = NULL; + +#ifdef DLL_EXPORT + +BOOL WINAPI DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved); + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_ATTACH) + gio_dll = hinstDLL; + + return TRUE; +} + +#endif + +void * +_g_io_win32_get_module (void) +{ + if (!gio_dll) + GetModuleHandleExA (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (const char *) _g_io_win32_get_module, + &gio_dll); + return gio_dll; +} + +#endif + +void +_g_io_modules_ensure_extension_points_registered (void) +{ + static gboolean registered_extensions = FALSE; + GIOExtensionPoint *ep; + + G_LOCK (registered_extensions); + + if (!registered_extensions) + { + registered_extensions = TRUE; + +#if defined(G_OS_UNIX) && !defined(HAVE_COCOA) +#if !GLIB_CHECK_VERSION (3, 0, 0) + ep = g_io_extension_point_register (G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_io_extension_point_set_required_type (ep, G_TYPE_DESKTOP_APP_INFO_LOOKUP); + G_GNUC_END_IGNORE_DEPRECATIONS +#endif +#endif + + ep = g_io_extension_point_register (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR); + + ep = g_io_extension_point_register (G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR); + + ep = g_io_extension_point_register (G_VOLUME_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_VOLUME_MONITOR); + + ep = g_io_extension_point_register (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_NATIVE_VOLUME_MONITOR); + + ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_VFS); + + ep = g_io_extension_point_register ("gsettings-backend"); + g_io_extension_point_set_required_type (ep, G_TYPE_OBJECT); + + ep = g_io_extension_point_register (G_PROXY_RESOLVER_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_PROXY_RESOLVER); + + ep = g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_PROXY); + + ep = g_io_extension_point_register (G_TLS_BACKEND_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_TLS_BACKEND); + + ep = g_io_extension_point_register (G_NETWORK_MONITOR_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_NETWORK_MONITOR); + + ep = g_io_extension_point_register (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME); + g_io_extension_point_set_required_type (ep, G_TYPE_NOTIFICATION_BACKEND); + } + + G_UNLOCK (registered_extensions); +} + +static gchar * +get_gio_module_dir (void) +{ + gchar *module_dir; + + module_dir = g_strdup (g_getenv ("GIO_MODULE_DIR")); + if (module_dir == NULL) + { +#ifdef G_OS_WIN32 + gchar *install_dir; + + install_dir = g_win32_get_package_installation_directory_of_module (gio_dll); +#ifdef _MSC_VER + /* On Visual Studio builds we have all the libraries and binaries in bin + * so better load the gio modules from bin instead of lib + */ + module_dir = g_build_filename (install_dir, + "bin", "gio", "modules", + NULL); +#else + module_dir = g_build_filename (install_dir, + "lib", "gio", "modules", + NULL); +#endif + g_free (install_dir); +#else + module_dir = g_strdup (GIO_MODULE_DIR); +#endif + } + + return module_dir; +} + +void +_g_io_modules_ensure_loaded (void) +{ + static gboolean loaded_dirs = FALSE; + const char *module_path; + GIOModuleScope *scope; + + _g_io_modules_ensure_extension_points_registered (); + + G_LOCK (loaded_dirs); + + if (!loaded_dirs) + { + gchar *module_dir; + + loaded_dirs = TRUE; + scope = g_io_module_scope_new (G_IO_MODULE_SCOPE_BLOCK_DUPLICATES); + + /* First load any overrides, extras */ + module_path = g_getenv ("GIO_EXTRA_MODULES"); + if (module_path) + { + gchar **paths; + int i; + + paths = g_strsplit (module_path, G_SEARCHPATH_SEPARATOR_S, 0); + + for (i = 0; paths[i] != NULL; i++) + { + g_io_modules_scan_all_in_directory_with_scope (paths[i], scope); + } + + g_strfreev (paths); + } + + /* Then load the compiled in path */ + module_dir = get_gio_module_dir (); + + g_io_modules_scan_all_in_directory_with_scope (module_dir, scope); + g_free (module_dir); + + g_io_module_scope_free (scope); + + /* Initialize types from built-in "modules" */ + g_type_ensure (g_null_settings_backend_get_type ()); + g_type_ensure (g_memory_settings_backend_get_type ()); +#if defined(HAVE_INOTIFY_INIT1) + g_type_ensure (g_inotify_file_monitor_get_type ()); +#endif +#if defined(HAVE_KQUEUE) + g_type_ensure (g_kqueue_file_monitor_get_type ()); +#endif +#if defined(HAVE_FEN) + g_type_ensure (g_fen_file_monitor_get_type ()); +#endif +#ifdef G_OS_WIN32 + g_type_ensure (_g_win32_volume_monitor_get_type ()); + g_type_ensure (g_win32_file_monitor_get_type ()); + g_type_ensure (g_registry_backend_get_type ()); +#endif +#ifdef HAVE_COCOA + g_type_ensure (g_nextstep_settings_backend_get_type ()); + g_type_ensure (g_osx_app_info_get_type ()); +#endif +#ifdef G_OS_UNIX + g_type_ensure (_g_unix_volume_monitor_get_type ()); + g_type_ensure (g_fdo_notification_backend_get_type ()); + g_type_ensure (g_gtk_notification_backend_get_type ()); + g_type_ensure (g_portal_notification_backend_get_type ()); + g_type_ensure (g_network_monitor_portal_get_type ()); + g_type_ensure (g_proxy_resolver_portal_get_type ()); +#endif +#if HAVE_MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + g_type_ensure (g_cocoa_notification_backend_get_type ()); +#endif +#ifdef G_OS_WIN32 + g_type_ensure (g_win32_notification_backend_get_type ()); + g_type_ensure (_g_winhttp_vfs_get_type ()); +#endif + g_type_ensure (_g_local_vfs_get_type ()); + g_type_ensure (_g_dummy_proxy_resolver_get_type ()); + g_type_ensure (_g_http_proxy_get_type ()); + g_type_ensure (_g_https_proxy_get_type ()); + g_type_ensure (_g_socks4a_proxy_get_type ()); + g_type_ensure (_g_socks4_proxy_get_type ()); + g_type_ensure (_g_socks5_proxy_get_type ()); + g_type_ensure (_g_dummy_tls_backend_get_type ()); + g_type_ensure (g_network_monitor_base_get_type ()); +#ifdef HAVE_NETLINK + g_type_ensure (_g_network_monitor_netlink_get_type ()); + g_type_ensure (_g_network_monitor_nm_get_type ()); +#endif +#ifdef G_OS_WIN32 + g_type_ensure (_g_win32_network_monitor_get_type ()); +#endif + } + + G_UNLOCK (loaded_dirs); +} + +static void +g_io_extension_point_free (GIOExtensionPoint *ep) +{ + g_free (ep->name); + g_free (ep); +} + +/** + * g_io_extension_point_register: + * @name: The name of the extension point + * + * Registers an extension point. + * + * Returns: (transfer none): the new #GIOExtensionPoint. This object is + * owned by GIO and should not be freed. + */ +GIOExtensionPoint * +g_io_extension_point_register (const char *name) +{ + GIOExtensionPoint *ep; + + G_LOCK (extension_points); + if (extension_points == NULL) + extension_points = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify)g_io_extension_point_free); + + ep = g_hash_table_lookup (extension_points, name); + if (ep != NULL) + { + G_UNLOCK (extension_points); + return ep; + } + + ep = g_new0 (GIOExtensionPoint, 1); + ep->name = g_strdup (name); + + g_hash_table_insert (extension_points, ep->name, ep); + + G_UNLOCK (extension_points); + + return ep; +} + +/** + * g_io_extension_point_lookup: + * @name: the name of the extension point + * + * Looks up an existing extension point. + * + * Returns: (transfer none): the #GIOExtensionPoint, or %NULL if there + * is no registered extension point with the given name. + */ +GIOExtensionPoint * +g_io_extension_point_lookup (const char *name) +{ + GIOExtensionPoint *ep; + + G_LOCK (extension_points); + ep = NULL; + if (extension_points != NULL) + ep = g_hash_table_lookup (extension_points, name); + + G_UNLOCK (extension_points); + + return ep; + +} + +/** + * g_io_extension_point_set_required_type: + * @extension_point: a #GIOExtensionPoint + * @type: the #GType to require + * + * Sets the required type for @extension_point to @type. + * All implementations must henceforth have this type. + */ +void +g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point, + GType type) +{ + extension_point->required_type = type; +} + +/** + * g_io_extension_point_get_required_type: + * @extension_point: a #GIOExtensionPoint + * + * Gets the required type for @extension_point. + * + * Returns: the #GType that all implementations must have, + * or #G_TYPE_INVALID if the extension point has no required type + */ +GType +g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point) +{ + return extension_point->required_type; +} + +static void +lazy_load_modules (GIOExtensionPoint *extension_point) +{ + GIOModule *module; + GList *l; + + for (l = extension_point->lazy_load_modules; l != NULL; l = l->next) + { + module = l->data; + + if (!module->initialized) + { + if (g_type_module_use (G_TYPE_MODULE (module))) + g_type_module_unuse (G_TYPE_MODULE (module)); /* Unload */ + else + g_printerr ("Failed to load module: %s\n", + module->filename); + } + } +} + +/** + * g_io_extension_point_get_extensions: + * @extension_point: a #GIOExtensionPoint + * + * Gets a list of all extensions that implement this extension point. + * The list is sorted by priority, beginning with the highest priority. + * + * Returns: (element-type GIOExtension) (transfer none): a #GList of + * #GIOExtensions. The list is owned by GIO and should not be + * modified. + */ +GList * +g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point) +{ + g_return_val_if_fail (extension_point != NULL, NULL); + + lazy_load_modules (extension_point); + return extension_point->extensions; +} + +/** + * g_io_extension_point_get_extension_by_name: + * @extension_point: a #GIOExtensionPoint + * @name: the name of the extension to get + * + * Finds a #GIOExtension for an extension point by name. + * + * Returns: (transfer none): the #GIOExtension for @extension_point that has the + * given name, or %NULL if there is no extension with that name + */ +GIOExtension * +g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point, + const char *name) +{ + GList *l; + + g_return_val_if_fail (name != NULL, NULL); + + lazy_load_modules (extension_point); + for (l = extension_point->extensions; l != NULL; l = l->next) + { + GIOExtension *e = l->data; + + if (e->name != NULL && + strcmp (e->name, name) == 0) + return e; + } + + return NULL; +} + +static gint +extension_prio_compare (gconstpointer a, + gconstpointer b) +{ + const GIOExtension *extension_a = a, *extension_b = b; + + if (extension_a->priority > extension_b->priority) + return -1; + + if (extension_b->priority > extension_a->priority) + return 1; + + return 0; +} + +/** + * g_io_extension_point_implement: + * @extension_point_name: the name of the extension point + * @type: the #GType to register as extension + * @extension_name: the name for the extension + * @priority: the priority for the extension + * + * Registers @type as extension for the extension point with name + * @extension_point_name. + * + * If @type has already been registered as an extension for this + * extension point, the existing #GIOExtension object is returned. + * + * Returns: (transfer none): a #GIOExtension object for #GType + */ +GIOExtension * +g_io_extension_point_implement (const char *extension_point_name, + GType type, + const char *extension_name, + gint priority) +{ + GIOExtensionPoint *extension_point; + GIOExtension *extension; + GList *l; + + g_return_val_if_fail (extension_point_name != NULL, NULL); + + extension_point = g_io_extension_point_lookup (extension_point_name); + if (extension_point == NULL) + { + g_warning ("Tried to implement non-registered extension point %s", extension_point_name); + return NULL; + } + + if (extension_point->required_type != 0 && + !g_type_is_a (type, extension_point->required_type)) + { + g_warning ("Tried to register an extension of the type %s to extension point %s. " + "Expected type is %s.", + g_type_name (type), + extension_point_name, + g_type_name (extension_point->required_type)); + return NULL; + } + + /* It's safe to register the same type multiple times */ + for (l = extension_point->extensions; l != NULL; l = l->next) + { + extension = l->data; + if (extension->type == type) + return extension; + } + + extension = g_slice_new0 (GIOExtension); + extension->type = type; + extension->name = g_strdup (extension_name); + extension->priority = priority; + + extension_point->extensions = g_list_insert_sorted (extension_point->extensions, + extension, extension_prio_compare); + + return extension; +} + +/** + * g_io_extension_ref_class: + * @extension: a #GIOExtension + * + * Gets a reference to the class for the type that is + * associated with @extension. + * + * Returns: (transfer full): the #GTypeClass for the type of @extension + */ +GTypeClass * +g_io_extension_ref_class (GIOExtension *extension) +{ + return g_type_class_ref (extension->type); +} + +/** + * g_io_extension_get_type: + * @extension: a #GIOExtension + * + * Gets the type associated with @extension. + * + * Returns: the type of @extension + */ +GType +g_io_extension_get_type (GIOExtension *extension) +{ + return extension->type; +} + +/** + * g_io_extension_get_name: + * @extension: a #GIOExtension + * + * Gets the name under which @extension was registered. + * + * Note that the same type may be registered as extension + * for multiple extension points, under different names. + * + * Returns: the name of @extension. + */ +const char * +g_io_extension_get_name (GIOExtension *extension) +{ + return extension->name; +} + +/** + * g_io_extension_get_priority: + * @extension: a #GIOExtension + * + * Gets the priority with which @extension was registered. + * + * Returns: the priority of @extension + */ +gint +g_io_extension_get_priority (GIOExtension *extension) +{ + return extension->priority; +} diff -Nru glib2.0-2.59.2/.pc/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch/tests/refcount/closures.c glib2.0-2.59.3/.pc/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch/tests/refcount/closures.c --- glib2.0-2.59.2/.pc/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch/tests/refcount/closures.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/closures-test-Skip-on-arm-unless-flaky-tests-are-allowed.patch/tests/refcount/closures.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,297 @@ +/* Copyright (C) 2005 Imendio AB + * + * This software is provided "as is"; redistribution and modification + * is permitted, provided that the following disclaimer is retained. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#include + +#ifdef G_OS_UNIX +#include +#endif + +#define TEST_POINTER1 ((gpointer) 47) +#define TEST_POINTER2 ((gpointer) 49) +#define TEST_INT1 (-77) +#define TEST_INT2 (78) + +/* --- GTest class --- */ +typedef struct { + GObject object; + gint value; + gpointer test_pointer1; + gpointer test_pointer2; +} GTest; +typedef struct { + GObjectClass parent_class; + void (*test_signal1) (GTest * test, gint an_int); + void (*test_signal2) (GTest * test, gint an_int); +} GTestClass; + +#define G_TYPE_TEST (my_test_get_type ()) +#define MY_TEST(test) (G_TYPE_CHECK_INSTANCE_CAST ((test), G_TYPE_TEST, GTest)) +#define MY_IS_TEST(test) (G_TYPE_CHECK_INSTANCE_TYPE ((test), G_TYPE_TEST)) +#define MY_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_CAST ((tclass), G_TYPE_TEST, GTestClass)) +#define MY_IS_TEST_CLASS(tclass) (G_TYPE_CHECK_CLASS_TYPE ((tclass), G_TYPE_TEST)) +#define MY_TEST_GET_CLASS(test) (G_TYPE_INSTANCE_GET_CLASS ((test), G_TYPE_TEST, GTestClass)) + +static GType my_test_get_type (void); +G_DEFINE_TYPE (GTest, my_test, G_TYPE_OBJECT) + +/* --- variables --- */ +static volatile gboolean stopping = FALSE; +static guint test_signal1 = 0; +static guint test_signal2 = 0; +static gboolean seen_signal_handler = FALSE; +static gboolean seen_cleanup = FALSE; +static gboolean seen_test_int1 = FALSE; +static gboolean seen_test_int2 = FALSE; +static gboolean seen_thread1 = FALSE; +static gboolean seen_thread2 = FALSE; + +/* --- functions --- */ +static void +my_test_init (GTest * test) +{ + g_print ("init %p\n", test); + + test->value = 0; + test->test_pointer1 = TEST_POINTER1; + test->test_pointer2 = TEST_POINTER2; +} + +enum { + ARG_0, + ARG_TEST_PROP +}; + +static void +my_test_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GTest *test = MY_TEST (object); + switch (prop_id) + { + case ARG_TEST_PROP: + test->value = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GTest *test = MY_TEST (object); + switch (prop_id) + { + case ARG_TEST_PROP: + g_value_set_int (value, test->value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +my_test_test_signal2 (GTest *test, + gint an_int) +{ +} + +static void +my_test_emit_test_signal1 (GTest *test, + gint vint) +{ + g_signal_emit (G_OBJECT (test), test_signal1, 0, vint); +} + +static void +my_test_emit_test_signal2 (GTest *test, + gint vint) +{ + g_signal_emit (G_OBJECT (test), test_signal2, 0, vint); +} + +static void +my_test_class_init (GTestClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = my_test_set_property; + gobject_class->get_property = my_test_get_property; + + test_signal1 = g_signal_new ("test-signal1", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GTestClass, test_signal1), NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + test_signal2 = g_signal_new ("test-signal2", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GTestClass, test_signal2), NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TEST_PROP, + g_param_spec_int ("test-prop", "Test Prop", "Test property", + 0, 1, 0, G_PARAM_READWRITE)); + klass->test_signal2 = my_test_test_signal2; +} + +static void +test_closure (GClosure *closure) +{ + /* try to produce high contention in closure->ref_count */ + guint i = 0, n = g_random_int () % 199; + for (i = 0; i < n; i++) + g_closure_ref (closure); + g_closure_sink (closure); /* NOP */ + for (i = 0; i < n; i++) + g_closure_unref (closure); +} + +static gpointer +thread1_main (gpointer data) +{ + GClosure *closure = data; + while (!stopping) + { + static guint count = 0; + test_closure (closure); + if (++count % 10000 == 0) + { + g_printerr ("c"); + g_thread_yield(); /* force context switch */ + seen_thread1 = TRUE; + } + } + return NULL; +} + +static gpointer +thread2_main (gpointer data) +{ + GClosure *closure = data; + while (!stopping) + { + static guint count = 0; + test_closure (closure); + if (++count % 10000 == 0) + { + g_printerr ("C"); + g_thread_yield(); /* force context switch */ + seen_thread2 = TRUE; + } + } + return NULL; +} + +static void +test_signal_handler (GTest *test, + gint vint, + gpointer data) +{ + g_assert (data == TEST_POINTER2); + g_assert (test->test_pointer1 == TEST_POINTER1); + seen_signal_handler = TRUE; + seen_test_int1 |= vint == TEST_INT1; + seen_test_int2 |= vint == TEST_INT2; +} + +static void +destroy_data (gpointer data, + GClosure *closure) +{ + seen_cleanup = data == TEST_POINTER2; + g_assert (closure->ref_count == 0); +} + +static void +test_emissions (GTest *test) +{ + my_test_emit_test_signal1 (test, TEST_INT1); + my_test_emit_test_signal2 (test, TEST_INT2); +} + +int +main (int argc, + char **argv) +{ + GThread *thread1, *thread2; + GClosure *closure; + GTest *object; + guint i; + + g_print ("START: %s\n", argv[0]); + g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); + + object = g_object_new (G_TYPE_TEST, NULL); + closure = g_cclosure_new (G_CALLBACK (test_signal_handler), TEST_POINTER2, destroy_data); + + g_signal_connect_closure (object, "test-signal1", closure, FALSE); + g_signal_connect_closure (object, "test-signal2", closure, FALSE); + + stopping = FALSE; + + thread1 = g_thread_create (thread1_main, closure, TRUE, NULL); + thread2 = g_thread_create (thread2_main, closure, TRUE, NULL); + + /* The 16-bit compare-and-swap operations currently used for closure + * refcounts are really slow on some ARM CPUs, notably Cortex-A57. + * Reduce the number of iterations so that the test completes in a + * finite time, but don't reduce it so much that the main thread + * starves the other threads and causes a test failure. + * + * https://gitlab.gnome.org/GNOME/glib/issues/1316 + * aka https://bugs.debian.org/880883 */ +#if defined(__aarch64__) || defined(__arm__) + for (i = 0; i < 100000; i++) +#else + for (i = 0; i < 1000000; i++) +#endif + { + static guint count = 0; + test_emissions (object); + if (++count % 10000 == 0) + { + g_printerr (".\n"); + g_thread_yield(); /* force context switch */ + } + } + + stopping = TRUE; + g_print ("\nstopping\n"); + + /* wait for thread shutdown */ + g_thread_join (thread1); + g_thread_join (thread2); + + /* finalize object, destroy signals, run cleanup code */ + g_object_unref (object); + + g_print ("stopped\n"); + + g_assert (seen_thread1 != FALSE); + g_assert (seen_thread2 != FALSE); + g_assert (seen_test_int1 != FALSE); + g_assert (seen_test_int2 != FALSE); + g_assert (seen_signal_handler != FALSE); + g_assert (seen_cleanup != FALSE); + + return 0; +} diff -Nru glib2.0-2.59.2/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/gio/tests/socket.c glib2.0-2.59.3/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/gio/tests/socket.c --- glib2.0-2.59.2/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/gio/tests/socket.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/gio/tests/socket.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,1919 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + */ + +#include + +#ifdef G_OS_UNIX +#include +#include +#include +#include +#include +#include +#endif + +#include "gnetworkingprivate.h" + +static gboolean ipv6_supported; + +typedef struct { + GSocket *server; + GSocket *client; + GSocketFamily family; + GThread *thread; + GMainLoop *loop; + GCancellable *cancellable; /* to shut down dgram echo server thread */ +} IPTestData; + +static gpointer +echo_server_dgram_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocketAddress *sa; + GCancellable *cancellable = data->cancellable; + GSocket *sock; + GError *error = NULL; + gssize nread, nwrote; + gchar buf[128]; + + sock = data->server; + + while (TRUE) + { + nread = g_socket_receive_from (sock, &sa, buf, sizeof (buf), cancellable, &error); + if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + break; + g_assert_no_error (error); + g_assert_cmpint (nread, >=, 0); + + nwrote = g_socket_send_to (sock, sa, buf, nread, cancellable, &error); + if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + break; + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, nread); + + g_object_unref (sa); + } + + g_clear_error (&error); + + return NULL; +} + +static gpointer +echo_server_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocket *sock; + GError *error = NULL; + gssize nread, nwrote; + gchar buf[128]; + + sock = g_socket_accept (data->server, NULL, &error); + g_assert_no_error (error); + + while (TRUE) + { + nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nread, >=, 0); + + if (nread == 0) + break; + + nwrote = g_socket_send (sock, buf, nread, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (nwrote, ==, nread); + } + + g_socket_close (sock, &error); + g_assert_no_error (error); + g_object_unref (sock); + return NULL; +} + +static IPTestData * +create_server_full (GSocketFamily family, + GSocketType socket_type, + GThreadFunc server_thread, + gboolean v4mapped, + GError **error) +{ + IPTestData *data; + GSocket *server; + GSocketAddress *addr; + GInetAddress *iaddr; + + data = g_slice_new (IPTestData); + data->family = family; + + data->server = server = g_socket_new (family, + socket_type, + G_SOCKET_PROTOCOL_DEFAULT, + error); + if (server == NULL) + goto error; + + g_assert_cmpint (g_socket_get_family (server), ==, family); + g_assert_cmpint (g_socket_get_socket_type (server), ==, socket_type); + g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (server, TRUE); + +#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY) + if (v4mapped) + { + g_socket_set_option (data->server, IPPROTO_IPV6, IPV6_V6ONLY, FALSE, NULL); + if (!g_socket_speaks_ipv4 (data->server)) + goto error; + } +#endif + + if (v4mapped) + iaddr = g_inet_address_new_any (family); + else + iaddr = g_inet_address_new_loopback (family); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), ==, 0); + if (!g_socket_bind (server, addr, TRUE, error)) + { + g_object_unref (addr); + goto error; + } + g_object_unref (addr); + + addr = g_socket_get_local_address (server, error); + if (addr == NULL) + goto error; + g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), !=, 0); + g_object_unref (addr); + + if (socket_type == G_SOCKET_TYPE_STREAM) + { + if (!g_socket_listen (server, error)) + goto error; + } + else + { + data->cancellable = g_cancellable_new (); + } + + data->thread = g_thread_new ("server", server_thread, data); + + return data; + +error: + g_clear_object (&data->server); + g_slice_free (IPTestData, data); + + return NULL; +} + +static IPTestData * +create_server (GSocketFamily family, + GThreadFunc server_thread, + gboolean v4mapped, + GError **error) +{ + return create_server_full (family, G_SOCKET_TYPE_STREAM, server_thread, v4mapped, error); +} + +static const gchar *testbuf = "0123456789abcdef"; + +static gboolean +test_ip_async_read_ready (GSocket *client, + GIOCondition cond, + gpointer user_data) +{ + IPTestData *data = user_data; + GError *error = NULL; + gssize len; + gchar buf[128]; + + g_assert_cmpint (cond, ==, G_IO_IN); + + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + g_assert_cmpstr (testbuf, ==, buf); + + g_main_loop_quit (data->loop); + + return FALSE; +} + +static gboolean +test_ip_async_write_ready (GSocket *client, + GIOCondition cond, + gpointer user_data) +{ + IPTestData *data = user_data; + GError *error = NULL; + GSource *source; + gssize len; + + g_assert_cmpint (cond, ==, G_IO_OUT); + + len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + source = g_socket_create_source (client, G_IO_IN, NULL); + g_source_set_callback (source, (GSourceFunc)test_ip_async_read_ready, + data, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + + return FALSE; +} + +static gboolean +test_ip_async_timed_out (GSocket *client, + GIOCondition cond, + gpointer user_data) +{ + IPTestData *data = user_data; + GError *error = NULL; + GSource *source; + gssize len; + gchar buf[128]; + + if (data->family == G_SOCKET_FAMILY_IPV4) + { + g_assert_cmpint (cond, ==, G_IO_IN); + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_cmpint (len, ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_clear_error (&error); + } + + source = g_socket_create_source (client, G_IO_OUT, NULL); + g_source_set_callback (source, (GSourceFunc)test_ip_async_write_ready, + data, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + + return FALSE; +} + +static gboolean +test_ip_async_connected (GSocket *client, + GIOCondition cond, + gpointer user_data) +{ + IPTestData *data = user_data; + GError *error = NULL; + GSource *source; + gssize len; + gchar buf[128]; + + g_socket_check_connect_result (client, &error); + g_assert_no_error (error); + /* We do this after the check_connect_result, since that will give a + * more useful assertion in case of error. + */ + g_assert_cmpint (cond, ==, G_IO_OUT); + + g_assert (g_socket_is_connected (client)); + + /* This adds 1 second to "make check", so let's just only do it once. */ + if (data->family == G_SOCKET_FAMILY_IPV4) + { + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_cmpint (len, ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_clear_error (&error); + + source = g_socket_create_source (client, G_IO_IN, NULL); + g_source_set_callback (source, (GSourceFunc)test_ip_async_timed_out, + data, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + } + else + test_ip_async_timed_out (client, 0, data); + + return FALSE; +} + +static gboolean +idle_test_ip_async_connected (gpointer user_data) +{ + IPTestData *data = user_data; + + return test_ip_async_connected (data->client, G_IO_OUT, data); +} + +static void +test_ip_async (GSocketFamily family) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr; + GSource *source; + gssize len; + gchar buf[128]; + + data = create_server (family, echo_server_thread, FALSE, &error); + if (error != NULL) + { + gchar *message = g_strdup_printf ("Failed to create server: %s", error->message); + g_test_skip (message); + g_free (message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + data->client = client; + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (client, FALSE); + g_socket_set_timeout (client, 1); + + if (g_socket_connect (client, addr, NULL, &error)) + { + g_assert_no_error (error); + g_idle_add (idle_test_ip_async_connected, data); + } + else + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING); + g_clear_error (&error); + source = g_socket_create_source (client, G_IO_OUT, NULL); + g_source_set_callback (source, (GSourceFunc)test_ip_async_connected, + data, NULL); + g_source_attach (source, NULL); + g_source_unref (source); + } + g_object_unref (addr); + + data->loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (data->loop); + g_main_loop_unref (data->loop); + + g_socket_shutdown (client, FALSE, TRUE, &error); + g_assert_no_error (error); + + g_thread_join (data->thread); + + if (family == G_SOCKET_FAMILY_IPV4) + { + /* Test that reading on a remote-closed socket gets back 0 bytes. */ + len = g_socket_receive_with_blocking (client, buf, sizeof (buf), + TRUE, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 0); + } + else + { + /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */ + len = g_socket_send_with_blocking (client, testbuf, strlen (testbuf) + 1, + TRUE, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED); + g_assert_cmpint (len, ==, -1); + g_clear_error (&error); + } + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +static void +test_ipv4_async (void) +{ + test_ip_async (G_SOCKET_FAMILY_IPV4); +} + +static void +test_ipv6_async (void) +{ + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + test_ip_async (G_SOCKET_FAMILY_IPV6); +} + +static const gchar testbuf2[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + +static void +test_ip_sync (GSocketFamily family) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr; + gssize len; + gchar buf[128]; + + data = create_server (family, echo_server_thread, FALSE, &error); + if (error != NULL) + { + gchar *message = g_strdup_printf ("Failed to create server: %s", error->message); + g_test_skip (message); + g_free (message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_assert (g_socket_is_connected (client)); + g_object_unref (addr); + + /* This adds 1 second to "make check", so let's just only do it once. */ + if (family == G_SOCKET_FAMILY_IPV4) + { + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_cmpint (len, ==, -1); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_clear_error (&error); + } + + len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + g_assert_cmpstr (testbuf, ==, buf); + + { + GOutputVector v[7] = { { NULL, }, }; + + v[0].buffer = testbuf2 + 0; + v[0].size = 3; + v[1].buffer = testbuf2 + 3; + v[1].size = 5; + v[2].buffer = testbuf2 + 3 + 5; + v[2].size = 0; + v[3].buffer = testbuf2 + 3 + 5; + v[3].size = 6; + v[4].buffer = testbuf2 + 3 + 5 + 6; + v[4].size = 2; + v[5].buffer = testbuf2 + 3 + 5 + 6 + 2; + v[5].size = 1; + v[6].buffer = testbuf2 + 3 + 5 + 6 + 2 + 1; + v[6].size = strlen (testbuf2) - (3 + 5 + 6 + 2 + 1); + + len = g_socket_send_message (client, NULL, v, G_N_ELEMENTS (v), NULL, 0, 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf2)); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf2)); + g_assert_cmpstr (testbuf2, ==, buf); + } + + g_socket_shutdown (client, FALSE, TRUE, &error); + g_assert_no_error (error); + + g_thread_join (data->thread); + + if (family == G_SOCKET_FAMILY_IPV4) + { + /* Test that reading on a remote-closed socket gets back 0 bytes. */ + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 0); + } + else + { + /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */ + len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED); + g_assert_cmpint (len, ==, -1); + g_clear_error (&error); + } + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +static void +test_ipv4_sync (void) +{ + test_ip_sync (G_SOCKET_FAMILY_IPV4); +} + +static void +test_ipv6_sync (void) +{ + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + test_ip_sync (G_SOCKET_FAMILY_IPV6); +} + +static void +test_ip_sync_dgram (GSocketFamily family) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *dest_addr; + gssize len; + gchar buf[128]; + + data = create_server_full (family, G_SOCKET_TYPE_DATAGRAM, + echo_server_dgram_thread, FALSE, &error); + if (error != NULL) + { + gchar *message = g_strdup_printf ("Failed to create server: %s", error->message); + g_test_skip (message); + g_free (message); + g_clear_error (&error); + return; + } + + dest_addr = g_socket_get_local_address (data->server, &error); + + client = g_socket_new (family, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + len = g_socket_send_to (client, dest_addr, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + g_assert_cmpstr (testbuf, ==, buf); + + { + GOutputMessage m[3] = { { NULL, }, }; + GInputMessage im[3] = { { NULL, }, }; + GOutputVector v[7] = { { NULL, }, }; + GInputVector iv[7] = { { NULL, }, }; + + v[0].buffer = testbuf2 + 0; + v[0].size = 3; + v[1].buffer = testbuf2 + 3; + v[1].size = 5; + v[2].buffer = testbuf2 + 3 + 5; + v[2].size = 0; + v[3].buffer = testbuf2 + 3 + 5; + v[3].size = 6; + v[4].buffer = testbuf2 + 3 + 5 + 6; + v[4].size = 2; + v[5].buffer = testbuf2 + 3 + 5 + 6 + 2; + v[5].size = 1; + v[6].buffer = testbuf2 + 3 + 5 + 6 + 2 + 1; + v[6].size = strlen (testbuf2) - (3 + 5 + 6 + 2 + 1); + + iv[0].buffer = buf + 0; + iv[0].size = 3; + iv[1].buffer = buf + 3; + iv[1].size = 5; + iv[2].buffer = buf + 3 + 5; + iv[2].size = 0; + iv[3].buffer = buf + 3 + 5; + iv[3].size = 6; + iv[4].buffer = buf + 3 + 5 + 6; + iv[4].size = 2; + iv[5].buffer = buf + 3 + 5 + 6 + 2; + iv[5].size = 1; + iv[6].buffer = buf + 3 + 5 + 6 + 2 + 1; + iv[6].size = sizeof (buf) - (3 + 5 + 6 + 2 + 1); + + len = g_socket_send_message (client, dest_addr, v, G_N_ELEMENTS (v), NULL, 0, 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf2)); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf2)); + g_assert_cmpstr (testbuf2, ==, buf); + + m[0].vectors = &v[0]; + m[0].num_vectors = 1; + m[0].address = dest_addr; + m[1].vectors = &v[0]; + m[1].num_vectors = 6; + m[1].address = dest_addr; + m[2].vectors = &v[6]; + m[2].num_vectors = 1; + m[2].address = dest_addr; + + len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, G_N_ELEMENTS (m)); + g_assert_cmpint (m[0].bytes_sent, ==, 3); + g_assert_cmpint (m[1].bytes_sent, ==, 17); + g_assert_cmpint (m[2].bytes_sent, ==, v[6].size); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 3); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + /* v[0].size + v[1].size + v[2].size + v[3].size + v[4].size + v[5].size */ + g_assert_cmpint (len, ==, 17); + g_assert (memcmp (testbuf2, buf, 17) == 0); + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, v[6].size); + g_assert_cmpstr (buf, ==, v[6].buffer); + + /* reset since we're re-using the message structs */ + m[0].bytes_sent = 0; + m[1].bytes_sent = 0; + m[2].bytes_sent = 0; + + /* now try receiving multiple messages */ + len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, G_N_ELEMENTS (m)); + g_assert_cmpint (m[0].bytes_sent, ==, 3); + g_assert_cmpint (m[1].bytes_sent, ==, 17); + g_assert_cmpint (m[2].bytes_sent, ==, v[6].size); + + im[0].vectors = &iv[0]; + im[0].num_vectors = 1; + im[1].vectors = &iv[0]; + im[1].num_vectors = 6; + im[2].vectors = &iv[6]; + im[2].num_vectors = 1; + + memset (buf, 0, sizeof (buf)); + len = g_socket_receive_messages (client, im, G_N_ELEMENTS (im), 0, + NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, G_N_ELEMENTS (im)); + + g_assert_cmpuint (im[0].bytes_received, ==, 3); + /* v[0].size + v[1].size + v[2].size + v[3].size + v[4].size + v[5].size */ + g_assert_cmpuint (im[1].bytes_received, ==, 17); + g_assert_cmpuint (im[2].bytes_received, ==, v[6].size); + + /* reset since we're re-using the message structs */ + m[0].bytes_sent = 0; + m[1].bytes_sent = 0; + m[2].bytes_sent = 0; + + /* now try to generate an early return by omitting the destination address on [1] */ + m[1].address = NULL; + len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 1); + + g_assert_cmpint (m[0].bytes_sent, ==, 3); + g_assert_cmpint (m[1].bytes_sent, ==, 0); + g_assert_cmpint (m[2].bytes_sent, ==, 0); + + /* reset since we're re-using the message structs */ + m[0].bytes_sent = 0; + m[1].bytes_sent = 0; + m[2].bytes_sent = 0; + + /* now try to generate an error by omitting all destination addresses */ + m[0].address = NULL; + m[1].address = NULL; + m[2].address = NULL; + len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); + g_clear_error (&error); + g_assert_cmpint (len, ==, -1); + + g_assert_cmpint (m[0].bytes_sent, ==, 0); + g_assert_cmpint (m[1].bytes_sent, ==, 0); + g_assert_cmpint (m[2].bytes_sent, ==, 0); + + len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error); + g_assert_cmpint (len, ==, 3); + } + + g_cancellable_cancel (data->cancellable); + + g_thread_join (data->thread); + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (data->cancellable); + g_object_unref (client); + g_object_unref (dest_addr); + + g_slice_free (IPTestData, data); +} + +static void +test_ipv4_sync_dgram (void) +{ + test_ip_sync_dgram (G_SOCKET_FAMILY_IPV4); +} + +static void +test_ipv6_sync_dgram (void) +{ + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + test_ip_sync_dgram (G_SOCKET_FAMILY_IPV6); +} + +static gpointer +cancellable_thread_cb (gpointer data) +{ + GCancellable *cancellable = data; + + g_usleep (0.1 * G_USEC_PER_SEC); + g_cancellable_cancel (cancellable); + g_object_unref (cancellable); + + return NULL; +} + +static void +test_ip_sync_dgram_timeouts (GSocketFamily family) +{ + GError *error = NULL; + GSocket *client = NULL; + GCancellable *cancellable = NULL; + GThread *cancellable_thread = NULL; + gssize len; + + client = g_socket_new (family, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + /* No overall timeout: test the per-operation timeouts instead. */ + g_socket_set_timeout (client, 0); + + cancellable = g_cancellable_new (); + + /* Check for timeouts when no server is running. */ + { + gint64 start_time; + GInputMessage im = { NULL, }; + GInputVector iv = { NULL, }; + guint8 buf[128]; + + iv.buffer = buf; + iv.size = sizeof (buf); + + im.vectors = &iv; + im.num_vectors = 1; + + memset (buf, 0, sizeof (buf)); + + /* Try a non-blocking read. */ + g_socket_set_blocking (client, FALSE); + len = g_socket_receive_messages (client, &im, 1, 0 /* flags */, + NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_assert_cmpint (len, ==, -1); + g_clear_error (&error); + + /* Try a timeout read. Can’t really validate the time taken more than + * checking it’s positive. */ + g_socket_set_timeout (client, 1); + g_socket_set_blocking (client, TRUE); + start_time = g_get_monotonic_time (); + len = g_socket_receive_messages (client, &im, 1, 0 /* flags */, + NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_assert_cmpint (len, ==, -1); + g_assert_cmpint (g_get_monotonic_time () - start_time, >, 0); + g_clear_error (&error); + + /* Try a blocking read, cancelled from another thread. */ + g_socket_set_timeout (client, 0); + cancellable_thread = g_thread_new ("cancellable", + cancellable_thread_cb, + g_object_ref (cancellable)); + + start_time = g_get_monotonic_time (); + len = g_socket_receive_messages (client, &im, 1, 0 /* flags */, + cancellable, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert_cmpint (len, ==, -1); + g_assert_cmpint (g_get_monotonic_time () - start_time, >, 0); + g_clear_error (&error); + + g_thread_join (cancellable_thread); + } + + g_socket_close (client, &error); + g_assert_no_error (error); + + g_object_unref (client); + g_object_unref (cancellable); +} + +static void +test_ipv4_sync_dgram_timeouts (void) +{ + test_ip_sync_dgram_timeouts (G_SOCKET_FAMILY_IPV4); +} + +static void +test_ipv6_sync_dgram_timeouts (void) +{ + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + test_ip_sync_dgram_timeouts (G_SOCKET_FAMILY_IPV6); +} + +static gpointer +graceful_server_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocket *sock; + GError *error = NULL; + gssize len; + + sock = g_socket_accept (data->server, NULL, &error); + g_assert_no_error (error); + + len = g_socket_send (sock, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + return sock; +} + +static void +test_close_graceful (void) +{ + GSocketFamily family = G_SOCKET_FAMILY_IPV4; + IPTestData *data; + GError *error = NULL; + GSocket *client, *server; + GSocketAddress *addr; + gssize len; + gchar buf[128]; + + data = create_server (family, graceful_server_thread, FALSE, &error); + if (error != NULL) + { + gchar *message = g_strdup_printf ("Failed to create server: %s", error->message); + g_test_skip (message); + g_free (message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (family, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client), ==, family); + g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM); + g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_assert (g_socket_is_connected (client)); + g_object_unref (addr); + + server = g_thread_join (data->thread); + + /* similar to g_tcp_connection_set_graceful_disconnect(), but explicit */ + g_socket_shutdown (server, FALSE, TRUE, &error); + g_assert_no_error (error); + + /* we must timeout */ + g_socket_condition_wait (client, G_IO_HUP, NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_clear_error (&error); + + /* check that the remaining data is received */ + len = g_socket_receive (client, buf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + /* and only then the connection is closed */ + len = g_socket_receive (client, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, 0); + + g_socket_close (server, &error); + g_assert_no_error (error); + + g_socket_close (client, &error); + g_assert_no_error (error); + + g_object_unref (server); + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY) +static gpointer +v4mapped_server_thread (gpointer user_data) +{ + IPTestData *data = user_data; + GSocket *sock; + GError *error = NULL; + GSocketAddress *addr; + + sock = g_socket_accept (data->server, NULL, &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (sock), ==, G_SOCKET_FAMILY_IPV6); + + addr = g_socket_get_local_address (sock, &error); + g_assert_no_error (error); + g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4); + g_object_unref (addr); + + addr = g_socket_get_remote_address (sock, &error); + g_assert_no_error (error); + g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4); + g_object_unref (addr); + + g_socket_close (sock, &error); + g_assert_no_error (error); + g_object_unref (sock); + return NULL; +} + +static void +test_ipv6_v4mapped (void) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr, *v4addr; + GInetAddress *iaddr; + + if (!ipv6_supported) + { + g_test_skip ("No support for IPv6"); + return; + } + + data = create_server (G_SOCKET_FAMILY_IPV6, v4mapped_server_thread, TRUE, &error); + if (error != NULL) + { + gchar *message = g_strdup_printf ("Failed to create server: %s", error->message); + g_test_skip (message); + g_free (message); + g_clear_error (&error); + return; + } + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + v4addr = g_inet_socket_address_new (iaddr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr))); + g_object_unref (iaddr); + g_object_unref (addr); + + g_socket_connect (client, v4addr, NULL, &error); + g_assert_no_error (error); + g_assert (g_socket_is_connected (client)); + + g_thread_join (data->thread); + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + g_object_unref (v4addr); + + g_slice_free (IPTestData, data); +} +#endif + +static void +test_timed_wait (void) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocketAddress *addr; + gint64 start_time; + gint poll_duration; + + data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error); + if (error != NULL) + { + gchar *message = g_strdup_printf ("Failed to create server: %s", error->message); + g_test_skip (message); + g_free (message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_object_unref (addr); + + start_time = g_get_monotonic_time (); + g_socket_condition_timed_wait (client, G_IO_IN, 100000 /* 100 ms */, + NULL, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); + g_clear_error (&error); + poll_duration = g_get_monotonic_time () - start_time; + + g_assert_cmpint (poll_duration, >=, 98000); + g_assert_cmpint (poll_duration, <, 112000); + + g_socket_close (client, &error); + g_assert_no_error (error); + + g_thread_join (data->thread); + + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_object_unref (data->server); + g_object_unref (client); + + g_slice_free (IPTestData, data); +} + +static int +duplicate_fd (int fd) +{ +#ifdef G_OS_WIN32 + HANDLE newfd; + + if (!DuplicateHandle (GetCurrentProcess (), + (HANDLE)fd, + GetCurrentProcess (), + &newfd, + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) + { + return -1; + } + + return (int)newfd; +#else + return dup (fd); +#endif +} + +static void +test_fd_reuse (void) +{ + IPTestData *data; + GError *error = NULL; + GSocket *client; + GSocket *client2; + GSocketAddress *addr; + int fd; + gssize len; + gchar buf[128]; + + g_test_bug ("741707"); + + data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error); + if (error != NULL) + { + gchar *message = g_strdup_printf ("Failed to create server: %s", error->message); + g_test_skip (message); + g_free (message); + g_clear_error (&error); + return; + } + + addr = g_socket_get_local_address (data->server, &error); + g_assert_no_error (error); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + g_socket_set_blocking (client, TRUE); + g_socket_set_timeout (client, 1); + + g_socket_connect (client, addr, NULL, &error); + g_assert_no_error (error); + g_assert (g_socket_is_connected (client)); + g_object_unref (addr); + + /* we have to dup otherwise the fd gets closed twice on unref */ + fd = duplicate_fd (g_socket_get_fd (client)); + client2 = g_socket_new_from_fd (fd, &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_family (client2), ==, g_socket_get_family (client)); + g_assert_cmpint (g_socket_get_socket_type (client2), ==, g_socket_get_socket_type (client)); + g_assert_cmpint (g_socket_get_protocol (client2), ==, G_SOCKET_PROTOCOL_TCP); + + len = g_socket_send (client2, testbuf, strlen (testbuf) + 1, NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + len = g_socket_receive (client2, buf, sizeof (buf), NULL, &error); + g_assert_no_error (error); + g_assert_cmpint (len, ==, strlen (testbuf) + 1); + + g_assert_cmpstr (testbuf, ==, buf); + + g_socket_shutdown (client, FALSE, TRUE, &error); + g_assert_no_error (error); + /* The semantics of dup()+shutdown() are ambiguous; this call will succeed + * on Linux, but return ENOTCONN on OS X. + */ + g_socket_shutdown (client2, FALSE, TRUE, NULL); + + g_thread_join (data->thread); + + g_socket_close (client, &error); + g_assert_no_error (error); + g_socket_close (client2, &error); + g_assert_no_error (error); + g_socket_close (data->server, &error); + g_assert_no_error (error); + + g_assert_cmpint (g_socket_get_fd (client), ==, -1); + g_assert_cmpint (g_socket_get_fd (client2), ==, -1); + g_assert_cmpint (g_socket_get_fd (data->server), ==, -1); + + g_object_unref (data->server); + g_object_unref (client); + g_object_unref (client2); + + g_slice_free (IPTestData, data); +} + +static void +test_sockaddr (void) +{ + struct sockaddr_in6 sin6, gsin6; + GSocketAddress *saddr; + GInetSocketAddress *isaddr; + GInetAddress *iaddr; + GError *error = NULL; + + memset (&sin6, 0, sizeof (sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = in6addr_loopback; + sin6.sin6_port = g_htons (42); + sin6.sin6_scope_id = 17; + sin6.sin6_flowinfo = 1729; + + saddr = g_socket_address_new_from_native (&sin6, sizeof (sin6)); + g_assert (G_IS_INET_SOCKET_ADDRESS (saddr)); + + isaddr = G_INET_SOCKET_ADDRESS (saddr); + iaddr = g_inet_socket_address_get_address (isaddr); + g_assert_cmpint (g_inet_address_get_family (iaddr), ==, G_SOCKET_FAMILY_IPV6); + g_assert (g_inet_address_get_is_loopback (iaddr)); + + g_assert_cmpint (g_inet_socket_address_get_port (isaddr), ==, 42); + g_assert_cmpint (g_inet_socket_address_get_scope_id (isaddr), ==, 17); + g_assert_cmpint (g_inet_socket_address_get_flowinfo (isaddr), ==, 1729); + + g_socket_address_to_native (saddr, &gsin6, sizeof (gsin6), &error); + g_assert_no_error (error); + + g_assert (memcmp (&sin6.sin6_addr, &gsin6.sin6_addr, sizeof (struct in6_addr)) == 0); + g_assert_cmpint (sin6.sin6_port, ==, gsin6.sin6_port); + g_assert_cmpint (sin6.sin6_scope_id, ==, gsin6.sin6_scope_id); + g_assert_cmpint (sin6.sin6_flowinfo, ==, gsin6.sin6_flowinfo); + + g_object_unref (saddr); +} + +#ifdef G_OS_UNIX +static void +test_unix_from_fd (void) +{ + gint fd; + GError *error; + GSocket *s; + + fd = socket (AF_UNIX, SOCK_STREAM, 0); + g_assert_cmpint (fd, !=, -1); + + error = NULL; + s = g_socket_new_from_fd (fd, &error); + g_assert_no_error (error); + g_assert_cmpint (g_socket_get_family (s), ==, G_SOCKET_FAMILY_UNIX); + g_assert_cmpint (g_socket_get_socket_type (s), ==, G_SOCKET_TYPE_STREAM); + g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT); + g_object_unref (s); +} + +static void +test_unix_connection (void) +{ + gint fd; + GError *error; + GSocket *s; + GSocketConnection *c; + + fd = socket (AF_UNIX, SOCK_STREAM, 0); + g_assert_cmpint (fd, !=, -1); + + error = NULL; + s = g_socket_new_from_fd (fd, &error); + g_assert_no_error (error); + c = g_socket_connection_factory_create_connection (s); + g_assert (G_IS_UNIX_CONNECTION (c)); + g_object_unref (c); + g_object_unref (s); +} + +static GSocketConnection * +create_connection_for_fd (int fd) +{ + GError *err = NULL; + GSocket *socket; + GSocketConnection *connection; + + socket = g_socket_new_from_fd (fd, &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (socket)); + connection = g_socket_connection_factory_create_connection (socket); + g_assert (G_IS_UNIX_CONNECTION (connection)); + g_object_unref (socket); + return connection; +} + +#define TEST_DATA "failure to say failure to say 'i love gnome-panel!'." + +static void +test_unix_connection_ancillary_data (void) +{ + GError *err = NULL; + gint pv[2], sv[3]; + gint status, fd, len; + char buffer[1024]; + pid_t pid; + + status = pipe (pv); + g_assert_cmpint (status, ==, 0); + + status = socketpair (PF_UNIX, SOCK_STREAM, 0, sv); + g_assert_cmpint (status, ==, 0); + + pid = fork (); + g_assert_cmpint (pid, >=, 0); + + /* Child: close its copy of the write end of the pipe, receive it + * again from the parent over the socket, and write some text to it. + * + * Parent: send the write end of the pipe (still open for the + * parent) over the socket, close it, and read some text from the + * read end of the pipe. + */ + if (pid == 0) + { + GSocketConnection *connection; + + close (sv[1]); + connection = create_connection_for_fd (sv[0]); + + status = close (pv[1]); + g_assert_cmpint (status, ==, 0); + + err = NULL; + fd = g_unix_connection_receive_fd (G_UNIX_CONNECTION (connection), NULL, + &err); + g_assert_no_error (err); + g_assert_cmpint (fd, >, -1); + g_object_unref (connection); + + do + len = write (fd, TEST_DATA, sizeof (TEST_DATA)); + while (len == -1 && errno == EINTR); + g_assert_cmpint (len, ==, sizeof (TEST_DATA)); + exit (0); + } + else + { + GSocketConnection *connection; + + close (sv[0]); + connection = create_connection_for_fd (sv[1]); + + err = NULL; + g_unix_connection_send_fd (G_UNIX_CONNECTION (connection), pv[1], NULL, + &err); + g_assert_no_error (err); + g_object_unref (connection); + + status = close (pv[1]); + g_assert_cmpint (status, ==, 0); + + memset (buffer, 0xff, sizeof buffer); + do + len = read (pv[0], buffer, sizeof buffer); + while (len == -1 && errno == EINTR); + + g_assert_cmpint (len, ==, sizeof (TEST_DATA)); + g_assert_cmpstr (buffer, ==, TEST_DATA); + + waitpid (pid, &status, 0); + g_assert (WIFEXITED (status)); + g_assert_cmpint (WEXITSTATUS (status), ==, 0); + } + + /* TODO: add test for g_unix_connection_send_credentials() and + * g_unix_connection_receive_credentials(). + */ +} + +static gboolean +postmortem_source_cb (GSocket *socket, + GIOCondition condition, + gpointer user_data) +{ + gboolean *been_here = user_data; + + g_assert_cmpint (condition, ==, G_IO_NVAL); + + *been_here = TRUE; + return FALSE; +} + +static void +test_source_postmortem (void) +{ + GMainContext *context; + GSocket *socket; + GSource *source; + GError *error = NULL; + gboolean callback_visited = FALSE; + + socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error); + g_assert_no_error (error); + + context = g_main_context_new (); + + source = g_socket_create_source (socket, G_IO_IN, NULL); + g_source_set_callback (source, (GSourceFunc) postmortem_source_cb, + &callback_visited, NULL); + g_source_attach (source, context); + g_source_unref (source); + + g_socket_close (socket, &error); + g_assert_no_error (error); + g_object_unref (socket); + + /* Test that, after a socket is closed, its source callback should be called + * exactly once. */ + g_main_context_iteration (context, FALSE); + g_assert (callback_visited); + g_assert (!g_main_context_pending (context)); + + g_main_context_unref (context); +} + +#endif /* G_OS_UNIX */ + +static void +test_reuse_tcp (void) +{ + GSocket *sock1, *sock2; + GError *error = NULL; + GInetAddress *iaddr; + GSocketAddress *addr; + + sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + g_socket_bind (sock1, addr, TRUE, &error); + g_object_unref (addr); + g_assert_no_error (error); + + g_socket_listen (sock1, &error); + g_assert_no_error (error); + + sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + addr = g_socket_get_local_address (sock1, &error); + g_assert_no_error (error); + g_socket_bind (sock2, addr, TRUE, &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE); + g_clear_error (&error); + g_object_unref (addr); + + g_object_unref (sock1); + g_object_unref (sock2); +} + +static void +test_reuse_udp (void) +{ + GSocket *sock1, *sock2; + GError *error = NULL; + GInetAddress *iaddr; + GSocketAddress *addr; + + sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + addr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + g_socket_bind (sock1, addr, TRUE, &error); + g_object_unref (addr); + g_assert_no_error (error); + + sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + g_assert_no_error (error); + + addr = g_socket_get_local_address (sock1, &error); + g_assert_no_error (error); + g_socket_bind (sock2, addr, TRUE, &error); + g_object_unref (addr); + g_assert_no_error (error); + + g_object_unref (sock1); + g_object_unref (sock2); +} + +static void +test_get_available (gconstpointer user_data) +{ + GSocketType socket_type = GPOINTER_TO_UINT (user_data); + GError *err = NULL; + GSocket *listener, *server, *client; + GInetAddress *addr; + GSocketAddress *saddr; + gchar data[] = "0123456789abcdef"; + gchar buf[34]; + gssize nread; + + listener = g_socket_new (G_SOCKET_FAMILY_IPV4, + socket_type, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (listener)); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + socket_type, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (client)); + + if (socket_type == G_SOCKET_TYPE_STREAM) + { + g_socket_set_option (client, IPPROTO_TCP, TCP_NODELAY, TRUE, &err); + g_assert_no_error (err); + } + + addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (addr, 0); + + g_socket_bind (listener, saddr, TRUE, &err); + g_assert_no_error (err); + g_object_unref (saddr); + g_object_unref (addr); + + saddr = g_socket_get_local_address (listener, &err); + g_assert_no_error (err); + + if (socket_type == G_SOCKET_TYPE_STREAM) + { + g_socket_listen (listener, &err); + g_assert_no_error (err); + g_socket_connect (client, saddr, NULL, &err); + g_assert_no_error (err); + + server = g_socket_accept (listener, NULL, &err); + g_assert_no_error (err); + g_socket_set_blocking (server, FALSE); + g_object_unref (listener); + } + else + server = listener; + + g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err); + g_assert_no_error (err); + + while (!g_socket_condition_wait (server, G_IO_IN, NULL, NULL)) + ; + g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data)); + + g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err); + g_assert_no_error (err); + + /* We need to wait until the data has actually been copied into the + * server socket's buffers, but g_socket_condition_wait() won't help + * here since the socket is definitely already readable. So there's + * a race condition in checking its available bytes. In the TCP + * case, we poll for a bit until the new data shows up. In the UDP + * case, there's not much we can do, but at least the failure mode + * is passes-when-it-shouldn't, not fails-when-it-shouldn't. + */ + if (socket_type == G_SOCKET_TYPE_STREAM) + { + int tries; + + for (tries = 0; tries < 100; tries++) + { + if (g_socket_get_available_bytes (server) > sizeof (data)) + break; + g_usleep (100000); + } + + g_assert_cmpint (g_socket_get_available_bytes (server), ==, 2 * sizeof (data)); + } + else + { + g_usleep (100000); + g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data)); + } + + g_assert_cmpint (sizeof (buf), >=, 2 * sizeof (data)); + nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err); + g_assert_no_error (err); + + if (socket_type == G_SOCKET_TYPE_STREAM) + { + g_assert_cmpint (nread, ==, 2 * sizeof (data)); + g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0); + } + else + { + g_assert_cmpint (nread, ==, sizeof (data)); + g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data)); + } + + nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err); + if (socket_type == G_SOCKET_TYPE_STREAM) + { + g_assert_cmpint (nread, ==, -1); + g_assert_error (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); + g_clear_error (&err); + } + else + { + g_assert_cmpint (nread, ==, sizeof (data)); + g_assert_no_error (err); + } + + g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0); + + g_socket_close (server, &err); + g_assert_no_error (err); + + g_object_unref (saddr); + g_object_unref (server); + g_object_unref (client); +} + +typedef struct { + GInputStream *is; + GOutputStream *os; + const guint8 *write_data; + guint8 *read_data; +} TestReadWriteData; + +static gpointer +test_read_write_write_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_written; + GError *error = NULL; + gboolean res; + + res = g_output_stream_write_all (data->os, data->write_data, 1024, &bytes_written, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_written, ==, 1024); + + return NULL; +} + +static gpointer +test_read_write_read_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_read; + GError *error = NULL; + gboolean res; + + res = g_input_stream_read_all (data->is, data->read_data, 1024, &bytes_read, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_read, ==, 1024); + + return NULL; +} + +static gpointer +test_read_write_writev_thread (gpointer user_data) +{ + TestReadWriteData *data = user_data; + gsize bytes_written; + GError *error = NULL; + gboolean res; + GOutputVector vectors[3]; + + vectors[0].buffer = data->write_data; + vectors[0].size = 256; + vectors[1].buffer = data->write_data + 256; + vectors[1].size = 256; + vectors[2].buffer = data->write_data + 512; + vectors[2].size = 512; + + res = g_output_stream_writev_all (data->os, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error); + g_assert_true (res); + g_assert_no_error (error); + g_assert_cmpint (bytes_written, ==, 1024); + + return NULL; +} + +/* test if normal read/write/writev via the GSocket*Streams works on TCP sockets */ +static void +test_read_write (gconstpointer user_data) +{ + gboolean writev = GPOINTER_TO_INT (user_data); + GError *err = NULL; + GSocket *listener, *server, *client; + GInetAddress *addr; + GSocketAddress *saddr; + TestReadWriteData data; + guint8 data_write[1024], data_read[1024]; + GSocketConnection *server_stream, *client_stream; + GThread *write_thread, *read_thread; + guint i; + + listener = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (listener)); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (client)); + + addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (addr, 0); + + g_socket_bind (listener, saddr, TRUE, &err); + g_assert_no_error (err); + g_object_unref (saddr); + g_object_unref (addr); + + saddr = g_socket_get_local_address (listener, &err); + g_assert_no_error (err); + + g_socket_listen (listener, &err); + g_assert_no_error (err); + g_socket_connect (client, saddr, NULL, &err); + g_assert_no_error (err); + + server = g_socket_accept (listener, NULL, &err); + g_assert_no_error (err); + g_socket_set_blocking (server, FALSE); + g_object_unref (listener); + + server_stream = g_socket_connection_factory_create_connection (server); + g_assert_nonnull (server_stream); + client_stream = g_socket_connection_factory_create_connection (client); + g_assert_nonnull (client_stream); + + for (i = 0; i < sizeof (data_write); i++) + data_write[i] = i; + + data.is = g_io_stream_get_input_stream (G_IO_STREAM (server_stream)); + data.os = g_io_stream_get_output_stream (G_IO_STREAM (client_stream)); + data.read_data = data_read; + data.write_data = data_write; + + if (writev) + write_thread = g_thread_new ("writer", test_read_write_writev_thread, &data); + else + write_thread = g_thread_new ("writer", test_read_write_write_thread, &data); + read_thread = g_thread_new ("reader", test_read_write_read_thread, &data); + + g_thread_join (write_thread); + g_thread_join (read_thread); + + g_assert_cmpmem (data_write, sizeof data_write, data_read, sizeof data_read); + + g_socket_close (server, &err); + g_assert_no_error (err); + + g_object_unref (server_stream); + g_object_unref (client_stream); + + g_object_unref (saddr); + g_object_unref (server); + g_object_unref (client); +} + +int +main (int argc, + char *argv[]) +{ + GSocket *sock; + GError *error = NULL; + + g_test_init (&argc, &argv, NULL); + g_test_bug_base ("https://bugzilla.gnome.org/"); + + sock = g_socket_new (G_SOCKET_FAMILY_IPV6, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_DEFAULT, + &error); + if (sock != NULL) + { + ipv6_supported = TRUE; + g_object_unref (sock); + } + else + { + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + } + + g_test_add_func ("/socket/ipv4_sync", test_ipv4_sync); + g_test_add_func ("/socket/ipv4_async", test_ipv4_async); + g_test_add_func ("/socket/ipv6_sync", test_ipv6_sync); + g_test_add_func ("/socket/ipv6_async", test_ipv6_async); + g_test_add_func ("/socket/ipv4_sync/datagram", test_ipv4_sync_dgram); + g_test_add_func ("/socket/ipv4_sync/datagram/timeouts", test_ipv4_sync_dgram_timeouts); + g_test_add_func ("/socket/ipv6_sync/datagram", test_ipv6_sync_dgram); + g_test_add_func ("/socket/ipv6_sync/datagram/timeouts", test_ipv6_sync_dgram_timeouts); +#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY) + g_test_add_func ("/socket/ipv6_v4mapped", test_ipv6_v4mapped); +#endif + g_test_add_func ("/socket/close_graceful", test_close_graceful); + g_test_add_func ("/socket/timed_wait", test_timed_wait); + g_test_add_func ("/socket/fd_reuse", test_fd_reuse); + g_test_add_func ("/socket/address", test_sockaddr); +#ifdef G_OS_UNIX + g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd); + g_test_add_func ("/socket/unix-connection", test_unix_connection); + g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data); + g_test_add_func ("/socket/source-postmortem", test_source_postmortem); +#endif + g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp); + g_test_add_func ("/socket/reuse/udp", test_reuse_udp); + g_test_add_data_func ("/socket/get_available/datagram", GUINT_TO_POINTER (G_SOCKET_TYPE_DATAGRAM), + test_get_available); + g_test_add_data_func ("/socket/get_available/stream", GUINT_TO_POINTER (G_SOCKET_TYPE_STREAM), + test_get_available); + g_test_add_data_func ("/socket/read_write", GUINT_TO_POINTER (FALSE), + test_read_write); + g_test_add_data_func ("/socket/read_writev", GUINT_TO_POINTER (TRUE), + test_read_write); + + return g_test_run(); +} + diff -Nru glib2.0-2.59.2/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/glib/tests/mainloop.c glib2.0-2.59.3/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/glib/tests/mainloop.c --- glib2.0-2.59.2/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/glib/tests/mainloop.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/glib/tests/mainloop.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,1776 @@ +/* Unit tests for GMainLoop + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ + +#include +#include "glib-private.h" +#include +#include + +static gboolean cb (gpointer data) +{ + return FALSE; +} + +static gboolean prepare (GSource *source, gint *time) +{ + return FALSE; +} +static gboolean check (GSource *source) +{ + return FALSE; +} +static gboolean dispatch (GSource *source, GSourceFunc cb, gpointer date) +{ + return FALSE; +} + +GSourceFuncs funcs = { + prepare, + check, + dispatch, + NULL +}; + +static void +test_maincontext_basic (void) +{ + GMainContext *ctx; + GSource *source; + guint id; + gpointer data = &funcs; + + ctx = g_main_context_new (); + + g_assert (!g_main_context_pending (ctx)); + g_assert (!g_main_context_iteration (ctx, FALSE)); + + source = g_source_new (&funcs, sizeof (GSource)); + g_assert_cmpint (g_source_get_priority (source), ==, G_PRIORITY_DEFAULT); + g_assert (!g_source_is_destroyed (source)); + + g_assert (!g_source_get_can_recurse (source)); + g_assert (g_source_get_name (source) == NULL); + + g_source_set_can_recurse (source, TRUE); + g_source_set_name (source, "d"); + + g_assert (g_source_get_can_recurse (source)); + g_assert_cmpstr (g_source_get_name (source), ==, "d"); + + g_assert (g_main_context_find_source_by_user_data (ctx, NULL) == NULL); + g_assert (g_main_context_find_source_by_funcs_user_data (ctx, &funcs, NULL) == NULL); + + id = g_source_attach (source, ctx); + g_assert_cmpint (g_source_get_id (source), ==, id); + g_assert (g_main_context_find_source_by_id (ctx, id) == source); + + g_source_set_priority (source, G_PRIORITY_HIGH); + g_assert_cmpint (g_source_get_priority (source), ==, G_PRIORITY_HIGH); + + g_source_destroy (source); + g_assert (g_source_get_context (source) == ctx); + g_assert (g_main_context_find_source_by_id (ctx, id) == NULL); + + g_main_context_unref (ctx); + + if (g_test_undefined ()) + { + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, + "*assertion*source->context != NULL*failed*"); + g_assert (g_source_get_context (source) == NULL); + g_test_assert_expected_messages (); + } + + g_source_unref (source); + + ctx = g_main_context_default (); + source = g_source_new (&funcs, sizeof (GSource)); + g_source_set_funcs (source, &funcs); + g_source_set_callback (source, cb, data, NULL); + id = g_source_attach (source, ctx); + g_source_unref (source); + g_source_set_name_by_id (id, "e"); + g_assert_cmpstr (g_source_get_name (source), ==, "e"); + g_assert (g_source_get_context (source) == ctx); + g_assert (g_source_remove_by_funcs_user_data (&funcs, data)); + + source = g_source_new (&funcs, sizeof (GSource)); + g_source_set_funcs (source, &funcs); + g_source_set_callback (source, cb, data, NULL); + id = g_source_attach (source, ctx); + g_source_unref (source); + g_assert (g_source_remove_by_user_data (data)); + g_assert (!g_source_remove_by_user_data ((gpointer)0x1234)); + + g_idle_add (cb, data); + g_assert (g_idle_remove_by_data (data)); +} + +static void +test_mainloop_basic (void) +{ + GMainLoop *loop; + GMainContext *ctx; + + loop = g_main_loop_new (NULL, FALSE); + + g_assert (!g_main_loop_is_running (loop)); + + g_main_loop_ref (loop); + + ctx = g_main_loop_get_context (loop); + g_assert (ctx == g_main_context_default ()); + + g_main_loop_unref (loop); + + g_assert_cmpint (g_main_depth (), ==, 0); + + g_main_loop_unref (loop); +} + +static gint a; +static gint b; +static gint c; + +static gboolean +count_calls (gpointer data) +{ + gint *i = data; + + (*i)++; + + return TRUE; +} + +static void +test_timeouts (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *source; + + a = b = c = 0; + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + source = g_timeout_source_new (100); + g_source_set_callback (source, count_calls, &a, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + source = g_timeout_source_new (250); + g_source_set_callback (source, count_calls, &b, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + source = g_timeout_source_new (330); + g_source_set_callback (source, count_calls, &c, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + source = g_timeout_source_new (1050); + g_source_set_callback (source, (GSourceFunc)g_main_loop_quit, loop, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + g_main_loop_run (loop); + + /* We may be delayed for an arbitrary amount of time - for example, + * it's possible for all timeouts to fire exactly once. + */ + g_assert_cmpint (a, >, 0); + g_assert_cmpint (a, >=, b); + g_assert_cmpint (b, >=, c); + + g_assert_cmpint (a, <=, 10); + g_assert_cmpint (b, <=, 4); + g_assert_cmpint (c, <=, 3); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +static void +test_priorities (void) +{ + GMainContext *ctx; + GSource *sourcea; + GSource *sourceb; + + a = b = c = 0; + + ctx = g_main_context_new (); + + sourcea = g_idle_source_new (); + g_source_set_callback (sourcea, count_calls, &a, NULL); + g_source_set_priority (sourcea, 1); + g_source_attach (sourcea, ctx); + g_source_unref (sourcea); + + sourceb = g_idle_source_new (); + g_source_set_callback (sourceb, count_calls, &b, NULL); + g_source_set_priority (sourceb, 0); + g_source_attach (sourceb, ctx); + g_source_unref (sourceb); + + g_assert (g_main_context_pending (ctx)); + g_assert (g_main_context_iteration (ctx, FALSE)); + g_assert_cmpint (a, ==, 0); + g_assert_cmpint (b, ==, 1); + + g_assert (g_main_context_iteration (ctx, FALSE)); + g_assert_cmpint (a, ==, 0); + g_assert_cmpint (b, ==, 2); + + g_source_destroy (sourceb); + + g_assert (g_main_context_iteration (ctx, FALSE)); + g_assert_cmpint (a, ==, 1); + g_assert_cmpint (b, ==, 2); + + g_assert (g_main_context_pending (ctx)); + g_source_destroy (sourcea); + g_assert (!g_main_context_pending (ctx)); + + g_main_context_unref (ctx); +} + +static gboolean +quit_loop (gpointer data) +{ + GMainLoop *loop = data; + + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static gint count; + +static gboolean +func (gpointer data) +{ + if (data != NULL) + g_assert (data == g_thread_self ()); + + count++; + + return FALSE; +} + +static gboolean +call_func (gpointer data) +{ + func (g_thread_self ()); + + return G_SOURCE_REMOVE; +} + +static GMutex mutex; +static GCond cond; +static gboolean thread_ready; + +static gpointer +thread_func (gpointer data) +{ + GMainContext *ctx = data; + GMainLoop *loop; + GSource *source; + + g_main_context_push_thread_default (ctx); + loop = g_main_loop_new (ctx, FALSE); + + g_mutex_lock (&mutex); + thread_ready = TRUE; + g_cond_signal (&cond); + g_mutex_unlock (&mutex); + + source = g_timeout_source_new (500); + g_source_set_callback (source, quit_loop, loop, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + + g_main_loop_run (loop); + + g_main_context_pop_thread_default (ctx); + g_main_loop_unref (loop); + + return NULL; +} + +static void +test_invoke (void) +{ + GMainContext *ctx; + GThread *thread; + + count = 0; + + /* this one gets invoked directly */ + g_main_context_invoke (NULL, func, g_thread_self ()); + g_assert_cmpint (count, ==, 1); + + /* invoking out of an idle works too */ + g_idle_add (call_func, NULL); + g_main_context_iteration (g_main_context_default (), FALSE); + g_assert_cmpint (count, ==, 2); + + /* test thread-default forcing the invocation to go + * to another thread + */ + ctx = g_main_context_new (); + thread = g_thread_new ("worker", thread_func, ctx); + + g_mutex_lock (&mutex); + while (!thread_ready) + g_cond_wait (&cond, &mutex); + g_mutex_unlock (&mutex); + + g_main_context_invoke (ctx, func, thread); + + g_thread_join (thread); + g_assert_cmpint (count, ==, 3); + + g_main_context_unref (ctx); +} + +/* We can't use timeout sources here because on slow or heavily-loaded + * machines, the test program might not get enough cycles to hit the + * timeouts at the expected times. So instead we define a source that + * is based on the number of GMainContext iterations. + */ + +static gint counter; +static gint64 last_counter_update; + +typedef struct { + GSource source; + gint interval; + gint timeout; +} CounterSource; + +static gboolean +counter_source_prepare (GSource *source, + gint *timeout) +{ + CounterSource *csource = (CounterSource *)source; + gint64 now; + + now = g_source_get_time (source); + if (now != last_counter_update) + { + last_counter_update = now; + counter++; + } + + *timeout = 1; + return counter >= csource->timeout; +} + +static gboolean +counter_source_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + CounterSource *csource = (CounterSource *) source; + gboolean again; + + again = callback (user_data); + + if (again) + csource->timeout = counter + csource->interval; + + return again; +} + +static GSourceFuncs counter_source_funcs = { + counter_source_prepare, + NULL, + counter_source_dispatch, + NULL, +}; + +static GSource * +counter_source_new (gint interval) +{ + GSource *source = g_source_new (&counter_source_funcs, sizeof (CounterSource)); + CounterSource *csource = (CounterSource *) source; + + csource->interval = interval; + csource->timeout = counter + interval; + + return source; +} + + +static gboolean +run_inner_loop (gpointer user_data) +{ + GMainContext *ctx = user_data; + GMainLoop *inner; + GSource *timeout; + + a++; + + inner = g_main_loop_new (ctx, FALSE); + timeout = counter_source_new (100); + g_source_set_callback (timeout, quit_loop, inner, NULL); + g_source_attach (timeout, ctx); + g_source_unref (timeout); + + g_main_loop_run (inner); + g_main_loop_unref (inner); + + return G_SOURCE_CONTINUE; +} + +static void +test_child_sources (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *parent, *child_b, *child_c, *end; + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + a = b = c = 0; + + parent = counter_source_new (2000); + g_source_set_callback (parent, run_inner_loop, ctx, NULL); + g_source_set_priority (parent, G_PRIORITY_LOW); + g_source_attach (parent, ctx); + + child_b = counter_source_new (250); + g_source_set_callback (child_b, count_calls, &b, NULL); + g_source_add_child_source (parent, child_b); + + child_c = counter_source_new (330); + g_source_set_callback (child_c, count_calls, &c, NULL); + g_source_set_priority (child_c, G_PRIORITY_HIGH); + g_source_add_child_source (parent, child_c); + + /* Child sources always have the priority of the parent */ + g_assert_cmpint (g_source_get_priority (parent), ==, G_PRIORITY_LOW); + g_assert_cmpint (g_source_get_priority (child_b), ==, G_PRIORITY_LOW); + g_assert_cmpint (g_source_get_priority (child_c), ==, G_PRIORITY_LOW); + g_source_set_priority (parent, G_PRIORITY_DEFAULT); + g_assert_cmpint (g_source_get_priority (parent), ==, G_PRIORITY_DEFAULT); + g_assert_cmpint (g_source_get_priority (child_b), ==, G_PRIORITY_DEFAULT); + g_assert_cmpint (g_source_get_priority (child_c), ==, G_PRIORITY_DEFAULT); + + end = counter_source_new (1050); + g_source_set_callback (end, quit_loop, loop, NULL); + g_source_attach (end, ctx); + g_source_unref (end); + + g_main_loop_run (loop); + + /* The parent source's own timeout will never trigger, so "a" will + * only get incremented when "b" or "c" does. And when timeouts get + * blocked, they still wait the full interval next time rather than + * "catching up". So the timing is: + * + * 250 - b++ -> a++, run_inner_loop + * 330 - (c is blocked) + * 350 - inner_loop ends + * 350 - c++ belatedly -> a++, run_inner_loop + * 450 - inner loop ends + * 500 - b++ -> a++, run_inner_loop + * 600 - inner_loop ends + * 680 - c++ -> a++, run_inner_loop + * 750 - (b is blocked) + * 780 - inner loop ends + * 780 - b++ belatedly -> a++, run_inner_loop + * 880 - inner loop ends + * 1010 - c++ -> a++, run_inner_loop + * 1030 - (b is blocked) + * 1050 - end runs, quits outer loop, which has no effect yet + * 1110 - inner loop ends, a returns, outer loop exits + */ + + g_assert_cmpint (a, ==, 6); + g_assert_cmpint (b, ==, 3); + g_assert_cmpint (c, ==, 3); + + g_source_destroy (parent); + g_source_unref (parent); + g_source_unref (child_b); + g_source_unref (child_c); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +static void +test_recursive_child_sources (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *parent, *child_b, *child_c, *end; + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + a = b = c = 0; + + parent = counter_source_new (500); + g_source_set_callback (parent, count_calls, &a, NULL); + + child_b = counter_source_new (220); + g_source_set_callback (child_b, count_calls, &b, NULL); + g_source_add_child_source (parent, child_b); + + child_c = counter_source_new (430); + g_source_set_callback (child_c, count_calls, &c, NULL); + g_source_add_child_source (child_b, child_c); + + g_source_attach (parent, ctx); + + end = counter_source_new (2010); + g_source_set_callback (end, (GSourceFunc)g_main_loop_quit, loop, NULL); + g_source_attach (end, ctx); + g_source_unref (end); + + g_main_loop_run (loop); + + /* Sequence of events: + * 220 b (b -> 440, a -> 720) + * 430 c (c -> 860, b -> 650, a -> 930) + * 650 b (b -> 870, a -> 1150) + * 860 c (c -> 1290, b -> 1080, a -> 1360) + * 1080 b (b -> 1300, a -> 1580) + * 1290 c (c -> 1720, b -> 1510, a -> 1790) + * 1510 b (b -> 1730, a -> 2010) + * 1720 c (c -> 2150, b -> 1940, a -> 2220) + * 1940 b (b -> 2160, a -> 2440) + */ + + g_assert_cmpint (a, ==, 9); + g_assert_cmpint (b, ==, 9); + g_assert_cmpint (c, ==, 4); + + g_source_destroy (parent); + g_source_unref (parent); + g_source_unref (child_b); + g_source_unref (child_c); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +typedef struct { + GSource *parent, *old_child, *new_child; + GMainLoop *loop; +} SwappingTestData; + +static gboolean +swap_sources (gpointer user_data) +{ + SwappingTestData *data = user_data; + + if (data->old_child) + { + g_source_remove_child_source (data->parent, data->old_child); + g_clear_pointer (&data->old_child, g_source_unref); + } + + if (!data->new_child) + { + data->new_child = g_timeout_source_new (0); + g_source_set_callback (data->new_child, quit_loop, data->loop, NULL); + g_source_add_child_source (data->parent, data->new_child); + } + + return G_SOURCE_CONTINUE; +} + +static gboolean +assert_not_reached_callback (gpointer user_data) +{ + g_assert_not_reached (); + + return G_SOURCE_REMOVE; +} + +static void +test_swapping_child_sources (void) +{ + GMainContext *ctx; + GMainLoop *loop; + SwappingTestData data; + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + data.parent = counter_source_new (50); + data.loop = loop; + g_source_set_callback (data.parent, swap_sources, &data, NULL); + g_source_attach (data.parent, ctx); + + data.old_child = counter_source_new (100); + g_source_add_child_source (data.parent, data.old_child); + g_source_set_callback (data.old_child, assert_not_reached_callback, NULL, NULL); + + data.new_child = NULL; + g_main_loop_run (loop); + + g_source_destroy (data.parent); + g_source_unref (data.parent); + g_source_unref (data.new_child); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +static gboolean +add_source_callback (gpointer user_data) +{ + GMainLoop *loop = user_data; + GSource *self = g_main_current_source (), *child; + GIOChannel *io; + + /* It doesn't matter whether this is a valid fd or not; it never + * actually gets polled; the test is just checking that + * g_source_add_child_source() doesn't crash. + */ + io = g_io_channel_unix_new (0); + child = g_io_create_watch (io, G_IO_IN); + g_source_add_child_source (self, child); + g_source_unref (child); + g_io_channel_unref (io); + + g_main_loop_quit (loop); + return FALSE; +} + +static void +test_blocked_child_sources (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *source; + + g_test_bug ("701283"); + + ctx = g_main_context_new (); + loop = g_main_loop_new (ctx, FALSE); + + source = g_idle_source_new (); + g_source_set_callback (source, add_source_callback, loop, NULL); + g_source_attach (source, ctx); + + g_main_loop_run (loop); + + g_source_destroy (source); + g_source_unref (source); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +typedef struct { + GMainContext *ctx; + GMainLoop *loop; + + GSource *timeout1, *timeout2; + gint64 time1; + GTimeVal tv; +} TimeTestData; + +static gboolean +timeout1_callback (gpointer user_data) +{ + TimeTestData *data = user_data; + GSource *source; + gint64 mtime1, mtime2, time2; + + source = g_main_current_source (); + g_assert (source == data->timeout1); + + if (data->time1 == -1) + { + /* First iteration */ + g_assert (!g_source_is_destroyed (data->timeout2)); + + mtime1 = g_get_monotonic_time (); + data->time1 = g_source_get_time (source); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_source_get_current_time (source, &data->tv); +G_GNUC_END_IGNORE_DEPRECATIONS + + /* g_source_get_time() does not change during a single callback */ + g_usleep (1000000); + mtime2 = g_get_monotonic_time (); + time2 = g_source_get_time (source); + + g_assert_cmpint (mtime1, <, mtime2); + g_assert_cmpint (data->time1, ==, time2); + } + else + { + GTimeVal tv; + + /* Second iteration */ + g_assert (g_source_is_destroyed (data->timeout2)); + + /* g_source_get_time() MAY change between iterations; in this + * case we know for sure that it did because of the g_usleep() + * last time. + */ + time2 = g_source_get_time (source); + g_assert_cmpint (data->time1, <, time2); + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_source_get_current_time (source, &tv); +G_GNUC_END_IGNORE_DEPRECATIONS + + g_assert (tv.tv_sec > data->tv.tv_sec || + (tv.tv_sec == data->tv.tv_sec && + tv.tv_usec > data->tv.tv_usec)); + + g_main_loop_quit (data->loop); + } + + return TRUE; +} + +static gboolean +timeout2_callback (gpointer user_data) +{ + TimeTestData *data = user_data; + GSource *source; + gint64 time2, time3; + + source = g_main_current_source (); + g_assert (source == data->timeout2); + + g_assert (!g_source_is_destroyed (data->timeout1)); + + /* g_source_get_time() does not change between different sources in + * a single iteration of the mainloop. + */ + time2 = g_source_get_time (source); + g_assert_cmpint (data->time1, ==, time2); + + /* The source should still have a valid time even after being + * destroyed, since it's currently running. + */ + g_source_destroy (source); + time3 = g_source_get_time (source); + g_assert_cmpint (time2, ==, time3); + + return FALSE; +} + +static void +test_source_time (void) +{ + TimeTestData data; + + data.ctx = g_main_context_new (); + data.loop = g_main_loop_new (data.ctx, FALSE); + + data.timeout1 = g_timeout_source_new (0); + g_source_set_callback (data.timeout1, timeout1_callback, &data, NULL); + g_source_attach (data.timeout1, data.ctx); + + data.timeout2 = g_timeout_source_new (0); + g_source_set_callback (data.timeout2, timeout2_callback, &data, NULL); + g_source_attach (data.timeout2, data.ctx); + + data.time1 = -1; + + g_main_loop_run (data.loop); + + g_assert (!g_source_is_destroyed (data.timeout1)); + g_assert (g_source_is_destroyed (data.timeout2)); + + g_source_destroy (data.timeout1); + g_source_unref (data.timeout1); + g_source_unref (data.timeout2); + + g_main_loop_unref (data.loop); + g_main_context_unref (data.ctx); +} + +typedef struct { + guint outstanding_ops; + GMainLoop *loop; +} TestOverflowData; + +static gboolean +on_source_fired_cb (gpointer user_data) +{ + TestOverflowData *data = user_data; + GSource *current_source; + GMainContext *current_context; + guint source_id; + + data->outstanding_ops--; + + current_source = g_main_current_source (); + current_context = g_source_get_context (current_source); + source_id = g_source_get_id (current_source); + g_assert (g_main_context_find_source_by_id (current_context, source_id) != NULL); + g_source_destroy (current_source); + g_assert (g_main_context_find_source_by_id (current_context, source_id) == NULL); + + if (data->outstanding_ops == 0) + g_main_loop_quit (data->loop); + return FALSE; +} + +static GSource * +add_idle_source (GMainContext *ctx, + TestOverflowData *data) +{ + GSource *source; + + source = g_idle_source_new (); + g_source_set_callback (source, on_source_fired_cb, data, NULL); + g_source_attach (source, ctx); + g_source_unref (source); + data->outstanding_ops++; + + return source; +} + +static void +test_mainloop_overflow (void) +{ + GMainContext *ctx; + GMainLoop *loop; + GSource *source; + TestOverflowData data; + guint i; + + g_test_bug ("687098"); + + memset (&data, 0, sizeof (data)); + + ctx = GLIB_PRIVATE_CALL (g_main_context_new_with_next_id) (G_MAXUINT-1); + + loop = g_main_loop_new (ctx, TRUE); + data.outstanding_ops = 0; + data.loop = loop; + + source = add_idle_source (ctx, &data); + g_assert_cmpint (source->source_id, ==, G_MAXUINT-1); + + source = add_idle_source (ctx, &data); + g_assert_cmpint (source->source_id, ==, G_MAXUINT); + + source = add_idle_source (ctx, &data); + g_assert_cmpint (source->source_id, !=, 0); + + /* Now, a lot more sources */ + for (i = 0; i < 50; i++) + { + source = add_idle_source (ctx, &data); + g_assert_cmpint (source->source_id, !=, 0); + } + + g_main_loop_run (loop); + g_assert_cmpint (data.outstanding_ops, ==, 0); + + g_main_loop_unref (loop); + g_main_context_unref (ctx); +} + +static volatile gint ready_time_dispatched; + +static gboolean +ready_time_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + g_atomic_int_set (&ready_time_dispatched, TRUE); + + g_source_set_ready_time (source, -1); + + return TRUE; +} + +static gpointer +run_context (gpointer user_data) +{ + g_main_loop_run (user_data); + + return NULL; +} + +static void +test_ready_time (void) +{ + GThread *thread; + GSource *source; + GSourceFuncs source_funcs = { + NULL, NULL, ready_time_dispatch + }; + GMainLoop *loop; + + source = g_source_new (&source_funcs, sizeof (GSource)); + g_source_attach (source, NULL); + g_source_unref (source); + + /* Unfortunately we can't do too many things with respect to timing + * without getting into trouble on slow systems or heavily loaded + * builders. + * + * We can test that the basics are working, though. + */ + + /* A source with no ready time set should not fire */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + while (g_main_context_iteration (NULL, FALSE)); + g_assert (!ready_time_dispatched); + + /* The ready time should not have been changed */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* Of course this shouldn't change anything either */ + g_source_set_ready_time (source, -1); + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* A source with a ready time set to tomorrow should not fire on any + * builder, no matter how badly loaded... + */ + g_source_set_ready_time (source, g_get_monotonic_time () + G_TIME_SPAN_DAY); + while (g_main_context_iteration (NULL, FALSE)); + g_assert (!ready_time_dispatched); + /* Make sure it didn't get reset */ + g_assert_cmpint (g_source_get_ready_time (source), !=, -1); + + /* Ready time of -1 -> don't fire */ + g_source_set_ready_time (source, -1); + while (g_main_context_iteration (NULL, FALSE)); + g_assert (!ready_time_dispatched); + /* Not reset, but should still be -1 from above */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* A ready time of the current time should fire immediately */ + g_source_set_ready_time (source, g_get_monotonic_time ()); + while (g_main_context_iteration (NULL, FALSE)); + g_assert (ready_time_dispatched); + ready_time_dispatched = FALSE; + /* Should have gotten reset by the handler function */ + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* As well as one in the recent past... */ + g_source_set_ready_time (source, g_get_monotonic_time () - G_TIME_SPAN_SECOND); + while (g_main_context_iteration (NULL, FALSE)); + g_assert (ready_time_dispatched); + ready_time_dispatched = FALSE; + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* Zero is the 'official' way to get a source to fire immediately */ + g_source_set_ready_time (source, 0); + while (g_main_context_iteration (NULL, FALSE)); + g_assert (ready_time_dispatched); + ready_time_dispatched = FALSE; + g_assert_cmpint (g_source_get_ready_time (source), ==, -1); + + /* Now do some tests of cross-thread wakeups. + * + * Make sure it wakes up right away from the start. + */ + g_source_set_ready_time (source, 0); + loop = g_main_loop_new (NULL, FALSE); + thread = g_thread_new ("context thread", run_context, loop); + while (!g_atomic_int_get (&ready_time_dispatched)); + + /* Now let's see if it can wake up from sleeping. */ + g_usleep (G_TIME_SPAN_SECOND / 2); + g_atomic_int_set (&ready_time_dispatched, FALSE); + g_source_set_ready_time (source, 0); + while (!g_atomic_int_get (&ready_time_dispatched)); + + /* kill the thread */ + g_main_loop_quit (loop); + g_thread_join (thread); + g_main_loop_unref (loop); + + g_source_destroy (source); +} + +static void +test_wakeup(void) +{ + GMainContext *ctx; + int i; + + ctx = g_main_context_new (); + + /* run a random large enough number of times because + * main contexts tend to wake up a few times after creation. + */ + for (i = 0; i < 100; i++) + { + /* This is the invariant we care about: + * g_main_context_wakeup(ctx,) ensures that the next call to + * g_main_context_iteration (ctx, TRUE) returns and doesn't + * block. + * This is important in threaded apps where we might not know + * if the thread calls g_main_context_wakeup() before or after + * we enter g_main_context_iteration(). + */ + g_main_context_wakeup (ctx); + g_main_context_iteration (ctx, TRUE); + } + + g_main_context_unref (ctx); +} + +static void +test_remove_invalid (void) +{ + g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL, "Source ID 3000000000 was not found*"); + g_source_remove (3000000000u); + g_test_assert_expected_messages (); +} + +static gboolean +trivial_prepare (GSource *source, + gint *timeout) +{ + *timeout = 0; + return TRUE; +} + +static gint n_finalized; + +static void +trivial_finalize (GSource *source) +{ + n_finalized++; +} + +static void +test_unref_while_pending (void) +{ + static GSourceFuncs funcs = { trivial_prepare, NULL, NULL, trivial_finalize }; + GMainContext *context; + GSource *source; + + context = g_main_context_new (); + + source = g_source_new (&funcs, sizeof (GSource)); + g_source_attach (source, context); + g_source_unref (source); + + /* Do incomplete main iteration -- get a pending source but don't dispatch it. */ + g_main_context_prepare (context, NULL); + g_main_context_query (context, 0, NULL, NULL, 0); + g_main_context_check (context, 1000, NULL, 0); + + /* Destroy the context */ + g_main_context_unref (context); + + /* Make sure we didn't leak the source */ + g_assert_cmpint (n_finalized, ==, 1); +} + +#ifdef G_OS_UNIX + +#include +#include + +static gchar zeros[1024]; + +static gsize +fill_a_pipe (gint fd) +{ + gsize written = 0; + GPollFD pfd; + + pfd.fd = fd; + pfd.events = G_IO_OUT; + while (g_poll (&pfd, 1, 0) == 1) + /* we should never see -1 here */ + written += write (fd, zeros, sizeof zeros); + + return written; +} + +static gboolean +write_bytes (gint fd, + GIOCondition condition, + gpointer user_data) +{ + gssize *to_write = user_data; + gint limit; + + if (*to_write == 0) + return FALSE; + + /* Detect if we run before we should */ + g_assert (*to_write >= 0); + + limit = MIN (*to_write, sizeof zeros); + *to_write -= write (fd, zeros, limit); + + return TRUE; +} + +static gboolean +read_bytes (gint fd, + GIOCondition condition, + gpointer user_data) +{ + static gchar buffer[1024]; + gssize *to_read = user_data; + + *to_read -= read (fd, buffer, sizeof buffer); + + /* The loop will exit when there is nothing else to read, then we will + * use g_source_remove() to destroy this source. + */ + return TRUE; +} + +#ifdef G_OS_UNIX +static void +test_unix_fd (void) +{ + gssize to_write = -1; + gssize to_read; + gint fds[2]; + gint a, b; + gint s; + GSource *source_a; + GSource *source_b; + + s = pipe (fds); + g_assert (s == 0); + + to_read = fill_a_pipe (fds[1]); + /* write at higher priority to keep the pipe full... */ + a = g_unix_fd_add_full (G_PRIORITY_HIGH, fds[1], G_IO_OUT, write_bytes, &to_write, NULL); + source_a = g_source_ref (g_main_context_find_source_by_id (NULL, a)); + /* make sure no 'writes' get dispatched yet */ + while (g_main_context_iteration (NULL, FALSE)); + + to_read += 128 * 1024 * 1024; + to_write = 128 * 1024 * 1024; + b = g_unix_fd_add (fds[0], G_IO_IN, read_bytes, &to_read); + source_b = g_source_ref (g_main_context_find_source_by_id (NULL, b)); + + /* Assuming the kernel isn't internally 'laggy' then there will always + * be either data to read or room in which to write. That will keep + * the loop running until all data has been read and written. + */ + while (TRUE) + { + gssize to_write_was = to_write; + gssize to_read_was = to_read; + + if (!g_main_context_iteration (NULL, FALSE)) + break; + + /* Since the sources are at different priority, only one of them + * should possibly have run. + */ + g_assert (to_write == to_write_was || to_read == to_read_was); + } + + g_assert (to_write == 0); + g_assert (to_read == 0); + + /* 'a' is already removed by itself */ + g_assert (g_source_is_destroyed (source_a)); + g_source_unref (source_a); + g_source_remove (b); + g_assert (g_source_is_destroyed (source_b)); + g_source_unref (source_b); + close (fds[1]); + close (fds[0]); +} +#endif + +static void +assert_main_context_state (gint n_to_poll, + ...) +{ + GMainContext *context; + gboolean consumed[10] = { }; + GPollFD poll_fds[10]; + gboolean acquired; + gboolean immediate; + gint max_priority; + gint timeout; + gint n; + gint i, j; + va_list ap; + + context = g_main_context_default (); + + acquired = g_main_context_acquire (context); + g_assert (acquired); + + immediate = g_main_context_prepare (context, &max_priority); + g_assert (!immediate); + n = g_main_context_query (context, max_priority, &timeout, poll_fds, 10); + g_assert_cmpint (n, ==, n_to_poll + 1); /* one will be the gwakeup */ + + va_start (ap, n_to_poll); + for (i = 0; i < n_to_poll; i++) + { + gint expected_fd = va_arg (ap, gint); + GIOCondition expected_events = va_arg (ap, GIOCondition); + GIOCondition report_events = va_arg (ap, GIOCondition); + + for (j = 0; j < n; j++) + if (!consumed[j] && poll_fds[j].fd == expected_fd && poll_fds[j].events == expected_events) + { + poll_fds[j].revents = report_events; + consumed[j] = TRUE; + break; + } + + if (j == n) + g_error ("Unable to find fd %d (index %d) with events 0x%x", expected_fd, i, (guint) expected_events); + } + va_end (ap); + + /* find the gwakeup, flag as non-ready */ + for (i = 0; i < n; i++) + if (!consumed[i]) + poll_fds[i].revents = 0; + + if (g_main_context_check (context, max_priority, poll_fds, n)) + g_main_context_dispatch (context); + + g_main_context_release (context); +} + +static gboolean +flag_bool (gint fd, + GIOCondition condition, + gpointer user_data) +{ + gboolean *flag = user_data; + + *flag = TRUE; + + return TRUE; +} + +static void +test_unix_fd_source (void) +{ + GSource *out_source; + GSource *in_source; + GSource *source; + gboolean out, in; + gint fds[2]; + gint s; + + assert_main_context_state (0); + + s = pipe (fds); + g_assert (s == 0); + + source = g_unix_fd_source_new (fds[1], G_IO_OUT); + g_source_attach (source, NULL); + + /* Check that a source with no callback gets successfully detached + * with a warning printed. + */ + g_test_expect_message ("GLib", G_LOG_LEVEL_WARNING, "*GUnixFDSource dispatched without callback*"); + while (g_main_context_iteration (NULL, FALSE)); + g_test_assert_expected_messages (); + g_assert (g_source_is_destroyed (source)); + g_source_unref (source); + + out = in = FALSE; + out_source = g_unix_fd_source_new (fds[1], G_IO_OUT); + /* -Wcast-function-type complains about casting 'flag_bool' to GSourceFunc. + * GCC has no way of knowing that it will be cast back to GUnixFDSourceFunc + * before being called. Although GLib itself is not compiled with + * -Wcast-function-type, applications that use GLib may well be (since + * -Wextra includes it), so we provide a G_SOURCE_FUNC() macro to suppress + * the warning. We check that it works here. + */ +#if G_GNUC_CHECK_VERSION(8, 0) +#pragma GCC diagnostic push +#pragma GCC diagnostic error "-Wcast-function-type" +#endif + g_source_set_callback (out_source, G_SOURCE_FUNC (flag_bool), &out, NULL); +#if G_GNUC_CHECK_VERSION(8, 0) +#pragma GCC diagnostic pop +#endif + g_source_attach (out_source, NULL); + assert_main_context_state (1, + fds[1], G_IO_OUT, 0); + g_assert (!in && !out); + + in_source = g_unix_fd_source_new (fds[0], G_IO_IN); + g_source_set_callback (in_source, (GSourceFunc) flag_bool, &in, NULL); + g_source_set_priority (in_source, G_PRIORITY_DEFAULT_IDLE); + g_source_attach (in_source, NULL); + assert_main_context_state (2, + fds[0], G_IO_IN, G_IO_IN, + fds[1], G_IO_OUT, G_IO_OUT); + /* out is higher priority so only it should fire */ + g_assert (!in && out); + + /* raise the priority of the in source to higher than out*/ + in = out = FALSE; + g_source_set_priority (in_source, G_PRIORITY_HIGH); + assert_main_context_state (2, + fds[0], G_IO_IN, G_IO_IN, + fds[1], G_IO_OUT, G_IO_OUT); + g_assert (in && !out); + + /* now, let them be equal */ + in = out = FALSE; + g_source_set_priority (in_source, G_PRIORITY_DEFAULT); + assert_main_context_state (2, + fds[0], G_IO_IN, G_IO_IN, + fds[1], G_IO_OUT, G_IO_OUT); + g_assert (in && out); + + g_source_destroy (out_source); + g_source_unref (out_source); + g_source_destroy (in_source); + g_source_unref (in_source); + close (fds[1]); + close (fds[0]); +} + +typedef struct +{ + GSource parent; + gboolean flagged; +} FlagSource; + +static gboolean +return_true (GSource *source, GSourceFunc callback, gpointer user_data) +{ + FlagSource *flag_source = (FlagSource *) source; + + flag_source->flagged = TRUE; + + return TRUE; +} + +#define assert_flagged(s) g_assert (((FlagSource *) (s))->flagged); +#define assert_not_flagged(s) g_assert (!((FlagSource *) (s))->flagged); +#define clear_flag(s) ((FlagSource *) (s))->flagged = 0 + +static void +test_source_unix_fd_api (void) +{ + GSourceFuncs no_funcs = { + NULL, NULL, return_true + }; + GSource *source_a; + GSource *source_b; + gpointer tag1, tag2; + gint fds_a[2]; + gint fds_b[2]; + + pipe (fds_a); + pipe (fds_b); + + source_a = g_source_new (&no_funcs, sizeof (FlagSource)); + source_b = g_source_new (&no_funcs, sizeof (FlagSource)); + + /* attach a source with more than one fd */ + g_source_add_unix_fd (source_a, fds_a[0], G_IO_IN); + g_source_add_unix_fd (source_a, fds_a[1], G_IO_OUT); + g_source_attach (source_a, NULL); + assert_main_context_state (2, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, 0); + assert_not_flagged (source_a); + + /* attach a higher priority source with no fds */ + g_source_set_priority (source_b, G_PRIORITY_HIGH); + g_source_attach (source_b, NULL); + assert_main_context_state (2, + fds_a[0], G_IO_IN, G_IO_IN, + fds_a[1], G_IO_OUT, 0); + assert_flagged (source_a); + assert_not_flagged (source_b); + clear_flag (source_a); + + /* add some fds to the second source, while attached */ + tag1 = g_source_add_unix_fd (source_b, fds_b[0], G_IO_IN); + tag2 = g_source_add_unix_fd (source_b, fds_b[1], G_IO_OUT); + assert_main_context_state (4, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, G_IO_OUT, + fds_b[0], G_IO_IN, 0, + fds_b[1], G_IO_OUT, G_IO_OUT); + /* only 'b' (higher priority) should have dispatched */ + assert_not_flagged (source_a); + assert_flagged (source_b); + clear_flag (source_b); + + /* change our events on b to the same as they were before */ + g_source_modify_unix_fd (source_b, tag1, G_IO_IN); + g_source_modify_unix_fd (source_b, tag2, G_IO_OUT); + assert_main_context_state (4, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, G_IO_OUT, + fds_b[0], G_IO_IN, 0, + fds_b[1], G_IO_OUT, G_IO_OUT); + assert_not_flagged (source_a); + assert_flagged (source_b); + clear_flag (source_b); + + /* now reverse them */ + g_source_modify_unix_fd (source_b, tag1, G_IO_OUT); + g_source_modify_unix_fd (source_b, tag2, G_IO_IN); + assert_main_context_state (4, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, G_IO_OUT, + fds_b[0], G_IO_OUT, 0, + fds_b[1], G_IO_IN, 0); + /* 'b' had no events, so 'a' can go this time */ + assert_flagged (source_a); + assert_not_flagged (source_b); + clear_flag (source_a); + + /* remove one of the fds from 'b' */ + g_source_remove_unix_fd (source_b, tag1); + assert_main_context_state (3, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, 0, + fds_b[1], G_IO_IN, 0); + assert_not_flagged (source_a); + assert_not_flagged (source_b); + + /* remove the other */ + g_source_remove_unix_fd (source_b, tag2); + assert_main_context_state (2, + fds_a[0], G_IO_IN, 0, + fds_a[1], G_IO_OUT, 0); + assert_not_flagged (source_a); + assert_not_flagged (source_b); + + /* destroy the sources */ + g_source_destroy (source_a); + g_source_destroy (source_b); + assert_main_context_state (0); + + g_source_unref (source_a); + g_source_unref (source_b); + close (fds_a[0]); + close (fds_a[1]); + close (fds_b[0]); + close (fds_b[1]); +} + +static gboolean +unixfd_quit_loop (gint fd, + GIOCondition condition, + gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_main_loop_quit (loop); + + return FALSE; +} + +static void +test_unix_file_poll (void) +{ + gint fd; + GSource *source; + GMainLoop *loop; + + fd = open ("/dev/null", O_RDONLY); + g_assert (fd >= 0); + + loop = g_main_loop_new (NULL, FALSE); + + source = g_unix_fd_source_new (fd, G_IO_IN); + g_source_set_callback (source, (GSourceFunc) unixfd_quit_loop, loop, NULL); + g_source_attach (source, NULL); + + /* Should not block */ + g_main_loop_run (loop); + + g_source_destroy (source); + + assert_main_context_state (0); + + g_source_unref (source); + + g_main_loop_unref (loop); + + close (fd); +} + +#endif + +#ifdef G_OS_UNIX +static gboolean +timeout_cb (gpointer data) +{ + GMainLoop *loop = data; + GMainContext *context; + + context = g_main_loop_get_context (loop); + g_assert (g_main_loop_is_running (loop)); + g_assert (g_main_context_is_owner (context)); + + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static gpointer +threadf (gpointer data) +{ + GMainContext *context = data; + GMainLoop *loop; + GSource *source; + + loop = g_main_loop_new (context, FALSE); + source = g_timeout_source_new (250); + g_source_set_callback (source, timeout_cb, loop, NULL); + g_source_attach (source, context); + g_source_unref (source); + + g_main_loop_run (loop); + + g_main_loop_unref (loop); + + return NULL; +} + +static void +test_mainloop_wait (void) +{ + GMainContext *context; + GThread *t1, *t2; + + context = g_main_context_new (); + + t1 = g_thread_new ("t1", threadf, context); + t2 = g_thread_new ("t2", threadf, context); + + g_thread_join (t1); + g_thread_join (t2); + + g_main_context_unref (context); +} +#endif + +static gboolean +nfds_in_cb (GIOChannel *io, + GIOCondition condition, + gpointer user_data) +{ + gboolean *in_cb_ran = user_data; + + *in_cb_ran = TRUE; + g_assert_cmpint (condition, ==, G_IO_IN); + return FALSE; +} + +static gboolean +nfds_out_cb (GIOChannel *io, + GIOCondition condition, + gpointer user_data) +{ + gboolean *out_cb_ran = user_data; + + *out_cb_ran = TRUE; + g_assert_cmpint (condition, ==, G_IO_OUT); + return FALSE; +} + +static gboolean +nfds_out_low_cb (GIOChannel *io, + GIOCondition condition, + gpointer user_data) +{ + g_assert_not_reached (); + return FALSE; +} + +static void +test_nfds (void) +{ + GMainContext *ctx; + GPollFD out_fds[3]; + gint fd, nfds; + GIOChannel *io; + GSource *source1, *source2, *source3; + gboolean source1_ran = FALSE, source3_ran = FALSE; + gchar *tmpfile; + GError *error = NULL; + + ctx = g_main_context_new (); + nfds = g_main_context_query (ctx, G_MAXINT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + /* An "empty" GMainContext will have a single GPollFD, for its + * internal GWakeup. + */ + g_assert_cmpint (nfds, ==, 1); + + fd = g_file_open_tmp (NULL, &tmpfile, &error); + g_assert_no_error (error); + + io = g_io_channel_unix_new (fd); +#ifdef G_OS_WIN32 + /* The fd in the pollfds won't be the same fd we passed in */ + g_io_channel_win32_make_pollfd (io, G_IO_IN, out_fds); + fd = out_fds[0].fd; +#endif + + /* Add our first pollfd */ + source1 = g_io_create_watch (io, G_IO_IN); + g_source_set_priority (source1, G_PRIORITY_DEFAULT); + g_source_set_callback (source1, (GSourceFunc) nfds_in_cb, + &source1_ran, NULL); + g_source_attach (source1, ctx); + + nfds = g_main_context_query (ctx, G_MAXINT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + g_assert_cmpint (nfds, ==, 2); + if (out_fds[0].fd == fd) + g_assert_cmpint (out_fds[0].events, ==, G_IO_IN); + else if (out_fds[1].fd == fd) + g_assert_cmpint (out_fds[1].events, ==, G_IO_IN); + else + g_assert_not_reached (); + + /* Add a second pollfd with the same fd but different event, and + * lower priority. + */ + source2 = g_io_create_watch (io, G_IO_OUT); + g_source_set_priority (source2, G_PRIORITY_LOW); + g_source_set_callback (source2, (GSourceFunc) nfds_out_low_cb, + NULL, NULL); + g_source_attach (source2, ctx); + + /* g_main_context_query() should still return only 2 pollfds, + * one of which has our fd, and a combined events field. + */ + nfds = g_main_context_query (ctx, G_MAXINT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + g_assert_cmpint (nfds, ==, 2); + if (out_fds[0].fd == fd) + g_assert_cmpint (out_fds[0].events, ==, G_IO_IN | G_IO_OUT); + else if (out_fds[1].fd == fd) + g_assert_cmpint (out_fds[1].events, ==, G_IO_IN | G_IO_OUT); + else + g_assert_not_reached (); + + /* But if we query with a max priority, we won't see the + * lower-priority one. + */ + nfds = g_main_context_query (ctx, G_PRIORITY_DEFAULT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + g_assert_cmpint (nfds, ==, 2); + if (out_fds[0].fd == fd) + g_assert_cmpint (out_fds[0].events, ==, G_IO_IN); + else if (out_fds[1].fd == fd) + g_assert_cmpint (out_fds[1].events, ==, G_IO_IN); + else + g_assert_not_reached (); + + /* Third pollfd */ + source3 = g_io_create_watch (io, G_IO_OUT); + g_source_set_priority (source3, G_PRIORITY_DEFAULT); + g_source_set_callback (source3, (GSourceFunc) nfds_out_cb, + &source3_ran, NULL); + g_source_attach (source3, ctx); + + nfds = g_main_context_query (ctx, G_MAXINT, NULL, + out_fds, G_N_ELEMENTS (out_fds)); + g_assert_cmpint (nfds, ==, 2); + if (out_fds[0].fd == fd) + g_assert_cmpint (out_fds[0].events, ==, G_IO_IN | G_IO_OUT); + else if (out_fds[1].fd == fd) + g_assert_cmpint (out_fds[1].events, ==, G_IO_IN | G_IO_OUT); + else + g_assert_not_reached (); + + /* Now actually iterate the loop; the fd should be readable and + * writable, so source1 and source3 should be triggered, but *not* + * source2, since it's lower priority than them. (Though on + * G_OS_WIN32, source3 doesn't get triggered, probably because of + * giowin32 weirdness...) + */ + g_main_context_iteration (ctx, FALSE); + + g_assert (source1_ran); +#ifndef G_OS_WIN32 + g_assert (source3_ran); +#endif + + g_source_destroy (source1); + g_source_unref (source1); + g_source_destroy (source2); + g_source_unref (source2); + g_source_destroy (source3); + g_source_unref (source3); + + g_io_channel_unref (io); + remove (tmpfile); + g_free (tmpfile); + + g_main_context_unref (ctx); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + g_test_bug_base ("http://bugzilla.gnome.org/"); + + g_test_add_func ("/maincontext/basic", test_maincontext_basic); + g_test_add_func ("/mainloop/basic", test_mainloop_basic); + g_test_add_func ("/mainloop/timeouts", test_timeouts); + g_test_add_func ("/mainloop/priorities", test_priorities); + g_test_add_func ("/mainloop/invoke", test_invoke); + g_test_add_func ("/mainloop/child_sources", test_child_sources); + g_test_add_func ("/mainloop/recursive_child_sources", test_recursive_child_sources); + g_test_add_func ("/mainloop/swapping_child_sources", test_swapping_child_sources); + g_test_add_func ("/mainloop/blocked_child_sources", test_blocked_child_sources); + g_test_add_func ("/mainloop/source_time", test_source_time); + g_test_add_func ("/mainloop/overflow", test_mainloop_overflow); + g_test_add_func ("/mainloop/ready-time", test_ready_time); + g_test_add_func ("/mainloop/wakeup", test_wakeup); + g_test_add_func ("/mainloop/remove-invalid", test_remove_invalid); + g_test_add_func ("/mainloop/unref-while-pending", test_unref_while_pending); +#ifdef G_OS_UNIX + g_test_add_func ("/mainloop/unix-fd", test_unix_fd); + g_test_add_func ("/mainloop/unix-fd-source", test_unix_fd_source); + g_test_add_func ("/mainloop/source-unix-fd-api", test_source_unix_fd_api); + g_test_add_func ("/mainloop/wait", test_mainloop_wait); + g_test_add_func ("/mainloop/unix-file-poll", test_unix_file_poll); +#endif + g_test_add_func ("/mainloop/nfds", test_nfds); + + return g_test_run (); +} diff -Nru glib2.0-2.59.2/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/glib/tests/timeout.c glib2.0-2.59.3/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/glib/tests/timeout.c --- glib2.0-2.59.2/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/glib/tests/timeout.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/Disable-some-tests-on-slow-architectures-which-keep-faili.patch/glib/tests/timeout.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,199 @@ +#include +#ifdef G_OS_UNIX +#include +#endif + +static GMainLoop *loop; + +static gboolean +stop_waiting (gpointer data) +{ + g_main_loop_quit (loop); + + return G_SOURCE_REMOVE; +} + +static gboolean +unreachable_callback (gpointer data) +{ + g_assert_not_reached (); + + return G_SOURCE_REMOVE; +} + +static void +test_seconds (void) +{ + guint id; + + /* Bug 642052 mentions that g_timeout_add_seconds(21475) schedules a + * job that runs once per second. + * + * Test that that isn't true anymore by scheduling two jobs: + * - one, as above + * - another that runs in 2100ms + * + * If everything is working properly, the 2100ms one should run first + * (and exit the mainloop). If we ever see the 21475 second job run + * then we have trouble (since it ran in less than 2 seconds). + * + * We need a timeout of at least 2 seconds because + * g_timeout_add_seconds() can add as much as an additional second of + * latency. + */ + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642052"); + loop = g_main_loop_new (NULL, FALSE); + + g_timeout_add (2100, stop_waiting, NULL); + id = g_timeout_add_seconds (21475, unreachable_callback, NULL); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_source_remove (id); +} + +static void +test_weeks_overflow (void) +{ + guint id; + guint interval_seconds; + + /* Internally, the guint interval (in seconds) was converted to milliseconds + * then stored in a guint variable. This meant that any interval larger than + * G_MAXUINT / 1000 would overflow. + * + * On a system with 32-bit guint, the interval (G_MAXUINT / 1000) + 1 seconds + * (49.7 days) would end wrapping to 704 milliseconds. + * + * Test that that isn't true anymore by scheduling two jobs: + * - one, as above + * - another that runs in 2100ms + * + * If everything is working properly, the 2100ms one should run first + * (and exit the mainloop). If we ever see the other job run + * then we have trouble (since it ran in less than 2 seconds). + * + * We need a timeout of at least 2 seconds because + * g_timeout_add_seconds() can add as much as an additional second of + * latency. + */ + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1600"); + loop = g_main_loop_new (NULL, FALSE); + + g_timeout_add (2100, stop_waiting, NULL); + interval_seconds = 1 + G_MAXUINT / 1000; + id = g_timeout_add_seconds (interval_seconds, unreachable_callback, NULL); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + g_source_remove (id); +} + +/* The ready_time for a GSource is stored as a gint64, as an absolute monotonic + * time in microseconds. To call poll(), this must be converted to a relative + * timeout, in milliseconds, as a gint. If the ready_time is sufficiently far + * in the future, the timeout will not fit. Previously, it would be narrowed in + * an implementation-defined way; if this gave a negative result, poll() would + * block forever. + * + * This test creates a GSource with the largest possible ready_time (a little + * over 292 millennia, assuming g_get_monotonic_time() starts from near 0 when + * the system boots), adds it to a GMainContext, queries it for the parameters + * to pass to poll() -- essentially the first half of + * g_main_context_iteration() -- and checks that the timeout is a large + * positive number. + */ +static void +test_far_future_ready_time (void) +{ + GSourceFuncs source_funcs = { 0 }; + GMainContext *context = g_main_context_new (); + GSource *source = g_source_new (&source_funcs, sizeof (GSource)); + gboolean acquired, ready; + gint priority, timeout_, n_fds; + + g_source_set_ready_time (source, G_MAXINT64); + g_source_attach (source, context); + + acquired = g_main_context_acquire (context); + g_assert_true (acquired); + + ready = g_main_context_prepare (context, &priority); + g_assert_false (ready); + + n_fds = 0; + n_fds = g_main_context_query (context, priority, &timeout_, NULL, n_fds); + + /* The true timeout in milliseconds doesn't fit into a gint. We definitely + * don't want poll() to block forever: + */ + g_assert_cmpint (timeout_, >=, 0); + /* Instead, we want it to block for as long as possible: */ + g_assert_cmpint (timeout_, ==, G_MAXINT); + + g_main_context_release (context); + g_main_context_unref (context); + g_source_unref (source); +} + +static gint64 last_time; +static gint count; + +static gboolean +test_func (gpointer data) +{ + gint64 current_time; + + current_time = g_get_monotonic_time (); + + /* We accept 2 on the first iteration because _add_seconds() can + * have an initial latency of 1 second, see its documentation. + */ + if (count == 0) + g_assert (current_time / 1000000 - last_time / 1000000 <= 2); + else + g_assert (current_time / 1000000 - last_time / 1000000 == 1); + + last_time = current_time; + count++; + + /* Make the timeout take up to 0.1 seconds. + * We should still get scheduled for the next second. + */ + g_usleep (count * 10000); + + if (count < 10) + return TRUE; + + g_main_loop_quit (loop); + + return FALSE; +} + +static void +test_rounding (void) +{ + loop = g_main_loop_new (NULL, FALSE); + + last_time = g_get_monotonic_time (); + g_timeout_add_seconds (1, test_func, NULL); + + g_main_loop_run (loop); + g_main_loop_unref (loop); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + g_test_bug_base (""); + + g_test_add_func ("/timeout/seconds", test_seconds); + g_test_add_func ("/timeout/weeks-overflow", test_weeks_overflow); + g_test_add_func ("/timeout/far-future-ready-time", test_far_future_ready_time); + g_test_add_func ("/timeout/rounding", test_rounding); + + return g_test_run (); +} diff -Nru glib2.0-2.59.2/.pc/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch/gio/gdesktopappinfo.c glib2.0-2.59.3/.pc/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch/gio/gdesktopappinfo.c --- glib2.0-2.59.2/.pc/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch/gio/gdesktopappinfo.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch/gio/gdesktopappinfo.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,4902 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * Copyright © 2007 Ryan Lortie + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + * + * Author: Alexander Larsson + * Ryan Lortie + */ + +/* Prelude {{{1 */ + +#include "config.h" + +#include +#include +#include + +#ifdef HAVE_CRT_EXTERNS_H +#include +#endif + +#include "gcontenttypeprivate.h" +#include "gdesktopappinfo.h" +#ifdef G_OS_UNIX +#include "glib-unix.h" +#endif +#include "gfile.h" +#include "gioerror.h" +#include "gthemedicon.h" +#include "gfileicon.h" +#include +#include "glibintl.h" +#include "giomodule-priv.h" +#include "gappinfo.h" +#include "gappinfoprivate.h" +#include "glocalfilemonitor.h" + +#ifdef G_OS_UNIX +#include "gdocumentportal.h" +#endif + +/** + * SECTION:gdesktopappinfo + * @title: GDesktopAppInfo + * @short_description: Application information from desktop files + * @include: gio/gdesktopappinfo.h + * + * #GDesktopAppInfo is an implementation of #GAppInfo based on + * desktop files. + * + * Note that `` belongs to the UNIX-specific + * GIO interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config + * file when using it. + */ + +#define DEFAULT_APPLICATIONS_GROUP "Default Applications" +#define ADDED_ASSOCIATIONS_GROUP "Added Associations" +#define REMOVED_ASSOCIATIONS_GROUP "Removed Associations" +#define MIME_CACHE_GROUP "MIME Cache" +#define GENERIC_NAME_KEY "GenericName" +#define FULL_NAME_KEY "X-GNOME-FullName" +#define KEYWORDS_KEY "Keywords" +#define STARTUP_WM_CLASS_KEY "StartupWMClass" + +enum { + PROP_0, + PROP_FILENAME +}; + +static void g_desktop_app_info_iface_init (GAppInfoIface *iface); +static gboolean g_desktop_app_info_ensure_saved (GDesktopAppInfo *info, + GError **error); + +/** + * GDesktopAppInfo: + * + * Information about an installed application from a desktop file. + */ +struct _GDesktopAppInfo +{ + GObject parent_instance; + + char *desktop_id; + char *filename; + char *app_id; + + GKeyFile *keyfile; + + char *name; + char *generic_name; + char *fullname; + char *comment; + char *icon_name; + GIcon *icon; + char **keywords; + char **only_show_in; + char **not_show_in; + char *try_exec; + char *exec; + char *binary; + char *path; + char *categories; + char *startup_wm_class; + char **mime_types; + char **actions; + + guint nodisplay : 1; + guint hidden : 1; + guint terminal : 1; + guint startup_notify : 1; + guint no_fuse : 1; +}; + +typedef enum { + UPDATE_MIME_NONE = 1 << 0, + UPDATE_MIME_SET_DEFAULT = 1 << 1, + UPDATE_MIME_SET_NON_DEFAULT = 1 << 2, + UPDATE_MIME_REMOVE = 1 << 3, + UPDATE_MIME_SET_LAST_USED = 1 << 4, +} UpdateMimeFlags; + +G_DEFINE_TYPE_WITH_CODE (GDesktopAppInfo, g_desktop_app_info, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_APP_INFO, g_desktop_app_info_iface_init)) + +/* DesktopFileDir implementation {{{1 */ + +typedef struct +{ + gchar *path; + gchar *alternatively_watching; + gboolean is_config; + gboolean is_setup; + GFileMonitor *monitor; + GHashTable *app_names; + GHashTable *mime_tweaks; + GHashTable *memory_index; + GHashTable *memory_implementations; +} DesktopFileDir; + +static DesktopFileDir *desktop_file_dirs; +static guint n_desktop_file_dirs; +static const gchar *desktop_file_dirs_config_dir = NULL; +static const guint desktop_file_dir_user_config_index = 0; +static guint desktop_file_dir_user_data_index; +static GMutex desktop_file_dir_lock; +static const gchar *gio_launch_desktop_path = NULL; + +/* Monitor 'changed' signal handler {{{2 */ +static void desktop_file_dir_reset (DesktopFileDir *dir); + +/*< internal > + * desktop_file_dir_get_alternative_dir: + * @dir: a #DesktopFileDir + * + * Gets the "alternative" directory to monitor in case the path + * doesn't exist. + * + * If the path exists this will return NULL, otherwise it will return a + * parent directory of the path. + * + * This is used to avoid inotify on a non-existent directory (which + * results in polling). + * + * See https://bugzilla.gnome.org/show_bug.cgi?id=522314 for more info. + */ +static gchar * +desktop_file_dir_get_alternative_dir (DesktopFileDir *dir) +{ + gchar *parent; + + /* If the directory itself exists then we need no alternative. */ + if (g_access (dir->path, R_OK | X_OK) == 0) + return NULL; + + /* Otherwise, try the parent directories until we find one. */ + parent = g_path_get_dirname (dir->path); + + while (g_access (parent, R_OK | X_OK) != 0) + { + gchar *tmp = parent; + + parent = g_path_get_dirname (tmp); + + /* If somehow we get to '/' or '.' then just stop... */ + if (g_str_equal (parent, tmp)) + { + g_free (tmp); + break; + } + + g_free (tmp); + } + + return parent; +} + +static void +desktop_file_dir_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + DesktopFileDir *dir = user_data; + gboolean do_nothing = FALSE; + + /* We are not interested in receiving notifications forever just + * because someone asked about one desktop file once. + * + * After we receive the first notification, reset the dir, destroying + * the monitor. We will take this as a hint, next time that we are + * asked, that we need to check if everything is up to date. + * + * If this is a notification for a parent directory (because the + * desktop directory didn't exist) then we shouldn't fire the signal + * unless something actually changed. + */ + g_mutex_lock (&desktop_file_dir_lock); + + if (dir->alternatively_watching) + { + gchar *alternative_dir; + + alternative_dir = desktop_file_dir_get_alternative_dir (dir); + do_nothing = alternative_dir && g_str_equal (dir->alternatively_watching, alternative_dir); + g_free (alternative_dir); + } + + if (!do_nothing) + desktop_file_dir_reset (dir); + + g_mutex_unlock (&desktop_file_dir_lock); + + /* Notify anyone else who may be interested */ + if (!do_nothing) + g_app_info_monitor_fire (); +} + +/* Internal utility functions {{{2 */ + +/*< internal > + * desktop_file_dir_app_name_is_masked: + * @dir: a #DesktopFileDir + * @app_name: an application ID + * + * Checks if @app_name is masked for @dir. + * + * An application is masked if a similarly-named desktop file exists in + * a desktop file directory with higher precedence. Masked desktop + * files should be ignored. + */ +static gboolean +desktop_file_dir_app_name_is_masked (DesktopFileDir *dir, + const gchar *app_name) +{ + while (dir > desktop_file_dirs) + { + dir--; + + if (dir->app_names && g_hash_table_contains (dir->app_names, app_name)) + return TRUE; + } + + return FALSE; +} + +static const gchar * const * +get_lowercase_current_desktops (void) +{ + static gchar **result; + + if (g_once_init_enter (&result)) + { + const gchar *envvar; + gchar **tmp; + + envvar = g_getenv ("XDG_CURRENT_DESKTOP"); + + if (envvar) + { + gint i, j; + + tmp = g_strsplit (envvar, G_SEARCHPATH_SEPARATOR_S, 0); + + for (i = 0; tmp[i]; i++) + for (j = 0; tmp[i][j]; j++) + tmp[i][j] = g_ascii_tolower (tmp[i][j]); + } + else + tmp = g_new0 (gchar *, 0 + 1); + + g_once_init_leave (&result, tmp); + } + + return (const gchar **) result; +} + +static const gchar * const * +get_current_desktops (const gchar *value) +{ + static gchar **result; + + if (g_once_init_enter (&result)) + { + gchar **tmp; + + if (!value) + value = g_getenv ("XDG_CURRENT_DESKTOP"); + + if (!value) + value = ""; + + tmp = g_strsplit (value, ":", 0); + + g_once_init_leave (&result, tmp); + } + + return (const gchar **) result; +} + +/*< internal > + * add_to_table_if_appropriate: + * @apps: a string to GDesktopAppInfo hash table + * @app_name: the name of the application + * @info: a #GDesktopAppInfo, or NULL + * + * If @info is non-%NULL and non-hidden, then add it to @apps, using + * @app_name as a key. + * + * If @info is non-%NULL then this function will consume the passed-in + * reference. + */ +static void +add_to_table_if_appropriate (GHashTable *apps, + const gchar *app_name, + GDesktopAppInfo *info) +{ + if (!info) + return; + + if (info->hidden) + { + g_object_unref (info); + return; + } + + g_free (info->desktop_id); + info->desktop_id = g_strdup (app_name); + + g_hash_table_insert (apps, g_strdup (info->desktop_id), info); +} + +enum +{ + DESKTOP_KEY_Comment, + DESKTOP_KEY_Exec, + DESKTOP_KEY_GenericName, + DESKTOP_KEY_Keywords, + DESKTOP_KEY_Name, + DESKTOP_KEY_X_GNOME_FullName, + + N_DESKTOP_KEYS +}; + +const gchar desktop_key_match_category[N_DESKTOP_KEYS] = { + /* Note: lower numbers are a better match. + * + * In case we want two keys to match at the same level, we can just + * use the same number for the two different keys. + */ + [DESKTOP_KEY_Name] = 1, + [DESKTOP_KEY_Exec] = 2, + [DESKTOP_KEY_Keywords] = 3, + [DESKTOP_KEY_GenericName] = 4, + [DESKTOP_KEY_X_GNOME_FullName] = 5, + [DESKTOP_KEY_Comment] = 6 +}; + +/* Common prefix commands to ignore from Exec= lines */ +const char * const exec_key_match_blacklist[] = { + "bash", + "env", + "flatpak", + "gjs", + "pkexec", + "python", + "python2", + "python3", + "sh", + "wine", + "wine64", + NULL +}; + +static gchar * +desktop_key_get_name (guint key_id) +{ + switch (key_id) + { + case DESKTOP_KEY_Comment: + return "Comment"; + case DESKTOP_KEY_Exec: + return "Exec"; + case DESKTOP_KEY_GenericName: + return GENERIC_NAME_KEY; + case DESKTOP_KEY_Keywords: + return KEYWORDS_KEY; + case DESKTOP_KEY_Name: + return "Name"; + case DESKTOP_KEY_X_GNOME_FullName: + return FULL_NAME_KEY; + default: + g_assert_not_reached (); + } +} + +/* Search global state {{{2 + * + * We only ever search under a global lock, so we can use (and reuse) + * some global data to reduce allocations made while searching. + * + * In short, we keep around arrays of results that we expand as needed + * (and never shrink). + * + * static_token_results: this is where we append the results for each + * token within a given desktop directory, as we handle it (which is + * a union of all matches for this term) + * + * static_search_results: this is where we build the complete results + * for a single directory (which is an intersection of the matches + * found for each term) + * + * static_total_results: this is where we build the complete results + * across all directories (which is a union of the matches found in + * each directory) + * + * The app_names that enter these tables are always pointer-unique (in + * the sense that string equality is the same as pointer equality). + * This can be guaranteed for two reasons: + * + * - we mask appids so that a given appid will only ever appear within + * the highest-precedence directory that contains it. We never + * return search results from a lower-level directory if a desktop + * file exists in a higher-level one. + * + * - within a given directory, the string is unique because it's the + * key in the hashtable of all app_ids for that directory. + * + * We perform a merging of the results in merge_token_results(). This + * works by ordering the two lists and moving through each of them (at + * the same time) looking for common elements, rejecting uncommon ones. + * "Order" here need not mean any particular thing, as long as it is + * some order. Because of the uniqueness of our strings, we can use + * pointer order. That's what's going on in compare_results() below. + */ +struct search_result +{ + const gchar *app_name; + gint category; +}; + +static struct search_result *static_token_results; +static gint static_token_results_size; +static gint static_token_results_allocated; +static struct search_result *static_search_results; +static gint static_search_results_size; +static gint static_search_results_allocated; +static struct search_result *static_total_results; +static gint static_total_results_size; +static gint static_total_results_allocated; + +/* And some functions for performing nice operations against it */ +static gint +compare_results (gconstpointer a, + gconstpointer b) +{ + const struct search_result *ra = a; + const struct search_result *rb = b; + + if (ra->app_name < rb->app_name) + return -1; + + else if (ra->app_name > rb->app_name) + return 1; + + else + return ra->category - rb->category; +} + +static gint +compare_categories (gconstpointer a, + gconstpointer b) +{ + const struct search_result *ra = a; + const struct search_result *rb = b; + + return ra->category - rb->category; +} + +static void +add_token_result (const gchar *app_name, + guint16 category) +{ + if G_UNLIKELY (static_token_results_size == static_token_results_allocated) + { + static_token_results_allocated = MAX (16, static_token_results_allocated * 2); + static_token_results = g_renew (struct search_result, static_token_results, static_token_results_allocated); + } + + static_token_results[static_token_results_size].app_name = app_name; + static_token_results[static_token_results_size].category = category; + static_token_results_size++; +} + +static void +merge_token_results (gboolean first) +{ + if (static_token_results_size != 0) + qsort (static_token_results, static_token_results_size, sizeof (struct search_result), compare_results); + + /* If this is the first token then we are basically merging a list with + * itself -- we only perform de-duplication. + * + * If this is not the first token then we are doing a real merge. + */ + if (first) + { + const gchar *last_name = NULL; + gint i; + + /* We must de-duplicate, but we do so by taking the best category + * in each case. + * + * The final list can be as large as the input here, so make sure + * we have enough room (even if it's too much room). + */ + + if G_UNLIKELY (static_search_results_allocated < static_token_results_size) + { + static_search_results_allocated = static_token_results_allocated; + static_search_results = g_renew (struct search_result, + static_search_results, + static_search_results_allocated); + } + + for (i = 0; i < static_token_results_size; i++) + { + /* The list is sorted so that the best match for a given id + * will be at the front, so once we have copied an id, skip + * the rest of the entries for the same id. + */ + if (static_token_results[i].app_name == last_name) + continue; + + last_name = static_token_results[i].app_name; + + static_search_results[static_search_results_size++] = static_token_results[i]; + } + } + else + { + const gchar *last_name = NULL; + gint i, j = 0; + gint k = 0; + + /* We only ever remove items from the results list, so no need to + * resize to ensure that we have enough room. + */ + for (i = 0; i < static_token_results_size; i++) + { + if (static_token_results[i].app_name == last_name) + continue; + + last_name = static_token_results[i].app_name; + + /* Now we only want to have a result in static_search_results + * if we already have it there *and* we have it in + * static_token_results as well. The category will be the + * lesser of the two. + * + * Skip past the results in static_search_results that are not + * going to be matches. + */ + while (k < static_search_results_size && + static_search_results[k].app_name < static_token_results[i].app_name) + k++; + + if (k < static_search_results_size && + static_search_results[k].app_name == static_token_results[i].app_name) + { + /* We have a match. + * + * Category should be the worse of the two (ie: + * numerically larger). + */ + static_search_results[j].app_name = static_search_results[k].app_name; + static_search_results[j].category = MAX (static_search_results[k].category, + static_token_results[i].category); + j++; + } + } + + static_search_results_size = j; + } + + /* Clear it out for next time... */ + static_token_results_size = 0; +} + +static void +reset_total_search_results (void) +{ + static_total_results_size = 0; +} + +static void +sort_total_search_results (void) +{ + if (static_total_results_size != 0) + qsort (static_total_results, static_total_results_size, sizeof (struct search_result), compare_categories); +} + +static void +merge_directory_results (void) +{ + if G_UNLIKELY (static_total_results_size + static_search_results_size > static_total_results_allocated) + { + static_total_results_allocated = MAX (16, static_total_results_allocated); + while (static_total_results_allocated < static_total_results_size + static_search_results_size) + static_total_results_allocated *= 2; + static_total_results = g_renew (struct search_result, static_total_results, static_total_results_allocated); + } + + if (static_total_results + static_total_results_size != 0) + memcpy (static_total_results + static_total_results_size, + static_search_results, + static_search_results_size * sizeof (struct search_result)); + + static_total_results_size += static_search_results_size; + + /* Clear it out for next time... */ + static_search_results_size = 0; +} + +/* Support for unindexed DesktopFileDirs {{{2 */ +static void +get_apps_from_dir (GHashTable **apps, + const char *dirname, + const char *prefix) +{ + const char *basename; + GDir *dir; + + dir = g_dir_open (dirname, 0, NULL); + + if (dir == NULL) + return; + + while ((basename = g_dir_read_name (dir)) != NULL) + { + gchar *filename; + + filename = g_build_filename (dirname, basename, NULL); + + if (g_str_has_suffix (basename, ".desktop")) + { + gchar *app_name; + + app_name = g_strconcat (prefix, basename, NULL); + + if (*apps == NULL) + *apps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + g_hash_table_insert (*apps, app_name, g_strdup (filename)); + } + else if (g_file_test (filename, G_FILE_TEST_IS_DIR)) + { + gchar *subprefix; + + subprefix = g_strconcat (prefix, basename, "-", NULL); + get_apps_from_dir (apps, filename, subprefix); + g_free (subprefix); + } + + g_free (filename); + } + + g_dir_close (dir); +} + +typedef struct +{ + gchar **additions; + gchar **removals; + gchar **defaults; +} UnindexedMimeTweaks; + +static void +free_mime_tweaks (gpointer data) +{ + UnindexedMimeTweaks *tweaks = data; + + g_strfreev (tweaks->additions); + g_strfreev (tweaks->removals); + g_strfreev (tweaks->defaults); + + g_slice_free (UnindexedMimeTweaks, tweaks); +} + +static UnindexedMimeTweaks * +desktop_file_dir_unindexed_get_tweaks (DesktopFileDir *dir, + const gchar *mime_type) +{ + UnindexedMimeTweaks *tweaks; + gchar *unaliased_type; + + unaliased_type = _g_unix_content_type_unalias (mime_type); + tweaks = g_hash_table_lookup (dir->mime_tweaks, unaliased_type); + + if (tweaks == NULL) + { + tweaks = g_slice_new0 (UnindexedMimeTweaks); + g_hash_table_insert (dir->mime_tweaks, unaliased_type, tweaks); + } + else + g_free (unaliased_type); + + return tweaks; +} + +/* consumes 'to_add' */ +static void +expand_strv (gchar ***strv_ptr, + gchar **to_add, + gchar * const *blacklist) +{ + guint strv_len, add_len; + gchar **strv; + guint i, j; + + if (!*strv_ptr) + { + *strv_ptr = to_add; + return; + } + + strv = *strv_ptr; + strv_len = g_strv_length (strv); + add_len = g_strv_length (to_add); + strv = g_renew (gchar *, strv, strv_len + add_len + 1); + + for (i = 0; to_add[i]; i++) + { + /* Don't add blacklisted strings */ + if (blacklist) + for (j = 0; blacklist[j]; j++) + if (g_str_equal (to_add[i], blacklist[j])) + goto no_add; + + /* Don't add duplicates already in the list */ + for (j = 0; j < strv_len; j++) + if (g_str_equal (to_add[i], strv[j])) + goto no_add; + + strv[strv_len++] = to_add[i]; + continue; + +no_add: + g_free (to_add[i]); + } + + strv[strv_len] = NULL; + *strv_ptr = strv; + + g_free (to_add); +} + +static void +desktop_file_dir_unindexed_read_mimeapps_list (DesktopFileDir *dir, + const gchar *filename, + const gchar *added_group, + gboolean tweaks_permitted) +{ + UnindexedMimeTweaks *tweaks; + char **desktop_file_ids; + GKeyFile *key_file; + gchar **mime_types; + int i; + + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL)) + { + g_key_file_free (key_file); + return; + } + + mime_types = g_key_file_get_keys (key_file, added_group, NULL, NULL); + + if G_UNLIKELY (mime_types != NULL && !tweaks_permitted) + { + g_warning ("%s contains a [%s] group, but it is not permitted here. Only the non-desktop-specific " + "mimeapps.list file may add or remove associations.", filename, added_group); + g_strfreev (mime_types); + mime_types = NULL; + } + + if (mime_types != NULL) + { + for (i = 0; mime_types[i] != NULL; i++) + { + desktop_file_ids = g_key_file_get_string_list (key_file, added_group, mime_types[i], NULL, NULL); + + if (desktop_file_ids) + { + tweaks = desktop_file_dir_unindexed_get_tweaks (dir, mime_types[i]); + expand_strv (&tweaks->additions, desktop_file_ids, tweaks->removals); + } + } + + g_strfreev (mime_types); + } + + mime_types = g_key_file_get_keys (key_file, REMOVED_ASSOCIATIONS_GROUP, NULL, NULL); + + if G_UNLIKELY (mime_types != NULL && !tweaks_permitted) + { + g_warning ("%s contains a [%s] group, but it is not permitted here. Only the non-desktop-specific " + "mimeapps.list file may add or remove associations.", filename, REMOVED_ASSOCIATIONS_GROUP); + g_strfreev (mime_types); + mime_types = NULL; + } + + if (mime_types != NULL) + { + for (i = 0; mime_types[i] != NULL; i++) + { + desktop_file_ids = g_key_file_get_string_list (key_file, REMOVED_ASSOCIATIONS_GROUP, mime_types[i], NULL, NULL); + + if (desktop_file_ids) + { + tweaks = desktop_file_dir_unindexed_get_tweaks (dir, mime_types[i]); + expand_strv (&tweaks->removals, desktop_file_ids, tweaks->additions); + } + } + + g_strfreev (mime_types); + } + + mime_types = g_key_file_get_keys (key_file, DEFAULT_APPLICATIONS_GROUP, NULL, NULL); + + if (mime_types != NULL) + { + for (i = 0; mime_types[i] != NULL; i++) + { + desktop_file_ids = g_key_file_get_string_list (key_file, DEFAULT_APPLICATIONS_GROUP, mime_types[i], NULL, NULL); + + if (desktop_file_ids) + { + tweaks = desktop_file_dir_unindexed_get_tweaks (dir, mime_types[i]); + expand_strv (&tweaks->defaults, desktop_file_ids, NULL); + } + } + + g_strfreev (mime_types); + } + + g_key_file_free (key_file); +} + +static void +desktop_file_dir_unindexed_read_mimeapps_lists (DesktopFileDir *dir) +{ + const gchar * const *desktops; + gchar *filename; + gint i; + + dir->mime_tweaks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_mime_tweaks); + + /* We process in order of precedence, using a blacklisting approach to + * avoid recording later instructions that conflict with ones we found + * earlier. + * + * We first start with the XDG_CURRENT_DESKTOP files, in precedence + * order. + */ + desktops = get_lowercase_current_desktops (); + for (i = 0; desktops[i]; i++) + { + filename = g_strdup_printf ("%s/%s-mimeapps.list", dir->path, desktops[i]); + desktop_file_dir_unindexed_read_mimeapps_list (dir, filename, ADDED_ASSOCIATIONS_GROUP, FALSE); + g_free (filename); + } + + /* Next, the non-desktop-specific mimeapps.list */ + filename = g_strdup_printf ("%s/mimeapps.list", dir->path); + desktop_file_dir_unindexed_read_mimeapps_list (dir, filename, ADDED_ASSOCIATIONS_GROUP, TRUE); + g_free (filename); + + /* The remaining files are only checked for in directories that might + * contain desktop files (ie: not the config dirs). + */ + if (dir->is_config) + return; + + /* We have 'defaults.list' which was only ever understood by GLib. It + * exists widely, but it has never been part of any spec and it should + * be treated as deprecated. This will be removed in a future + * version. + */ + filename = g_strdup_printf ("%s/defaults.list", dir->path); + desktop_file_dir_unindexed_read_mimeapps_list (dir, filename, ADDED_ASSOCIATIONS_GROUP, FALSE); + g_free (filename); + + /* Finally, the mimeinfo.cache, which is just a cached copy of what we + * would find in the MimeTypes= lines of all of the desktop files. + */ + filename = g_strdup_printf ("%s/mimeinfo.cache", dir->path); + desktop_file_dir_unindexed_read_mimeapps_list (dir, filename, MIME_CACHE_GROUP, TRUE); + g_free (filename); +} + +static void +desktop_file_dir_unindexed_init (DesktopFileDir *dir) +{ + if (!dir->is_config) + get_apps_from_dir (&dir->app_names, dir->path, ""); + + desktop_file_dir_unindexed_read_mimeapps_lists (dir); +} + +static GDesktopAppInfo * +desktop_file_dir_unindexed_get_app (DesktopFileDir *dir, + const gchar *desktop_id) +{ + const gchar *filename; + + filename = g_hash_table_lookup (dir->app_names, desktop_id); + + if (!filename) + return NULL; + + return g_desktop_app_info_new_from_filename (filename); +} + +static void +desktop_file_dir_unindexed_get_all (DesktopFileDir *dir, + GHashTable *apps) +{ + GHashTableIter iter; + gpointer app_name; + gpointer filename; + + if (dir->app_names == NULL) + return; + + g_hash_table_iter_init (&iter, dir->app_names); + while (g_hash_table_iter_next (&iter, &app_name, &filename)) + { + if (desktop_file_dir_app_name_is_masked (dir, app_name)) + continue; + + add_to_table_if_appropriate (apps, app_name, g_desktop_app_info_new_from_filename (filename)); + } +} + +typedef struct _MemoryIndexEntry MemoryIndexEntry; +typedef GHashTable MemoryIndex; + +struct _MemoryIndexEntry +{ + const gchar *app_name; /* pointer to the hashtable key */ + gint match_category; + MemoryIndexEntry *next; +}; + +static void +memory_index_entry_free (gpointer data) +{ + MemoryIndexEntry *mie = data; + + while (mie) + { + MemoryIndexEntry *next = mie->next; + + g_slice_free (MemoryIndexEntry, mie); + mie = next; + } +} + +static void +memory_index_add_token (MemoryIndex *mi, + const gchar *token, + gint match_category, + const gchar *app_name) +{ + MemoryIndexEntry *mie, *first; + + mie = g_slice_new (MemoryIndexEntry); + mie->app_name = app_name; + mie->match_category = match_category; + + first = g_hash_table_lookup (mi, token); + + if (first) + { + mie->next = first->next; + first->next = mie; + } + else + { + mie->next = NULL; + g_hash_table_insert (mi, g_strdup (token), mie); + } +} + +static void +memory_index_add_string (MemoryIndex *mi, + const gchar *string, + gint match_category, + const gchar *app_name) +{ + gchar **tokens, **alternates; + gint i; + + tokens = g_str_tokenize_and_fold (string, NULL, &alternates); + + for (i = 0; tokens[i]; i++) + memory_index_add_token (mi, tokens[i], match_category, app_name); + + for (i = 0; alternates[i]; i++) + memory_index_add_token (mi, alternates[i], match_category, app_name); + + g_strfreev (alternates); + g_strfreev (tokens); +} + +static MemoryIndex * +memory_index_new (void) +{ + return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, memory_index_entry_free); +} + +static void +desktop_file_dir_unindexed_setup_search (DesktopFileDir *dir) +{ + GHashTableIter iter; + gpointer app, path; + + dir->memory_index = memory_index_new (); + dir->memory_implementations = memory_index_new (); + + /* Nothing to search? */ + if (dir->app_names == NULL) + return; + + g_hash_table_iter_init (&iter, dir->app_names); + while (g_hash_table_iter_next (&iter, &app, &path)) + { + GKeyFile *key_file; + + if (desktop_file_dir_app_name_is_masked (dir, app)) + continue; + + key_file = g_key_file_new (); + + if (g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, NULL) && + !g_key_file_get_boolean (key_file, "Desktop Entry", "Hidden", NULL)) + { + /* Index the interesting keys... */ + gchar **implements; + gint i; + + for (i = 0; i < G_N_ELEMENTS (desktop_key_match_category); i++) + { + const gchar *value; + gchar *raw; + + if (!desktop_key_match_category[i]) + continue; + + raw = g_key_file_get_locale_string (key_file, "Desktop Entry", desktop_key_get_name (i), NULL, NULL); + value = raw; + + if (i == DESKTOP_KEY_Exec && raw != NULL) + { + /* Special handling: only match basename of first field */ + gchar *space; + gchar *slash; + + /* Remove extra arguments, if any */ + space = raw + strcspn (raw, " \t\n"); /* IFS */ + *space = '\0'; + + /* Skip the pathname, if any */ + if ((slash = strrchr (raw, '/'))) + value = slash + 1; + + /* Don't match on blacklisted binaries like interpreters */ + if (g_strv_contains (exec_key_match_blacklist, value)) + value = NULL; + } + + if (value) + memory_index_add_string (dir->memory_index, value, desktop_key_match_category[i], app); + + g_free (raw); + } + + /* Make note of the Implements= line */ + implements = g_key_file_get_string_list (key_file, "Desktop Entry", "Implements", NULL, NULL); + for (i = 0; implements && implements[i]; i++) + memory_index_add_token (dir->memory_implementations, implements[i], 0, app); + g_strfreev (implements); + } + + g_key_file_free (key_file); + } +} + +static void +desktop_file_dir_unindexed_search (DesktopFileDir *dir, + const gchar *search_token) +{ + GHashTableIter iter; + gpointer key, value; + + if (!dir->memory_index) + desktop_file_dir_unindexed_setup_search (dir); + + g_hash_table_iter_init (&iter, dir->memory_index); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + MemoryIndexEntry *mie = value; + + if (!g_str_has_prefix (key, search_token)) + continue; + + while (mie) + { + add_token_result (mie->app_name, mie->match_category); + mie = mie->next; + } + } +} + +static gboolean +array_contains (GPtrArray *array, + const gchar *str) +{ + gint i; + + for (i = 0; i < array->len; i++) + if (g_str_equal (array->pdata[i], str)) + return TRUE; + + return FALSE; +} + +static void +desktop_file_dir_unindexed_mime_lookup (DesktopFileDir *dir, + const gchar *mime_type, + GPtrArray *hits, + GPtrArray *blacklist) +{ + UnindexedMimeTweaks *tweaks; + gint i; + + tweaks = g_hash_table_lookup (dir->mime_tweaks, mime_type); + + if (!tweaks) + return; + + if (tweaks->additions) + { + for (i = 0; tweaks->additions[i]; i++) + { + gchar *app_name = tweaks->additions[i]; + + if (!desktop_file_dir_app_name_is_masked (dir, app_name) && + !array_contains (blacklist, app_name) && !array_contains (hits, app_name)) + g_ptr_array_add (hits, app_name); + } + } + + if (tweaks->removals) + { + for (i = 0; tweaks->removals[i]; i++) + { + gchar *app_name = tweaks->removals[i]; + + if (!desktop_file_dir_app_name_is_masked (dir, app_name) && + !array_contains (blacklist, app_name) && !array_contains (hits, app_name)) + g_ptr_array_add (blacklist, app_name); + } + } +} + +static void +desktop_file_dir_unindexed_default_lookup (DesktopFileDir *dir, + const gchar *mime_type, + GPtrArray *results) +{ + UnindexedMimeTweaks *tweaks; + gint i; + + tweaks = g_hash_table_lookup (dir->mime_tweaks, mime_type); + + if (!tweaks || !tweaks->defaults) + return; + + for (i = 0; tweaks->defaults[i]; i++) + { + gchar *app_name = tweaks->defaults[i]; + + if (!array_contains (results, app_name)) + g_ptr_array_add (results, app_name); + } +} + +static void +desktop_file_dir_unindexed_get_implementations (DesktopFileDir *dir, + GList **results, + const gchar *interface) +{ + MemoryIndexEntry *mie; + + if (!dir->memory_index) + desktop_file_dir_unindexed_setup_search (dir); + + for (mie = g_hash_table_lookup (dir->memory_implementations, interface); mie; mie = mie->next) + *results = g_list_prepend (*results, g_strdup (mie->app_name)); +} + +/* DesktopFileDir "API" {{{2 */ + +/*< internal > + * desktop_file_dir_create: + * @array: the #GArray to add a new item to + * @data_dir: an XDG_DATA_DIR + * + * Creates a #DesktopFileDir for the corresponding @data_dir, adding it + * to @array. + */ +static void +desktop_file_dir_create (GArray *array, + const gchar *data_dir) +{ + DesktopFileDir dir = { 0, }; + + dir.path = g_build_filename (data_dir, "applications", NULL); + + g_array_append_val (array, dir); +} + +/*< internal > + * desktop_file_dir_create: + * @array: the #GArray to add a new item to + * @config_dir: an XDG_CONFIG_DIR + * + * Just the same as desktop_file_dir_create() except that it does not + * add the "applications" directory. It also marks the directory as + * config-only, which prevents us from attempting to find desktop files + * here. + */ +static void +desktop_file_dir_create_for_config (GArray *array, + const gchar *config_dir) +{ + DesktopFileDir dir = { 0, }; + + dir.path = g_strdup (config_dir); + dir.is_config = TRUE; + + g_array_append_val (array, dir); +} + +/*< internal > + * desktop_file_dir_reset: + * @dir: a #DesktopFileDir + * + * Cleans up @dir, releasing most resources that it was using. + */ +static void +desktop_file_dir_reset (DesktopFileDir *dir) +{ + if (dir->alternatively_watching) + { + g_free (dir->alternatively_watching); + dir->alternatively_watching = NULL; + } + + if (dir->monitor) + { + g_signal_handlers_disconnect_by_func (dir->monitor, desktop_file_dir_changed, dir); + g_object_unref (dir->monitor); + dir->monitor = NULL; + } + + if (dir->app_names) + { + g_hash_table_unref (dir->app_names); + dir->app_names = NULL; + } + + if (dir->memory_index) + { + g_hash_table_unref (dir->memory_index); + dir->memory_index = NULL; + } + + if (dir->mime_tweaks) + { + g_hash_table_unref (dir->mime_tweaks); + dir->mime_tweaks = NULL; + } + + if (dir->memory_implementations) + { + g_hash_table_unref (dir->memory_implementations); + dir->memory_implementations = NULL; + } + + dir->is_setup = FALSE; +} + +/*< internal > + * desktop_file_dir_init: + * @dir: a #DesktopFileDir + * + * Does initial setup for @dir + * + * You should only call this if @dir is not already setup. + */ +static void +desktop_file_dir_init (DesktopFileDir *dir) +{ + const gchar *watch_dir; + + g_assert (!dir->is_setup); + + g_assert (!dir->alternatively_watching); + g_assert (!dir->monitor); + + dir->alternatively_watching = desktop_file_dir_get_alternative_dir (dir); + watch_dir = dir->alternatively_watching ? dir->alternatively_watching : dir->path; + + /* There is a very thin race here if the watch_dir has been _removed_ + * between when we checked for it and when we establish the watch. + * Removes probably don't happen in usual operation, and even if it + * does (and we catch the unlikely race), the only degradation is that + * we will fall back to polling. + */ + dir->monitor = g_local_file_monitor_new_in_worker (watch_dir, TRUE, G_FILE_MONITOR_NONE, + desktop_file_dir_changed, dir, NULL); + + desktop_file_dir_unindexed_init (dir); + + dir->is_setup = TRUE; +} + +/*< internal > + * desktop_file_dir_get_app: + * @dir: a DesktopFileDir + * @desktop_id: the desktop ID to load + * + * Creates the #GDesktopAppInfo for the given @desktop_id if it exists + * within @dir, even if it is hidden. + * + * This function does not check if @desktop_id would be masked by a + * directory with higher precedence. The caller must do so. + */ +static GDesktopAppInfo * +desktop_file_dir_get_app (DesktopFileDir *dir, + const gchar *desktop_id) +{ + if (!dir->app_names) + return NULL; + + return desktop_file_dir_unindexed_get_app (dir, desktop_id); +} + +/*< internal > + * desktop_file_dir_get_all: + * @dir: a DesktopFileDir + * @apps: a #GHashTable + * + * Loads all desktop files in @dir and adds them to @apps, careful to + * ensure we don't add any files masked by a similarly-named file in a + * higher-precedence directory. + */ +static void +desktop_file_dir_get_all (DesktopFileDir *dir, + GHashTable *apps) +{ + desktop_file_dir_unindexed_get_all (dir, apps); +} + +/*< internal > + * desktop_file_dir_mime_lookup: + * @dir: a #DesktopFileDir + * @mime_type: the mime type to look up + * @hits: the array to store the hits + * @blacklist: the array to store the blacklist + * + * Does a lookup of a mimetype against one desktop file directory, + * recording any hits and blacklisting and "Removed" associations (so + * later directories don't record them as hits). + * + * The items added to @hits are duplicated, but the ones in @blacklist + * are weak pointers. This facilitates simply freeing the blacklist + * (which is only used for internal bookkeeping) but using the pdata of + * @hits as the result of the operation. + */ +static void +desktop_file_dir_mime_lookup (DesktopFileDir *dir, + const gchar *mime_type, + GPtrArray *hits, + GPtrArray *blacklist) +{ + desktop_file_dir_unindexed_mime_lookup (dir, mime_type, hits, blacklist); +} + +/*< internal > + * desktop_file_dir_default_lookup: + * @dir: a #DesktopFileDir + * @mime_type: the mime type to look up + * @results: an array to store the results in + * + * Collects the "default" applications for a given mime type from @dir. + */ +static void +desktop_file_dir_default_lookup (DesktopFileDir *dir, + const gchar *mime_type, + GPtrArray *results) +{ + desktop_file_dir_unindexed_default_lookup (dir, mime_type, results); +} + +/*< internal > + * desktop_file_dir_search: + * @dir: a #DesktopFileDir + * @term: a normalised and casefolded search term + * + * Finds the names of applications in @dir that match @term. + */ +static void +desktop_file_dir_search (DesktopFileDir *dir, + const gchar *search_token) +{ + desktop_file_dir_unindexed_search (dir, search_token); +} + +static void +desktop_file_dir_get_implementations (DesktopFileDir *dir, + GList **results, + const gchar *interface) +{ + desktop_file_dir_unindexed_get_implementations (dir, results, interface); +} + +/* Lock/unlock and global setup API {{{2 */ + +static void +desktop_file_dirs_lock (void) +{ + gint i; + const gchar *user_config_dir = g_get_user_config_dir (); + + g_mutex_lock (&desktop_file_dir_lock); + + /* If the XDG dirs configuration has changed (expected only during tests), + * clear and reload the state. */ + if (g_strcmp0 (desktop_file_dirs_config_dir, user_config_dir) != 0) + { + g_debug ("%s: Resetting desktop app info dirs from %s to %s", + G_STRFUNC, desktop_file_dirs_config_dir, user_config_dir); + + for (i = 0; i < n_desktop_file_dirs; i++) + desktop_file_dir_reset (&desktop_file_dirs[i]); + g_clear_pointer (&desktop_file_dirs, g_free); + n_desktop_file_dirs = 0; + desktop_file_dir_user_data_index = 0; + } + + if (desktop_file_dirs == NULL) + { + const char * const *dirs; + GArray *tmp; + gint i; + + tmp = g_array_new (FALSE, FALSE, sizeof (DesktopFileDir)); + + /* First, the configs. Highest priority: the user's ~/.config */ + desktop_file_dir_create_for_config (tmp, user_config_dir); + + /* Next, the system configs (/etc/xdg, and so on). */ + dirs = g_get_system_config_dirs (); + for (i = 0; dirs[i]; i++) + desktop_file_dir_create_for_config (tmp, dirs[i]); + + /* Now the data. Highest priority: the user's ~/.local/share/applications */ + desktop_file_dir_user_data_index = tmp->len; + desktop_file_dir_create (tmp, g_get_user_data_dir ()); + + /* Following that, XDG_DATA_DIRS/applications, in order */ + dirs = g_get_system_data_dirs (); + for (i = 0; dirs[i]; i++) + desktop_file_dir_create (tmp, dirs[i]); + + /* The list of directories will never change after this, unless + * g_get_user_config_dir() changes due to %G_TEST_OPTION_ISOLATE_DIRS. */ + desktop_file_dirs = (DesktopFileDir *) tmp->data; + n_desktop_file_dirs = tmp->len; + desktop_file_dirs_config_dir = user_config_dir; + + g_array_free (tmp, FALSE); + } + + for (i = 0; i < n_desktop_file_dirs; i++) + if (!desktop_file_dirs[i].is_setup) + desktop_file_dir_init (&desktop_file_dirs[i]); +} + +static void +desktop_file_dirs_unlock (void) +{ + g_mutex_unlock (&desktop_file_dir_lock); +} + +static void +desktop_file_dirs_invalidate_user_config (void) +{ + g_mutex_lock (&desktop_file_dir_lock); + + if (n_desktop_file_dirs) + desktop_file_dir_reset (&desktop_file_dirs[desktop_file_dir_user_config_index]); + + g_mutex_unlock (&desktop_file_dir_lock); +} + +static void +desktop_file_dirs_invalidate_user_data (void) +{ + g_mutex_lock (&desktop_file_dir_lock); + + if (n_desktop_file_dirs) + desktop_file_dir_reset (&desktop_file_dirs[desktop_file_dir_user_data_index]); + + g_mutex_unlock (&desktop_file_dir_lock); +} + +/* GDesktopAppInfo implementation {{{1 */ +/* GObject implementation {{{2 */ +static void +g_desktop_app_info_finalize (GObject *object) +{ + GDesktopAppInfo *info; + + info = G_DESKTOP_APP_INFO (object); + + g_free (info->desktop_id); + g_free (info->filename); + + if (info->keyfile) + g_key_file_unref (info->keyfile); + + g_free (info->name); + g_free (info->generic_name); + g_free (info->fullname); + g_free (info->comment); + g_free (info->icon_name); + if (info->icon) + g_object_unref (info->icon); + g_strfreev (info->keywords); + g_strfreev (info->only_show_in); + g_strfreev (info->not_show_in); + g_free (info->try_exec); + g_free (info->exec); + g_free (info->binary); + g_free (info->path); + g_free (info->categories); + g_free (info->startup_wm_class); + g_strfreev (info->mime_types); + g_free (info->app_id); + g_strfreev (info->actions); + + G_OBJECT_CLASS (g_desktop_app_info_parent_class)->finalize (object); +} + +static void +g_desktop_app_info_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GDesktopAppInfo *self = G_DESKTOP_APP_INFO (object); + + switch (prop_id) + { + case PROP_FILENAME: + self->filename = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_desktop_app_info_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GDesktopAppInfo *self = G_DESKTOP_APP_INFO (object); + + switch (prop_id) + { + case PROP_FILENAME: + g_value_set_string (value, self->filename); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +g_desktop_app_info_class_init (GDesktopAppInfoClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = g_desktop_app_info_get_property; + gobject_class->set_property = g_desktop_app_info_set_property; + gobject_class->finalize = g_desktop_app_info_finalize; + + /** + * GDesktopAppInfo:filename: + * + * The origin filename of this #GDesktopAppInfo + */ + g_object_class_install_property (gobject_class, + PROP_FILENAME, + g_param_spec_string ("filename", "Filename", "", NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + +static void +g_desktop_app_info_init (GDesktopAppInfo *local) +{ +} + +/* Construction... {{{2 */ + +/*< internal > + * binary_from_exec: + * @exec: an exec line + * + * Returns the first word in an exec line (ie: the binary name). + * + * If @exec is " progname --foo %F" then returns "progname". + */ +static char * +binary_from_exec (const char *exec) +{ + const char *p, *start; + + p = exec; + while (*p == ' ') + p++; + start = p; + while (*p != ' ' && *p != 0) + p++; + + return g_strndup (start, p - start); +} + +static gboolean +g_desktop_app_info_load_from_keyfile (GDesktopAppInfo *info, + GKeyFile *key_file) +{ + char *start_group; + char *type; + char *try_exec; + char *exec; + gboolean bus_activatable; + + start_group = g_key_file_get_start_group (key_file); + if (start_group == NULL || strcmp (start_group, G_KEY_FILE_DESKTOP_GROUP) != 0) + { + g_free (start_group); + return FALSE; + } + g_free (start_group); + + type = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TYPE, + NULL); + if (type == NULL || strcmp (type, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0) + { + g_free (type); + return FALSE; + } + g_free (type); + + try_exec = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, + NULL); + if (try_exec && try_exec[0] != '\0') + { + char *t; + t = g_find_program_in_path (try_exec); + if (t == NULL) + { + g_free (try_exec); + return FALSE; + } + g_free (t); + } + + exec = g_key_file_get_string (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, + NULL); + if (exec && exec[0] != '\0') + { + gint argc; + char **argv; + if (!g_shell_parse_argv (exec, &argc, &argv, NULL)) + { + g_free (exec); + g_free (try_exec); + return FALSE; + } + else + { + char *t; + t = g_find_program_in_path (argv[0]); + g_strfreev (argv); + + if (t == NULL) + { + g_free (exec); + g_free (try_exec); + return FALSE; + } + g_free (t); + } + } + + info->name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, NULL, NULL); + info->generic_name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, GENERIC_NAME_KEY, NULL, NULL); + info->fullname = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, FULL_NAME_KEY, NULL, NULL); + info->keywords = g_key_file_get_locale_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, KEYWORDS_KEY, NULL, NULL, NULL); + info->comment = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, NULL, NULL); + info->nodisplay = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL) != FALSE; + info->icon_name = g_key_file_get_locale_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL, NULL); + info->only_show_in = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN, NULL, NULL); + info->not_show_in = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN, NULL, NULL); + info->try_exec = try_exec; + info->exec = exec; + info->path = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_PATH, NULL); + info->terminal = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TERMINAL, NULL) != FALSE; + info->startup_notify = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY, NULL) != FALSE; + info->no_fuse = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GIO-NoFuse", NULL) != FALSE; + info->hidden = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL) != FALSE; + info->categories = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_CATEGORIES, NULL); + info->startup_wm_class = g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, STARTUP_WM_CLASS_KEY, NULL); + info->mime_types = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_MIME_TYPE, NULL, NULL); + bus_activatable = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_DBUS_ACTIVATABLE, NULL); + info->actions = g_key_file_get_string_list (key_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ACTIONS, NULL, NULL); + + /* Remove the special-case: no Actions= key just means 0 extra actions */ + if (info->actions == NULL) + info->actions = g_new0 (gchar *, 0 + 1); + + info->icon = NULL; + if (info->icon_name) + { + if (g_path_is_absolute (info->icon_name)) + { + GFile *file; + + file = g_file_new_for_path (info->icon_name); + info->icon = g_file_icon_new (file); + g_object_unref (file); + } + else + { + char *p; + + /* Work around a common mistake in desktop files */ + if ((p = strrchr (info->icon_name, '.')) != NULL && + (strcmp (p, ".png") == 0 || + strcmp (p, ".xpm") == 0 || + strcmp (p, ".svg") == 0)) + *p = 0; + + info->icon = g_themed_icon_new (info->icon_name); + } + } + + if (info->exec) + info->binary = binary_from_exec (info->exec); + + if (info->path && info->path[0] == '\0') + { + g_free (info->path); + info->path = NULL; + } + + /* Can only be DBusActivatable if we know the filename, which means + * that this won't work for the load-from-keyfile case. + */ + if (bus_activatable && info->filename) + { + gchar *basename; + gchar *last_dot; + + basename = g_path_get_basename (info->filename); + last_dot = strrchr (basename, '.'); + + if (last_dot && g_str_equal (last_dot, ".desktop")) + { + *last_dot = '\0'; + + if (g_dbus_is_name (basename) && basename[0] != ':') + info->app_id = g_strdup (basename); + } + + g_free (basename); + } + + info->keyfile = g_key_file_ref (key_file); + + return TRUE; +} + +static gboolean +g_desktop_app_info_load_file (GDesktopAppInfo *self) +{ + GKeyFile *key_file; + gboolean retval = FALSE; + + g_return_val_if_fail (self->filename != NULL, FALSE); + + self->desktop_id = g_path_get_basename (self->filename); + + key_file = g_key_file_new (); + + if (g_key_file_load_from_file (key_file, self->filename, G_KEY_FILE_NONE, NULL)) + retval = g_desktop_app_info_load_from_keyfile (self, key_file); + + g_key_file_unref (key_file); + return retval; +} + +/** + * g_desktop_app_info_new_from_keyfile: + * @key_file: an opened #GKeyFile + * + * Creates a new #GDesktopAppInfo. + * + * Returns: (nullable): a new #GDesktopAppInfo or %NULL on error. + * + * Since: 2.18 + **/ +GDesktopAppInfo * +g_desktop_app_info_new_from_keyfile (GKeyFile *key_file) +{ + GDesktopAppInfo *info; + + info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL); + info->filename = NULL; + if (!g_desktop_app_info_load_from_keyfile (info, key_file)) + { + g_object_unref (info); + return NULL; + } + return info; +} + +/** + * g_desktop_app_info_new_from_filename: + * @filename: (type filename): the path of a desktop file, in the GLib + * filename encoding + * + * Creates a new #GDesktopAppInfo. + * + * Returns: (nullable): a new #GDesktopAppInfo or %NULL on error. + **/ +GDesktopAppInfo * +g_desktop_app_info_new_from_filename (const char *filename) +{ + GDesktopAppInfo *info = NULL; + + info = g_object_new (G_TYPE_DESKTOP_APP_INFO, "filename", filename, NULL); + if (!g_desktop_app_info_load_file (info)) + { + g_object_unref (info); + return NULL; + } + return info; +} + +/** + * g_desktop_app_info_new: + * @desktop_id: the desktop file id + * + * Creates a new #GDesktopAppInfo based on a desktop file id. + * + * A desktop file id is the basename of the desktop file, including the + * .desktop extension. GIO is looking for a desktop file with this name + * in the `applications` subdirectories of the XDG + * data directories (i.e. the directories specified in the `XDG_DATA_HOME` + * and `XDG_DATA_DIRS` environment variables). GIO also supports the + * prefix-to-subdirectory mapping that is described in the + * [Menu Spec](http://standards.freedesktop.org/menu-spec/latest/) + * (i.e. a desktop id of kde-foo.desktop will match + * `/usr/share/applications/kde/foo.desktop`). + * + * Returns: (nullable): a new #GDesktopAppInfo, or %NULL if no desktop + * file with that id exists. + */ +GDesktopAppInfo * +g_desktop_app_info_new (const char *desktop_id) +{ + GDesktopAppInfo *appinfo = NULL; + guint i; + + desktop_file_dirs_lock (); + + for (i = 0; i < n_desktop_file_dirs; i++) + { + appinfo = desktop_file_dir_get_app (&desktop_file_dirs[i], desktop_id); + + if (appinfo) + break; + } + + desktop_file_dirs_unlock (); + + if (appinfo == NULL) + return NULL; + + g_free (appinfo->desktop_id); + appinfo->desktop_id = g_strdup (desktop_id); + + if (g_desktop_app_info_get_is_hidden (appinfo)) + { + g_object_unref (appinfo); + appinfo = NULL; + } + + return appinfo; +} + +static GAppInfo * +g_desktop_app_info_dup (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + GDesktopAppInfo *new_info; + + new_info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL); + + new_info->filename = g_strdup (info->filename); + new_info->desktop_id = g_strdup (info->desktop_id); + + if (info->keyfile) + new_info->keyfile = g_key_file_ref (info->keyfile); + + new_info->name = g_strdup (info->name); + new_info->generic_name = g_strdup (info->generic_name); + new_info->fullname = g_strdup (info->fullname); + new_info->keywords = g_strdupv (info->keywords); + new_info->comment = g_strdup (info->comment); + new_info->nodisplay = info->nodisplay; + new_info->icon_name = g_strdup (info->icon_name); + if (info->icon) + new_info->icon = g_object_ref (info->icon); + new_info->only_show_in = g_strdupv (info->only_show_in); + new_info->not_show_in = g_strdupv (info->not_show_in); + new_info->try_exec = g_strdup (info->try_exec); + new_info->exec = g_strdup (info->exec); + new_info->binary = g_strdup (info->binary); + new_info->path = g_strdup (info->path); + new_info->app_id = g_strdup (info->app_id); + new_info->hidden = info->hidden; + new_info->terminal = info->terminal; + new_info->startup_notify = info->startup_notify; + + return G_APP_INFO (new_info); +} + +/* GAppInfo interface implementation functions {{{2 */ + +static gboolean +g_desktop_app_info_equal (GAppInfo *appinfo1, + GAppInfo *appinfo2) +{ + GDesktopAppInfo *info1 = G_DESKTOP_APP_INFO (appinfo1); + GDesktopAppInfo *info2 = G_DESKTOP_APP_INFO (appinfo2); + + if (info1->desktop_id == NULL || + info2->desktop_id == NULL) + return info1 == info2; + + return strcmp (info1->desktop_id, info2->desktop_id) == 0; +} + +static const char * +g_desktop_app_info_get_id (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->desktop_id; +} + +static const char * +g_desktop_app_info_get_name (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->name == NULL) + return _("Unnamed"); + return info->name; +} + +static const char * +g_desktop_app_info_get_display_name (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->fullname == NULL) + return g_desktop_app_info_get_name (appinfo); + return info->fullname; +} + +/** + * g_desktop_app_info_get_is_hidden: + * @info: a #GDesktopAppInfo. + * + * A desktop file is hidden if the Hidden key in it is + * set to True. + * + * Returns: %TRUE if hidden, %FALSE otherwise. + **/ +gboolean +g_desktop_app_info_get_is_hidden (GDesktopAppInfo *info) +{ + return info->hidden; +} + +/** + * g_desktop_app_info_get_filename: + * @info: a #GDesktopAppInfo + * + * When @info was created from a known filename, return it. In some + * situations such as the #GDesktopAppInfo returned from + * g_desktop_app_info_new_from_keyfile(), this function will return %NULL. + * + * Returns: (type filename): The full path to the file for @info, + * or %NULL if not known. + * Since: 2.24 + */ +const char * +g_desktop_app_info_get_filename (GDesktopAppInfo *info) +{ + return info->filename; +} + +static const char * +g_desktop_app_info_get_description (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->comment; +} + +static const char * +g_desktop_app_info_get_executable (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->binary; +} + +static const char * +g_desktop_app_info_get_commandline (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->exec; +} + +static GIcon * +g_desktop_app_info_get_icon (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->icon; +} + +/** + * g_desktop_app_info_get_categories: + * @info: a #GDesktopAppInfo + * + * Gets the categories from the desktop file. + * + * Returns: The unparsed Categories key from the desktop file; + * i.e. no attempt is made to split it by ';' or validate it. + */ +const char * +g_desktop_app_info_get_categories (GDesktopAppInfo *info) +{ + return info->categories; +} + +/** + * g_desktop_app_info_get_keywords: + * @info: a #GDesktopAppInfo + * + * Gets the keywords from the desktop file. + * + * Returns: (transfer none): The value of the Keywords key + * + * Since: 2.32 + */ +const char * const * +g_desktop_app_info_get_keywords (GDesktopAppInfo *info) +{ + return (const char * const *)info->keywords; +} + +/** + * g_desktop_app_info_get_generic_name: + * @info: a #GDesktopAppInfo + * + * Gets the generic name from the destkop file. + * + * Returns: The value of the GenericName key + */ +const char * +g_desktop_app_info_get_generic_name (GDesktopAppInfo *info) +{ + return info->generic_name; +} + +/** + * g_desktop_app_info_get_nodisplay: + * @info: a #GDesktopAppInfo + * + * Gets the value of the NoDisplay key, which helps determine if the + * application info should be shown in menus. See + * #G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY and g_app_info_should_show(). + * + * Returns: The value of the NoDisplay key + * + * Since: 2.30 + */ +gboolean +g_desktop_app_info_get_nodisplay (GDesktopAppInfo *info) +{ + return info->nodisplay; +} + +/** + * g_desktop_app_info_get_show_in: + * @info: a #GDesktopAppInfo + * @desktop_env: (nullable): a string specifying a desktop name + * + * Checks if the application info should be shown in menus that list available + * applications for a specific name of the desktop, based on the + * `OnlyShowIn` and `NotShowIn` keys. + * + * @desktop_env should typically be given as %NULL, in which case the + * `XDG_CURRENT_DESKTOP` environment variable is consulted. If you want + * to override the default mechanism then you may specify @desktop_env, + * but this is not recommended. + * + * Note that g_app_info_should_show() for @info will include this check (with + * %NULL for @desktop_env) as well as additional checks. + * + * Returns: %TRUE if the @info should be shown in @desktop_env according to the + * `OnlyShowIn` and `NotShowIn` keys, %FALSE + * otherwise. + * + * Since: 2.30 + */ +gboolean +g_desktop_app_info_get_show_in (GDesktopAppInfo *info, + const gchar *desktop_env) +{ + const gchar *specified_envs[] = { desktop_env, NULL }; + const gchar * const *envs; + gint i; + + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), FALSE); + + if (desktop_env) + envs = specified_envs; + else + envs = get_current_desktops (NULL); + + for (i = 0; envs[i]; i++) + { + gint j; + + if (info->only_show_in) + for (j = 0; info->only_show_in[j]; j++) + if (g_str_equal (info->only_show_in[j], envs[i])) + return TRUE; + + if (info->not_show_in) + for (j = 0; info->not_show_in[j]; j++) + if (g_str_equal (info->not_show_in[j], envs[i])) + return FALSE; + } + + return info->only_show_in == NULL; +} + +/* Launching... {{{2 */ + +static char * +expand_macro_single (char macro, const char *uri) +{ + GFile *file; + char *result = NULL; + char *path = NULL; + char *name; + + file = g_file_new_for_uri (uri); + + switch (macro) + { + case 'u': + case 'U': + result = g_shell_quote (uri); + break; + case 'f': + case 'F': + path = g_file_get_path (file); + if (path) + result = g_shell_quote (path); + break; + case 'd': + case 'D': + path = g_file_get_path (file); + if (path) + { + name = g_path_get_dirname (path); + result = g_shell_quote (name); + g_free (name); + } + break; + case 'n': + case 'N': + path = g_file_get_path (file); + if (path) + { + name = g_path_get_basename (path); + result = g_shell_quote (name); + g_free (name); + } + break; + } + + g_object_unref (file); + g_free (path); + + return result; +} + +static char * +expand_macro_uri (char macro, const char *uri, gboolean force_file_uri, char force_file_uri_macro) +{ + char *expanded = NULL; + + g_return_val_if_fail (uri != NULL, NULL); + + if (!force_file_uri || + /* Pass URI if it contains an anchor */ + strchr (uri, '#') != NULL) + { + expanded = expand_macro_single (macro, uri); + } + else + { + expanded = expand_macro_single (force_file_uri_macro, uri); + if (expanded == NULL) + expanded = expand_macro_single (macro, uri); + } + + return expanded; +} + +static void +expand_macro (char macro, + GString *exec, + GDesktopAppInfo *info, + GList **uri_list) +{ + GList *uris = *uri_list; + char *expanded = NULL; + gboolean force_file_uri; + char force_file_uri_macro; + const char *uri; + + g_return_if_fail (exec != NULL); + + /* On %u and %U, pass POSIX file path pointing to the URI via + * the FUSE mount in ~/.gvfs. Note that if the FUSE daemon isn't + * running or the URI doesn't have a POSIX file path via FUSE + * we'll just pass the URI. + */ + force_file_uri_macro = macro; + force_file_uri = FALSE; + if (!info->no_fuse) + { + switch (macro) + { + case 'u': + force_file_uri_macro = 'f'; + force_file_uri = TRUE; + break; + case 'U': + force_file_uri_macro = 'F'; + force_file_uri = TRUE; + break; + default: + break; + } + } + + switch (macro) + { + case 'u': + case 'f': + case 'd': + case 'n': + if (uris) + { + uri = uris->data; + expanded = expand_macro_uri (macro, uri, + force_file_uri, force_file_uri_macro); + if (expanded) + { + g_string_append (exec, expanded); + g_free (expanded); + } + uris = uris->next; + } + + break; + + case 'U': + case 'F': + case 'D': + case 'N': + while (uris) + { + uri = uris->data; + expanded = expand_macro_uri (macro, uri, + force_file_uri, force_file_uri_macro); + if (expanded) + { + g_string_append (exec, expanded); + g_free (expanded); + } + + uris = uris->next; + + if (uris != NULL && expanded) + g_string_append_c (exec, ' '); + } + + break; + + case 'i': + if (info->icon_name) + { + g_string_append (exec, "--icon "); + expanded = g_shell_quote (info->icon_name); + g_string_append (exec, expanded); + g_free (expanded); + } + break; + + case 'c': + if (info->name) + { + expanded = g_shell_quote (info->name); + g_string_append (exec, expanded); + g_free (expanded); + } + break; + + case 'k': + if (info->filename) + { + expanded = g_shell_quote (info->filename); + g_string_append (exec, expanded); + g_free (expanded); + } + break; + + case 'm': /* deprecated */ + break; + + case '%': + g_string_append_c (exec, '%'); + break; + } + + *uri_list = uris; +} + +static gboolean +expand_application_parameters (GDesktopAppInfo *info, + const gchar *exec_line, + GList **uris, + int *argc, + char ***argv, + GError **error) +{ + GList *uri_list = *uris; + const char *p = exec_line; + GString *expanded_exec; + gboolean res; + + if (exec_line == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Desktop file didn’t specify Exec field")); + return FALSE; + } + + expanded_exec = g_string_new (NULL); + + while (*p) + { + if (p[0] == '%' && p[1] != '\0') + { + expand_macro (p[1], expanded_exec, info, uris); + p++; + } + else + g_string_append_c (expanded_exec, *p); + + p++; + } + + /* No file substitutions */ + if (uri_list == *uris && uri_list != NULL) + { + /* If there is no macro default to %f. This is also what KDE does */ + g_string_append_c (expanded_exec, ' '); + expand_macro ('f', expanded_exec, info, uris); + } + + res = g_shell_parse_argv (expanded_exec->str, argc, argv, error); + g_string_free (expanded_exec, TRUE); + return res; +} + +static gboolean +prepend_terminal_to_vector (int *argc, + char ***argv) +{ +#ifndef G_OS_WIN32 + char **real_argv; + int real_argc; + int i, j; + char **term_argv = NULL; + int term_argc = 0; + char *check; + char **the_argv; + + g_return_val_if_fail (argc != NULL, FALSE); + g_return_val_if_fail (argv != NULL, FALSE); + + /* sanity */ + if(*argv == NULL) + *argc = 0; + + the_argv = *argv; + + /* compute size if not given */ + if (*argc < 0) + { + for (i = 0; the_argv[i] != NULL; i++) + ; + *argc = i; + } + + term_argc = 2; + term_argv = g_new0 (char *, 3); + + check = g_find_program_in_path ("gnome-terminal"); + if (check != NULL) + { + term_argv[0] = check; + /* Note that gnome-terminal takes -x and + * as -e in gnome-terminal is broken we use that. */ + term_argv[1] = g_strdup ("-x"); + } + else + { + if (check == NULL) + check = g_find_program_in_path ("nxterm"); + if (check == NULL) + check = g_find_program_in_path ("color-xterm"); + if (check == NULL) + check = g_find_program_in_path ("rxvt"); + if (check == NULL) + check = g_find_program_in_path ("dtterm"); + if (check == NULL) + { + check = g_strdup ("xterm"); + g_debug ("Couldn’t find a terminal: falling back to xterm"); + } + term_argv[0] = check; + term_argv[1] = g_strdup ("-e"); + } + + real_argc = term_argc + *argc; + real_argv = g_new (char *, real_argc + 1); + + for (i = 0; i < term_argc; i++) + real_argv[i] = term_argv[i]; + + for (j = 0; j < *argc; j++, i++) + real_argv[i] = (char *)the_argv[j]; + + real_argv[i] = NULL; + + g_free (*argv); + *argv = real_argv; + *argc = real_argc; + + /* we use g_free here as we sucked all the inner strings + * out from it into real_argv */ + g_free (term_argv); + return TRUE; +#else + return FALSE; +#endif /* G_OS_WIN32 */ +} + +static GList * +create_files_for_uris (GList *uris) +{ + GList *res; + GList *iter; + + res = NULL; + + for (iter = uris; iter; iter = iter->next) + { + GFile *file = g_file_new_for_uri ((char *)iter->data); + res = g_list_prepend (res, file); + } + + return g_list_reverse (res); +} + +static void +notify_desktop_launch (GDBusConnection *session_bus, + GDesktopAppInfo *info, + long pid, + const char *display, + const char *sn_id, + GList *uris) +{ + GDBusMessage *msg; + GVariantBuilder uri_variant; + GVariantBuilder extras_variant; + GList *iter; + const char *desktop_file_id; + const char *gio_desktop_file; + + if (session_bus == NULL) + return; + + g_variant_builder_init (&uri_variant, G_VARIANT_TYPE ("as")); + for (iter = uris; iter; iter = iter->next) + g_variant_builder_add (&uri_variant, "s", iter->data); + + g_variant_builder_init (&extras_variant, G_VARIANT_TYPE ("a{sv}")); + if (sn_id != NULL && g_utf8_validate (sn_id, -1, NULL)) + g_variant_builder_add (&extras_variant, "{sv}", + "startup-id", + g_variant_new ("s", + sn_id)); + gio_desktop_file = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE"); + if (gio_desktop_file != NULL) + g_variant_builder_add (&extras_variant, "{sv}", + "origin-desktop-file", + g_variant_new_bytestring (gio_desktop_file)); + if (g_get_prgname () != NULL) + g_variant_builder_add (&extras_variant, "{sv}", + "origin-prgname", + g_variant_new_bytestring (g_get_prgname ())); + g_variant_builder_add (&extras_variant, "{sv}", + "origin-pid", + g_variant_new ("x", + (gint64)getpid ())); + + if (info->filename) + desktop_file_id = info->filename; + else if (info->desktop_id) + desktop_file_id = info->desktop_id; + else + desktop_file_id = ""; + + msg = g_dbus_message_new_signal ("/org/gtk/gio/DesktopAppInfo", + "org.gtk.gio.DesktopAppInfo", + "Launched"); + g_dbus_message_set_body (msg, g_variant_new ("(@aysxasa{sv})", + g_variant_new_bytestring (desktop_file_id), + display ? display : "", + (gint64)pid, + &uri_variant, + &extras_variant)); + g_dbus_connection_send_message (session_bus, + msg, 0, + NULL, + NULL); + g_object_unref (msg); +} + +#define _SPAWN_FLAGS_DEFAULT (G_SPAWN_SEARCH_PATH) + +static gboolean +g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info, + GDBusConnection *session_bus, + const gchar *exec_line, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + GError **error) +{ + gboolean completed = FALSE; + GList *old_uris; + GList *dup_uris; + + char **argv, **envp; + int argc; + + g_return_val_if_fail (info != NULL, FALSE); + + argv = NULL; + + if (launch_context) + envp = g_app_launch_context_get_environment (launch_context); + else + envp = g_get_environ (); + + /* The GList* passed to expand_application_parameters() will be modified + * internally by expand_macro(), so we need to pass a copy of it instead, + * and also use that copy to control the exit condition of the loop below. + */ + dup_uris = g_list_copy (uris); + do + { + GPid pid; + GList *launched_uris; + GList *iter; + char *sn_id = NULL; + char **wrapped_argv; + int i; + + old_uris = dup_uris; + if (!expand_application_parameters (info, exec_line, &dup_uris, &argc, &argv, error)) + goto out; + + /* Get the subset of URIs we're launching with this process */ + launched_uris = NULL; + for (iter = old_uris; iter != NULL && iter != dup_uris; iter = iter->next) + launched_uris = g_list_prepend (launched_uris, iter->data); + launched_uris = g_list_reverse (launched_uris); + + if (info->terminal && !prepend_terminal_to_vector (&argc, &argv)) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Unable to find terminal required for application")); + goto out; + } + + if (info->filename) + envp = g_environ_setenv (envp, + "GIO_LAUNCHED_DESKTOP_FILE", + info->filename, + TRUE); + + sn_id = NULL; + if (launch_context) + { + GList *launched_files = create_files_for_uris (launched_uris); + + if (info->startup_notify) + { + sn_id = g_app_launch_context_get_startup_notify_id (launch_context, + G_APP_INFO (info), + launched_files); + if (sn_id) + envp = g_environ_setenv (envp, "DESKTOP_STARTUP_ID", sn_id, TRUE); + } + + g_list_free_full (launched_files, g_object_unref); + } + + if (g_once_init_enter (&gio_launch_desktop_path)) + { + const gchar *tmp; + + /* Allow test suite to specify path to gio-launch-desktop */ + tmp = g_getenv ("GIO_LAUNCH_DESKTOP"); + + /* Fall back on usual searching in $PATH */ + if (tmp == NULL) + tmp = "gio-launch-desktop"; + g_once_init_leave (&gio_launch_desktop_path, tmp); + } + + wrapped_argv = g_new (char *, argc + 2); + wrapped_argv[0] = g_strdup (gio_launch_desktop_path); + + for (i = 0; i < argc; i++) + wrapped_argv[i + 1] = g_steal_pointer (&argv[i]); + + wrapped_argv[i + 1] = NULL; + g_free (argv); + argv = NULL; + + if (!g_spawn_async_with_fds (info->path, + wrapped_argv, + envp, + spawn_flags, + user_setup, + user_setup_data, + &pid, + stdin_fd, + stdout_fd, + stderr_fd, + error)) + { + if (sn_id) + g_app_launch_context_launch_failed (launch_context, sn_id); + + g_free (sn_id); + g_list_free (launched_uris); + + goto out; + } + + if (pid_callback != NULL) + pid_callback (info, pid, pid_callback_data); + + if (launch_context != NULL) + { + GVariantBuilder builder; + GVariant *platform_data; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (&builder, "{sv}", "pid", g_variant_new_int32 (pid)); + if (sn_id) + g_variant_builder_add (&builder, "{sv}", "startup-notification-id", g_variant_new_string (sn_id)); + platform_data = g_variant_ref_sink (g_variant_builder_end (&builder)); + g_signal_emit_by_name (launch_context, "launched", info, platform_data); + g_variant_unref (platform_data); + } + + notify_desktop_launch (session_bus, + info, + pid, + NULL, + sn_id, + launched_uris); + + g_free (sn_id); + g_list_free (launched_uris); + + g_strfreev (wrapped_argv); + wrapped_argv = NULL; + } + while (dup_uris != NULL); + + completed = TRUE; + + out: + g_list_free (dup_uris); + g_strfreev (argv); + g_strfreev (envp); + + return completed; +} + +static gchar * +object_path_from_appid (const gchar *appid) +{ + gchar *appid_path, *iter; + + appid_path = g_strconcat ("/", appid, NULL); + for (iter = appid_path; *iter; iter++) + { + if (*iter == '.') + *iter = '/'; + + if (*iter == '-') + *iter = '_'; + } + + return appid_path; +} + +static GVariant * +g_desktop_app_info_make_platform_data (GDesktopAppInfo *info, + GList *uris, + GAppLaunchContext *launch_context) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + + if (launch_context) + { + GList *launched_files = create_files_for_uris (uris); + + if (info->startup_notify) + { + gchar *sn_id; + + sn_id = g_app_launch_context_get_startup_notify_id (launch_context, G_APP_INFO (info), launched_files); + if (sn_id) + g_variant_builder_add (&builder, "{sv}", "desktop-startup-id", g_variant_new_take_string (sn_id)); + } + + g_list_free_full (launched_files, g_object_unref); + } + + return g_variant_builder_end (&builder); +} + +static void +launch_uris_with_dbus (GDesktopAppInfo *info, + GDBusConnection *session_bus, + GList *uris, + GAppLaunchContext *launch_context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GVariantBuilder builder; + gchar *object_path; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); + + if (uris) + { + GList *iter; + + g_variant_builder_open (&builder, G_VARIANT_TYPE_STRING_ARRAY); + for (iter = uris; iter; iter = iter->next) + g_variant_builder_add (&builder, "s", iter->data); + g_variant_builder_close (&builder); + } + + g_variant_builder_add_value (&builder, g_desktop_app_info_make_platform_data (info, uris, launch_context)); + + object_path = object_path_from_appid (info->app_id); + g_dbus_connection_call (session_bus, info->app_id, object_path, "org.freedesktop.Application", + uris ? "Open" : "Activate", g_variant_builder_end (&builder), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + cancellable, callback, user_data); + g_free (object_path); +} + +static gboolean +g_desktop_app_info_launch_uris_with_dbus (GDesktopAppInfo *info, + GDBusConnection *session_bus, + GList *uris, + GAppLaunchContext *launch_context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GList *ruris = uris; + char *app_id = NULL; + + g_return_val_if_fail (info != NULL, FALSE); + +#ifdef G_OS_UNIX + app_id = g_desktop_app_info_get_string (info, "X-Flatpak"); + if (app_id && *app_id) + { + ruris = g_document_portal_add_documents (uris, app_id, NULL); + if (ruris == NULL) + ruris = uris; + } +#endif + + launch_uris_with_dbus (info, session_bus, ruris, launch_context, + cancellable, callback, user_data); + + if (ruris != uris) + g_list_free_full (ruris, g_free); + + g_free (app_id); + + return TRUE; +} + +static gboolean +g_desktop_app_info_launch_uris_internal (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + GDBusConnection *session_bus; + gboolean success = TRUE; + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + if (session_bus && info->app_id) + /* This is non-blocking API. Similar to launching via fork()/exec() + * we don't wait around to see if the program crashed during startup. + * This is what startup-notification's job is... + */ + g_desktop_app_info_launch_uris_with_dbus (info, session_bus, uris, launch_context, + NULL, NULL, NULL); + else + success = g_desktop_app_info_launch_uris_with_spawn (info, session_bus, info->exec, uris, launch_context, + spawn_flags, user_setup, user_setup_data, + pid_callback, pid_callback_data, + stdin_fd, stdout_fd, stderr_fd, error); + + if (session_bus != NULL) + { + /* This asynchronous flush holds a reference until it completes, + * which ensures that the following unref won't immediately kill + * the connection if we were the initial owner. + */ + g_dbus_connection_flush (session_bus, NULL, NULL, NULL); + g_object_unref (session_bus); + } + + return success; +} + +static gboolean +g_desktop_app_info_launch_uris (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GError **error) +{ + return g_desktop_app_info_launch_uris_internal (appinfo, uris, + launch_context, + _SPAWN_FLAGS_DEFAULT, + NULL, NULL, NULL, NULL, + -1, -1, -1, + error); +} + +typedef struct +{ + GAppInfo *appinfo; + GList *uris; + GAppLaunchContext *context; +} LaunchUrisData; + +static void +launch_uris_data_free (LaunchUrisData *data) +{ + g_clear_object (&data->context); + g_list_free_full (data->uris, g_free); + g_free (data); +} + +static void +launch_uris_with_dbus_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + GError *error = NULL; + + g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error); + if (error != NULL) + { + g_dbus_error_strip_remote_error (error); + g_task_return_error (task, g_steal_pointer (&error)); + } + else + g_task_return_boolean (task, TRUE); + + g_object_unref (task); +} + +static void +launch_uris_flush_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + + g_dbus_connection_flush_finish (G_DBUS_CONNECTION (object), result, NULL); + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +launch_uris_bus_get_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GTask *task = G_TASK (user_data); + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (g_task_get_source_object (task)); + LaunchUrisData *data = g_task_get_task_data (task); + GCancellable *cancellable = g_task_get_cancellable (task); + GDBusConnection *session_bus; + GError *error = NULL; + + session_bus = g_bus_get_finish (result, NULL); + + if (session_bus && info->app_id) + { + /* FIXME: The g_document_portal_add_documents() function, which is called + * from the g_desktop_app_info_launch_uris_with_dbus() function, still + * uses blocking calls. + */ + g_desktop_app_info_launch_uris_with_dbus (info, session_bus, + data->uris, data->context, + cancellable, + launch_uris_with_dbus_cb, + g_steal_pointer (&task)); + } + else + { + /* FIXME: The D-Bus message from the notify_desktop_launch() function + * can be still lost even if flush is called later. See: + * https://gitlab.freedesktop.org/dbus/dbus/issues/72 + */ + g_desktop_app_info_launch_uris_with_spawn (info, session_bus, info->exec, + data->uris, data->context, + _SPAWN_FLAGS_DEFAULT, NULL, + NULL, NULL, NULL, -1, -1, -1, + &error); + if (error != NULL) + { + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + } + else + g_dbus_connection_flush (session_bus, + cancellable, + launch_uris_flush_cb, + g_steal_pointer (&task)); + } + + g_clear_object (&session_bus); +} + +static void +g_desktop_app_info_launch_uris_async (GAppInfo *appinfo, + GList *uris, + GAppLaunchContext *context, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + LaunchUrisData *data; + + task = g_task_new (appinfo, cancellable, callback, user_data); + g_task_set_source_tag (task, g_desktop_app_info_launch_uris_async); + + data = g_new0 (LaunchUrisData, 1); + data->uris = g_list_copy_deep (uris, (GCopyFunc) g_strdup, NULL); + data->context = (context != NULL) ? g_object_ref (context) : NULL; + g_task_set_task_data (task, g_steal_pointer (&data), (GDestroyNotify) launch_uris_data_free); + + g_bus_get (G_BUS_TYPE_SESSION, cancellable, launch_uris_bus_get_cb, task); +} + +static gboolean +g_desktop_app_info_launch_uris_finish (GAppInfo *appinfo, + GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, appinfo), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static gboolean +g_desktop_app_info_supports_uris (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->exec && + ((strstr (info->exec, "%u") != NULL) || + (strstr (info->exec, "%U") != NULL)); +} + +static gboolean +g_desktop_app_info_supports_files (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return info->exec && + ((strstr (info->exec, "%f") != NULL) || + (strstr (info->exec, "%F") != NULL)); +} + +static gboolean +g_desktop_app_info_launch (GAppInfo *appinfo, + GList *files, + GAppLaunchContext *launch_context, + GError **error) +{ + GList *uris; + char *uri; + gboolean res; + + uris = NULL; + while (files) + { + uri = g_file_get_uri (files->data); + uris = g_list_prepend (uris, uri); + files = files->next; + } + + uris = g_list_reverse (uris); + + res = g_desktop_app_info_launch_uris (appinfo, uris, launch_context, error); + + g_list_free_full (uris, g_free); + + return res; +} + +/** + * g_desktop_app_info_launch_uris_as_manager_with_fds: + * @appinfo: a #GDesktopAppInfo + * @uris: (element-type utf8): List of URIs + * @launch_context: (nullable): a #GAppLaunchContext + * @spawn_flags: #GSpawnFlags, used for each process + * @user_setup: (scope async) (nullable): a #GSpawnChildSetupFunc, used once + * for each process. + * @user_setup_data: (closure user_setup) (nullable): User data for @user_setup + * @pid_callback: (scope call) (nullable): Callback for child processes + * @pid_callback_data: (closure pid_callback) (nullable): User data for @callback + * @stdin_fd: file descriptor to use for child's stdin, or -1 + * @stdout_fd: file descriptor to use for child's stdout, or -1 + * @stderr_fd: file descriptor to use for child's stderr, or -1 + * @error: return location for a #GError, or %NULL + * + * Equivalent to g_desktop_app_info_launch_uris_as_manager() but allows + * you to pass in file descriptors for the stdin, stdout and stderr streams + * of the launched process. + * + * If application launching occurs via some non-spawn mechanism (e.g. D-Bus + * activation) then @stdin_fd, @stdout_fd and @stderr_fd are ignored. + * + * Returns: %TRUE on successful launch, %FALSE otherwise. + * + * Since: 2.58 + */ +gboolean +g_desktop_app_info_launch_uris_as_manager_with_fds (GDesktopAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + GError **error) +{ + return g_desktop_app_info_launch_uris_internal ((GAppInfo*)appinfo, + uris, + launch_context, + spawn_flags, + user_setup, + user_setup_data, + pid_callback, + pid_callback_data, + stdin_fd, + stdout_fd, + stderr_fd, + error); +} + +/** + * g_desktop_app_info_launch_uris_as_manager: + * @appinfo: a #GDesktopAppInfo + * @uris: (element-type utf8): List of URIs + * @launch_context: (nullable): a #GAppLaunchContext + * @spawn_flags: #GSpawnFlags, used for each process + * @user_setup: (scope async) (nullable): a #GSpawnChildSetupFunc, used once + * for each process. + * @user_setup_data: (closure user_setup) (nullable): User data for @user_setup + * @pid_callback: (scope call) (nullable): Callback for child processes + * @pid_callback_data: (closure pid_callback) (nullable): User data for @callback + * @error: return location for a #GError, or %NULL + * + * This function performs the equivalent of g_app_info_launch_uris(), + * but is intended primarily for operating system components that + * launch applications. Ordinary applications should use + * g_app_info_launch_uris(). + * + * If the application is launched via GSpawn, then @spawn_flags, @user_setup + * and @user_setup_data are used for the call to g_spawn_async(). + * Additionally, @pid_callback (with @pid_callback_data) will be called to + * inform about the PID of the created process. See g_spawn_async_with_pipes() + * for information on certain parameter conditions that can enable an + * optimized posix_spawn() codepath to be used. + * + * If application launching occurs via some other mechanism (eg: D-Bus + * activation) then @spawn_flags, @user_setup, @user_setup_data, + * @pid_callback and @pid_callback_data are ignored. + * + * Returns: %TRUE on successful launch, %FALSE otherwise. + */ +gboolean +g_desktop_app_info_launch_uris_as_manager (GDesktopAppInfo *appinfo, + GList *uris, + GAppLaunchContext *launch_context, + GSpawnFlags spawn_flags, + GSpawnChildSetupFunc user_setup, + gpointer user_setup_data, + GDesktopAppLaunchCallback pid_callback, + gpointer pid_callback_data, + GError **error) +{ + return g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo, + uris, + launch_context, + spawn_flags, + user_setup, + user_setup_data, + pid_callback, + pid_callback_data, + -1, -1, -1, + error); +} + +/* OnlyShowIn API support {{{2 */ + +/** + * g_desktop_app_info_set_desktop_env: + * @desktop_env: a string specifying what desktop this is + * + * Sets the name of the desktop that the application is running in. + * This is used by g_app_info_should_show() and + * g_desktop_app_info_get_show_in() to evaluate the + * `OnlyShowIn` and `NotShowIn` + * desktop entry fields. + * + * Should be called only once; subsequent calls are ignored. + * + * Deprecated:2.42:do not use this API. Since 2.42 the value of the + * `XDG_CURRENT_DESKTOP` environment variable will be used. + */ +void +g_desktop_app_info_set_desktop_env (const gchar *desktop_env) +{ + get_current_desktops (desktop_env); +} + +static gboolean +g_desktop_app_info_should_show (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->nodisplay) + return FALSE; + + return g_desktop_app_info_get_show_in (info, NULL); +} + +/* mime types/default apps support {{{2 */ + +typedef enum { + CONF_DIR, + APP_DIR, + MIMETYPE_DIR +} DirType; + +static char * +ensure_dir (DirType type, + GError **error) +{ + char *path, *display_name; + int errsv; + + switch (type) + { + case CONF_DIR: + path = g_build_filename (g_get_user_config_dir (), NULL); + break; + + case APP_DIR: + path = g_build_filename (g_get_user_data_dir (), "applications", NULL); + break; + + case MIMETYPE_DIR: + path = g_build_filename (g_get_user_data_dir (), "mime", "packages", NULL); + break; + + default: + g_assert_not_reached (); + } + + g_debug ("%s: Ensuring %s", G_STRFUNC, path); + + errno = 0; + if (g_mkdir_with_parents (path, 0700) == 0) + return path; + + errsv = errno; + display_name = g_filename_display_name (path); + if (type == APP_DIR) + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Can’t create user application configuration folder %s: %s"), + display_name, g_strerror (errsv)); + else + g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), + _("Can’t create user MIME configuration folder %s: %s"), + display_name, g_strerror (errsv)); + + g_free (display_name); + g_free (path); + + return NULL; +} + +static gboolean +update_mimeapps_list (const char *desktop_id, + const char *content_type, + UpdateMimeFlags flags, + GError **error) +{ + char *dirname, *filename, *string; + GKeyFile *key_file; + gboolean load_succeeded, res; + char **old_list, **list; + gsize length, data_size; + char *data; + int i, j, k; + char **content_types; + + /* Don't add both at start and end */ + g_assert (!((flags & UPDATE_MIME_SET_DEFAULT) && + (flags & UPDATE_MIME_SET_NON_DEFAULT))); + + dirname = ensure_dir (CONF_DIR, error); + if (!dirname) + return FALSE; + + filename = g_build_filename (dirname, "mimeapps.list", NULL); + g_free (dirname); + + key_file = g_key_file_new (); + load_succeeded = g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL); + if (!load_succeeded || + (!g_key_file_has_group (key_file, ADDED_ASSOCIATIONS_GROUP) && + !g_key_file_has_group (key_file, REMOVED_ASSOCIATIONS_GROUP) && + !g_key_file_has_group (key_file, DEFAULT_APPLICATIONS_GROUP))) + { + g_key_file_free (key_file); + key_file = g_key_file_new (); + } + + if (content_type) + { + content_types = g_new (char *, 2); + content_types[0] = g_strdup (content_type); + content_types[1] = NULL; + } + else + { + content_types = g_key_file_get_keys (key_file, DEFAULT_APPLICATIONS_GROUP, NULL, NULL); + } + + for (k = 0; content_types && content_types[k]; k++) + { + /* set as default, if requested so */ + string = g_key_file_get_string (key_file, + DEFAULT_APPLICATIONS_GROUP, + content_types[k], + NULL); + + if (g_strcmp0 (string, desktop_id) != 0 && + (flags & UPDATE_MIME_SET_DEFAULT)) + { + g_free (string); + string = g_strdup (desktop_id); + + /* add in the non-default list too, if it's not already there */ + flags |= UPDATE_MIME_SET_NON_DEFAULT; + } + + if (string == NULL || desktop_id == NULL) + g_key_file_remove_key (key_file, + DEFAULT_APPLICATIONS_GROUP, + content_types[k], + NULL); + else + g_key_file_set_string (key_file, + DEFAULT_APPLICATIONS_GROUP, + content_types[k], + string); + + g_free (string); + } + + if (content_type) + { + /* reuse the list from above */ + } + else + { + g_strfreev (content_types); + content_types = g_key_file_get_keys (key_file, ADDED_ASSOCIATIONS_GROUP, NULL, NULL); + } + + for (k = 0; content_types && content_types[k]; k++) + { + /* Add to the right place in the list */ + + length = 0; + old_list = g_key_file_get_string_list (key_file, ADDED_ASSOCIATIONS_GROUP, + content_types[k], &length, NULL); + + list = g_new (char *, 1 + length + 1); + + i = 0; + + /* if we're adding a last-used hint, just put the application in front of the list */ + if (flags & UPDATE_MIME_SET_LAST_USED) + { + /* avoid adding this again as non-default later */ + if (flags & UPDATE_MIME_SET_NON_DEFAULT) + flags ^= UPDATE_MIME_SET_NON_DEFAULT; + + list[i++] = g_strdup (desktop_id); + } + + if (old_list) + { + for (j = 0; old_list[j] != NULL; j++) + { + if (g_strcmp0 (old_list[j], desktop_id) != 0) + { + /* rewrite other entries if they're different from the new one */ + list[i++] = g_strdup (old_list[j]); + } + else if (flags & UPDATE_MIME_SET_NON_DEFAULT) + { + /* we encountered an old entry which is equal to the one we're adding as non-default, + * don't change its position in the list. + */ + flags ^= UPDATE_MIME_SET_NON_DEFAULT; + list[i++] = g_strdup (old_list[j]); + } + } + } + + /* add it at the end of the list */ + if (flags & UPDATE_MIME_SET_NON_DEFAULT) + list[i++] = g_strdup (desktop_id); + + list[i] = NULL; + + g_strfreev (old_list); + + if (list[0] == NULL || desktop_id == NULL) + g_key_file_remove_key (key_file, + ADDED_ASSOCIATIONS_GROUP, + content_types[k], + NULL); + else + g_key_file_set_string_list (key_file, + ADDED_ASSOCIATIONS_GROUP, + content_types[k], + (const char * const *)list, i); + + g_strfreev (list); + } + + if (content_type) + { + /* reuse the list from above */ + } + else + { + g_strfreev (content_types); + content_types = g_key_file_get_keys (key_file, REMOVED_ASSOCIATIONS_GROUP, NULL, NULL); + } + + for (k = 0; content_types && content_types[k]; k++) + { + /* Remove from removed associations group (unless remove) */ + + length = 0; + old_list = g_key_file_get_string_list (key_file, REMOVED_ASSOCIATIONS_GROUP, + content_types[k], &length, NULL); + + list = g_new (char *, 1 + length + 1); + + i = 0; + if (flags & UPDATE_MIME_REMOVE) + list[i++] = g_strdup (desktop_id); + if (old_list) + { + for (j = 0; old_list[j] != NULL; j++) + { + if (g_strcmp0 (old_list[j], desktop_id) != 0) + list[i++] = g_strdup (old_list[j]); + } + } + list[i] = NULL; + + g_strfreev (old_list); + + if (list[0] == NULL || desktop_id == NULL) + g_key_file_remove_key (key_file, + REMOVED_ASSOCIATIONS_GROUP, + content_types[k], + NULL); + else + g_key_file_set_string_list (key_file, + REMOVED_ASSOCIATIONS_GROUP, + content_types[k], + (const char * const *)list, i); + + g_strfreev (list); + } + + g_strfreev (content_types); + + data = g_key_file_to_data (key_file, &data_size, error); + g_key_file_free (key_file); + + res = g_file_set_contents (filename, data, data_size, error); + + desktop_file_dirs_invalidate_user_config (); + + g_free (filename); + g_free (data); + + return res; +} + +static gboolean +g_desktop_app_info_set_as_last_used_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (!g_desktop_app_info_ensure_saved (info, error)) + return FALSE; + + if (!info->desktop_id) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Application information lacks an identifier")); + return FALSE; + } + + /* both add support for the content type and set as last used */ + return update_mimeapps_list (info->desktop_id, content_type, + UPDATE_MIME_SET_NON_DEFAULT | + UPDATE_MIME_SET_LAST_USED, + error); +} + +static gboolean +g_desktop_app_info_set_as_default_for_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (!g_desktop_app_info_ensure_saved (info, error)) + return FALSE; + + if (!info->desktop_id) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Application information lacks an identifier")); + return FALSE; + } + + return update_mimeapps_list (info->desktop_id, content_type, + UPDATE_MIME_SET_DEFAULT, + error); +} + +static void +update_program_done (GPid pid, + gint status, + gpointer data) +{ + /* Did the application exit correctly */ + if (g_spawn_check_exit_status (status, NULL)) + { + /* Here we could clean out any caches in use */ + } +} + +static void +run_update_command (char *command, + char *subdir) +{ + char *argv[3] = { + NULL, + NULL, + NULL, + }; + GPid pid = 0; + GError *error = NULL; + + argv[0] = command; + argv[1] = g_build_filename (g_get_user_data_dir (), subdir, NULL); + + if (g_spawn_async ("/", argv, + NULL, /* envp */ + G_SPAWN_SEARCH_PATH | + G_SPAWN_STDOUT_TO_DEV_NULL | + G_SPAWN_STDERR_TO_DEV_NULL | + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, /* No setup function */ + &pid, + &error)) + g_child_watch_add (pid, update_program_done, NULL); + else + { + /* If we get an error at this point, it's quite likely the user doesn't + * have an installed copy of either 'update-mime-database' or + * 'update-desktop-database'. I don't think we want to popup an error + * dialog at this point, so we just do a g_warning to give the user a + * chance of debugging it. + */ + g_warning ("%s", error->message); + g_error_free (error); + } + + g_free (argv[1]); +} + +static gboolean +g_desktop_app_info_set_as_default_for_extension (GAppInfo *appinfo, + const char *extension, + GError **error) +{ + char *filename, *basename, *mimetype; + char *dirname; + gboolean res; + + if (!g_desktop_app_info_ensure_saved (G_DESKTOP_APP_INFO (appinfo), error)) + return FALSE; + + dirname = ensure_dir (MIMETYPE_DIR, error); + if (!dirname) + return FALSE; + + basename = g_strdup_printf ("user-extension-%s.xml", extension); + filename = g_build_filename (dirname, basename, NULL); + g_free (basename); + g_free (dirname); + + mimetype = g_strdup_printf ("application/x-extension-%s", extension); + + if (!g_file_test (filename, G_FILE_TEST_EXISTS)) + { + char *contents; + + contents = + g_strdup_printf ("\n" + "\n" + " \n" + " %s document\n" + " \n" + " \n" + "\n", mimetype, extension, extension); + + g_file_set_contents (filename, contents, -1, NULL); + g_free (contents); + + run_update_command ("update-mime-database", "mime"); + } + g_free (filename); + + res = g_desktop_app_info_set_as_default_for_type (appinfo, + mimetype, + error); + + g_free (mimetype); + + return res; +} + +static gboolean +g_desktop_app_info_add_supports_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (!g_desktop_app_info_ensure_saved (G_DESKTOP_APP_INFO (info), error)) + return FALSE; + + return update_mimeapps_list (info->desktop_id, content_type, + UPDATE_MIME_SET_NON_DEFAULT, + error); +} + +static gboolean +g_desktop_app_info_can_remove_supports_type (GAppInfo *appinfo) +{ + return TRUE; +} + +static gboolean +g_desktop_app_info_remove_supports_type (GAppInfo *appinfo, + const char *content_type, + GError **error) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (!g_desktop_app_info_ensure_saved (G_DESKTOP_APP_INFO (info), error)) + return FALSE; + + return update_mimeapps_list (info->desktop_id, content_type, + UPDATE_MIME_REMOVE, + error); +} + +static const char ** +g_desktop_app_info_get_supported_types (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + return (const char**) info->mime_types; +} + +/* Saving and deleting {{{2 */ + +static gboolean +g_desktop_app_info_ensure_saved (GDesktopAppInfo *info, + GError **error) +{ + GKeyFile *key_file; + char *dirname; + char *filename; + char *data, *desktop_id; + gsize data_size; + int fd; + gboolean res; + + if (info->filename != NULL) + return TRUE; + + /* This is only used for object created with + * g_app_info_create_from_commandline. All other + * object should have a filename + */ + + dirname = ensure_dir (APP_DIR, error); + if (!dirname) + return FALSE; + + key_file = g_key_file_new (); + + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + "Encoding", "UTF-8"); + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_VERSION, "1.0"); + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TYPE, + G_KEY_FILE_DESKTOP_TYPE_APPLICATION); + if (info->terminal) + g_key_file_set_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_TERMINAL, TRUE); + if (info->nodisplay) + g_key_file_set_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, TRUE); + + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_EXEC, info->exec); + + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NAME, info->name); + + if (info->generic_name != NULL) + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + GENERIC_NAME_KEY, info->generic_name); + + if (info->fullname != NULL) + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + FULL_NAME_KEY, info->fullname); + + g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_COMMENT, info->comment); + + g_key_file_set_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, TRUE); + + data = g_key_file_to_data (key_file, &data_size, NULL); + g_key_file_free (key_file); + + desktop_id = g_strdup_printf ("userapp-%s-XXXXXX.desktop", info->name); + filename = g_build_filename (dirname, desktop_id, NULL); + g_free (desktop_id); + g_free (dirname); + + fd = g_mkstemp (filename); + if (fd == -1) + { + char *display_name; + + display_name = g_filename_display_name (filename); + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Can’t create user desktop file %s"), display_name); + g_free (display_name); + g_free (filename); + g_free (data); + return FALSE; + } + + desktop_id = g_path_get_basename (filename); + + /* FIXME - actually handle error */ + (void) g_close (fd, NULL); + + res = g_file_set_contents (filename, data, data_size, error); + g_free (data); + if (!res) + { + g_free (desktop_id); + g_free (filename); + return FALSE; + } + + info->filename = filename; + info->desktop_id = desktop_id; + + run_update_command ("update-desktop-database", "applications"); + + /* We just dropped a file in the user's desktop file directory. Save + * the monitor the bother of having to notice it and invalidate + * immediately. + * + * This means that calls directly following this will be able to see + * the results immediately. + */ + desktop_file_dirs_invalidate_user_data (); + + return TRUE; +} + +static gboolean +g_desktop_app_info_can_delete (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->filename) + { + if (strstr (info->filename, "/userapp-")) + return g_access (info->filename, W_OK) == 0; + } + + return FALSE; +} + +static gboolean +g_desktop_app_info_delete (GAppInfo *appinfo) +{ + GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo); + + if (info->filename) + { + if (g_remove (info->filename) == 0) + { + update_mimeapps_list (info->desktop_id, NULL, + UPDATE_MIME_NONE, + NULL); + + g_free (info->filename); + info->filename = NULL; + g_free (info->desktop_id); + info->desktop_id = NULL; + + return TRUE; + } + } + + return FALSE; +} + +/* Create for commandline {{{2 */ +/** + * g_app_info_create_from_commandline: + * @commandline: (type filename): the commandline to use + * @application_name: (nullable): the application name, or %NULL to use @commandline + * @flags: flags that can specify details of the created #GAppInfo + * @error: a #GError location to store the error occurring, %NULL to ignore. + * + * Creates a new #GAppInfo from the given information. + * + * Note that for @commandline, the quoting rules of the Exec key of the + * [freedesktop.org Desktop Entry Specification](http://freedesktop.org/Standards/desktop-entry-spec) + * are applied. For example, if the @commandline contains + * percent-encoded URIs, the percent-character must be doubled in order to prevent it from + * being swallowed by Exec key unquoting. See the specification for exact quoting rules. + * + * Returns: (transfer full): new #GAppInfo for given command. + **/ +GAppInfo * +g_app_info_create_from_commandline (const char *commandline, + const char *application_name, + GAppInfoCreateFlags flags, + GError **error) +{ + char **split; + char *basename; + GDesktopAppInfo *info; + + g_return_val_if_fail (commandline, NULL); + + info = g_object_new (G_TYPE_DESKTOP_APP_INFO, NULL); + + info->filename = NULL; + info->desktop_id = NULL; + + info->terminal = (flags & G_APP_INFO_CREATE_NEEDS_TERMINAL) != 0; + info->startup_notify = (flags & G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION) != 0; + info->hidden = FALSE; + if ((flags & G_APP_INFO_CREATE_SUPPORTS_URIS) != 0) + info->exec = g_strconcat (commandline, " %u", NULL); + else + info->exec = g_strconcat (commandline, " %f", NULL); + info->nodisplay = TRUE; + info->binary = binary_from_exec (info->exec); + + if (application_name) + info->name = g_strdup (application_name); + else + { + /* FIXME: this should be more robust. Maybe g_shell_parse_argv and use argv[0] */ + split = g_strsplit (commandline, " ", 2); + basename = split[0] ? g_path_get_basename (split[0]) : NULL; + g_strfreev (split); + info->name = basename; + if (info->name == NULL) + info->name = g_strdup ("custom"); + } + info->comment = g_strdup_printf (_("Custom definition for %s"), info->name); + + return G_APP_INFO (info); +} + +/* GAppInfo interface init */ + +static void +g_desktop_app_info_iface_init (GAppInfoIface *iface) +{ + iface->dup = g_desktop_app_info_dup; + iface->equal = g_desktop_app_info_equal; + iface->get_id = g_desktop_app_info_get_id; + iface->get_name = g_desktop_app_info_get_name; + iface->get_description = g_desktop_app_info_get_description; + iface->get_executable = g_desktop_app_info_get_executable; + iface->get_icon = g_desktop_app_info_get_icon; + iface->launch = g_desktop_app_info_launch; + iface->supports_uris = g_desktop_app_info_supports_uris; + iface->supports_files = g_desktop_app_info_supports_files; + iface->launch_uris = g_desktop_app_info_launch_uris; + iface->launch_uris_async = g_desktop_app_info_launch_uris_async; + iface->launch_uris_finish = g_desktop_app_info_launch_uris_finish; + iface->should_show = g_desktop_app_info_should_show; + iface->set_as_default_for_type = g_desktop_app_info_set_as_default_for_type; + iface->set_as_default_for_extension = g_desktop_app_info_set_as_default_for_extension; + iface->add_supports_type = g_desktop_app_info_add_supports_type; + iface->can_remove_supports_type = g_desktop_app_info_can_remove_supports_type; + iface->remove_supports_type = g_desktop_app_info_remove_supports_type; + iface->can_delete = g_desktop_app_info_can_delete; + iface->do_delete = g_desktop_app_info_delete; + iface->get_commandline = g_desktop_app_info_get_commandline; + iface->get_display_name = g_desktop_app_info_get_display_name; + iface->set_as_last_used_for_type = g_desktop_app_info_set_as_last_used_for_type; + iface->get_supported_types = g_desktop_app_info_get_supported_types; +} + +/* Recommended applications {{{2 */ + +/* Converts content_type into a list of itself with all of its parent + * types (if include_fallback is enabled) or just returns a single-item + * list with the unaliased content type. + */ +static gchar ** +get_list_of_mimetypes (const gchar *content_type, + gboolean include_fallback) +{ + gchar *unaliased; + GPtrArray *array; + + array = g_ptr_array_new (); + unaliased = _g_unix_content_type_unalias (content_type); + g_ptr_array_add (array, unaliased); + + if (include_fallback) + { + gint i; + + /* Iterate the array as we grow it, until we have nothing more to add */ + for (i = 0; i < array->len; i++) + { + gchar **parents = _g_unix_content_type_get_parents (g_ptr_array_index (array, i)); + gint j; + + for (j = 0; parents[j]; j++) + /* Don't add duplicates */ + if (!array_contains (array, parents[j])) + g_ptr_array_add (array, parents[j]); + else + g_free (parents[j]); + + /* We already stole or freed each element. Free the container. */ + g_free (parents); + } + } + + g_ptr_array_add (array, NULL); + + return (gchar **) g_ptr_array_free (array, FALSE); +} + +static gchar ** +g_desktop_app_info_get_desktop_ids_for_content_type (const gchar *content_type, + gboolean include_fallback) +{ + GPtrArray *hits, *blacklist; + gchar **types; + gint i, j; + + hits = g_ptr_array_new (); + blacklist = g_ptr_array_new (); + + types = get_list_of_mimetypes (content_type, include_fallback); + + desktop_file_dirs_lock (); + + for (i = 0; types[i]; i++) + for (j = 0; j < n_desktop_file_dirs; j++) + desktop_file_dir_mime_lookup (&desktop_file_dirs[j], types[i], hits, blacklist); + + /* We will keep the hits past unlocking, so we must dup them */ + for (i = 0; i < hits->len; i++) + hits->pdata[i] = g_strdup (hits->pdata[i]); + + desktop_file_dirs_unlock (); + + g_ptr_array_add (hits, NULL); + + g_ptr_array_free (blacklist, TRUE); + g_strfreev (types); + + return (gchar **) g_ptr_array_free (hits, FALSE); +} + +/** + * g_app_info_get_recommended_for_type: + * @content_type: the content type to find a #GAppInfo for + * + * Gets a list of recommended #GAppInfos for a given content type, i.e. + * those applications which claim to support the given content type exactly, + * and not by MIME type subclassing. + * Note that the first application of the list is the last used one, i.e. + * the last one for which g_app_info_set_as_last_used_for_type() has been + * called. + * + * Returns: (element-type GAppInfo) (transfer full): #GList of #GAppInfos + * for given @content_type or %NULL on error. + * + * Since: 2.28 + **/ +GList * +g_app_info_get_recommended_for_type (const gchar *content_type) +{ + gchar **desktop_ids; + GList *infos; + gint i; + + g_return_val_if_fail (content_type != NULL, NULL); + + desktop_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, FALSE); + + infos = NULL; + for (i = 0; desktop_ids[i]; i++) + { + GDesktopAppInfo *info; + + info = g_desktop_app_info_new (desktop_ids[i]); + if (info) + infos = g_list_prepend (infos, info); + } + + g_strfreev (desktop_ids); + + return g_list_reverse (infos); +} + +/** + * g_app_info_get_fallback_for_type: + * @content_type: the content type to find a #GAppInfo for + * + * Gets a list of fallback #GAppInfos for a given content type, i.e. + * those applications which claim to support the given content type + * by MIME type subclassing and not directly. + * + * Returns: (element-type GAppInfo) (transfer full): #GList of #GAppInfos + * for given @content_type or %NULL on error. + * + * Since: 2.28 + **/ +GList * +g_app_info_get_fallback_for_type (const gchar *content_type) +{ + gchar **recommended_ids; + gchar **all_ids; + GList *infos; + gint i; + + g_return_val_if_fail (content_type != NULL, NULL); + + recommended_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, FALSE); + all_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, TRUE); + + infos = NULL; + for (i = 0; all_ids[i]; i++) + { + GDesktopAppInfo *info; + gint j; + + /* Don't return the ones on the recommended list */ + for (j = 0; recommended_ids[j]; j++) + if (g_str_equal (all_ids[i], recommended_ids[j])) + break; + + if (recommended_ids[j]) + continue; + + info = g_desktop_app_info_new (all_ids[i]); + + if (info) + infos = g_list_prepend (infos, info); + } + + g_strfreev (recommended_ids); + g_strfreev (all_ids); + + return g_list_reverse (infos); +} + +/** + * g_app_info_get_all_for_type: + * @content_type: the content type to find a #GAppInfo for + * + * Gets a list of all #GAppInfos for a given content type, + * including the recommended and fallback #GAppInfos. See + * g_app_info_get_recommended_for_type() and + * g_app_info_get_fallback_for_type(). + * + * Returns: (element-type GAppInfo) (transfer full): #GList of #GAppInfos + * for given @content_type or %NULL on error. + **/ +GList * +g_app_info_get_all_for_type (const char *content_type) +{ + gchar **desktop_ids; + GList *infos; + gint i; + + g_return_val_if_fail (content_type != NULL, NULL); + + desktop_ids = g_desktop_app_info_get_desktop_ids_for_content_type (content_type, TRUE); + + infos = NULL; + for (i = 0; desktop_ids[i]; i++) + { + GDesktopAppInfo *info; + + info = g_desktop_app_info_new (desktop_ids[i]); + if (info) + infos = g_list_prepend (infos, info); + } + + g_strfreev (desktop_ids); + + return g_list_reverse (infos); +} + +/** + * g_app_info_reset_type_associations: + * @content_type: a content type + * + * Removes all changes to the type associations done by + * g_app_info_set_as_default_for_type(), + * g_app_info_set_as_default_for_extension(), + * g_app_info_add_supports_type() or + * g_app_info_remove_supports_type(). + * + * Since: 2.20 + */ +void +g_app_info_reset_type_associations (const char *content_type) +{ + update_mimeapps_list (NULL, content_type, + UPDATE_MIME_NONE, + NULL); +} + +/** + * g_app_info_get_default_for_type: + * @content_type: the content type to find a #GAppInfo for + * @must_support_uris: if %TRUE, the #GAppInfo is expected to + * support URIs + * + * Gets the default #GAppInfo for a given content type. + * + * Returns: (transfer full): #GAppInfo for given @content_type or + * %NULL on error. + */ +GAppInfo * +g_app_info_get_default_for_type (const char *content_type, + gboolean must_support_uris) +{ + GPtrArray *blacklist; + GPtrArray *results; + GAppInfo *info; + gchar **types; + gint i, j, k; + + g_return_val_if_fail (content_type != NULL, NULL); + + types = get_list_of_mimetypes (content_type, TRUE); + + blacklist = g_ptr_array_new (); + results = g_ptr_array_new (); + info = NULL; + + desktop_file_dirs_lock (); + + for (i = 0; types[i]; i++) + { + /* Collect all the default apps for this type */ + for (j = 0; j < n_desktop_file_dirs; j++) + desktop_file_dir_default_lookup (&desktop_file_dirs[j], types[i], results); + + /* Consider the associations as well... */ + for (j = 0; j < n_desktop_file_dirs; j++) + desktop_file_dir_mime_lookup (&desktop_file_dirs[j], types[i], results, blacklist); + + /* (If any), see if one of those apps is installed... */ + for (j = 0; j < results->len; j++) + { + const gchar *desktop_id = g_ptr_array_index (results, j); + + for (k = 0; k < n_desktop_file_dirs; k++) + { + info = (GAppInfo *) desktop_file_dir_get_app (&desktop_file_dirs[k], desktop_id); + + if (info) + { + if (!must_support_uris || g_app_info_supports_uris (info)) + goto out; + + g_clear_object (&info); + } + } + } + + /* Reset the list, ready to try again with the next (parent) + * mimetype, but keep the blacklist in place. + */ + g_ptr_array_set_size (results, 0); + } + +out: + desktop_file_dirs_unlock (); + + g_ptr_array_unref (blacklist); + g_ptr_array_unref (results); + g_strfreev (types); + + return info; +} + +/** + * g_app_info_get_default_for_uri_scheme: + * @uri_scheme: a string containing a URI scheme. + * + * Gets the default application for handling URIs with + * the given URI scheme. A URI scheme is the initial part + * of the URI, up to but not including the ':', e.g. "http", + * "ftp" or "sip". + * + * Returns: (transfer full): #GAppInfo for given @uri_scheme or %NULL on error. + */ +GAppInfo * +g_app_info_get_default_for_uri_scheme (const char *uri_scheme) +{ + GAppInfo *app_info; + char *content_type, *scheme_down; + + scheme_down = g_ascii_strdown (uri_scheme, -1); + content_type = g_strdup_printf ("x-scheme-handler/%s", scheme_down); + g_free (scheme_down); + app_info = g_app_info_get_default_for_type (content_type, FALSE); + g_free (content_type); + + return app_info; +} + +/* "Get all" API {{{2 */ + +/** + * g_desktop_app_info_get_implementations: + * @interface: the name of the interface + * + * Gets all applications that implement @interface. + * + * An application implements an interface if that interface is listed in + * the Implements= line of the desktop file of the application. + * + * Returns: (element-type GDesktopAppInfo) (transfer full): a list of #GDesktopAppInfo + * objects. + * + * Since: 2.42 + **/ +GList * +g_desktop_app_info_get_implementations (const gchar *interface) +{ + GList *result = NULL; + GList **ptr; + gint i; + + desktop_file_dirs_lock (); + + for (i = 0; i < n_desktop_file_dirs; i++) + desktop_file_dir_get_implementations (&desktop_file_dirs[i], &result, interface); + + desktop_file_dirs_unlock (); + + ptr = &result; + while (*ptr) + { + gchar *name = (*ptr)->data; + GDesktopAppInfo *app; + + app = g_desktop_app_info_new (name); + g_free (name); + + if (app) + { + (*ptr)->data = app; + ptr = &(*ptr)->next; + } + else + *ptr = g_list_delete_link (*ptr, *ptr); + } + + return result; +} + +/** + * g_desktop_app_info_search: + * @search_string: the search string to use + * + * Searches desktop files for ones that match @search_string. + * + * The return value is an array of strvs. Each strv contains a list of + * applications that matched @search_string with an equal score. The + * outer list is sorted by score so that the first strv contains the + * best-matching applications, and so on. + * The algorithm for determining matches is undefined and may change at + * any time. + * + * Returns: (array zero-terminated=1) (element-type GStrv) (transfer full): a + * list of strvs. Free each item with g_strfreev() and free the outer + * list with g_free(). + */ +gchar *** +g_desktop_app_info_search (const gchar *search_string) +{ + gchar **search_tokens; + gint last_category = -1; + gchar ***results; + gint n_categories = 0; + gint start_of_category; + gint i, j; + + search_tokens = g_str_tokenize_and_fold (search_string, NULL, NULL); + + desktop_file_dirs_lock (); + + reset_total_search_results (); + + for (i = 0; i < n_desktop_file_dirs; i++) + { + for (j = 0; search_tokens[j]; j++) + { + desktop_file_dir_search (&desktop_file_dirs[i], search_tokens[j]); + merge_token_results (j == 0); + } + merge_directory_results (); + } + + sort_total_search_results (); + + /* Count the total number of unique categories */ + for (i = 0; i < static_total_results_size; i++) + if (static_total_results[i].category != last_category) + { + last_category = static_total_results[i].category; + n_categories++; + } + + results = g_new (gchar **, n_categories + 1); + + /* Start loading into the results list */ + start_of_category = 0; + for (i = 0; i < n_categories; i++) + { + gint n_items_in_category = 0; + gint this_category; + gint j; + + this_category = static_total_results[start_of_category].category; + + while (start_of_category + n_items_in_category < static_total_results_size && + static_total_results[start_of_category + n_items_in_category].category == this_category) + n_items_in_category++; + + results[i] = g_new (gchar *, n_items_in_category + 1); + for (j = 0; j < n_items_in_category; j++) + results[i][j] = g_strdup (static_total_results[start_of_category + j].app_name); + results[i][j] = NULL; + + start_of_category += n_items_in_category; + } + results[i] = NULL; + + desktop_file_dirs_unlock (); + + g_strfreev (search_tokens); + + return results; +} + +/** + * g_app_info_get_all: + * + * Gets a list of all of the applications currently registered + * on this system. + * + * For desktop files, this includes applications that have + * `NoDisplay=true` set or are excluded from display by means + * of `OnlyShowIn` or `NotShowIn`. See g_app_info_should_show(). + * The returned list does not include applications which have + * the `Hidden` key set. + * + * Returns: (element-type GAppInfo) (transfer full): a newly allocated #GList of references to #GAppInfos. + **/ +GList * +g_app_info_get_all (void) +{ + GHashTable *apps; + GHashTableIter iter; + gpointer value; + int i; + GList *infos; + + apps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + desktop_file_dirs_lock (); + + for (i = 0; i < n_desktop_file_dirs; i++) + desktop_file_dir_get_all (&desktop_file_dirs[i], apps); + + desktop_file_dirs_unlock (); + + infos = NULL; + g_hash_table_iter_init (&iter, apps); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + if (value) + infos = g_list_prepend (infos, value); + } + + g_hash_table_destroy (apps); + + return infos; +} + +/* GDesktopAppInfoLookup interface {{{2 */ + +/** + * GDesktopAppInfoLookup: + * + * #GDesktopAppInfoLookup is an opaque data structure and can only be accessed + * using the following functions. + **/ + +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + +typedef GDesktopAppInfoLookupIface GDesktopAppInfoLookupInterface; +G_DEFINE_INTERFACE (GDesktopAppInfoLookup, g_desktop_app_info_lookup, G_TYPE_OBJECT) + +static void +g_desktop_app_info_lookup_default_init (GDesktopAppInfoLookupInterface *iface) +{ +} + +/* "Get for mime type" APIs {{{2 */ + +/** + * g_desktop_app_info_lookup_get_default_for_uri_scheme: + * @lookup: a #GDesktopAppInfoLookup + * @uri_scheme: a string containing a URI scheme. + * + * Gets the default application for launching applications + * using this URI scheme for a particular GDesktopAppInfoLookup + * implementation. + * + * The GDesktopAppInfoLookup interface and this function is used + * to implement g_app_info_get_default_for_uri_scheme() backends + * in a GIO module. There is no reason for applications to use it + * directly. Applications should use g_app_info_get_default_for_uri_scheme(). + * + * Returns: (transfer full): #GAppInfo for given @uri_scheme or %NULL on error. + * + * Deprecated: The #GDesktopAppInfoLookup interface is deprecated and unused by gio. + */ +GAppInfo * +g_desktop_app_info_lookup_get_default_for_uri_scheme (GDesktopAppInfoLookup *lookup, + const char *uri_scheme) +{ + GDesktopAppInfoLookupIface *iface; + + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO_LOOKUP (lookup), NULL); + + iface = G_DESKTOP_APP_INFO_LOOKUP_GET_IFACE (lookup); + + return (* iface->get_default_for_uri_scheme) (lookup, uri_scheme); +} + +G_GNUC_END_IGNORE_DEPRECATIONS + +/* Misc getter APIs {{{2 */ + +/** + * g_desktop_app_info_get_startup_wm_class: + * @info: a #GDesktopAppInfo that supports startup notify + * + * Retrieves the StartupWMClass field from @info. This represents the + * WM_CLASS property of the main window of the application, if launched + * through @info. + * + * Returns: (transfer none): the startup WM class, or %NULL if none is set + * in the desktop file. + * + * Since: 2.34 + */ +const char * +g_desktop_app_info_get_startup_wm_class (GDesktopAppInfo *info) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + + return info->startup_wm_class; +} + +/** + * g_desktop_app_info_get_string: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * + * Looks up a string value in the keyfile backing @info. + * + * The @key is looked up in the "Desktop Entry" group. + * + * Returns: a newly allocated string, or %NULL if the key + * is not found + * + * Since: 2.36 + */ +char * +g_desktop_app_info_get_string (GDesktopAppInfo *info, + const char *key) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + + return g_key_file_get_string (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, key, NULL); +} + +/** + * g_desktop_app_info_get_locale_string: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * + * Looks up a localized string value in the keyfile backing @info + * translated to the current locale. + * + * The @key is looked up in the "Desktop Entry" group. + * + * Returns: (nullable): a newly allocated string, or %NULL if the key + * is not found + * + * Since: 2.56 + */ +char * +g_desktop_app_info_get_locale_string (GDesktopAppInfo *info, + const char *key) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + g_return_val_if_fail (key != NULL && *key != '\0', NULL); + + return g_key_file_get_locale_string (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, + key, NULL, NULL); +} + +/** + * g_desktop_app_info_get_boolean: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * + * Looks up a boolean value in the keyfile backing @info. + * + * The @key is looked up in the "Desktop Entry" group. + * + * Returns: the boolean value, or %FALSE if the key + * is not found + * + * Since: 2.36 + */ +gboolean +g_desktop_app_info_get_boolean (GDesktopAppInfo *info, + const char *key) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), FALSE); + + return g_key_file_get_boolean (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, key, NULL); +} + +/** + * g_desktop_app_info_get_string_list: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * @length: (out) (optional): return location for the number of returned strings, or %NULL + * + * Looks up a string list value in the keyfile backing @info. + * + * The @key is looked up in the "Desktop Entry" group. + * + * Returns: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): + * a %NULL-terminated string array or %NULL if the specified + * key cannot be found. The array should be freed with g_strfreev(). + * + * Since: 2.60.0 + */ +gchar ** +g_desktop_app_info_get_string_list (GDesktopAppInfo *info, + const char *key, + gsize *length) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + + return g_key_file_get_string_list (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, key, length, NULL); +} + +/** + * g_desktop_app_info_has_key: + * @info: a #GDesktopAppInfo + * @key: the key to look up + * + * Returns whether @key exists in the "Desktop Entry" group + * of the keyfile backing @info. + * + * Returns: %TRUE if the @key exists + * + * Since: 2.36 + */ +gboolean +g_desktop_app_info_has_key (GDesktopAppInfo *info, + const char *key) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), FALSE); + + return g_key_file_has_key (info->keyfile, + G_KEY_FILE_DESKTOP_GROUP, key, NULL); +} + +/* Desktop actions support {{{2 */ + +/** + * g_desktop_app_info_list_actions: + * @info: a #GDesktopAppInfo + * + * Returns the list of "additional application actions" supported on the + * desktop file, as per the desktop file specification. + * + * As per the specification, this is the list of actions that are + * explicitly listed in the "Actions" key of the [Desktop Entry] group. + * + * Returns: (array zero-terminated=1) (element-type utf8) (transfer none): a list of strings, always non-%NULL + * + * Since: 2.38 + **/ +const gchar * const * +g_desktop_app_info_list_actions (GDesktopAppInfo *info) +{ + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + + return (const gchar **) info->actions; +} + +static gboolean +app_info_has_action (GDesktopAppInfo *info, + const gchar *action_name) +{ + gint i; + + for (i = 0; info->actions[i]; i++) + if (g_str_equal (info->actions[i], action_name)) + return TRUE; + + return FALSE; +} + +/** + * g_desktop_app_info_get_action_name: + * @info: a #GDesktopAppInfo + * @action_name: the name of the action as from + * g_desktop_app_info_list_actions() + * + * Gets the user-visible display name of the "additional application + * action" specified by @action_name. + * + * This corresponds to the "Name" key within the keyfile group for the + * action. + * + * Returns: (transfer full): the locale-specific action name + * + * Since: 2.38 + */ +gchar * +g_desktop_app_info_get_action_name (GDesktopAppInfo *info, + const gchar *action_name) +{ + gchar *group_name; + gchar *result; + + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (info), NULL); + g_return_val_if_fail (action_name != NULL, NULL); + g_return_val_if_fail (app_info_has_action (info, action_name), NULL); + + group_name = g_strdup_printf ("Desktop Action %s", action_name); + result = g_key_file_get_locale_string (info->keyfile, group_name, "Name", NULL, NULL); + g_free (group_name); + + /* The spec says that the Name field must be given. + * + * If it's not, let's follow the behaviour of our get_name() + * implementation above and never return %NULL. + */ + if (result == NULL) + result = g_strdup (_("Unnamed")); + + return result; +} + +/** + * g_desktop_app_info_launch_action: + * @info: a #GDesktopAppInfo + * @action_name: the name of the action as from + * g_desktop_app_info_list_actions() + * @launch_context: (nullable): a #GAppLaunchContext + * + * Activates the named application action. + * + * You may only call this function on action names that were + * returned from g_desktop_app_info_list_actions(). + * + * Note that if the main entry of the desktop file indicates that the + * application supports startup notification, and @launch_context is + * non-%NULL, then startup notification will be used when activating the + * action (and as such, invocation of the action on the receiving side + * must signal the end of startup notification when it is completed). + * This is the expected behaviour of applications declaring additional + * actions, as per the desktop file specification. + * + * As with g_app_info_launch() there is no way to detect failures that + * occur while using this function. + * + * Since: 2.38 + */ +void +g_desktop_app_info_launch_action (GDesktopAppInfo *info, + const gchar *action_name, + GAppLaunchContext *launch_context) +{ + GDBusConnection *session_bus; + + g_return_if_fail (G_IS_DESKTOP_APP_INFO (info)); + g_return_if_fail (action_name != NULL); + g_return_if_fail (app_info_has_action (info, action_name)); + + session_bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + if (session_bus && info->app_id) + { + gchar *object_path; + + object_path = object_path_from_appid (info->app_id); + g_dbus_connection_call (session_bus, info->app_id, object_path, + "org.freedesktop.Application", "ActivateAction", + g_variant_new ("(sav@a{sv})", action_name, NULL, + g_desktop_app_info_make_platform_data (info, NULL, launch_context)), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); + g_free (object_path); + } + else + { + gchar *group_name; + gchar *exec_line; + + group_name = g_strdup_printf ("Desktop Action %s", action_name); + exec_line = g_key_file_get_string (info->keyfile, group_name, "Exec", NULL); + g_free (group_name); + + if (exec_line) + g_desktop_app_info_launch_uris_with_spawn (info, session_bus, exec_line, NULL, launch_context, + _SPAWN_FLAGS_DEFAULT, NULL, NULL, NULL, NULL, + -1, -1, -1, NULL); + + g_free (exec_line); + } + + if (session_bus != NULL) + { + g_dbus_connection_flush (session_bus, NULL, NULL, NULL); + g_object_unref (session_bus); + } +} +/* Epilogue {{{1 */ + +/* vim:set foldmethod=marker: */ diff -Nru glib2.0-2.59.2/.pc/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch/gio/meson.build glib2.0-2.59.3/.pc/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch/gio/meson.build --- glib2.0-2.59.2/.pc/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch/gio/meson.build 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/Look-for-gio-launch-desktop-in-libdir-glib-2.0.patch/gio/meson.build 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,996 @@ +gio_c_args = [ + '-DG_LOG_DOMAIN="GLib-GIO"', + '-DGIO_COMPILATION', + '-DGIO_MODULE_DIR="@0@"'.format(glib_giomodulesdir), +] + +gio_c_args += glib_hidden_visibility_args + +# FIXME: Install empty glib_giomodulesdir + +gnetworking_h_conf = configuration_data() + +gnetworking_h_wspiapi_include = '' +gnetworking_h_nameser_compat_include = '' + +if host_system == 'windows' + # in the Windows SDK and in mingw-w64 has wrappers for + # inline workarounds for getaddrinfo, getnameinfo and freeaddrinfo if + # they aren't present at run-time (on Windows 2000). + gnetworking_h_wspiapi_include = '#include ' +elif not host_system.contains('android') + # Don't check for C_IN on Android since it does not define it in public + # headers, we define it ourselves wherever necessary + if not cc.compiles('''#include + #include + int qclass = C_IN;''', + name : 'C_IN in public headers (no arpa/nameser_compat.h needed)') + if cc.compiles('''#include + #include + #include + int qclass = C_IN;''', + name : 'arpa/nameser_compat.h needed for C_IN') + gnetworking_h_nameser_compat_include = '#include ' + else + error('Could not find required includes for ARPA C_IN') + endif + endif +endif + +network_libs = [ ] +network_args = [ ] +if host_system != 'windows' + # res_query() + res_query_test = '''#include + int main (int argc, char ** argv) { + return res_query("test", 0, 0, (void *)0, 0); + }''' + res_query_test_full = '''#include + #include + #include + ''' + res_query_test + if not cc.links(res_query_test_full, name : 'res_query()') + if cc.links(res_query_test_full, args : '-lresolv', name : 'res_query() in -lresolv') + network_libs += [ cc.find_library('resolv') ] + network_args += [ '-lresolv' ] + elif cc.links(res_query_test, args : '-lbind', name : 'res_query() in -lbind') + network_libs += [ cc.find_library('bind') ] + network_args += [ '-lbind' ] + else + error('Could not find res_query()') + endif + endif + + # socket() + socket_test = '''#include + #include + int main (int argc, char ** argv) { + return socket(1, 2, 3); + }''' + if not cc.links(socket_test, name : 'socket()') + if cc.links(socket_test, args : '-lsocket', name : 'socket() in -lsocket') + network_libs += [ cc.find_library('socket') ] + network_args += [ '-lsocket' ] + else + error('Could not find socket()') + endif + endif + + # res_init() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + return res_init(); + }''', args : network_args, name : 'res_init()') + glib_conf.set('HAVE_RES_INIT', 1) + endif + + # res_nclose() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + res_nclose(&res); + return 0; + }''', args : network_args, name : 'res_nclose()') + glib_conf.set('HAVE_RES_NCLOSE', 1) + endif + + # res_ndestroy() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + res_ndestroy(&res); + return 0; + }''', args : network_args, name : 'res_ndestroy()') + glib_conf.set('HAVE_RES_NDESTROY', 1) + endif + + # res_ninit() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + return res_ninit(&res); + }''', args : network_args, name : 'res_ninit()') + glib_conf.set('HAVE_RES_NINIT', 1) + endif + + # res_nquery() + if cc.links('''#include + #include + #include + #include + int main (int argc, char ** argv) { + struct __res_state res; + return res_nquery(&res, "test", 0, 0, (void *)0, 0); + }''', args : network_args, name : 'res_nquery()') + glib_conf.set('HAVE_RES_NQUERY', 1) + endif + + if cc.has_type('struct ip_mreqn', prefix : '#include ') + glib_conf.set('HAVE_IP_MREQN', 1) + endif + + if cc.compiles('''#include + #include + int main (int argc, char ** argv) { + struct ifreq ifr; + ioctl(0, SIOCGIFADDR, &ifr); + return 0; + }''', + name : 'ioctl with request SIOCGIFADDR') + glib_conf.set('HAVE_SIOCGIFADDR', '/**/') + endif + +endif + +if host_system.contains('android') + # struct ip_mreq_source definition is broken on Android NDK <= r16 + # See https://bugzilla.gnome.org/show_bug.cgi?id=740791 + if not cc.compiles('''#include + int main(int argc, char ** argv) { + struct ip_mreq_source mc_req_src; + mc_req_src.imr_interface.s_addr = 0; + return 0; + }''', + name : 'ip_mreq_source.imr_interface has s_addr member') + glib_conf.set('BROKEN_IP_MREQ_SOURCE_STRUCT', 1) + endif +endif + +gnetworking_h_conf.set('WSPIAPI_INCLUDE', gnetworking_h_wspiapi_include) +gnetworking_h_conf.set('NAMESER_COMPAT_INCLUDE', gnetworking_h_nameser_compat_include) + +gnetworking_h = configure_file(input : 'gnetworking.h.in', + output : 'gnetworking.h', + install_dir : join_paths(get_option('includedir'), 'glib-2.0/gio'), + configuration : gnetworking_h_conf) + +gdbus_headers = files( + 'gdbusauthobserver.h', + 'gcredentials.h', + 'gdbusutils.h', + 'gdbuserror.h', + 'gdbusaddress.h', + 'gdbusconnection.h', + 'gdbusmessage.h', + 'gdbusnameowning.h', + 'gdbusnamewatching.h', + 'gdbusproxy.h', + 'gdbusintrospection.h', + 'gdbusmethodinvocation.h', + 'gdbusserver.h', + 'gdbusinterface.h', + 'gdbusinterfaceskeleton.h', + 'gdbusobject.h', + 'gdbusobjectskeleton.h', + 'gdbusobjectproxy.h', + 'gdbusobjectmanager.h', + 'gdbusobjectmanagerclient.h', + 'gdbusobjectmanagerserver.h', + 'gtestdbus.h', +) + +gdbus_sources = files( + 'gdbusutils.c', + 'gdbusaddress.c', + 'gdbusauthobserver.c', + 'gdbusauth.c', + 'gdbusauthmechanism.c', + 'gdbusauthmechanismanon.c', + 'gdbusauthmechanismexternal.c', + 'gdbusauthmechanismsha1.c', + 'gdbuserror.c', + 'gdbusconnection.c', + 'gdbusmessage.c', + 'gdbusnameowning.c', + 'gdbusnamewatching.c', + 'gdbusproxy.c', + 'gdbusprivate.c', + 'gdbusintrospection.c', + 'gdbusmethodinvocation.c', + 'gdbusserver.c', + 'gdbusinterface.c', + 'gdbusinterfaceskeleton.c', + 'gdbusobject.c', + 'gdbusobjectskeleton.c', + 'gdbusobjectproxy.c', + 'gdbusobjectmanager.c', + 'gdbusobjectmanagerclient.c', + 'gdbusobjectmanagerserver.c', + 'gtestdbus.c', +) + +# Generate gdbus-codegen +subdir('gdbus-2.0/codegen') + +# Generate xdp-dbus.{c,h} +xdp_dbus_generated = custom_target('xdp-dbus', + input : ['org.freedesktop.portal.Documents.xml', + 'org.freedesktop.portal.OpenURI.xml', + 'org.freedesktop.portal.ProxyResolver.xml', + 'org.freedesktop.portal.Trash.xml'], + output : ['xdp-dbus.h', 'xdp-dbus.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.freedesktop.portal.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'xdp-dbus', + '--c-namespace', 'GXdp', + '--annotate', 'org.freedesktop.portal.Documents.Add()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '--annotate', 'org.freedesktop.portal.Documents.AddNamed()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '--annotate', 'org.freedesktop.portal.Documents.AddFull()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '--annotate', 'org.freedesktop.portal.OpenURI.OpenFile()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '--annotate', 'org.freedesktop.portal.Trash.TrashFile()', + 'org.gtk.GDBus.C.UnixFD', 'true', + '@INPUT@']) + +# Generate gdbus-generated.{c,h} +gdbus_daemon_generated = custom_target('gdbus-daemon-generated', + input : ['dbus-daemon.xml'], + output : ['gdbus-daemon-generated.h', 'gdbus-daemon-generated.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'gdbus-daemon-generated', + '--c-namespace', '_G', '@INPUT@']) + +settings_headers = files( + 'gsettingsbackend.h', + 'gsettingsschema.h', + 'gsettings.h', +) + +settings_sources = files( + 'gvdb/gvdb-reader.c', + 'gdelayedsettingsbackend.c', + 'gkeyfilesettingsbackend.c', + 'gmemorysettingsbackend.c', + 'gnullsettingsbackend.c', + 'gsettingsbackend.c', + 'gsettingsschema.c', + 'gsettings-mapping.c', + 'gsettings.c', +) + +if host_system == 'windows' + settings_sources += files('gregistrysettingsbackend.c') +endif + +application_headers = files( + 'gapplication.h', + 'gapplicationcommandline.h', + + 'gactiongroup.h', + 'gactionmap.h', + 'gsimpleactiongroup.h', + 'gremoteactiongroup.h', + 'gactiongroupexporter.h', + 'gdbusactiongroup.h', + 'gaction.h', + 'gpropertyaction.h', + 'gsimpleaction.h', + + 'gmenumodel.h', + 'gmenu.h', + 'gmenuexporter.h', + 'gdbusmenumodel.h', + 'gnotification.h', +) + +application_sources = files( + 'gapplication.c', + 'gapplicationcommandline.c', + 'gapplicationimpl-dbus.c', + + 'gactiongroup.c', + 'gactionmap.c', + 'gsimpleactiongroup.c', + 'gremoteactiongroup.c', + 'gactiongroupexporter.c', + 'gdbusactiongroup.c', + 'gaction.c', + 'gpropertyaction.c', + 'gsimpleaction.c', + + 'gmenumodel.c', + 'gmenu.c', + 'gmenuexporter.c', + 'gdbusmenumodel.c', + 'gnotification.c', + 'gnotificationbackend.c', +) + +local_sources = files( + 'ghttpproxy.c', + 'glocalfile.c', + 'glocalfileenumerator.c', + 'glocalfileinfo.c', + 'glocalfileinputstream.c', + 'glocalfilemonitor.c', + 'glocalfileoutputstream.c', + 'glocalfileiostream.c', + 'glocalvfs.c', + 'gsocks4proxy.c', + 'gsocks4aproxy.c', + 'gsocks5proxy.c', + 'thumbnail-verify.c', +) + +platform_deps = [] +internal_deps = [] +# TODO: internal_objects is a workaround for +# and +# . When we can depend +# on a meson version where those are fixed, revert the commit that +# introduced this workaround. +internal_objects = [] +appinfo_sources = [] +contenttype_sources = [] +portal_sources = [] +unix_sources = [] +win32_sources = [] + +# This is also used by tests/gdbus-daemon, so use files() to include the path +gdbus_daemon_sources = [ + files('gdbusdaemon.c'), + gdbus_daemon_generated, +] + +if host_system != 'windows' + unix_sources = files( + 'gfiledescriptorbased.c', + 'gunixconnection.c', + 'gunixcredentialsmessage.c', + 'gunixfdlist.c', + 'gunixfdmessage.c', + 'gunixmount.c', + 'gunixmounts.c', + 'gunixsocketaddress.c', + 'gunixvolume.c', + 'gunixvolumemonitor.c', + 'gunixinputstream.c', + 'gunixoutputstream.c', + 'gfdonotificationbackend.c', + 'ggtknotificationbackend.c', + ) + + portal_sources = [files( + 'gdocumentportal.c', + 'gopenuriportal.c', + 'gnetworkmonitorportal.c', + 'gproxyresolverportal.c', + 'gtrashportal.c', + 'gportalsupport.c', + 'gportalnotificationbackend.c'), + xdp_dbus_generated + ] + + gio_unix_include_headers = files( + 'gfiledescriptorbased.h', + 'gunixconnection.h', + 'gunixcredentialsmessage.h', + 'gunixmounts.h', + 'gunixfdlist.h', + 'gunixfdmessage.h', + 'gunixinputstream.h', + 'gunixoutputstream.h', + 'gunixsocketaddress.h', + ) + + if glib_have_cocoa + settings_sources += files('gnextstepsettingsbackend.m') + contenttype_sources += files('gosxcontenttype.m') + appinfo_sources += files('gosxappinfo.m') + if glib_have_os_x_9_or_later + unix_sources += files('gcocoanotificationbackend.m') + endif + else + contenttype_sources += files('gcontenttype.c') + appinfo_sources += files('gdesktopappinfo.c') + gio_unix_include_headers += files('gdesktopappinfo.h') + + executable('gio-launch-desktop', 'gio-launch-desktop.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args) + endif + + subdir('xdgmime') + internal_deps += [xdgmime_lib] + internal_objects += [xdgmime_lib.extract_all_objects()] + + install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio') + + if glib_conf.has('HAVE_NETLINK') + unix_sources += files( + 'gnetworkmonitornetlink.c', + 'gnetworkmonitornm.c', + ) + endif +else + appinfo_sources += files('gwin32appinfo.c') + contenttype_sources += files('gcontenttype-win32.c') + platform_deps += [cc.find_library('shlwapi'), + cc.find_library('dnsapi'), + iphlpapi_dep, + winsock2] + win32_sources += files( + 'gwin32registrykey.c', + 'gwin32mount.c', + 'gwin32volumemonitor.c', + 'gwin32inputstream.c', + 'gwin32outputstream.c', + 'gwin32networkmonitor.c', + 'gwin32networkmonitor.h', + 'gwin32notificationbackend.c', + ) + + gio_win_rc = configure_file( + input: 'gio.rc.in', + output: 'gio.rc', + configuration: glibconfig_conf, + ) + gio_win_res = windows.compile_resources(gio_win_rc) + win32_sources += [gio_win_res] + + gio_win32_include_headers = files( + 'gwin32inputstream.h', + 'gwin32outputstream.h', + ) + install_headers(gio_win32_include_headers, subdir : 'gio-win32-2.0/gio') +endif + +gio_sources = files( + 'gappinfo.c', + 'gasynchelper.c', + 'gasyncinitable.c', + 'gasyncresult.c', + 'gbufferedinputstream.c', + 'gbufferedoutputstream.c', + 'gbytesicon.c', + 'gcancellable.c', + 'gcharsetconverter.c', + 'gcontextspecificgroup.c', + 'gconverter.c', + 'gconverterinputstream.c', + 'gconverteroutputstream.c', + 'gcredentials.c', + 'gdatagrambased.c', + 'gdatainputstream.c', + 'gdataoutputstream.c', + 'gdrive.c', + 'gdummyfile.c', + 'gdummyproxyresolver.c', + 'gdummytlsbackend.c', + 'gemblem.c', + 'gemblemedicon.c', + 'gfile.c', + 'gfileattribute.c', + 'gfileenumerator.c', + 'gfileicon.c', + 'gfileinfo.c', + 'gfileinputstream.c', + 'gfilemonitor.c', + 'gfilenamecompleter.c', + 'gfileoutputstream.c', + 'gfileiostream.c', + 'gfilterinputstream.c', + 'gfilteroutputstream.c', + 'gicon.c', + 'ginetaddress.c', + 'ginetaddressmask.c', + 'ginetsocketaddress.c', + 'ginitable.c', + 'ginputstream.c', + 'gioerror.c', + 'giomodule.c', + 'giomodule-priv.c', + 'gioscheduler.c', + 'giostream.c', + 'gloadableicon.c', + 'gmount.c', + 'gmemoryinputstream.c', + 'gmemoryoutputstream.c', + 'gmountoperation.c', + 'gnativevolumemonitor.c', + 'gnativesocketaddress.c', + 'gnetworkaddress.c', + 'gnetworking.c', + 'gnetworkmonitor.c', + 'gnetworkmonitorbase.c', + 'gnetworkservice.c', + 'goutputstream.c', + 'gpermission.c', + 'gpollableinputstream.c', + 'gpollableoutputstream.c', + 'gpollableutils.c', + 'gpollfilemonitor.c', + 'gproxy.c', + 'gproxyaddress.c', + 'gproxyaddressenumerator.c', + 'gproxyresolver.c', + 'gresolver.c', + 'gresource.c', + 'gresourcefile.c', + 'gseekable.c', + 'gsimpleasyncresult.c', + 'gsimpleiostream.c', + 'gsimplepermission.c', + 'gsocket.c', + 'gsocketaddress.c', + 'gsocketaddressenumerator.c', + 'gsocketclient.c', + 'gsocketconnectable.c', + 'gsocketconnection.c', + 'gsocketcontrolmessage.c', + 'gsocketinputstream.c', + 'gsocketlistener.c', + 'gsocketoutputstream.c', + 'gsubprocesslauncher.c', + 'gsubprocess.c', + 'gsocketservice.c', + 'gsrvtarget.c', + 'gsimpleproxyresolver.c', + 'gtask.c', + 'gtcpconnection.c', + 'gtcpwrapperconnection.c', + 'gthreadedsocketservice.c', + 'gthemedicon.c', + 'gthreadedresolver.c', + 'gthreadedresolver.h', + 'gtlsbackend.c', + 'gtlscertificate.c', + 'gtlsclientconnection.c', + 'gtlsconnection.c', + 'gtlsdatabase.c', + 'gtlsfiledatabase.c', + 'gtlsinteraction.c', + 'gtlspassword.c', + 'gtlsserverconnection.c', + 'gdtlsconnection.c', + 'gdtlsclientconnection.c', + 'gdtlsserverconnection.c', + 'gunionvolumemonitor.c', + 'gvfs.c', + 'gvolume.c', + 'gvolumemonitor.c', + 'gzlibcompressor.c', + 'gzlibdecompressor.c', + 'glistmodel.c', + 'gliststore.c', +) + +gio_sources += appinfo_sources +gio_sources += contenttype_sources +gio_sources += gdbus_daemon_sources +gio_sources += unix_sources +gio_sources += win32_sources +gio_sources += application_sources +gio_sources += settings_sources +gio_sources += gdbus_sources +gio_sources += portal_sources +gio_sources += local_sources + +MISSING_STUFF = ''' +# This is read by gobject-introspection/misc/ and gtk-doc +gio-public-headers.txt: Makefile + '$(AM_V_GEN) echo $(gioinclude_HEADERS) $(giowin32include_HEADERS) $(giounixinclude_HEADERS) > $@.tmp && mv $@.tmp $@ + +gio.def: libgio-2.0.la + '$(AM_V_GEN) dumpbin.exe -exports .libs/libgio-2.0-0.dll | awk 'BEGIN { print "EXPORTS" } / +[[:digit:]]+ +[[:xdigit:]]+ +[[:xdigit:]]+/{ print $$4 }' > gio.def.tmp && mv gio.def.tmp gio.def + +gio-2.0.lib: libgio-2.0.la gio.def + '$(AM_V_GEN) lib.exe -machine:@LIB_EXE_MACHINE_FLAG@ -name:libgio-2.0-$(LT_CURRENT_MINUS_AGE).dll -def:$(builddir)/gio.def -out:$@ +''' + +gio_headers = files( + 'gappinfo.h', + 'gasyncinitable.h', + 'gasyncresult.h', + 'gbufferedinputstream.h', + 'gbufferedoutputstream.h', + 'gbytesicon.h', + 'gcancellable.h', + 'gcontenttype.h', + 'gcharsetconverter.h', + 'gconverter.h', + 'gconverterinputstream.h', + 'gconverteroutputstream.h', + 'gdatagrambased.h', + 'gdatainputstream.h', + 'gdataoutputstream.h', + 'gdrive.h', + 'gemblem.h', + 'gemblemedicon.h', + 'gfile.h', + 'gfileattribute.h', + 'gfileenumerator.h', + 'gfileicon.h', + 'gfileinfo.h', + 'gfileinputstream.h', + 'gfilemonitor.h', + 'gfilenamecompleter.h', + 'gfileoutputstream.h', + 'gfileiostream.h', + 'gfilterinputstream.h', + 'gfilteroutputstream.h', + 'gicon.h', + 'ginetaddress.h', + 'ginetaddressmask.h', + 'ginetsocketaddress.h', + 'ginputstream.h', + 'ginitable.h', + 'gio.h', + 'gio-autocleanups.h', + 'giotypes.h', + 'gioenums.h', + 'gioerror.h', + 'giomodule.h', + 'gioscheduler.h', + 'giostream.h', + 'gloadableicon.h', + 'gmount.h', + 'gmemoryinputstream.h', + 'gmemoryoutputstream.h', + 'gmountoperation.h', + 'gnativevolumemonitor.h', + 'gnetworkaddress.h', + 'gnetworkmonitor.h', + 'gnetworkservice.h', + 'goutputstream.h', + 'gpermission.h', + 'gpollableinputstream.h', + 'gpollableoutputstream.h', + 'gpollableutils.h', + 'gproxyaddress.h', + 'gproxy.h', + 'gproxyaddressenumerator.h', + 'gproxyresolver.h', + 'gresolver.h', + 'gresource.h', + 'gseekable.h', + 'gsimpleasyncresult.h', + 'gsimpleiostream.h', + 'gsimplepermission.h', + 'gsocket.h', + 'gsocketaddress.h', + 'gsocketaddressenumerator.h', + 'gsocketclient.h', + 'gsocketconnectable.h', + 'gsocketconnection.h', + 'gsocketcontrolmessage.h', + 'gsocketlistener.h', + 'gsocketservice.h', + 'gsrvtarget.h', + 'gsimpleproxyresolver.h', + 'gtask.h', + 'gsubprocess.h', + 'gsubprocesslauncher.h', + 'gtcpconnection.h', + 'gtcpwrapperconnection.h', + 'gthreadedsocketservice.h', + 'gthemedicon.h', + 'gtlsbackend.h', + 'gtlscertificate.h', + 'gtlsclientconnection.h', + 'gtlsconnection.h', + 'gtlsdatabase.h', + 'gtlsfiledatabase.h', + 'gtlsinteraction.h', + 'gtlspassword.h', + 'gtlsserverconnection.h', + 'gdtlsconnection.h', + 'gdtlsclientconnection.h', + 'gdtlsserverconnection.h', + 'gvfs.h', + 'gvolume.h', + 'gvolumemonitor.h', + 'gzlibcompressor.h', + 'gzlibdecompressor.h', + 'glistmodel.h', + 'gliststore.h', +) + +gio_headers += application_headers +gio_headers += settings_headers +gio_headers += gdbus_headers +install_headers(gio_headers, subdir : 'glib-2.0/gio/') + +# We can't use gnome.mkenums() because the GNOME module looks for glib-mkenums +# in PATH, which means you can't bootstrap glib with its own glib-mkenums. +gioenumtypes_h = custom_target('gioenumtypes_h', + output : 'gioenumtypes.h', + capture : true, + input : gio_headers, + install : true, + install_dir : join_paths(get_option('includedir'), 'glib-2.0/gio'), + command : [python, glib_mkenums, + '--template', files('gioenumtypes.h.template'), + '@INPUT@', gnetworking_h]) + +gioenumtypes_c = custom_target('gioenumtypes_c', + output : 'gioenumtypes.c', + capture : true, + input : gio_headers, + depends : [gioenumtypes_h], + command : [python, glib_mkenums, + '--template', files('gioenumtypes.c.template'), + '@INPUT@', gnetworking_h]) + +gioenumtypes_dep = declare_dependency(sources : [gioenumtypes_h]) + +# inotify +if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1 + subdir('inotify') + internal_deps += [ inotify_lib ] + internal_objects += [inotify_lib.extract_all_objects()] +endif + +# kevent +if have_func_kqueue and have_func_kevent + subdir('kqueue') + internal_deps += [ kqueue_lib ] + internal_objects += [kqueue_lib.extract_all_objects()] +endif + +if host_system == 'windows' + subdir('win32') + internal_deps += [ giowin32_lib ] + internal_objects += [giowin32_lib.extract_all_objects()] +endif + +if have_bash + install_data([ + 'completion/gapplication', + 'completion/gdbus', + 'completion/gio', + 'completion/gsettings', + 'completion/gresource' + ], + install_dir: join_paths(get_option('datadir'), 'bash-completion/completions')) +endif + +if enable_dtrace + gio_dtrace_obj = dtrace_obj_gen.process('gio_probes.d') + gio_dtrace_hdr = dtrace_hdr_gen.process('gio_probes.d') +else + gio_dtrace_obj = [] + gio_dtrace_hdr = [] +endif + +libgio = library('gio-2.0', + gioenumtypes_h, gioenumtypes_c, gnetworking_h, gio_sources, + gio_dtrace_hdr, gio_dtrace_obj, + objects : internal_objects, + version : library_version, + soversion : soversion, + darwin_versions : darwin_versions, + install : true, + include_directories : [configinc, gioinc], + # '$(gio_win32_res_ldflag)', + dependencies : [libz_dep, libdl_dep, libmount_dep, libglib_dep, + libgobject_dep, libgmodule_dep, selinux_dep, xattr_dep, + platform_deps, network_libs], + c_args : gio_c_args, + objc_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : [noseh_link_args, glib_link_flags], +) + +giomodulesdir = get_option('gio_module_dir') +if giomodulesdir == '' + giomodulesdir = join_paths('${libdir}', 'gio', 'modules') +endif + +schemas_subdir = join_paths('glib-2.0', 'schemas') + +pkg.generate(libgio, + libraries_private : [osx_ldflags], + requires : ['glib-2.0', 'gobject-2.0'], + variables : ['datadir=' + join_paths('${prefix}', get_option('datadir')), + 'schemasdir=' + join_paths('${datadir}', schemas_subdir), + 'bindir=' + join_paths('${prefix}', get_option('bindir')), + 'giomoduledir=' + giomodulesdir, + 'glib_compile_schemas=' + join_paths('${libdir}', 'glib-2.0', 'glib-compile-schemas'), + 'glib_compile_resources=' + join_paths('${bindir}', 'glib-compile-resources'), + 'gdbus_codegen=' + join_paths('${bindir}', 'gdbus-codegen')], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-2.0', + name : 'GIO', + description : 'glib I/O library', +) + +if host_system == 'windows' + pkg.generate(requires : ['gobject-2.0', 'gmodule-no-export-2.0', 'gio-2.0'], + subdirs : ['gio-win32-2.0'], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-windows-2.0', + name : 'GIO Windows specific APIs', + description : 'Windows specific headers for glib I/O library', + ) +else + pkg.generate(requires : ['gobject-2.0', 'gio-2.0'], + subdirs : ['gio-unix-2.0'], + version : glib_version, + install_dir : glib_pkgconfigreldir, + filebase : 'gio-unix-2.0', + name : 'GIO unix specific APIs', + description : 'unix specific headers for glib I/O library', + ) +endif + +libgio_dep = declare_dependency(link_with : libgio, + dependencies : [libgmodule_dep, libgobject_dep, gioenumtypes_dep], + include_directories : [gioinc]) + +if host_system == 'windows' + # Hack till https://github.com/mesonbuild/meson/issues/2324 is fixed + libgiounix_dep = dependency('', required : false) + libgiowin32_dep = libgio_dep +else + libgiowin32_dep = dependency('', required : false) + libgiounix_dep = libgio_dep +endif + +# Dependencies used by executables below +have_libelf = false +libelf = dependency('libelf', version : '>= 0.8.12', required : false) +if libelf.found() + have_libelf = true +else + # This fallback is necessary on *BSD. elfutils isn't the only libelf + # implementation, and *BSD usually includes their own libelf as a system + # library which doesn't have a corresponding .pc file. + libelf = cc.find_library('elf', required : false) + have_libelf = libelf.found() + have_libelf = have_libelf and cc.has_function('elf_begin', dependencies : libelf) + have_libelf = have_libelf and cc.has_function('elf_getshdrstrndx', dependencies : libelf) + have_libelf = have_libelf and cc.has_function('elf_getshdrnum', dependencies : libelf) + have_libelf = have_libelf and cc.has_header('libelf.h') +endif + +if have_libelf + glib_conf.set('HAVE_LIBELF', 1) +else + libelf = [] +endif + +gconstructor_as_data_h = custom_target('gconstructor_as_data.h', + input : ['data-to-c.py', files('../glib/gconstructor.h')], + output : ['gconstructor_as_data.h'], + command : [python, '@INPUT0@', '@INPUT1@', 'gconstructor_code', '@OUTPUT@']) + +# Several installed executables +gio_tool_sources = [ + 'gio-tool.c', + 'gio-tool.h', + 'gio-tool-cat.c', + 'gio-tool-copy.c', + 'gio-tool-info.c', + 'gio-tool-list.c', + 'gio-tool-mime.c', + 'gio-tool-mkdir.c', + 'gio-tool-monitor.c', + 'gio-tool-mount.c', + 'gio-tool-move.c', + 'gio-tool-open.c', + 'gio-tool-rename.c', + 'gio-tool-remove.c', + 'gio-tool-save.c', + 'gio-tool-set.c', + 'gio-tool-trash.c', + 'gio-tool-tree.c', +] + +executable('gio', gio_tool_sources, + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +executable('gresource', 'gresource-tool.c', + install : true, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libelf, libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +gio_querymodules = executable('gio-querymodules', 'gio-querymodules.c', 'giomodule-priv.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +glib_compile_schemas = executable('glib-compile-schemas', + [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-schemas.c'], + install : true, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +glib_compile_resources = executable('glib-compile-resources', + [gconstructor_as_data_h, 'gvdb/gvdb-builder.c', 'glib-compile-resources.c'], + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +executable('gsettings', 'gsettings-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) +install_data('gschema.dtd', + install_dir : join_paths(get_option('datadir'), schemas_subdir)) + +install_data(['gschema.loc', 'gschema.its'], + install_dir : join_paths(get_option('datadir'), 'gettext/its')) + +executable('gdbus', 'gdbus-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) + +if host_system != 'windows' and not glib_have_cocoa + executable('gapplication', 'gapplication-tool.c', + install : true, + c_args : gio_c_args, + # intl.lib is not compatible with SAFESEH + link_args : noseh_link_args, + dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) +endif + +if enable_systemtap + gio_stp = configure_file(input : 'gio.stp.in', + output : '@0@.stp'.format(libgio.full_path().split('/').get(-1)), + configuration : stp_cdata, + install_dir : tapset_install_dir, + install : true) +endif + +subdir('fam') +subdir('tests') diff -Nru glib2.0-2.59.2/.pc/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch/glib/tests/timer.c glib2.0-2.59.3/.pc/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch/glib/tests/timer.c --- glib2.0-2.59.2/.pc/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch/glib/tests/timer.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/Skip-test-which-performs-some-unreliable-floating-point-c.patch/glib/tests/timer.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,291 @@ +/* Unit tests for GTimer + * Copyright (C) 2013 Red Hat, Inc. + * + * This work is provided "as is"; redistribution and modification + * in whole or in part, in any medium, physical or electronic is + * permitted without restriction. + * + * This work is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + * + * Author: Matthias Clasen + */ + +#include "glib.h" + +static void +test_timer_basic (void) +{ + GTimer *timer; + volatile gdouble elapsed; + gulong micros; + + timer = g_timer_new (); + + elapsed = g_timer_elapsed (timer, µs); + + g_assert_cmpfloat (elapsed, <, 1.0); + g_assert_cmpuint (micros, ==, ((guint64)(elapsed * 1e6)) % 1000000); + + g_timer_destroy (timer); +} + +static void +test_timer_stop (void) +{ + GTimer *timer; + volatile gdouble elapsed, elapsed2; + + timer = g_timer_new (); + + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_usleep (100); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, ==, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timer_continue (void) +{ + GTimer *timer; + gdouble elapsed, elapsed2; + + timer = g_timer_new (); + g_usleep (100); + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_timer_continue (timer); + g_usleep (100); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, <, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timer_reset (void) +{ + GTimer *timer; + gdouble elapsed, elapsed2; + + timer = g_timer_new (); + g_usleep (100); + g_timer_stop (timer); + + elapsed = g_timer_elapsed (timer, NULL); + g_timer_reset (timer); + elapsed2 = g_timer_elapsed (timer, NULL); + + g_assert_cmpfloat (elapsed, >, elapsed2); + + g_timer_destroy (timer); +} + +static void +test_timeval_add (void) +{ + GTimeVal time = { 1, 0 }; + + g_time_val_add (&time, 10); + + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 10); + + g_time_val_add (&time, -500); + g_assert_cmpint (time.tv_sec, ==, 0); + g_assert_cmpint (time.tv_usec, ==, G_USEC_PER_SEC - 490); + + g_time_val_add (&time, 1000); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 510); + + g_time_val_add (&time, 0); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 510); + + g_time_val_add (&time, -210); + g_assert_cmpint (time.tv_sec, ==, 1); + g_assert_cmpint (time.tv_usec, ==, 300); +} + +typedef struct { + gboolean success; + const gchar *in; + GTimeVal val; +} TimeValParseTest; + +static void +test_timeval_from_iso8601 (void) +{ + gchar *old_tz = g_strdup (g_getenv ("TZ")); + TimeValParseTest tests[] = { + { TRUE, "1990-11-01T10:21:17Z", { 657454877, 0 } }, + { TRUE, "19901101T102117Z", { 657454877, 0 } }, + { TRUE, "19901101T102117+5", { 657454577, 0 } }, + { TRUE, "19901101T102117+3:15", { 657443177, 0 } }, + { TRUE, " 1990-11-01T10:21:17Z ", { 657454877, 0 } }, + { TRUE, "1970-01-01T00:00:17.12Z", { 17, 120000 } }, + { TRUE, "1970-01-01T00:00:17.1234Z", { 17, 123400 } }, + { TRUE, "1970-01-01T00:00:17.123456Z", { 17, 123456 } }, + { TRUE, "1980-02-22T12:36:00+02:00", { 320063760, 0 } }, + { FALSE, " ", { 0, 0 } }, + { FALSE, "x", { 0, 0 } }, + { FALSE, "123x", { 0, 0 } }, + { FALSE, "2001-10+x", { 0, 0 } }, + { FALSE, "1980-02-22T", { 0, 0 } }, + { FALSE, "2001-10-08Tx", { 0, 0 } }, + { FALSE, "2001-10-08T10:11x", { 0, 0 } }, + { FALSE, "Wed Dec 19 17:20:20 GMT 2007", { 0, 0 } }, + { FALSE, "1980-02-22T10:36:00Zulu", { 0, 0 } }, + { FALSE, "2T0+819855292164632335", { 0, 0 } }, + { TRUE, "2018-08-03T14:08:05.446178377+01:00", { 1533301685, 446178 } }, + { FALSE, "2147483648-08-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-13-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-00-03T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-00T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-32T14:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T24:08:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:60:05.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:63.446178377+01:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:05.446178377+100:00", { 0, 0 } }, + { FALSE, "2018-08-03T14:08:05.446178377+01:60", { 0, 0 } }, + { TRUE, "20180803T140805.446178377+0100", { 1533301685, 446178 } }, + { FALSE, "21474836480803T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20181303T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180003T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180800T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180832T140805.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T240805.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T146005.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T140863.446178377+0100", { 0, 0 } }, + { FALSE, "20180803T140805.446178377+10000", { 0, 0 } }, + { FALSE, "20180803T140805.446178377+0160", { 0, 0 } }, + { TRUE, "+1980-02-22T12:36:00+02:00", { 320063760, 0 } }, + { FALSE, "-0005-01-01T00:00:00Z", { 0, 0 } }, + { FALSE, "2018-08-06", { 0, 0 } }, + { FALSE, "2018-08-06 13:51:00Z", { 0, 0 } }, + { TRUE, "20180803T140805,446178377+0100", { 1533301685, 446178 } }, + { TRUE, "2018-08-03T14:08:05.446178377-01:00", { 1533308885, 446178 } }, + { FALSE, "2018-08-03T14:08:05.446178377 01:00", { 0, 0 } }, + { TRUE, "1990-11-01T10:21:17", { 657454877, 0 } }, + { TRUE, "1990-11-01T10:21:17 ", { 657454877, 0 } }, + }; + GTimeVal out; + gboolean success; + gint i; + + /* Always run in UTC so the comparisons of parsed values are valid. */ + if (!g_setenv ("TZ", "UTC", TRUE)) + { + g_test_skip ("Failed to set TZ=UTC"); + return; + } + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + out.tv_sec = 0; + out.tv_usec = 0; + success = g_time_val_from_iso8601 (tests[i].in, &out); + g_assert (success == tests[i].success); + if (tests[i].success) + { + g_assert_cmpint (out.tv_sec, ==, tests[i].val.tv_sec); + g_assert_cmpint (out.tv_usec, ==, tests[i].val.tv_usec); + } + } + + if (old_tz != NULL) + g_assert_true (g_setenv ("TZ", old_tz, TRUE)); + else + g_unsetenv ("TZ"); + + g_free (old_tz); +} + +typedef struct { + GTimeVal val; + const gchar *expected; +} TimeValFormatTest; + +static void +test_timeval_to_iso8601 (void) +{ + TimeValFormatTest tests[] = { + { { 657454877, 0 }, "1990-11-01T10:21:17Z" }, + { { 17, 123400 }, "1970-01-01T00:00:17.123400Z" } + }; + gint i; + gchar *out; + GTimeVal val; + gboolean ret; + + g_unsetenv ("TZ"); + + for (i = 0; i < G_N_ELEMENTS (tests); i++) + { + out = g_time_val_to_iso8601 (&(tests[i].val)); + g_assert_cmpstr (out, ==, tests[i].expected); + + ret = g_time_val_from_iso8601 (out, &val); + g_assert (ret); + g_assert_cmpint (val.tv_sec, ==, tests[i].val.tv_sec); + g_assert_cmpint (val.tv_usec, ==, tests[i].val.tv_usec); + g_free (out); + } +} + +/* Test error handling for g_time_val_to_iso8601() on dates which are too large. */ +static void +test_timeval_to_iso8601_overflow (void) +{ + GTimeVal val; + gchar *out = NULL; + + if ((glong) G_MAXINT == G_MAXLONG) + { + g_test_skip ("G_MAXINT == G_MAXLONG - we can't make g_time_val_to_iso8601() overflow."); + return; + } + + g_unsetenv ("TZ"); + + val.tv_sec = G_MAXLONG; + val.tv_usec = G_USEC_PER_SEC - 1; + + out = g_time_val_to_iso8601 (&val); + g_assert_null (out); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/timer/basic", test_timer_basic); + g_test_add_func ("/timer/stop", test_timer_stop); + g_test_add_func ("/timer/continue", test_timer_continue); + g_test_add_func ("/timer/reset", test_timer_reset); + g_test_add_func ("/timeval/add", test_timeval_add); + g_test_add_func ("/timeval/from-iso8601", test_timeval_from_iso8601); + g_test_add_func ("/timeval/to-iso8601", test_timeval_to_iso8601); + g_test_add_func ("/timeval/to-iso8601/overflow", test_timeval_to_iso8601_overflow); + + return g_test_run (); +} diff -Nru glib2.0-2.59.2/.pc/debian/Skip-unreliable-test_threaded_singleton-by-default.patch/gio/tests/gdbus-threading.c glib2.0-2.59.3/.pc/debian/Skip-unreliable-test_threaded_singleton-by-default.patch/gio/tests/gdbus-threading.c --- glib2.0-2.59.2/.pc/debian/Skip-unreliable-test_threaded_singleton-by-default.patch/gio/tests/gdbus-threading.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/debian/Skip-unreliable-test_threaded_singleton-by-default.patch/gio/tests/gdbus-threading.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,614 @@ +/* GLib testing framework examples and tests + * + * Copyright (C) 2008-2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see . + * + * Author: David Zeuthen + */ + +#include +#include +#include + +#include "gdbus-tests.h" + +/* all tests rely on a global connection */ +static GDBusConnection *c = NULL; + +/* ---------------------------------------------------------------------------------------------------- */ +/* Ensure that signal and method replies are delivered in the right thread */ +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + GThread *thread; + GMainLoop *thread_loop; + guint signal_count; +} DeliveryData; + +static void +msg_cb_expect_success (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + DeliveryData *data = user_data; + GError *error; + GVariant *result; + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_variant_unref (result); + + g_assert (g_thread_self () == data->thread); + + g_main_loop_quit (data->thread_loop); +} + +static void +msg_cb_expect_error_cancelled (GDBusConnection *connection, + GAsyncResult *res, + gpointer user_data) +{ + DeliveryData *data = user_data; + GError *error; + GVariant *result; + + error = NULL; + result = g_dbus_connection_call_finish (connection, + res, + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + g_assert (!g_dbus_error_is_remote_error (error)); + g_error_free (error); + g_assert (result == NULL); + + g_assert (g_thread_self () == data->thread); + + g_main_loop_quit (data->thread_loop); +} + +static void +signal_handler (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + DeliveryData *data = user_data; + + g_assert (g_thread_self () == data->thread); + + data->signal_count++; + + g_main_loop_quit (data->thread_loop); +} + +static gpointer +test_delivery_in_thread_func (gpointer _data) +{ + GMainLoop *thread_loop; + GMainContext *thread_context; + DeliveryData data; + GCancellable *ca; + guint subscription_id; + GDBusConnection *priv_c; + GError *error; + + error = NULL; + + thread_context = g_main_context_new (); + thread_loop = g_main_loop_new (thread_context, FALSE); + g_main_context_push_thread_default (thread_context); + + data.thread = g_thread_self (); + data.thread_loop = thread_loop; + data.signal_count = 0; + + /* ---------------------------------------------------------------------------------------------------- */ + + /* + * Check that we get a reply to the GetId() method call. + */ + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) msg_cb_expect_success, + &data); + g_main_loop_run (thread_loop); + + /* + * Check that we never actually send a message if the GCancellable + * is already cancelled - i.e. we should get #G_IO_ERROR_CANCELLED + * when the actual connection is not up. + */ + ca = g_cancellable_new (); + g_cancellable_cancel (ca); + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + ca, + (GAsyncReadyCallback) msg_cb_expect_error_cancelled, + &data); + g_main_loop_run (thread_loop); + g_object_unref (ca); + + /* + * Check that cancellation works when the message is already in flight. + */ + ca = g_cancellable_new (); + g_dbus_connection_call (c, + "org.freedesktop.DBus", /* bus_name */ + "/org/freedesktop/DBus", /* object path */ + "org.freedesktop.DBus", /* interface name */ + "GetId", /* method name */ + NULL, NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + ca, + (GAsyncReadyCallback) msg_cb_expect_error_cancelled, + &data); + g_cancellable_cancel (ca); + g_main_loop_run (thread_loop); + g_object_unref (ca); + + /* + * Check that signals are delivered to the correct thread. + * + * First we subscribe to the signal, then we create a a private + * connection. This should cause a NameOwnerChanged message from + * the message bus. + */ + subscription_id = g_dbus_connection_signal_subscribe (c, + "org.freedesktop.DBus", /* sender */ + "org.freedesktop.DBus", /* interface */ + "NameOwnerChanged", /* member */ + "/org/freedesktop/DBus", /* path */ + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + signal_handler, + &data, + NULL); + g_assert (subscription_id != 0); + g_assert (data.signal_count == 0); + + priv_c = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (priv_c != NULL); + + g_main_loop_run (thread_loop); + g_assert (data.signal_count == 1); + + g_object_unref (priv_c); + + g_dbus_connection_signal_unsubscribe (c, subscription_id); + + /* ---------------------------------------------------------------------------------------------------- */ + + g_main_context_pop_thread_default (thread_context); + g_main_loop_unref (thread_loop); + g_main_context_unref (thread_context); + + return NULL; +} + +static void +test_delivery_in_thread (void) +{ + GThread *thread; + + thread = g_thread_new ("deliver", + test_delivery_in_thread_func, + NULL); + + g_thread_join (thread); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +typedef struct { + GDBusProxy *proxy; + gint msec; + guint num; + gboolean async; + + GMainLoop *thread_loop; + GThread *thread; +} SyncThreadData; + +static void +sleep_cb (GDBusProxy *proxy, + GAsyncResult *res, + gpointer user_data) +{ + SyncThreadData *data = user_data; + GError *error; + GVariant *result; + + error = NULL; + result = g_dbus_proxy_call_finish (proxy, + res, + &error); + g_assert_no_error (error); + g_assert (result != NULL); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + + g_assert (data->thread == g_thread_self ()); + + g_main_loop_quit (data->thread_loop); + + //g_debug ("async cb (%p)", g_thread_self ()); +} + +static gpointer +test_sleep_in_thread_func (gpointer _data) +{ + SyncThreadData *data = _data; + GMainContext *thread_context; + guint n; + + thread_context = g_main_context_new (); + data->thread_loop = g_main_loop_new (thread_context, FALSE); + g_main_context_push_thread_default (thread_context); + + data->thread = g_thread_self (); + + for (n = 0; n < data->num; n++) + { + if (data->async) + { + //g_debug ("invoking async (%p)", g_thread_self ()); + g_dbus_proxy_call (data->proxy, + "Sleep", + g_variant_new ("(i)", data->msec), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + (GAsyncReadyCallback) sleep_cb, + data); + g_main_loop_run (data->thread_loop); + if (g_test_verbose ()) + g_printerr ("A"); + //g_debug ("done invoking async (%p)", g_thread_self ()); + } + else + { + GError *error; + GVariant *result; + + error = NULL; + //g_debug ("invoking sync (%p)", g_thread_self ()); + result = g_dbus_proxy_call_sync (data->proxy, + "Sleep", + g_variant_new ("(i)", data->msec), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (g_test_verbose ()) + g_printerr ("S"); + //g_debug ("done invoking sync (%p)", g_thread_self ()); + g_assert_no_error (error); + g_assert (result != NULL); + g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); + g_variant_unref (result); + } + } + + g_main_context_pop_thread_default (thread_context); + g_main_loop_unref (data->thread_loop); + g_main_context_unref (thread_context); + + return NULL; +} + +static void +test_method_calls_on_proxy (GDBusProxy *proxy) +{ + guint n; + + /* + * Check that multiple threads can do calls without interferring with + * each other. We do this by creating three threads that call the + * Sleep() method on the server (which handles it asynchronously, e.g. + * it won't block other requests) with different sleep durations and + * a number of times. We do this so each set of calls add up to 4000 + * milliseconds. + * + * The dbus test server that this code calls into uses glib timeouts + * to do the sleeping which have only a granularity of 1ms. It is + * therefore possible to lose as much as 40ms; the test could finish + * in slightly less than 4 seconds. + * + * We run this test twice - first with async calls in each thread, then + * again with sync calls + */ + + for (n = 0; n < 2; n++) + { + gboolean do_async; + GThread *thread1; + GThread *thread2; + GThread *thread3; + SyncThreadData data1; + SyncThreadData data2; + SyncThreadData data3; + GTimeVal start_time; + GTimeVal end_time; + guint elapsed_msec; + + do_async = (n == 0); + + g_get_current_time (&start_time); + + data1.proxy = proxy; + data1.msec = 40; + data1.num = 100; + data1.async = do_async; + thread1 = g_thread_new ("sleep", + test_sleep_in_thread_func, + &data1); + + data2.proxy = proxy; + data2.msec = 20; + data2.num = 200; + data2.async = do_async; + thread2 = g_thread_new ("sleep2", + test_sleep_in_thread_func, + &data2); + + data3.proxy = proxy; + data3.msec = 100; + data3.num = 40; + data3.async = do_async; + thread3 = g_thread_new ("sleep3", + test_sleep_in_thread_func, + &data3); + + g_thread_join (thread1); + g_thread_join (thread2); + g_thread_join (thread3); + + g_get_current_time (&end_time); + + elapsed_msec = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - + (start_time.tv_sec * G_USEC_PER_SEC + start_time.tv_usec)) / 1000; + + //g_debug ("Elapsed time for %s = %d msec", n == 0 ? "async" : "sync", elapsed_msec); + + /* elapsed_msec should be 4000 msec +/- change for overhead/inaccuracy */ + g_assert_cmpint (elapsed_msec, >=, 3950); + g_assert_cmpint (elapsed_msec, <, 30000); + + if (g_test_verbose ()) + g_printerr (" "); + } +} + +static void +test_method_calls_in_thread (void) +{ + GDBusProxy *proxy; + GDBusConnection *connection; + GError *error; + + error = NULL; + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, + NULL, + &error); + g_assert_no_error (error); + error = NULL; + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + "com.example.TestService", /* name */ + "/com/example/TestObject", /* object path */ + "com.example.Frob", /* interface */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + + test_method_calls_on_proxy (proxy); + + g_object_unref (proxy); + g_object_unref (connection); + + if (g_test_verbose ()) + g_printerr ("\n"); +} + +#define SLEEP_MIN_USEC 1 +#define SLEEP_MAX_USEC 10 + +/* Can run in any thread */ +static void +ensure_connection_works (GDBusConnection *conn) +{ + GVariant *v; + GError *error = NULL; + + v = g_dbus_connection_call_sync (conn, "org.freedesktop.DBus", + "/org/freedesktop/DBus", "org.freedesktop.DBus", "GetId", NULL, NULL, 0, -1, + NULL, &error); + g_assert_no_error (error); + g_assert (v != NULL); + g_assert (g_variant_is_of_type (v, G_VARIANT_TYPE ("(s)"))); + g_variant_unref (v); +} + +/** + * get_sync_in_thread: + * @data: (type guint): delay in microseconds + * + * Sleep for a short time, then get a session bus connection and call + * a method on it. + * + * Runs in a non-main thread. + * + * Returns: (transfer full): the connection + */ +static gpointer +get_sync_in_thread (gpointer data) +{ + guint delay = GPOINTER_TO_UINT (data); + GError *error = NULL; + GDBusConnection *conn; + + g_usleep (delay); + + conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + + ensure_connection_works (conn); + + return conn; +} + +static void +test_threaded_singleton (void) +{ + guint i, n; + guint unref_wins = 0; + guint get_wins = 0; + + if (g_test_thorough ()) + n = 100000; + else + n = 5000; + + for (i = 0; i < n; i++) + { + GThread *thread; + guint j; + guint unref_delay, get_delay; + GDBusConnection *new_conn; + + /* We want to be the last ref, so let it finish setting up */ + for (j = 0; j < 100; j++) + { + guint r = g_atomic_int_get (&G_OBJECT (c)->ref_count); + + if (r == 1) + break; + + g_debug ("run %u: refcount is %u, sleeping", i, r); + g_usleep (1000); + } + + if (j == 100) + g_error ("connection had too many refs"); + + if (g_test_verbose () && (i % (n/50)) == 0) + g_printerr ("%u%%\n", ((i * 100) / n)); + + /* Delay for a random time on each side of the race, to perturb the + * timing. Ideally, we want each side to win half the races; these + * timings are about right on smcv's laptop. + */ + unref_delay = g_random_int_range (SLEEP_MIN_USEC, SLEEP_MAX_USEC); + get_delay = g_random_int_range (SLEEP_MIN_USEC / 2, SLEEP_MAX_USEC / 2); + + /* One half of the race is to call g_bus_get_sync... */ + thread = g_thread_new ("get_sync_in_thread", get_sync_in_thread, + GUINT_TO_POINTER (get_delay)); + + /* ... and the other half is to unref the shared connection, which must + * have exactly one ref at this point + */ + g_usleep (unref_delay); + g_object_unref (c); + + /* Wait for the thread to run; see what it got */ + new_conn = g_thread_join (thread); + + /* If the thread won the race, it will have kept the same connection, + * and it'll have one ref + */ + if (new_conn == c) + { + get_wins++; + } + else + { + unref_wins++; + /* c is invalid now, but new_conn is suitable for the + * next round + */ + c = new_conn; + } + + ensure_connection_works (c); + } + + if (g_test_verbose ()) + g_printerr ("Unref won %u races; Get won %u races\n", unref_wins, get_wins); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +int +main (int argc, + char *argv[]) +{ + GError *error; + gint ret; + gchar *path; + + g_test_init (&argc, &argv, NULL); + + session_bus_up (); + + /* this is safe; testserver will exit once the bus goes away */ + path = g_test_build_filename (G_TEST_BUILT, "gdbus-testserver", NULL); + g_assert (g_spawn_command_line_async (path, NULL)); + g_free (path); + + ensure_gdbus_testserver_up (); + + /* Create the connection in the main thread */ + error = NULL; + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + g_assert (c != NULL); + + g_test_add_func ("/gdbus/delivery-in-thread", test_delivery_in_thread); + g_test_add_func ("/gdbus/method-calls-in-thread", test_method_calls_in_thread); + g_test_add_func ("/gdbus/threaded-singleton", test_threaded_singleton); + + ret = g_test_run(); + + g_object_unref (c); + + /* tear down bus */ + session_bus_down (); + + return ret; +} diff -Nru glib2.0-2.59.2/.pc/flaky-socket-service-test/tests-Fix-flaky-socket-service-test-caused-by-GTask-sched.patch/gio/tests/socket-service.c glib2.0-2.59.3/.pc/flaky-socket-service-test/tests-Fix-flaky-socket-service-test-caused-by-GTask-sched.patch/gio/tests/socket-service.c --- glib2.0-2.59.2/.pc/flaky-socket-service-test/tests-Fix-flaky-socket-service-test-caused-by-GTask-sched.patch/gio/tests/socket-service.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/flaky-socket-service-test/tests-Fix-flaky-socket-service-test-caused-by-GTask-sched.patch/gio/tests/socket-service.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,559 @@ +/* GLib testing framework examples and tests + * + * Copyright 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see + * . + */ + +#include + +static void +active_notify_cb (GSocketService *service, + GParamSpec *pspec, + gpointer data) +{ + gboolean *success = (gboolean *)data; + + if (g_socket_service_is_active (service)) + *success = TRUE; +} + +static void +connected_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketService *service = G_SOCKET_SERVICE (user_data); + GSocketConnection *conn; + GError *error = NULL; + + g_assert_true (g_socket_service_is_active (service)); + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_object_unref (conn); + + g_socket_service_stop (service); + g_assert_false (g_socket_service_is_active (service)); +} + +static void +test_start_stop (void) +{ + gboolean success = FALSE; + GInetAddress *iaddr; + GSocketAddress *saddr, *listening_addr; + GSocketService *service; + GError *error = NULL; + GSocketClient *client; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + /* instanciate with g_object_new so we can pass active = false */ + service = g_object_new (G_TYPE_SOCKET_SERVICE, "active", FALSE, NULL); + g_assert_false (g_socket_service_is_active (service)); + + g_signal_connect (service, "notify::active", G_CALLBACK (active_notify_cb), &success); + + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (saddr); + + client = g_socket_client_new (); + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_cb, service); + g_object_unref (client); + g_object_unref (listening_addr); + + g_socket_service_start (service); + g_assert_true (g_socket_service_is_active (service)); + + do + g_main_context_iteration (NULL, TRUE); + while (!success); + + g_object_unref (service); +} + +GMutex mutex_712570; +GCond cond_712570; +volatile gboolean finalized; + +GType test_threaded_socket_service_get_type (void); +typedef GThreadedSocketService TestThreadedSocketService; +typedef GThreadedSocketServiceClass TestThreadedSocketServiceClass; + +G_DEFINE_TYPE (TestThreadedSocketService, test_threaded_socket_service, G_TYPE_THREADED_SOCKET_SERVICE) + +static void +test_threaded_socket_service_init (TestThreadedSocketService *service) +{ +} + +static void +test_threaded_socket_service_finalize (GObject *object) +{ + G_OBJECT_CLASS (test_threaded_socket_service_parent_class)->finalize (object); + + /* Signal the main thread that finalization completed successfully + * rather than hanging. + */ + finalized = TRUE; + g_cond_signal (&cond_712570); + g_mutex_unlock (&mutex_712570); +} + +static void +test_threaded_socket_service_class_init (TestThreadedSocketServiceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = test_threaded_socket_service_finalize; +} + +static gboolean +connection_cb (GThreadedSocketService *service, + GSocketConnection *connection, + GObject *source_object, + gpointer user_data) +{ + /* Block until the main thread has dropped its ref to @service, so that we + * will drop the final ref from this thread. + */ + g_mutex_lock (&mutex_712570); + + /* The service should now have 1 ref owned by the current "run" + * signal emission, and another added by GThreadedSocketService for + * this thread. Both will be dropped after we return. + */ + g_assert_cmpint (G_OBJECT (service)->ref_count, ==, 2); + + return FALSE; +} + +static void +client_connected_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GMainLoop *loop = user_data; + GSocketConnection *conn; + GError *error = NULL; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + + g_object_unref (conn); + g_main_loop_quit (loop); +} + +static void +test_threaded_712570 (void) +{ + GSocketService *service; + GSocketAddress *addr, *listening_addr; + GMainLoop *loop; + GSocketClient *client; + GError *error = NULL; + + g_test_bug ("712570"); + + g_mutex_lock (&mutex_712570); + + service = g_object_new (test_threaded_socket_service_get_type (), NULL); + + addr = g_inet_socket_address_new_from_string ("127.0.0.1", 0); + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + addr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (addr); + + g_signal_connect (service, "run", G_CALLBACK (connection_cb), NULL); + + loop = g_main_loop_new (NULL, FALSE); + + client = g_socket_client_new (); + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + client_connected_cb, loop); + g_object_unref (client); + g_object_unref (listening_addr); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + /* Stop the service and then wait for it to asynchronously cancel + * its outstanding accept() call (and drop the associated ref). + * At least one main context iteration is required in some circumstances + * to ensure that the cancellation actually happens. + */ + g_socket_service_stop (G_SOCKET_SERVICE (service)); + g_assert_false (g_socket_service_is_active (G_SOCKET_SERVICE (service))); + + do + g_main_context_iteration (NULL, TRUE); + while (G_OBJECT (service)->ref_count > 3); + + /* Drop our ref, then unlock the mutex and wait for the service to be + * finalized. (Without the fix for 712570 it would hang forever here.) + */ + g_object_unref (service); + + while (!finalized) + g_cond_wait (&cond_712570, &mutex_712570); + g_mutex_unlock (&mutex_712570); +} + +static void +closed_read_write_async_cb (GSocketConnection *conn, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + gboolean res; + + res = g_io_stream_close_finish (G_IO_STREAM (conn), result, &error); + g_assert_no_error (error); + g_assert_true (res); +} + +typedef struct { + GSocketConnection *conn; + guint8 *data; +} WriteAsyncData; + +static void +written_read_write_async_cb (GOutputStream *ostream, + GAsyncResult *result, + gpointer user_data) +{ + WriteAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_written; + GSocketConnection *conn; + + conn = data->conn; + + g_free (data->data); + g_free (data); + + res = g_output_stream_write_all_finish (ostream, result, &bytes_written, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (bytes_written, ==, 20); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +connected_read_write_async_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GOutputStream *ostream; + GError *error = NULL; + WriteAsyncData *data; + gsize i; + GSocketConnection **sconn = user_data; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_assert_nonnull (conn); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (conn)); + + data = g_new0 (WriteAsyncData, 1); + data->conn = conn; + data->data = g_new0 (guint8, 20); + for (i = 0; i < 20; i++) + data->data[i] = i; + + g_output_stream_write_all_async (ostream, + data->data, + 20, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) written_read_write_async_cb, + data /* stolen */); + + *sconn = g_object_ref (conn); +} + +typedef struct { + GSocketConnection *conn; + GOutputVector *vectors; + guint n_vectors; + guint8 *data; +} WritevAsyncData; + +static void +writtenv_read_write_async_cb (GOutputStream *ostream, + GAsyncResult *result, + gpointer user_data) +{ + WritevAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_written; + GSocketConnection *conn; + + conn = data->conn; + g_free (data->data); + g_free (data); + + res = g_output_stream_writev_all_finish (ostream, result, &bytes_written, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (bytes_written, ==, 20); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +connected_read_writev_async_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GOutputStream *ostream; + GError *error = NULL; + WritevAsyncData *data; + gsize i; + GSocketConnection **sconn = user_data; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_assert_nonnull (conn); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (conn)); + + data = g_new0 (WritevAsyncData, 1); + data->conn = conn; + data->vectors = g_new0 (GOutputVector, 3); + data->n_vectors = 3; + data->data = g_new0 (guint8, 20); + for (i = 0; i < 20; i++) + data->data[i] = i; + + data->vectors[0].buffer = data->data; + data->vectors[0].size = 5; + data->vectors[1].buffer = data->data + 5; + data->vectors[1].size = 10; + data->vectors[2].buffer = data->data + 15; + data->vectors[2].size = 5; + + g_output_stream_writev_all_async (ostream, + data->vectors, + data->n_vectors, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) writtenv_read_write_async_cb, + data /* stolen */); + + *sconn = g_object_ref (conn); +} + +typedef struct { + GSocketConnection *conn; + guint8 *data; +} ReadAsyncData; + +static void +read_read_write_async_cb (GInputStream *istream, + GAsyncResult *result, + gpointer user_data) +{ + ReadAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_read; + GSocketConnection *conn; + const guint8 expected_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + + res = g_input_stream_read_all_finish (istream, result, &bytes_read, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_assert_cmpmem (expected_data, sizeof expected_data, data->data, bytes_read); + + conn = data->conn; + g_object_set_data (G_OBJECT (conn), "test-data-read", GINT_TO_POINTER (TRUE)); + + g_free (data->data); + g_free (data); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +incoming_read_write_async_cb (GSocketService *service, + GSocketConnection *conn, + GObject *source_object, + gpointer user_data) +{ + ReadAsyncData *data; + GSocketConnection **cconn = user_data; + GInputStream *istream; + + istream = g_io_stream_get_input_stream (G_IO_STREAM (conn)); + + data = g_new0 (ReadAsyncData, 1); + data->conn = g_object_ref (conn); + data->data = g_new0 (guint8, 20); + + g_input_stream_read_all_async (istream, + data->data, + 20, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) read_read_write_async_cb, + data /* stolen */); + + *cconn = g_object_ref (conn); +} + +static void +test_read_write_async_internal (gboolean writev) +{ + GInetAddress *iaddr; + GSocketAddress *saddr, *listening_addr; + GSocketService *service; + GError *error = NULL; + GSocketClient *client; + GSocketConnection *sconn = NULL, *cconn = NULL; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + service = g_socket_service_new (); + + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (saddr); + + g_signal_connect (service, "incoming", G_CALLBACK (incoming_read_write_async_cb), &sconn); + + client = g_socket_client_new (); + + if (writev) + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_read_writev_async_cb, + &cconn); + else + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_read_write_async_cb, + &cconn); + + g_object_unref (client); + g_object_unref (listening_addr); + + g_socket_service_start (service); + g_assert_true (g_socket_service_is_active (service)); + + do + { + g_main_context_iteration (NULL, TRUE); + } + while (!sconn || !cconn || + !g_io_stream_is_closed (G_IO_STREAM (sconn)) || + !g_io_stream_is_closed (G_IO_STREAM (cconn))); + + g_assert_true (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (sconn), "test-data-read"))); + + g_object_unref (sconn); + g_object_unref (cconn); + g_object_unref (service); +} + +/* Test if connecting to a socket service and asynchronously writing data on + * one side followed by reading the same data on the other side of the + * connection works correctly + */ +static void +test_read_write_async (void) +{ + test_read_write_async_internal (FALSE); +} + +/* Test if connecting to a socket service and asynchronously writing data on + * one side followed by reading the same data on the other side of the + * connection works correctly. This uses writev() instead of normal write(). + */ +static void +test_read_writev_async (void) +{ + test_read_write_async_internal (TRUE); +} + + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_bug_base ("http://bugzilla.gnome.org/"); + + g_test_add_func ("/socket-service/start-stop", test_start_stop); + g_test_add_func ("/socket-service/threaded/712570", test_threaded_712570); + g_test_add_func ("/socket-service/read_write_async", test_read_write_async); + g_test_add_func ("/socket-service/read_writev_async", test_read_writev_async); + + return g_test_run(); +} diff -Nru glib2.0-2.59.2/.pc/flaky-socket-service-test/tests-Fix-unlikely-race-in-socket-service-test.patch/gio/tests/socket-service.c glib2.0-2.59.3/.pc/flaky-socket-service-test/tests-Fix-unlikely-race-in-socket-service-test.patch/gio/tests/socket-service.c --- glib2.0-2.59.2/.pc/flaky-socket-service-test/tests-Fix-unlikely-race-in-socket-service-test.patch/gio/tests/socket-service.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/flaky-socket-service-test/tests-Fix-unlikely-race-in-socket-service-test.patch/gio/tests/socket-service.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,564 @@ +/* GLib testing framework examples and tests + * + * Copyright 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * 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, see + * . + */ + +#include + +static void +active_notify_cb (GSocketService *service, + GParamSpec *pspec, + gpointer data) +{ + gboolean *success = (gboolean *)data; + + if (g_socket_service_is_active (service)) + *success = TRUE; +} + +static void +connected_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketService *service = G_SOCKET_SERVICE (user_data); + GSocketConnection *conn; + GError *error = NULL; + + g_assert_true (g_socket_service_is_active (service)); + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_object_unref (conn); + + g_socket_service_stop (service); + g_assert_false (g_socket_service_is_active (service)); +} + +static void +test_start_stop (void) +{ + gboolean success = FALSE; + GInetAddress *iaddr; + GSocketAddress *saddr, *listening_addr; + GSocketService *service; + GError *error = NULL; + GSocketClient *client; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + /* instanciate with g_object_new so we can pass active = false */ + service = g_object_new (G_TYPE_SOCKET_SERVICE, "active", FALSE, NULL); + g_assert_false (g_socket_service_is_active (service)); + + g_signal_connect (service, "notify::active", G_CALLBACK (active_notify_cb), &success); + + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (saddr); + + client = g_socket_client_new (); + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_cb, service); + g_object_unref (client); + g_object_unref (listening_addr); + + g_socket_service_start (service); + g_assert_true (g_socket_service_is_active (service)); + + do + g_main_context_iteration (NULL, TRUE); + while (!success); + + g_object_unref (service); +} + +GMutex mutex_712570; +GCond cond_712570; +volatile gboolean finalized; + +GType test_threaded_socket_service_get_type (void); +typedef GThreadedSocketService TestThreadedSocketService; +typedef GThreadedSocketServiceClass TestThreadedSocketServiceClass; + +G_DEFINE_TYPE (TestThreadedSocketService, test_threaded_socket_service, G_TYPE_THREADED_SOCKET_SERVICE) + +static void +test_threaded_socket_service_init (TestThreadedSocketService *service) +{ +} + +static void +test_threaded_socket_service_finalize (GObject *object) +{ + G_OBJECT_CLASS (test_threaded_socket_service_parent_class)->finalize (object); + + /* Signal the main thread that finalization completed successfully + * rather than hanging. + */ + finalized = TRUE; + g_cond_signal (&cond_712570); + g_mutex_unlock (&mutex_712570); +} + +static void +test_threaded_socket_service_class_init (TestThreadedSocketServiceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = test_threaded_socket_service_finalize; +} + +static gboolean +connection_cb (GThreadedSocketService *service, + GSocketConnection *connection, + GObject *source_object, + gpointer user_data) +{ + /* Block until the main thread has dropped its ref to @service, so that we + * will drop the final ref from this thread. + */ + g_mutex_lock (&mutex_712570); + + /* The service should now have 1 ref owned by the current "run" + * signal emission, and another added by GThreadedSocketService for + * this thread. Both will be dropped after we return. + */ + g_assert_cmpint (G_OBJECT (service)->ref_count, ==, 2); + + return FALSE; +} + +static void +client_connected_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GMainLoop *loop = user_data; + GSocketConnection *conn; + GError *error = NULL; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + + g_object_unref (conn); + g_main_loop_quit (loop); +} + +static void +test_threaded_712570 (void) +{ + GSocketService *service; + GSocketAddress *addr, *listening_addr; + GMainLoop *loop; + GSocketClient *client; + GError *error = NULL; + + g_test_bug ("712570"); + + g_mutex_lock (&mutex_712570); + + service = g_object_new (test_threaded_socket_service_get_type (), NULL); + + addr = g_inet_socket_address_new_from_string ("127.0.0.1", 0); + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + addr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (addr); + + g_signal_connect (service, "run", G_CALLBACK (connection_cb), NULL); + + loop = g_main_loop_new (NULL, FALSE); + + client = g_socket_client_new (); + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + client_connected_cb, loop); + g_object_unref (client); + g_object_unref (listening_addr); + + g_main_loop_run (loop); + g_main_loop_unref (loop); + + /* Stop the service and then wait for it to asynchronously cancel + * its outstanding accept() call (and drop the associated ref). + * At least one main context iteration is required in some circumstances + * to ensure that the cancellation actually happens. + */ + g_socket_service_stop (G_SOCKET_SERVICE (service)); + g_assert_false (g_socket_service_is_active (G_SOCKET_SERVICE (service))); + + do + g_main_context_iteration (NULL, TRUE); + while (G_OBJECT (service)->ref_count > 3); + + /* Wait some more iterations, as #GTask results are deferred to the next + * #GMainContext iteration, and propagation of a #GTask result takes an + * additional ref on the source object. */ + g_main_context_iteration (NULL, FALSE); + + /* Drop our ref, then unlock the mutex and wait for the service to be + * finalized. (Without the fix for 712570 it would hang forever here.) + */ + g_object_unref (service); + + while (!finalized) + g_cond_wait (&cond_712570, &mutex_712570); + g_mutex_unlock (&mutex_712570); +} + +static void +closed_read_write_async_cb (GSocketConnection *conn, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + gboolean res; + + res = g_io_stream_close_finish (G_IO_STREAM (conn), result, &error); + g_assert_no_error (error); + g_assert_true (res); +} + +typedef struct { + GSocketConnection *conn; + guint8 *data; +} WriteAsyncData; + +static void +written_read_write_async_cb (GOutputStream *ostream, + GAsyncResult *result, + gpointer user_data) +{ + WriteAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_written; + GSocketConnection *conn; + + conn = data->conn; + + g_free (data->data); + g_free (data); + + res = g_output_stream_write_all_finish (ostream, result, &bytes_written, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (bytes_written, ==, 20); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +connected_read_write_async_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GOutputStream *ostream; + GError *error = NULL; + WriteAsyncData *data; + gsize i; + GSocketConnection **sconn = user_data; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_assert_nonnull (conn); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (conn)); + + data = g_new0 (WriteAsyncData, 1); + data->conn = conn; + data->data = g_new0 (guint8, 20); + for (i = 0; i < 20; i++) + data->data[i] = i; + + g_output_stream_write_all_async (ostream, + data->data, + 20, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) written_read_write_async_cb, + data /* stolen */); + + *sconn = g_object_ref (conn); +} + +typedef struct { + GSocketConnection *conn; + GOutputVector *vectors; + guint n_vectors; + guint8 *data; +} WritevAsyncData; + +static void +writtenv_read_write_async_cb (GOutputStream *ostream, + GAsyncResult *result, + gpointer user_data) +{ + WritevAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_written; + GSocketConnection *conn; + + conn = data->conn; + g_free (data->data); + g_free (data); + + res = g_output_stream_writev_all_finish (ostream, result, &bytes_written, &error); + g_assert_no_error (error); + g_assert_true (res); + g_assert_cmpuint (bytes_written, ==, 20); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +connected_read_writev_async_cb (GObject *client, + GAsyncResult *result, + gpointer user_data) +{ + GSocketConnection *conn; + GOutputStream *ostream; + GError *error = NULL; + WritevAsyncData *data; + gsize i; + GSocketConnection **sconn = user_data; + + conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client), result, &error); + g_assert_no_error (error); + g_assert_nonnull (conn); + + ostream = g_io_stream_get_output_stream (G_IO_STREAM (conn)); + + data = g_new0 (WritevAsyncData, 1); + data->conn = conn; + data->vectors = g_new0 (GOutputVector, 3); + data->n_vectors = 3; + data->data = g_new0 (guint8, 20); + for (i = 0; i < 20; i++) + data->data[i] = i; + + data->vectors[0].buffer = data->data; + data->vectors[0].size = 5; + data->vectors[1].buffer = data->data + 5; + data->vectors[1].size = 10; + data->vectors[2].buffer = data->data + 15; + data->vectors[2].size = 5; + + g_output_stream_writev_all_async (ostream, + data->vectors, + data->n_vectors, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) writtenv_read_write_async_cb, + data /* stolen */); + + *sconn = g_object_ref (conn); +} + +typedef struct { + GSocketConnection *conn; + guint8 *data; +} ReadAsyncData; + +static void +read_read_write_async_cb (GInputStream *istream, + GAsyncResult *result, + gpointer user_data) +{ + ReadAsyncData *data = user_data; + GError *error = NULL; + gboolean res; + gsize bytes_read; + GSocketConnection *conn; + const guint8 expected_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; + + res = g_input_stream_read_all_finish (istream, result, &bytes_read, &error); + g_assert_no_error (error); + g_assert_true (res); + + g_assert_cmpmem (expected_data, sizeof expected_data, data->data, bytes_read); + + conn = data->conn; + g_object_set_data (G_OBJECT (conn), "test-data-read", GINT_TO_POINTER (TRUE)); + + g_free (data->data); + g_free (data); + + g_io_stream_close_async (G_IO_STREAM (conn), + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) closed_read_write_async_cb, + NULL); + g_object_unref (conn); +} + +static void +incoming_read_write_async_cb (GSocketService *service, + GSocketConnection *conn, + GObject *source_object, + gpointer user_data) +{ + ReadAsyncData *data; + GSocketConnection **cconn = user_data; + GInputStream *istream; + + istream = g_io_stream_get_input_stream (G_IO_STREAM (conn)); + + data = g_new0 (ReadAsyncData, 1); + data->conn = g_object_ref (conn); + data->data = g_new0 (guint8, 20); + + g_input_stream_read_all_async (istream, + data->data, + 20, + G_PRIORITY_DEFAULT, + NULL, + (GAsyncReadyCallback) read_read_write_async_cb, + data /* stolen */); + + *cconn = g_object_ref (conn); +} + +static void +test_read_write_async_internal (gboolean writev) +{ + GInetAddress *iaddr; + GSocketAddress *saddr, *listening_addr; + GSocketService *service; + GError *error = NULL; + GSocketClient *client; + GSocketConnection *sconn = NULL, *cconn = NULL; + + iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (iaddr, 0); + g_object_unref (iaddr); + + service = g_socket_service_new (); + + g_socket_listener_add_address (G_SOCKET_LISTENER (service), + saddr, + G_SOCKET_TYPE_STREAM, + G_SOCKET_PROTOCOL_TCP, + NULL, + &listening_addr, + &error); + g_assert_no_error (error); + g_object_unref (saddr); + + g_signal_connect (service, "incoming", G_CALLBACK (incoming_read_write_async_cb), &sconn); + + client = g_socket_client_new (); + + if (writev) + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_read_writev_async_cb, + &cconn); + else + g_socket_client_connect_async (client, + G_SOCKET_CONNECTABLE (listening_addr), + NULL, + connected_read_write_async_cb, + &cconn); + + g_object_unref (client); + g_object_unref (listening_addr); + + g_socket_service_start (service); + g_assert_true (g_socket_service_is_active (service)); + + do + { + g_main_context_iteration (NULL, TRUE); + } + while (!sconn || !cconn || + !g_io_stream_is_closed (G_IO_STREAM (sconn)) || + !g_io_stream_is_closed (G_IO_STREAM (cconn))); + + g_assert_true (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (sconn), "test-data-read"))); + + g_object_unref (sconn); + g_object_unref (cconn); + g_object_unref (service); +} + +/* Test if connecting to a socket service and asynchronously writing data on + * one side followed by reading the same data on the other side of the + * connection works correctly + */ +static void +test_read_write_async (void) +{ + test_read_write_async_internal (FALSE); +} + +/* Test if connecting to a socket service and asynchronously writing data on + * one side followed by reading the same data on the other side of the + * connection works correctly. This uses writev() instead of normal write(). + */ +static void +test_read_writev_async (void) +{ + test_read_write_async_internal (TRUE); +} + + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_bug_base ("http://bugzilla.gnome.org/"); + + g_test_add_func ("/socket-service/start-stop", test_start_stop); + g_test_add_func ("/socket-service/threaded/712570", test_threaded_712570); + g_test_add_func ("/socket-service/read_write_async", test_read_write_async); + g_test_add_func ("/socket-service/read_writev_async", test_read_writev_async); + + return g_test_run(); +} diff -Nru glib2.0-2.59.2/.pc/flaky-socket-service-test/tests-Unmark-socket-service-test-as-flaky.patch/gio/tests/meson.build glib2.0-2.59.3/.pc/flaky-socket-service-test/tests-Unmark-socket-service-test-as-flaky.patch/gio/tests/meson.build --- glib2.0-2.59.2/.pc/flaky-socket-service-test/tests-Unmark-socket-service-test-as-flaky.patch/gio/tests/meson.build 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/flaky-socket-service-test/tests-Unmark-socket-service-test-as-flaky.patch/gio/tests/meson.build 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,663 @@ +common_gio_tests_deps = [ + libglib_dep, + libgmodule_dep, + libgobject_dep, + libgio_dep, +] + +test_c_args = [ + '-DG_LOG_DOMAIN="GLib-GIO"', + '-DTEST_SERVICES="@0@/gio/tests/services"'.format(meson.build_root()), + '-DGLIB_MKENUMS="@0@"'.format(glib_mkenums), + '-DGLIB_COMPILE_SCHEMAS="@0@"'.format(glib_compile_schemas.full_path()), +] + +if host_machine.system() == 'windows' + common_gio_tests_deps += [iphlpapi_dep, winsock2, cc.find_library ('secur32')] +endif + +subdir('gdbus-object-manager-example') + +gengiotypefuncs_prog = find_program('gengiotypefuncs.py') +giotypefuncs_inc = custom_target( + 'giotypefuncs.inc', + output : 'giotypefuncs.inc', + input : gio_headers + [gioenumtypes_h] + gobject_install_headers, + command: [gengiotypefuncs_prog, '@OUTPUT@', '@INPUT@']) + +# Test programs buildable on all platforms +gio_tests = { + 'appmonitor' : {}, + 'async-close-output-stream' : {}, + 'async-splice-output-stream' : {}, + 'buffered-input-stream' : {}, + 'buffered-output-stream' : {}, + 'cancellable' : {}, + 'contexts' : {}, + 'contenttype' : {}, + 'converter-stream' : {}, + 'credentials' : {}, + 'data-input-stream' : {}, + 'data-output-stream' : {}, + 'defaultvalue' : {'extra_sources' : [giotypefuncs_inc]}, + 'fileattributematcher' : {}, + 'filter-streams' : {}, + 'giomodule' : {}, + 'gsubprocess' : {}, + 'g-file' : {}, + 'g-file-info' : {}, + 'g-icon' : {}, + 'gdbus-addresses' : {}, + 'gdbus-message' : {}, + 'inet-address' : {}, + 'io-stream' : {}, + 'memory-input-stream' : {}, + 'memory-output-stream' : {}, + 'monitor' : {}, + 'mount-operation' : {}, + 'network-address' : {'extra_sources': ['mock-resolver.c']}, + 'network-monitor' : {}, + 'network-monitor-race' : {}, + 'permission' : {}, + 'pollable' : {}, + 'proxy-test' : {}, + 'readwrite' : {}, + 'simple-async-result' : {}, + 'simple-proxy' : {}, + 'sleepy-stream' : {}, + 'socket' : {}, + 'socket-listener' : {}, + 'socket-service' : { 'suite': ['flaky'] }, + 'srvtarget' : {}, + 'task' : {}, + 'vfs' : {}, + 'volumemonitor' : {}, + 'glistmodel' : {}, + 'testfilemonitor' : {'suite' : ['slow', 'flaky']}, + 'thumbnail-verification' : {}, + 'tls-certificate' : {'extra_sources' : ['gtesttlsbackend.c']}, + 'tls-interaction' : {'extra_sources' : ['gtesttlsbackend.c']}, + 'tls-database' : {'extra_sources' : ['gtesttlsbackend.c']}, +} + +test_extra_programs = { + 'gdbus-connection-flush-helper' : {}, + 'gdbus-testserver' : {}, + 'gsubprocess-testprog' : {}, +} + +test_env = environment() +test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) +test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) +test_env.set('GIO_MODULE_DIR', '') +test_env.set('GIO_LAUNCH_DESKTOP', meson.build_root() + '/gio/gio-launch-desktop') + +# Check for libdbus1 - Optional - is only used in the GDBus test cases +# 1.2.14 required for dbus_message_set_serial +dbus1_dep = dependency('dbus-1', required : false, version : '>= 1.2.14') +if not dbus1_dep.found() + if cc.get_id() == 'msvc' + # MSVC: Search for the DBus library by the configuration, which corresponds + # to the output of CMake builds of DBus. Note that debugoptimized + # is really a Release build with .PDB files. + if buildtype == 'debug' + dbus1_dep = cc.find_library('dbus-1d', required : false) + else + dbus1_dep = cc.find_library('dbus-1', required : false) + endif + endif +endif +if dbus1_dep.found() + glib_conf.set('HAVE_DBUS1', 1) + + gio_tests += { + 'gdbus-serialization' : { + 'extra_sources' : ['gdbus-tests.c'], + 'dependencies' : [dbus1_dep], + } + } +endif + +# Test programs buildable on UNIX only +if host_machine.system() != 'windows' + gio_tests += { + 'file' : {}, + 'gdbus-peer' : { + 'dependencies' : [libgdbus_example_objectmanager_dep], + 'install_rpath' : installed_tests_execdir + }, + 'gdbus-peer-object-manager' : {}, + 'live-g-file' : {}, + 'socket-address' : {}, + 'stream-rw_all' : {}, + 'unix-fd' : {}, + 'unix-mounts' : {}, + 'unix-streams' : {}, + 'g-file-info-filesystem-readonly' : {}, + 'gsocketclient-slow' : { + 'depends' : [ + shared_library('slow-connect-preload', + 'slow-connect-preload.c', + name_prefix : '', + dependencies: cc.find_library('dl'), + install_dir : installed_tests_execdir, + install: installed_tests_enabled, + ) + ], + 'env' : { + 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(meson.current_build_dir()) + }, + 'installed_tests_env' : { + 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(installed_tests_execdir), + }, + 'suite': ['flaky'], + }, + 'gschema-compile' : {'install' : false}, + 'trash' : {}, + } + + # Uninstalled because of the check-for-executable logic in DesktopAppInfo + # unable to find the installed executable + if not glib_have_cocoa + gio_tests += { + 'appinfo' : { + 'install' : false, + }, + 'desktop-app-info' : { + 'install' : false, + }, + } + endif + + test_extra_programs += { + 'basic-application' : {}, + 'dbus-launch' : {}, + 'appinfo-test' : {}, + } + + if not glib_have_cocoa + test_extra_programs += { + 'apps' : {}, + } + gio_tests += { + 'mimeapps' : {}, + } + endif + + # Test programs that need to bring up a session bus (requires dbus-daemon) + have_dbus_daemon = find_program('dbus-daemon', required : false).found() + if have_dbus_daemon + annotate_args = [ + '--annotate', 'org.project.Bar', 'Key1', 'Value1', + '--annotate', 'org.project.Bar', 'org.gtk.GDBus.Internal', 'Value2', + '--annotate', 'org.project.Bar.HelloWorld()', 'Key3', 'Value3', + '--annotate', 'org.project.Bar::TestSignal', 'Key4', 'Value4', + '--annotate', 'org.project.Bar:ay', 'Key5', 'Value5', + '--annotate', 'org.project.Bar.TestPrimitiveTypes()[val_int32]', 'Key6', 'Value6', + '--annotate', 'org.project.Bar.TestPrimitiveTypes()[ret_uint32]', 'Key7', 'Value7', + '--annotate', 'org.project.Bar::TestSignal[array_of_strings]', 'Key8', 'Value8', + ] + # Generate gdbus-test-codegen-generated.{c,h} + gdbus_test_codegen_generated = custom_target('gdbus-test-codegen-generated', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated.h', + 'gdbus-test-codegen-generated.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-prefix', 'org.project.', + '--output-directory', '@OUTDIR@', + '--generate-c-code', 'gdbus-test-codegen-generated', + '--c-generate-object-manager', + '--c-generate-autocleanup', 'all', + '--c-namespace', 'Foo_iGen', + '--generate-docbook', 'gdbus-test-codegen-generated-doc', + annotate_args, + '@INPUT@']) + + gdbus_test_codegen_generated_interface_info = [ + custom_target('gdbus-test-codegen-generated-interface-info-h', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated-interface-info.h'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-info-header', + annotate_args, + '--output', '@OUTPUT@', + '@INPUT@']), + custom_target('gdbus-test-codegen-generated-interface-info-c', + input : ['test-codegen.xml'], + output : ['gdbus-test-codegen-generated-interface-info.c'], + depend_files : gdbus_codegen_built_files, + command : [python, gdbus_codegen, + '--interface-info-body', + annotate_args, + '--output', '@OUTPUT@', + '@INPUT@']), + ] + + extra_sources = ['gdbus-sessionbus.c', 'gdbus-tests.c'] + + gio_tests += { + 'actions' : { + 'extra_sources' : extra_sources, + 'suite' : ['slow'], + }, + 'gdbus-auth' : {'extra_sources' : extra_sources, 'suite': ['flaky']}, + 'gdbus-bz627724' : {'extra_sources' : extra_sources, 'suite': ['flaky']}, + 'gdbus-close-pending' : {'extra_sources' : extra_sources}, + 'gdbus-connection' : {'extra_sources' : extra_sources, 'suite': ['flaky']}, + 'gdbus-connection-loss' : {'extra_sources' : extra_sources}, + 'gdbus-connection-slow' : {'extra_sources' : extra_sources}, + 'gdbus-error' : {'extra_sources' : extra_sources}, + 'gdbus-exit-on-close' : {'extra_sources' : extra_sources}, + 'gdbus-export' : { + 'extra_sources' : extra_sources, + 'suite' : ['slow'], + }, + 'gdbus-introspection' : {'extra_sources' : extra_sources}, + 'gdbus-names' : {'extra_sources' : extra_sources}, + 'gdbus-proxy' : {'extra_sources' : extra_sources}, + 'gdbus-proxy-threads' : { + 'extra_sources' : extra_sources, + 'dependencies' : [dbus1_dep], + }, + 'gdbus-proxy-unique-name' : {'extra_sources' : extra_sources}, + 'gdbus-proxy-well-known-name' : {'extra_sources' : extra_sources}, + 'gdbus-test-codegen' : { + 'extra_sources' : [extra_sources, gdbus_test_codegen_generated, gdbus_test_codegen_generated_interface_info], + }, + 'gdbus-threading' : { + 'extra_sources' : extra_sources, + 'suite' : ['slow', 'flaky'], + }, + 'gmenumodel' : { + 'extra_sources' : extra_sources, + 'suite' : ['slow'], + }, + 'gnotification' : { + 'extra_sources' : [extra_sources, 'gnotification-server.c'], + }, + 'gdbus-test-codegen-old' : { + 'source' : 'gdbus-test-codegen.c', + 'extra_sources' : [extra_sources, gdbus_test_codegen_generated, gdbus_test_codegen_generated_interface_info], + 'c_args' : ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_36', + '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36'], + }, + 'gapplication' : {'extra_sources' : extra_sources}, + 'gdbus-unix-addresses' : {}, + } + + if not glib_have_cocoa + gio_tests += { + 'dbus-appinfo' : { + 'extra_sources' : extra_sources, + }, + } + endif + endif # have_dbus_daemon + + # This test is currently unreliable + executable('gdbus-overflow', 'gdbus-overflow.c', + c_args : test_c_args, + dependencies : common_gio_tests_deps, + install_dir : installed_tests_execdir, + install : installed_tests_enabled) + + gio_tests += { + 'gdbus-connection-flush' : { + 'extra_sources' : ['test-io-stream.c', 'test-pipe-unix.c'], + }, + 'gdbus-non-socket' : { + 'extra_sources' : ['gdbus-tests.c', 'test-io-stream.c', 'test-pipe-unix.c'], + }, + } + + # Generate test.mo from de.po using msgfmt + msgfmt = find_program('msgfmt', required : false) + if msgfmt.found() + subdir('de/LC_MESSAGES') + gio_tests += { + 'gsettings' : { + 'extra_sources' : [test_mo], + 'c_args' : ['-DSRCDIR="@0@"'.format(meson.current_source_dir()), + '-DTEST_LOCALE_PATH="@0@"'.format(test_mo_dir)], + 'install' : false, + }, + } + endif +endif # unix + +# Test programs buildable on Windows only +if host_machine.system() == 'windows' + gio_tests += {'win32-streams' : {}} +endif + +if cc.get_id() != 'msvc' + gio_tests += { + 'autoptr-gio' : { + 'source' : 'autoptr.c', + }, + } +endif + +test_extra_programs += { + 'gio-du' : {'install' : false}, + 'echo-server' : {'install' : false}, + 'filter-cat' : {'install' : false}, + 'gapplication-example-actions' : {'install' : false}, + 'gapplication-example-cmdline' : {'install' : false}, + 'gapplication-example-cmdline2' : {'install' : false}, + 'gapplication-example-cmdline3' : {'install' : false}, + 'gapplication-example-cmdline4' : {'install' : false}, + 'gapplication-example-dbushooks' : {'install' : false}, + 'gapplication-example-open' : {'install' : false}, + 'gdbus-daemon' : { + 'extra_sources' : gdbus_daemon_sources, + 'install' : false, + }, + 'gdbus-example-export' : {'install' : false}, + 'gdbus-example-own-name' : {'install' : false}, + 'gdbus-example-peer' : {'install' : false}, + 'gdbus-example-proxy-subclass' : {'install' : false}, + 'gdbus-example-server' : {'install' : false}, + 'gdbus-example-subtree' : {'install' : false}, + 'gdbus-example-watch-name' : {'install' : false}, + 'gdbus-example-watch-proxy' : {'install' : false}, + 'httpd' : {'install' : false}, + 'proxy' : {'install' : false}, + 'resolver' : {'install' : false}, + 'send-data' : {'install' : false}, + 'socket-server' : {'install' : false}, + 'socket-client' : { + 'extra_sources' : ['gtlsconsoleinteraction.c'], + 'install' : false, + }, +} + +if cc.get_id() != 'msvc' + test_extra_programs += { + # These three are manual-run tests because they need a session bus but don't bring one up themselves + # FIXME: these build but don't seem to work! + 'gdbus-example-objectmanager-client' : { + 'dependencies' : [libgdbus_example_objectmanager_dep], + 'install' : false, + }, + 'gdbus-example-objectmanager-server' : { + 'dependencies' : [libgdbus_example_objectmanager_dep], + 'install' : false, + }, + 'gdbus-test-fixture' : { + 'dependencies' : [libgdbus_example_objectmanager_dep], + 'install' : false, + }, + } +endif + +if host_machine.system() != 'windows' + test_extra_programs += { + 'gdbus-example-unix-fd-client' : { + 'install' : false, + }, + } +endif + +appinfo_test_desktop_files = [ + 'appinfo-test-gnome.desktop', + 'appinfo-test-notgnome.desktop', + 'appinfo-test.desktop', + 'appinfo-test2.desktop', +] + +cdata = configuration_data() +if installed_tests_enabled + cdata.set('installed_tests_dir', installed_tests_execdir) +else + cdata.set('installed_tests_dir', meson.current_build_dir()) +endif + +foreach appinfo_test_desktop_file : appinfo_test_desktop_files + configure_file( + input: appinfo_test_desktop_file + '.in', + output: appinfo_test_desktop_file, + install_dir: installed_tests_execdir, + install: installed_tests_enabled, + configuration: cdata, + ) +endforeach + +if installed_tests_enabled + install_data( + 'contexts.c', + 'g-icon.c', + 'appinfo-test-actions.desktop', + 'appinfo-test-static.desktop', + 'file.c', + 'org.gtk.test.dbusappinfo.desktop', + 'test1.overlay', + install_dir : installed_tests_execdir, + ) + install_subdir('x-content', install_dir : installed_tests_execdir) + install_subdir('desktop-files', install_dir : installed_tests_execdir) + install_subdir('thumbnails', install_dir : installed_tests_execdir) + install_subdir('cert-tests', install_dir : installed_tests_execdir) + + cdata = configuration_data() + cdata.set('installed_tests_dir', installed_tests_execdir) + cdata.set('program', 'static-link.py ' + glib_pkgconfigreldir) + configure_file( + input: installed_tests_template, + output: 'static-link.test', + install_dir: installed_tests_metadir, + configuration: cdata + ) + install_subdir('static-link', install_dir : installed_tests_execdir) + install_data('static-link.py', install_dir : installed_tests_execdir) +endif + +if not meson.is_cross_build() or meson.has_exe_wrapper() + + plugin_resources_c = custom_target('plugin-resources.c', + input : 'test4.gresource.xml', + output : 'plugin-resources.c', + command : [glib_compile_resources, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--generate-source', + '--c-name', '_g_plugin', + '@INPUT@']) + + shared_module('resourceplugin', 'resourceplugin.c', plugin_resources_c, + link_args : export_dynamic_ldflags, + dependencies : common_gio_tests_deps, + install_dir : installed_tests_execdir, + install : installed_tests_enabled + ) + + # referenced by test2.gresource.xml + big_test_resource = custom_target( + 'gresource-big-test.txt', + input : ['gen-big-test-resource.py'], + output : ['gresource-big-test.txt'], + command : [python, '@INPUT0@', '@OUTPUT@']) + + test_gresource = custom_target('test.gresource', + input : 'test.gresource.xml', + output : 'test.gresource', + command : [glib_compile_resources, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '@INPUT@'], + install_dir : installed_tests_execdir, + install : installed_tests_enabled) + + test_resources2_c = custom_target('test_resources2.c', + input : 'test3.gresource.xml', + output : 'test_resources2.c', + command : [glib_compile_resources, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--generate', + '--c-name', '_g_test2', + '--manual-register', + '@INPUT@']) + + test_resources2_h = custom_target('test_resources2.h', + input : 'test3.gresource.xml', + output : 'test_resources2.h', + command : [glib_compile_resources, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--generate', + '--c-name', '_g_test2', + '--manual-register', + '@INPUT@']) + + test_resources_c = custom_target('test_resources.c', + input : 'test2.gresource.xml', + depends : big_test_resource, + output : 'test_resources.c', + command : [glib_compile_resources, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '--generate-source', + '--c-name', '_g_test1', + '@INPUT@']) + + # referenced by test.gresource.xml + test_generated_txt = configure_file(input : 'test1.txt', + output : 'test-generated.txt', + copy : true, + install : false) + + # Create object file containing resource data + # for testing the external data option + if build_machine.system() == 'linux' + test_gresource_binary = custom_target('test5.gresource', + input : 'test5.gresource.xml', + output : 'test5.gresource', + command : [glib_compile_resources, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '@INPUT@'], + install_dir : installed_tests_execdir, + install : installed_tests_enabled) + + # Create resource data file + test_resources_binary_c = custom_target('test_resources_binary.c', + input : 'test5.gresource.xml', + output : 'test_resources_binary.c', + command : [glib_compile_resources, + '--target=@OUTPUT@', + '--sourcedir=' + meson.current_source_dir(), + '--sourcedir=' + meson.current_build_dir(), + '--generate-source', + '--external-data', + '--c-name', '_g_binary_test1', + '@INPUT@']) + + # Create object file containing resource data + test_resources_binary = custom_target('test_resources.o', + input : test_gresource_binary, + output : 'test_resources.o', + command : ['ld', + '-r', + '-b','binary', + '@INPUT@', + '-o','@OUTPUT@']) + + # Rename symbol to match the one in the C file + test_resources_binary2 = custom_target('test_resources2.o', + input : test_resources_binary, + output : 'test_resources2.o', + command : ['objcopy', + '--add-symbol','_g_binary_test1_resource_data=.data:0', + '@INPUT@', + '@OUTPUT@']) + + gio_tests += { + 'resources' : { + 'extra_sources' : [test_gresource, test_resources_c, test_resources2_c, + test_resources2_h, test_resources_binary_c, + test_resources_binary2], + }, + } + else + gio_tests += { + 'resources' : { + 'extra_sources' : [test_gresource, test_resources_c, test_resources2_c, + test_resources2_h], + }, + } + endif +endif + +foreach test_name, extra_args : gio_tests + source = extra_args.get('source', test_name + '.c') + extra_sources = extra_args.get('extra_sources', []) + install = installed_tests_enabled and extra_args.get('install', true) + installed_tests_env = extra_args.get('installed_tests_env', {}) + + if install + test_conf = configuration_data() + test_conf.set('installed_tests_dir', installed_tests_execdir) + test_conf.set('program', test_name) + test_env_override = '' + if installed_tests_env != {} + envs = [] + foreach var, value : installed_tests_env + envs += '@0@=@1@'.format(var, value) + endforeach + test_env_override = '@0@ @1@ '.format(env_program.path(), ' '.join(envs)) + endif + test_conf.set('env', test_env_override) + configure_file( + input: installed_tests_template_tap, + output: test_name + '.test', + install_dir: installed_tests_metadir, + configuration: test_conf + ) + endif + + exe = executable(test_name, [source, extra_sources], + c_args : test_c_args + extra_args.get('c_args', []), + dependencies : common_gio_tests_deps + extra_args.get('dependencies', []), + install_rpath : extra_args.get('install_rpath', ''), + install_dir: installed_tests_execdir, + install: install, + ) + + suite = ['gio'] + extra_args.get('suite', []) + timeout = suite.contains('slow') ? test_timeout_slow : test_timeout + local_test_env = test_env + + foreach var, value : extra_args.get('env', {}) + local_test_env.append(var, value) + endforeach + + test(test_name, exe, + env : local_test_env, + timeout : timeout, + suite : suite, + args : ['--tap'], + is_parallel : extra_args.get('is_parallel', true), + depends : extra_args.get('depends', []), + ) +endforeach + +foreach program_name, extra_args : test_extra_programs + source = extra_args.get('source', program_name + '.c') + extra_sources = extra_args.get('extra_sources', []) + install = installed_tests_enabled and extra_args.get('install', true) + executable(program_name, [source, extra_sources], + c_args : test_c_args, + dependencies : common_gio_tests_deps + extra_args.get('dependencies', []), + install_dir : installed_tests_execdir, + install : install, + ) +endforeach + +# FIXME: subdir('services') +subdir('modules') diff -Nru glib2.0-2.59.2/.pc/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch/glib/tests/gwakeuptest.c glib2.0-2.59.3/.pc/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch/glib/tests/gwakeuptest.c --- glib2.0-2.59.2/.pc/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch/glib/tests/gwakeuptest.c 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/gwakeuptest-Be-less-parallel-unless-invoked-with-m-slow.patch/glib/tests/gwakeuptest.c 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1,276 @@ +#include +#include +#ifdef G_OS_UNIX +#include +#endif + +#ifdef _WIN32 +static void alarm (int sec) { } +#endif + +static gboolean +check_signaled (GWakeup *wakeup) +{ + GPollFD fd; + + g_wakeup_get_pollfd (wakeup, &fd); + return g_poll (&fd, 1, 0); +} + +static void +wait_for_signaled (GWakeup *wakeup) +{ + GPollFD fd; + + g_wakeup_get_pollfd (wakeup, &fd); + g_poll (&fd, 1, -1); +} + +static void +test_semantics (void) +{ + GWakeup *wakeup; + gint i; + + /* prevent the test from deadlocking */ + alarm (60); + + wakeup = g_wakeup_new (); + g_assert (!check_signaled (wakeup)); + + g_wakeup_signal (wakeup); + g_assert (check_signaled (wakeup)); + + g_wakeup_acknowledge (wakeup); + g_assert (!check_signaled (wakeup)); + + g_wakeup_free (wakeup); + + /* free unused */ + wakeup = g_wakeup_new (); + g_wakeup_free (wakeup); + + /* free while signaled */ + wakeup = g_wakeup_new (); + g_wakeup_signal (wakeup); + g_wakeup_free (wakeup); + + /* ensure excessive signalling doesn't deadlock */ + wakeup = g_wakeup_new (); + for (i = 0; i < 1000000; i++) + g_wakeup_signal (wakeup); + g_assert (check_signaled (wakeup)); + + /* ensure a single acknowledgement is sufficient */ + g_wakeup_acknowledge (wakeup); + g_assert (!check_signaled (wakeup)); + + g_wakeup_free (wakeup); + + /* cancel the alarm */ + alarm (0); +} + +struct token +{ + gpointer owner; + gint ttl; +}; + +struct context +{ + GSList *pending_tokens; + GMutex lock; + GWakeup *wakeup; + gboolean quit; +}; + +#define NUM_THREADS 50 +#define NUM_TOKENS 5 +#define TOKEN_TTL 100000 + +static struct context contexts[NUM_THREADS]; +static GThread *threads[NUM_THREADS]; +static GWakeup *last_token_wakeup; +static volatile gint tokens_alive; + +static void +context_init (struct context *ctx) +{ + ctx->pending_tokens = NULL; + g_mutex_init (&ctx->lock); + ctx->wakeup = g_wakeup_new (); + ctx->quit = FALSE; +} + +static void +context_clear (struct context *ctx) +{ + g_assert (ctx->pending_tokens == NULL); + g_assert (ctx->quit); + + g_mutex_clear (&ctx->lock); + g_wakeup_free (ctx->wakeup); +} + +static void +context_quit (struct context *ctx) +{ + g_atomic_int_set (&ctx->quit, TRUE); + g_wakeup_signal (ctx->wakeup); +} + +static struct token * +context_try_pop_token (struct context *ctx) +{ + struct token *token = NULL; + + g_mutex_lock (&ctx->lock); + if (ctx->pending_tokens != NULL) + { + token = ctx->pending_tokens->data; + ctx->pending_tokens = g_slist_delete_link (ctx->pending_tokens, + ctx->pending_tokens); + } + g_mutex_unlock (&ctx->lock); + + return token; +} + +static void +context_push_token (struct context *ctx, + struct token *token) +{ + g_assert (token->owner == ctx); + + g_mutex_lock (&ctx->lock); + ctx->pending_tokens = g_slist_prepend (ctx->pending_tokens, token); + g_mutex_unlock (&ctx->lock); + + g_wakeup_signal (ctx->wakeup); +} + +static void +dispatch_token (struct token *token) +{ + if (token->ttl > 0) + { + struct context *ctx; + gint next_ctx; + + next_ctx = g_test_rand_int_range (0, NUM_THREADS); + ctx = &contexts[next_ctx]; + token->owner = ctx; + token->ttl--; + + context_push_token (ctx, token); + } + else + { + g_slice_free (struct token, token); + + if (g_atomic_int_dec_and_test (&tokens_alive)) + g_wakeup_signal (last_token_wakeup); + } +} + +static struct token * +token_new (int ttl) +{ + struct token *token; + + token = g_slice_new (struct token); + token->ttl = ttl; + + g_atomic_int_inc (&tokens_alive); + + return token; +} + +static gpointer +thread_func (gpointer data) +{ + struct context *ctx = data; + struct token *token; + + while (!g_atomic_int_get (&ctx->quit)) + { + wait_for_signaled (ctx->wakeup); + g_wakeup_acknowledge (ctx->wakeup); + + while ((token = context_try_pop_token (ctx)) != NULL) + { + g_assert (token->owner == ctx); + dispatch_token (token); + } + } + + return NULL; +} + +static void +test_threaded (void) +{ + gint i; + + /* make sure we don't block forever */ + alarm (60); + + /* simple mainloop test based on GWakeup. + * + * create a bunch of contexts and a thread to 'run' each one. create + * some tokens and randomly pass them between the threads, until the + * TTL on each token is zero. + * + * when no tokens are left, signal that we are done. the mainthread + * will then signal each worker thread to exit and join them to make + * sure that works. + */ + + last_token_wakeup = g_wakeup_new (); + + /* create contexts, assign to threads */ + for (i = 0; i < NUM_THREADS; i++) + { + context_init (&contexts[i]); + threads[i] = g_thread_new ("test", thread_func, &contexts[i]); + } + + /* dispatch tokens */ + for (i = 0; i < NUM_TOKENS; i++) + dispatch_token (token_new (TOKEN_TTL)); + + /* wait until all tokens are gone */ + wait_for_signaled (last_token_wakeup); + + /* ask threads to quit, join them, cleanup */ + for (i = 0; i < NUM_THREADS; i++) + { + context_quit (&contexts[i]); + g_thread_join (threads[i]); + context_clear (&contexts[i]); + } + + g_wakeup_free (last_token_wakeup); + + /* cancel alarm */ + alarm (0); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + +#ifdef TEST_EVENTFD_FALLBACK +#define TESTNAME_SUFFIX "-fallback" +#else +#define TESTNAME_SUFFIX +#endif + + + g_test_add_func ("/gwakeup/semantics" TESTNAME_SUFFIX, test_semantics); + g_test_add_func ("/gwakeup/threaded" TESTNAME_SUFFIX, test_threaded); + + return g_test_run (); +} diff -Nru glib2.0-2.59.2/.pc/.quilt_patches glib2.0-2.59.3/.pc/.quilt_patches --- glib2.0-2.59.2/.pc/.quilt_patches 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/.quilt_patches 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1 @@ +debian/patches diff -Nru glib2.0-2.59.2/.pc/.quilt_series glib2.0-2.59.3/.pc/.quilt_series --- glib2.0-2.59.2/.pc/.quilt_series 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/.quilt_series 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1 @@ +series diff -Nru glib2.0-2.59.2/.pc/.version glib2.0-2.59.3/.pc/.version --- glib2.0-2.59.2/.pc/.version 1970-01-01 00:00:00.000000000 +0000 +++ glib2.0-2.59.3/.pc/.version 2019-03-04 09:01:41.000000000 +0000 @@ -0,0 +1 @@ +2 diff -Nru glib2.0-2.59.2/po/ca.po glib2.0-2.59.3/po/ca.po --- glib2.0-2.59.2/po/ca.po 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/ca.po 2019-03-04 09:01:42.000000000 +0000 @@ -601,7 +601,7 @@ #: ../gio/gdbusauthmechanismsha1.c:296 #, c-format msgid "Error creating directory “%s”: %s" -msgstr "S'ha produït un error en crear el directori %s: %s" +msgstr "S'ha produït un error en crear el directori «%s»: %s" #: ../gio/gdbusauthmechanismsha1.c:379 #, c-format @@ -1310,7 +1310,7 @@ #: ../gio/gdbus-tool.c:2212 ../gio/gdbus-tool.c:2219 #, c-format msgid "Error: %s is not a valid well-known bus name.\n" -msgstr "Error: %s no és un nom de bus conegut vàlid\n" +msgstr "Error: %s no és un nom de bus conegut vàlid.\n" #: ../gio/gdesktopappinfo.c:2001 ../gio/gdesktopappinfo.c:4566 msgid "Unnamed" @@ -2521,7 +2521,7 @@ #: ../gio/glib-compile-schemas.c:475 #, c-format msgid "Failed to parse value of type “%s”: " -msgstr "No s'ha pogut analitzar el valor del tipus «%s»" +msgstr "No s'ha pogut analitzar el valor del tipus «%s»: " #: ../gio/glib-compile-schemas.c:492 msgid "" @@ -3187,7 +3187,7 @@ #: ../gio/glocalfileoutputstream.c:1045 ../gio/gsubprocess.c:380 #, c-format msgid "Error opening file “%s”: %s" -msgstr "S'ha produït un error en obrir el fitxer %s: %s" +msgstr "S'ha produït un error en obrir el fitxer «%s»: %s" #: ../gio/glocalfileoutputstream.c:826 msgid "Target file is a directory" @@ -4117,7 +4117,7 @@ #: ../gio/gtlspassword.c:117 msgid "The password entered is incorrect." -msgstr "La contrasenya introduïda no és correcte." +msgstr "La contrasenya introduïda no és correcta." #: ../gio/gunixconnection.c:166 ../gio/gunixconnection.c:563 #, c-format @@ -4416,7 +4416,7 @@ #: ../glib/gdatetime.c:208 msgctxt "GDateTime" msgid "%H:%M:%S" -msgstr "%H:%M:%S" +msgstr "%-H:%M:%S" #. Translators: this is the preferred format for expressing 12 hour time #: ../glib/gdatetime.c:211 @@ -4641,7 +4641,7 @@ #: ../glib/gfileutils.c:733 #, c-format msgid "Error reading file “%s”: %s" -msgstr "S'ha produït un error en llegir el fitxer %s: %s" +msgstr "S'ha produït un error en llegir el fitxer «%s»: %s" #: ../glib/gfileutils.c:769 #, c-format diff -Nru glib2.0-2.59.2/po/da.po glib2.0-2.59.3/po/da.po --- glib2.0-2.59.2/po/da.po 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/da.po 2019-03-04 09:01:42.000000000 +0000 @@ -9,6 +9,7 @@ # Kenneth Nielsen , 2011. # Joe Hansen (joedalton2@yahoo.dk), 2013. # Ask Hjorth Larsen , 2007, 08, 09, 10, 11, 12, 14, 15, 16, 17, 18. +# Alan Mortensen , 2019. # # Konventioner: # @@ -26,38 +27,43 @@ msgstr "" "Project-Id-Version: glib\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" -"POT-Creation-Date: 2018-07-30 18:46+0000\n" -"PO-Revision-Date: 2018-09-02 23:09+0200\n" -"Last-Translator: Ask Hjorth Larsen \n" +"POT-Creation-Date: 2019-01-24 14:43+0000\n" +"PO-Revision-Date: 2019-02-16 19:39+0100\n" +"Last-Translator: Alan Mortensen \n" "Language-Team: Danish \n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.0.6\n" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "GApplication options" msgstr "GApplication-indstillinger" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "Show GApplication options" msgstr "Vis GApplication-indstillinger" -#: gio/gapplication.c:541 +#: gio/gapplication.c:544 msgid "Enter GApplication service mode (use from D-Bus service files)" msgstr "Indtast GApplication-tjenestetilstand (brug fra D-Bus-tjenestefiler)" -#: gio/gapplication.c:553 +#: gio/gapplication.c:556 msgid "Override the application’s ID" msgstr "Tilsidesæt programmets id" +#: gio/gapplication.c:568 +msgid "Replace the running instance" +msgstr "Erstat den kørende instans" + #: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 -#: gio/gresource-tool.c:488 gio/gsettings-tool.c:569 +#: gio/gresource-tool.c:495 gio/gsettings-tool.c:569 msgid "Print help" msgstr "Udskriv hjælp" -#: gio/gapplication-tool.c:47 gio/gresource-tool.c:489 gio/gresource-tool.c:557 +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:496 gio/gresource-tool.c:564 msgid "[COMMAND]" msgstr "[KOMMANDO]" @@ -127,9 +133,9 @@ msgid "Application identifier in D-Bus format (eg: org.example.viewer)" msgstr "Programidentifikator i D-Bus-format (f.eks. org.eksempel.fremviser)" -#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:737 -#: gio/glib-compile-resources.c:743 gio/glib-compile-resources.c:770 -#: gio/gresource-tool.c:495 gio/gresource-tool.c:561 +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:502 gio/gresource-tool.c:568 msgid "FILE" msgstr "FIL" @@ -153,7 +159,7 @@ msgid "Optional parameter to the action invocation, in GVariant format" msgstr "Valgfri parameter til handlingen i GVariant-format" -#: gio/gapplication-tool.c:96 gio/gresource-tool.c:526 gio/gsettings-tool.c:661 +#: gio/gapplication-tool.c:96 gio/gresource-tool.c:533 gio/gsettings-tool.c:661 #, c-format msgid "" "Unknown command %s\n" @@ -166,7 +172,7 @@ msgid "Usage:\n" msgstr "Brug:\n" -#: gio/gapplication-tool.c:114 gio/gresource-tool.c:551 +#: gio/gapplication-tool.c:114 gio/gresource-tool.c:558 #: gio/gsettings-tool.c:696 msgid "Arguments:\n" msgstr "Argumenter:\n" @@ -266,8 +272,8 @@ #: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 #: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 -#: gio/ginputstream.c:1019 gio/goutputstream.c:203 gio/goutputstream.c:834 -#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:209 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 #, c-format msgid "Too large count value passed to %s" msgstr "For stor talværdi givet til %s" @@ -282,7 +288,7 @@ msgstr "Kan ikke beskære GBufferedInputStream" #: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 -#: gio/goutputstream.c:1661 +#: gio/goutputstream.c:2198 msgid "Stream is already closed" msgstr "Strømmen er allerede lukket" @@ -290,7 +296,7 @@ msgid "Truncate not supported on base stream" msgstr "Beskæring understøttes ikke af basisstrømmen" -#: gio/gcancellable.c:317 gio/gdbusconnection.c:1840 gio/gdbusprivate.c:1402 +#: gio/gcancellable.c:317 gio/gdbusconnection.c:1867 gio/gdbusprivate.c:1402 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 #, c-format msgid "Operation was cancelled" @@ -309,33 +315,33 @@ msgstr "Utilstrækkelig plads på destinationen" #: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 -#: gio/gdatainputstream.c:1261 glib/gconvert.c:454 glib/gconvert.c:883 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:455 glib/gconvert.c:885 #: glib/giochannel.c:1557 glib/giochannel.c:1599 glib/giochannel.c:2443 #: glib/gutf8.c:869 glib/gutf8.c:1322 msgid "Invalid byte sequence in conversion input" msgstr "Ugyldig bytesekvens i konverteringsinddata" -#: gio/gcharsetconverter.c:347 glib/gconvert.c:462 glib/gconvert.c:797 +#: gio/gcharsetconverter.c:347 glib/gconvert.c:463 glib/gconvert.c:799 #: glib/giochannel.c:1564 glib/giochannel.c:2455 #, c-format msgid "Error during conversion: %s" msgstr "Fejl under konvertering: %s" -#: gio/gcharsetconverter.c:445 gio/gsocket.c:1104 +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1093 msgid "Cancellable initialization not supported" msgstr "Initialisering med mulighed for afbrydelse understøttes ikke" -#: gio/gcharsetconverter.c:456 glib/gconvert.c:327 glib/giochannel.c:1385 +#: gio/gcharsetconverter.c:456 glib/gconvert.c:328 glib/giochannel.c:1385 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported" msgstr "Konvertering fra tegnsæt “%s” til “%s” er ikke understøttet" -#: gio/gcharsetconverter.c:460 glib/gconvert.c:331 +#: gio/gcharsetconverter.c:460 glib/gconvert.c:332 #, c-format msgid "Could not open converter from “%s” to “%s”" msgstr "Kunne ikke konvertere fra “%s” til “%s”" -#: gio/gcontenttype.c:358 +#: gio/gcontenttype.c:452 #, c-format msgid "%s type" msgstr "%s-type" @@ -516,7 +522,7 @@ "Kan ikke bestemme sessionsbussens adresse (ikke implementeret for dette " "operativsystem)" -#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7142 +#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7174 #, c-format msgid "" "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " @@ -525,7 +531,7 @@ "Kan ikke bestemme busadressen fra miljøvariablen DBUS_STARTER_BUS_TYPE — " "ukendt værdi “%s”" -#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7151 +#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7183 msgid "" "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " "variable is not set" @@ -620,12 +626,12 @@ #: gio/gdbusauthmechanismsha1.c:566 #, c-format msgid "Error closing (unlinked) lock file “%s”: %s" -msgstr "Fejl ved lukning af (aflænket) låsefil “%s”: %s" +msgstr "Fejl ved lukning af låsefil (uden link) “%s”: %s" #: gio/gdbusauthmechanismsha1.c:577 #, c-format msgid "Error unlinking lock file “%s”: %s" -msgstr "Fejl ved aflænkning af låsefil “%s”: %s" +msgstr "Fejl ved fjernelse af link til låsefil “%s”: %s" #: gio/gdbusauthmechanismsha1.c:654 #, c-format @@ -637,122 +643,122 @@ msgid "(Additionally, releasing the lock for “%s” also failed: %s) " msgstr "(Yderligere kunne låsen for “%s” ikke opgives: %s) " -#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2369 +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2396 msgid "The connection is closed" msgstr "Forbindelsen er lukket" -#: gio/gdbusconnection.c:1870 +#: gio/gdbusconnection.c:1897 msgid "Timeout was reached" msgstr "Tiden løb ud" -#: gio/gdbusconnection.c:2491 +#: gio/gdbusconnection.c:2518 msgid "" "Unsupported flags encountered when constructing a client-side connection" msgstr "" "Der blev fundet ikke-understøttede flag ved oprettelse af en forbindelse på " "klientsiden" -#: gio/gdbusconnection.c:4115 gio/gdbusconnection.c:4462 +#: gio/gdbusconnection.c:4147 gio/gdbusconnection.c:4494 #, c-format msgid "" "No such interface “org.freedesktop.DBus.Properties” on object at path %s" msgstr "" "Ingen grænseflade “org.freedesktop.DBus.Properties” på objekt ved stien %s" -#: gio/gdbusconnection.c:4257 +#: gio/gdbusconnection.c:4289 #, c-format msgid "No such property “%s”" msgstr "Ingen sådan egenskab “%s”" -#: gio/gdbusconnection.c:4269 +#: gio/gdbusconnection.c:4301 #, c-format msgid "Property “%s” is not readable" msgstr "Egenskaben “%s” kan ikke læses" -#: gio/gdbusconnection.c:4280 +#: gio/gdbusconnection.c:4312 #, c-format msgid "Property “%s” is not writable" msgstr "Egenskaben “%s” er skrivebeskyttet" -#: gio/gdbusconnection.c:4300 +#: gio/gdbusconnection.c:4332 #, c-format msgid "Error setting property “%s”: Expected type “%s” but got “%s”" msgstr "" "Fejl ved anvendelse af egenskaben “%s”: Forventede typen “%s”, men fik “%s”" -#: gio/gdbusconnection.c:4405 gio/gdbusconnection.c:4613 -#: gio/gdbusconnection.c:6582 +#: gio/gdbusconnection.c:4437 gio/gdbusconnection.c:4645 +#: gio/gdbusconnection.c:6614 #, c-format msgid "No such interface “%s”" msgstr "Ingen sådan grænseflade “%s”" -#: gio/gdbusconnection.c:4831 gio/gdbusconnection.c:7091 +#: gio/gdbusconnection.c:4863 gio/gdbusconnection.c:7123 #, c-format msgid "No such interface “%s” on object at path %s" msgstr "Ingen sådan grænseflade “%s” på objektet ved stien %s" -#: gio/gdbusconnection.c:4929 +#: gio/gdbusconnection.c:4961 #, c-format msgid "No such method “%s”" msgstr "Ingen sådan metode “%s”" -#: gio/gdbusconnection.c:4960 +#: gio/gdbusconnection.c:4992 #, c-format msgid "Type of message, “%s”, does not match expected type “%s”" msgstr "Beskedtypen “%s” er ikke den forventede type, “%s”" -#: gio/gdbusconnection.c:5158 +#: gio/gdbusconnection.c:5190 #, c-format msgid "An object is already exported for the interface %s at %s" msgstr "Der er allerede eksporteret et objekt for grænsefladen %s på %s" -#: gio/gdbusconnection.c:5384 +#: gio/gdbusconnection.c:5416 #, c-format msgid "Unable to retrieve property %s.%s" msgstr "Kan ikke hente egenskaben %s.%s" -#: gio/gdbusconnection.c:5440 +#: gio/gdbusconnection.c:5472 #, c-format msgid "Unable to set property %s.%s" msgstr "Kan ikke sætte egenskaben %s.%s" -#: gio/gdbusconnection.c:5618 +#: gio/gdbusconnection.c:5650 #, c-format msgid "Method “%s” returned type “%s”, but expected “%s”" msgstr "Metoden “%s” returnerede typen “%s”, men forventede “%s”" -#: gio/gdbusconnection.c:6693 +#: gio/gdbusconnection.c:6725 #, c-format msgid "Method “%s” on interface “%s” with signature “%s” does not exist" msgstr "Metoden “%s” på grænsefladen “%s” med signatur “%s” findes ikke" -#: gio/gdbusconnection.c:6814 +#: gio/gdbusconnection.c:6846 #, c-format msgid "A subtree is already exported for %s" msgstr "Der er allerede eksporteret et undertræ for %s" -#: gio/gdbusmessage.c:1248 +#: gio/gdbusmessage.c:1251 msgid "type is INVALID" msgstr "typen er INVALID" -#: gio/gdbusmessage.c:1259 +#: gio/gdbusmessage.c:1262 msgid "METHOD_CALL message: PATH or MEMBER header field is missing" msgstr "" "Meddelelse for METHOD_CALL: Et af teksthovederne PATH eller MEMBER mangler" -#: gio/gdbusmessage.c:1270 +#: gio/gdbusmessage.c:1273 msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" msgstr "Meddelelse for METHOD_RETURN: Teksthovedet REPLY_SERIAL mangler" -#: gio/gdbusmessage.c:1282 +#: gio/gdbusmessage.c:1285 msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" msgstr "FEJLmeddelelse: Teksthovedet REPLY_SERIAL eller ERROR_NAME mangler" -#: gio/gdbusmessage.c:1295 +#: gio/gdbusmessage.c:1298 msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" msgstr "SIGNALmeddelelse: Teksthovedet PATH, INTERFACE eller MEMBER mangler" -#: gio/gdbusmessage.c:1303 +#: gio/gdbusmessage.c:1306 msgid "" "SIGNAL message: The PATH header field is using the reserved value /org/" "freedesktop/DBus/Local" @@ -760,7 +766,7 @@ "SIGNALmeddelelse: Teksthovedet PATH bruger den reserverede værdi /org/" "freedesktop/DBus/Local" -#: gio/gdbusmessage.c:1311 +#: gio/gdbusmessage.c:1314 msgid "" "SIGNAL message: The INTERFACE header field is using the reserved value org." "freedesktop.DBus.Local" @@ -768,19 +774,19 @@ "SIGNALbesked: Teksthovedet INTERFACE bruger den reserverede værdi org." "freedesktop.DBus.Local" -#: gio/gdbusmessage.c:1359 gio/gdbusmessage.c:1419 +#: gio/gdbusmessage.c:1362 gio/gdbusmessage.c:1422 #, c-format msgid "Wanted to read %lu byte but only got %lu" msgid_plural "Wanted to read %lu bytes but only got %lu" msgstr[0] "Ville læse %lu byte men fik kun %lu" msgstr[1] "Ville læse %lu byte men fik kun %lu" -#: gio/gdbusmessage.c:1373 +#: gio/gdbusmessage.c:1376 #, c-format msgid "Expected NUL byte after the string “%s” but found byte %d" msgstr "Forventede NUL-byte efter strengen “%s”, men fandt byte %d" -#: gio/gdbusmessage.c:1392 +#: gio/gdbusmessage.c:1395 #, c-format msgid "" "Expected valid UTF-8 string but found invalid bytes at byte offset %d " @@ -790,17 +796,17 @@ "(strengens længde er %d). Den gyldige UTF-8-streng indtil dette punkt var " "“%s”" -#: gio/gdbusmessage.c:1595 +#: gio/gdbusmessage.c:1598 #, c-format msgid "Parsed value “%s” is not a valid D-Bus object path" msgstr "Den fortolkede værdi “%s” er ikke en gyldig objektsti til D-Bus" -#: gio/gdbusmessage.c:1617 +#: gio/gdbusmessage.c:1620 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature" msgstr "Fortolket værdi “%s” er ikke en gyldig D-Bus-signatur" -#: gio/gdbusmessage.c:1664 +#: gio/gdbusmessage.c:1667 #, c-format msgid "" "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." @@ -813,7 +819,7 @@ "Stødte på et array med længde %u bytes. Den maksimale længde er 2<<26 byte " "(64 MiB)." -#: gio/gdbusmessage.c:1684 +#: gio/gdbusmessage.c:1687 #, c-format msgid "" "Encountered array of type “a%c”, expected to have a length a multiple of %u " @@ -822,12 +828,12 @@ "Stødte på et array af typen “a%c”, som ventes at have en længde som er et " "multiplum af %u byte, men som havde længde %u byte" -#: gio/gdbusmessage.c:1851 +#: gio/gdbusmessage.c:1857 #, c-format msgid "Parsed value “%s” for variant is not a valid D-Bus signature" msgstr "Fortolket værdi “%s” for variant er ikke en gyldig D-Bus-signatur" -#: gio/gdbusmessage.c:1875 +#: gio/gdbusmessage.c:1881 #, c-format msgid "" "Error deserializing GVariant with type string “%s” from the D-Bus wire format" @@ -835,7 +841,7 @@ "Fejl ved deserialisering af GVariant med type-streng “%s” fra D-Bus-wire-" "formatet" -#: gio/gdbusmessage.c:2057 +#: gio/gdbusmessage.c:2066 #, c-format msgid "" "Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value " @@ -844,34 +850,38 @@ "Ugyldigt værdi for byterækkefølge (endianness). Forventede 0x6c (“l”) eller " "0x42 (“B”), men fandt værdien 0x%02x" -#: gio/gdbusmessage.c:2070 +#: gio/gdbusmessage.c:2079 #, c-format msgid "Invalid major protocol version. Expected 1 but found %d" msgstr "Igyldig hovedprotokolversion. Forventede 1 men fandt %d" -#: gio/gdbusmessage.c:2126 +#: gio/gdbusmessage.c:2132 gio/gdbusmessage.c:2724 +msgid "Signature header found but is not of type signature" +msgstr "Signaturteksthoved fundet, men er ikke af typen signatur" + +#: gio/gdbusmessage.c:2144 #, c-format msgid "Signature header with signature “%s” found but message body is empty" msgstr "" "Signaturteksthoved med signaturen “%s” fundet, men beskedteksten er tom" -#: gio/gdbusmessage.c:2140 +#: gio/gdbusmessage.c:2159 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature (for body)" msgstr "Fortolket værdi “%s” er ikke en gyldig D-Bus-signatur (for tekst)" -#: gio/gdbusmessage.c:2170 +#: gio/gdbusmessage.c:2190 #, c-format msgid "No signature header in message but the message body is %u byte" msgid_plural "No signature header in message but the message body is %u bytes" msgstr[0] "Intet signaturteksthoved i beskeden, men beskedteksten er %u byte" msgstr[1] "Intet signaturteksthoved i beskeden, men beskedteksten er %u bytes" -#: gio/gdbusmessage.c:2180 +#: gio/gdbusmessage.c:2200 msgid "Cannot deserialize message: " msgstr "Kan ikke deserialisere besked: " -#: gio/gdbusmessage.c:2521 +#: gio/gdbusmessage.c:2541 #, c-format msgid "" "Error serializing GVariant with type string “%s” to the D-Bus wire format" @@ -879,23 +889,23 @@ "Fejl ved serialisering af GVariant med typestreng “%s” til D-Bus-wire-" "formatet" -#: gio/gdbusmessage.c:2658 +#: gio/gdbusmessage.c:2678 #, c-format msgid "" "Number of file descriptors in message (%d) differs from header field (%d)" msgstr "" "Antal fildeskriptorer i meddelelsen (%d) er forskelligt fra teksthovedet (%d)" -#: gio/gdbusmessage.c:2666 +#: gio/gdbusmessage.c:2686 msgid "Cannot serialize message: " msgstr "Kan ikke serialisere besked: " -#: gio/gdbusmessage.c:2710 +#: gio/gdbusmessage.c:2740 #, c-format msgid "Message body has signature “%s” but there is no signature header" msgstr "Beskedteksten har signatur “%s”, men der er intet signaturteksthoved" -#: gio/gdbusmessage.c:2720 +#: gio/gdbusmessage.c:2750 #, c-format msgid "" "Message body has type signature “%s” but signature in the header field is " @@ -903,17 +913,17 @@ msgstr "" "Beskedteksten har typesignatur “%s”, men signaturen i teksthovedet er “%s”" -#: gio/gdbusmessage.c:2736 +#: gio/gdbusmessage.c:2766 #, c-format msgid "Message body is empty but signature in the header field is “(%s)”" msgstr "Beskedteksten er tom, men signaturen i teksthovedet er “(%s)”" -#: gio/gdbusmessage.c:3289 +#: gio/gdbusmessage.c:3319 #, c-format msgid "Error return with body of type “%s”" msgstr "Fejlagtig returværdi med beskedtekst af typen “%s”" -#: gio/gdbusmessage.c:3297 +#: gio/gdbusmessage.c:3327 msgid "Error return with empty body" msgstr "Fejlagtig returværdi - tom beskedtekst" @@ -926,23 +936,24 @@ msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " msgstr "Kan ikke indlæse /var/lib/dbus/machine-id eller /etc/machine-id: " -#: gio/gdbusproxy.c:1612 +#: gio/gdbusproxy.c:1611 #, c-format msgid "Error calling StartServiceByName for %s: " msgstr "Fejl ved kald til StartServiceByName for %s: " -#: gio/gdbusproxy.c:1635 +#: gio/gdbusproxy.c:1634 #, c-format msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" msgstr "Uventet svar %d fra metoden StartServiceByName(“%s”)" # Ved ikke helt hvad proxy dækker over her -#: gio/gdbusproxy.c:2726 gio/gdbusproxy.c:2860 +#: gio/gdbusproxy.c:2734 gio/gdbusproxy.c:2869 +#, c-format msgid "" -"Cannot invoke method; proxy is for a well-known name without an owner and " -"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" msgstr "" -"Kan ikke kalde metode; proxy er for et velkendt navn uden ejer, og proxy " +"Kan ikke kalde metode; proxy er for et velkendt navn %s uden ejer, og proxy " "blev konstrueret med flaget G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" #: gio/gdbusserver.c:708 @@ -1240,38 +1251,38 @@ msgid "Error: %s is not a valid well-known bus name.\n" msgstr "Fejl: %s er ikke et gyldigt velkendt busnavn.\n" -#: gio/gdesktopappinfo.c:2023 gio/gdesktopappinfo.c:4633 +#: gio/gdesktopappinfo.c:2041 gio/gdesktopappinfo.c:4680 msgid "Unnamed" msgstr "Unavngivet" -#: gio/gdesktopappinfo.c:2433 +#: gio/gdesktopappinfo.c:2451 msgid "Desktop file didn’t specify Exec field" msgstr "Skrivebordsfil angav intet Exec-felt" -#: gio/gdesktopappinfo.c:2692 +#: gio/gdesktopappinfo.c:2710 msgid "Unable to find terminal required for application" msgstr "Kan ikke finde terminal krævet af dette program" -#: gio/gdesktopappinfo.c:3202 +#: gio/gdesktopappinfo.c:3222 #, c-format msgid "Can’t create user application configuration folder %s: %s" msgstr "Kan ikke oprette konfigurationsfolder %s for brugerprogram: %s" -#: gio/gdesktopappinfo.c:3206 +#: gio/gdesktopappinfo.c:3226 #, c-format msgid "Can’t create user MIME configuration folder %s: %s" msgstr "Kan ikke oprette bruger-MIME-konfigurationsfolder %s: %s" -#: gio/gdesktopappinfo.c:3446 gio/gdesktopappinfo.c:3470 +#: gio/gdesktopappinfo.c:3466 gio/gdesktopappinfo.c:3490 msgid "Application information lacks an identifier" msgstr "Programinformation mangler en identifikator" -#: gio/gdesktopappinfo.c:3704 +#: gio/gdesktopappinfo.c:3724 #, c-format msgid "Can’t create user desktop file %s" msgstr "Kan ikke oprette brugerskrivebords-fil %s" -#: gio/gdesktopappinfo.c:3838 +#: gio/gdesktopappinfo.c:3858 #, c-format msgid "Custom definition for %s" msgstr "Tilpasset definition for %s" @@ -1350,7 +1361,7 @@ msgid "Containing mount does not exist" msgstr "Indeholdende montering findes ikke" -#: gio/gfile.c:2622 gio/glocalfile.c:2391 +#: gio/gfile.c:2622 gio/glocalfile.c:2441 msgid "Can’t copy over directory" msgstr "Kan ikke kopiere over mappe" @@ -1393,7 +1404,7 @@ #: gio/gfile.c:4019 msgid "Invalid symlink value given" -msgstr "Ugyldig værdi givet for symbolsk henvisning" +msgstr "Ugyldig værdi givet for symlink" # I koden er det en funktion der hedder g_file_trash, som kan give dette som en fejlmeddelelse #: gio/gfile.c:4180 @@ -1455,8 +1466,8 @@ msgid "Truncate not supported on stream" msgstr "Afskæring understøttes ikke på strømmen" -#: gio/ghttpproxy.c:91 gio/gresolver.c:410 gio/gresolver.c:476 -#: glib/gconvert.c:1786 +#: gio/ghttpproxy.c:91 gio/gresolver.c:377 gio/gresolver.c:529 +#: glib/gconvert.c:1785 msgid "Invalid hostname" msgstr "Ugyldigt værtsnavn" @@ -1485,38 +1496,38 @@ msgid "HTTP proxy server closed connection unexpectedly." msgstr "HTTP-proxyserveren lukkede uventet forbindelsen." -#: gio/gicon.c:290 +#: gio/gicon.c:298 #, c-format msgid "Wrong number of tokens (%d)" msgstr "Forkert antal tegn (%d)" -#: gio/gicon.c:310 +#: gio/gicon.c:318 #, c-format msgid "No type for class name %s" msgstr "Ingen type til klassenavn %s" -#: gio/gicon.c:320 +#: gio/gicon.c:328 #, c-format msgid "Type %s does not implement the GIcon interface" msgstr "Typen %s implementerer ikke GIcon-grænsefladen" -#: gio/gicon.c:331 +#: gio/gicon.c:339 #, c-format msgid "Type %s is not classed" msgstr "Typen %s har ingen klasse" -#: gio/gicon.c:345 +#: gio/gicon.c:353 #, c-format msgid "Malformed version number: %s" msgstr "Fejlformateret versionsnummer %s" -#: gio/gicon.c:359 +#: gio/gicon.c:367 #, c-format msgid "Type %s does not implement from_tokens() on the GIcon interface" msgstr "" "Typen %s implementerer ikke from_tokens(), som er del af GIcon-grænsefladen" -#: gio/gicon.c:461 +#: gio/gicon.c:469 msgid "Can’t handle the supplied version of the icon encoding" msgstr "Kan ikke håndtere den givne version af ikonkodningen" @@ -1557,7 +1568,7 @@ #. Translators: This is an error you get if there is #. * already an operation running against this stream when #. * you try to start one -#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:1671 +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 msgid "Stream has outstanding operation" msgstr "Strøm arbejder stadig" @@ -1662,7 +1673,7 @@ #: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:282 gio/gio-tool-list.c:165 #: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 #: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 -#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1235 gio/gio-tool-open.c:113 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:113 #: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 #: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 msgid "LOCATION" @@ -1683,7 +1694,7 @@ "server/ressource/fil.txt som sted." #: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:313 gio/gio-tool-mkdir.c:76 -#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1285 gio/gio-tool-open.c:139 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:139 #: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 msgid "No locations given" msgstr "Ingen steder givet" @@ -1974,96 +1985,96 @@ msgid "Monitor files or directories for changes." msgstr "Overvåg ændringer af filer eller mapper." -#: gio/gio-tool-mount.c:62 +#: gio/gio-tool-mount.c:63 msgid "Mount as mountable" msgstr "Montér som monterbar" -#: gio/gio-tool-mount.c:63 +#: gio/gio-tool-mount.c:64 msgid "Mount volume with device file" msgstr "Montér diskenhed med enhedsfil" -#: gio/gio-tool-mount.c:63 gio/gio-tool-mount.c:66 +#: gio/gio-tool-mount.c:64 gio/gio-tool-mount.c:67 msgid "DEVICE" msgstr "ENHED" -#: gio/gio-tool-mount.c:64 +#: gio/gio-tool-mount.c:65 msgid "Unmount" msgstr "Afmontér" -#: gio/gio-tool-mount.c:65 +#: gio/gio-tool-mount.c:66 msgid "Eject" msgstr "Skub ud" -#: gio/gio-tool-mount.c:66 +#: gio/gio-tool-mount.c:67 msgid "Stop drive with device file" msgstr "Stop drev med enhedsfil" # Ikke sikker jf. nedenfor -#: gio/gio-tool-mount.c:67 +#: gio/gio-tool-mount.c:68 msgid "Unmount all mounts with the given scheme" msgstr "Afmontér alle monteringer med et givent skema" # Ikke sikker på denne -#: gio/gio-tool-mount.c:67 +#: gio/gio-tool-mount.c:68 msgid "SCHEME" msgstr "SKEMA" -#: gio/gio-tool-mount.c:68 +#: gio/gio-tool-mount.c:69 msgid "Ignore outstanding file operations when unmounting or ejecting" msgstr "" "Ignorér afventende filoperationer ved afmontering eller når der skubbes ud" -#: gio/gio-tool-mount.c:69 +#: gio/gio-tool-mount.c:70 msgid "Use an anonymous user when authenticating" msgstr "Brug en anonym bruger ved godkendelse" #. Translator: List here is a verb as in 'List all mounts' -#: gio/gio-tool-mount.c:71 +#: gio/gio-tool-mount.c:72 msgid "List" msgstr "Vis" -#: gio/gio-tool-mount.c:72 +#: gio/gio-tool-mount.c:73 msgid "Monitor events" msgstr "Overvåg hændelser" -#: gio/gio-tool-mount.c:73 +#: gio/gio-tool-mount.c:74 msgid "Show extra information" msgstr "Vis yderligere oplysninger" -#: gio/gio-tool-mount.c:74 +#: gio/gio-tool-mount.c:75 msgid "The numeric PIM when unlocking a VeraCrypt volume" msgstr "Den numeriske PIN ved oplåsning af en VeraCrypt-diskenhed" -#: gio/gio-tool-mount.c:74 +#: gio/gio-tool-mount.c:75 msgid "PIM" msgstr "PIM" -#: gio/gio-tool-mount.c:75 +#: gio/gio-tool-mount.c:76 msgid "Mount a TCRYPT hidden volume" msgstr "Montér en skjult TCRYPT-diskenhed" -#: gio/gio-tool-mount.c:76 +#: gio/gio-tool-mount.c:77 msgid "Mount a TCRYPT system volume" msgstr "Montér en TCRYPT-systemdiskenhed" -#: gio/gio-tool-mount.c:264 gio/gio-tool-mount.c:296 +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 msgid "Anonymous access denied" msgstr "Anonym adgang nægtet" -#: gio/gio-tool-mount.c:524 +#: gio/gio-tool-mount.c:522 msgid "No drive for device file" msgstr "Intet drev for enhedsfilen" -#: gio/gio-tool-mount.c:989 +#: gio/gio-tool-mount.c:975 #, c-format msgid "Mounted %s at %s\n" msgstr "Monterede %s på %s\n" -#: gio/gio-tool-mount.c:1044 +#: gio/gio-tool-mount.c:1027 msgid "No volume for device file" msgstr "Ingen diskenhed for enhedsfilen" -#: gio/gio-tool-mount.c:1239 +#: gio/gio-tool-mount.c:1216 msgid "Mount or unmount the locations." msgstr "Montér eller afmontér stederne." @@ -2266,7 +2277,8 @@ #: gio/glib-compile-resources.c:427 #, c-format msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" -msgstr "%s-præprocessering forespurgt, men %s er ikke angivet, og %s er ikke i PATH" +msgstr "" +"%s-præprocessering forespurgt, men %s er ikke angivet, og %s er ikke i PATH" #: gio/glib-compile-resources.c:460 #, c-format @@ -2283,64 +2295,75 @@ msgid "text may not appear inside <%s>" msgstr "der må ikke være tekst inden i <%s>" -#: gio/glib-compile-resources.c:736 gio/glib-compile-schemas.c:2138 +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2139 msgid "Show program version and exit" msgstr "Vis programversion og afslut" -#: gio/glib-compile-resources.c:737 +#: gio/glib-compile-resources.c:738 msgid "Name of the output file" msgstr "Navnet på outputfilen" -#: gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:739 msgid "" "The directories to load files referenced in FILE from (default: current " "directory)" -msgstr "Katalogerne hvorfra filer fra henvisninger i FIL læses (som standard det nuværende katalog)" +msgstr "" +"Katalogerne hvorfra filer fra henvisninger i FIL læses (som standard det " +"nuværende katalog)" -#: gio/glib-compile-resources.c:738 gio/glib-compile-schemas.c:2139 -#: gio/glib-compile-schemas.c:2168 +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-schemas.c:2169 msgid "DIRECTORY" msgstr "KATALOG" -#: gio/glib-compile-resources.c:739 +#: gio/glib-compile-resources.c:740 msgid "" "Generate output in the format selected for by the target filename extension" msgstr "Generér output i formatet givet ved målets filendelse" -#: gio/glib-compile-resources.c:740 +#: gio/glib-compile-resources.c:741 msgid "Generate source header" msgstr "Generér kildeheader" -#: gio/glib-compile-resources.c:741 +#: gio/glib-compile-resources.c:742 msgid "Generate source code used to link in the resource file into your code" -msgstr "Generér kildekoden, der bruges til at linke fra ressourcefilen ind i din kode" +msgstr "" +"Generér kildekoden, der bruges til at linke fra ressourcefilen ind i din kode" -#: gio/glib-compile-resources.c:742 +#: gio/glib-compile-resources.c:743 msgid "Generate dependency list" msgstr "Generér liste af afhængigheder" -#: gio/glib-compile-resources.c:743 +#: gio/glib-compile-resources.c:744 msgid "Name of the dependency file to generate" msgstr "Navn på afhængighedsfil som skal oprettes" # phony er et nøgleord i make -#: gio/glib-compile-resources.c:744 +#: gio/glib-compile-resources.c:745 msgid "Include phony targets in the generated dependency file" msgstr "Inkludér falske (phony) mål i den genererede afhængighedsfil" -#: gio/glib-compile-resources.c:745 +#: gio/glib-compile-resources.c:746 msgid "Don’t automatically create and register resource" msgstr "Opret og registrér ikke ressource automatisk" -#: gio/glib-compile-resources.c:746 +#: gio/glib-compile-resources.c:747 msgid "Don’t export functions; declare them G_GNUC_INTERNAL" msgstr "Eksporter ikke funktioner; erklær dem G_GNUC_INTERNAL" -#: gio/glib-compile-resources.c:747 +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Indlejr ikke ressourcedata i C-filen; antag at den i stedet er linket " +"eksternt" + +#: gio/glib-compile-resources.c:749 msgid "C identifier name used for the generated source code" msgstr "C-identifikatornavn, der bruges til genereret kildekode" -#: gio/glib-compile-resources.c:773 +#: gio/glib-compile-resources.c:775 msgid "" "Compile a resource specification into a resource file.\n" "Resource specification files have the extension .gresource.xml,\n" @@ -2350,7 +2373,7 @@ "Ressourcespecifikationsfiler har filendelsen .gresource.xml,\n" "og ressourcefilen har filendelsen .gresource." -#: gio/glib-compile-resources.c:795 +#: gio/glib-compile-resources.c:797 msgid "You should give exactly one file name\n" msgstr "Du skal angive præcist ét filnavn\n" @@ -2730,7 +2753,9 @@ msgid "" "cannot provide per-desktop overrides for localised key “%s” in schema " "“%s” (override file “%s”)" -msgstr "kan ikke skrivebordsspecifikt overskrive den lokaliserede nøgle “%s” i skemaet “%s” (overskrivelsesfil “%s”)" +msgstr "" +"kan ikke skrivebordsspecifikt overskrive den lokaliserede nøgle “%s” i " +"skemaet “%s” (overskrivelsesfil “%s”)" #: gio/glib-compile-schemas.c:2011 #, c-format @@ -2759,25 +2784,27 @@ msgid "" "override for key “%s” in schema “%s” in override file “%s” is not in the " "list of valid choices" -msgstr "overskrivningen for nøglen “%s” i skemaet “%s” i overskrivningsfilen “%s” findes ikke i listen over gyldige valg" +msgstr "" +"overskrivningen for nøglen “%s” i skemaet “%s” i overskrivningsfilen “%s” " +"findes ikke i listen over gyldige valg" -#: gio/glib-compile-schemas.c:2139 +#: gio/glib-compile-schemas.c:2140 msgid "where to store the gschemas.compiled file" msgstr "hvor filen gschemas.compiled skal lægges" -#: gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-schemas.c:2141 msgid "Abort on any errors in schemas" msgstr "Afbryd ved enhver fejl i skemaer" -#: gio/glib-compile-schemas.c:2141 +#: gio/glib-compile-schemas.c:2142 msgid "Do not write the gschema.compiled file" msgstr "Skriv ikke filen gschema.compiled" -#: gio/glib-compile-schemas.c:2142 +#: gio/glib-compile-schemas.c:2143 msgid "Do not enforce key name restrictions" msgstr "Gennemtving ikke begrænsninger på nøglenavn" -#: gio/glib-compile-schemas.c:2171 +#: gio/glib-compile-schemas.c:2172 msgid "" "Compile all GSettings schema files into a schema cache.\n" "Schema files are required to have the extension .gschema.xml,\n" @@ -2787,22 +2814,22 @@ "Schemafiler skal have filendelsen .gschema.xml,\n" "og mellemlagerfilen kaldes gschemas.compiled." -#: gio/glib-compile-schemas.c:2192 +#: gio/glib-compile-schemas.c:2193 #, c-format msgid "You should give exactly one directory name\n" msgstr "Du skal give præcist et katalognavn\n" -#: gio/glib-compile-schemas.c:2234 +#: gio/glib-compile-schemas.c:2235 #, c-format msgid "No schema files found: " msgstr "Ingen skemafiler fundet: " -#: gio/glib-compile-schemas.c:2237 +#: gio/glib-compile-schemas.c:2238 #, c-format msgid "doing nothing.\n" msgstr "gør intet.\n" -#: gio/glib-compile-schemas.c:2240 +#: gio/glib-compile-schemas.c:2241 #, c-format msgid "removed existing output file.\n" msgstr "fjernede eksisterende uddatafil.\n" @@ -2812,7 +2839,7 @@ msgid "Invalid filename %s" msgstr "Ugyldigt filnavn %s" -#: gio/glocalfile.c:1006 +#: gio/glocalfile.c:1011 #, c-format msgid "Error getting filesystem info for %s: %s" msgstr "Fejl ved hentning af filsysteminfo for %s: %s" @@ -2821,128 +2848,128 @@ #. * the enclosing (user visible) mount of a file, but none #. * exists. #. -#: gio/glocalfile.c:1145 +#: gio/glocalfile.c:1150 #, c-format msgid "Containing mount for file %s not found" msgstr "Indeholdende montering for filen %s ikke fundet" -#: gio/glocalfile.c:1168 +#: gio/glocalfile.c:1173 msgid "Can’t rename root directory" msgstr "Kan ikke omdøbe rodmappen" -#: gio/glocalfile.c:1186 gio/glocalfile.c:1209 +#: gio/glocalfile.c:1191 gio/glocalfile.c:1214 #, c-format msgid "Error renaming file %s: %s" msgstr "Fejl ved omdøbning af filen %s: %s" -#: gio/glocalfile.c:1193 +#: gio/glocalfile.c:1198 msgid "Can’t rename file, filename already exists" msgstr "Kan ikke omdøbe fil, filnavn findes allerede" -#: gio/glocalfile.c:1206 gio/glocalfile.c:2267 gio/glocalfile.c:2295 -#: gio/glocalfile.c:2452 gio/glocalfileoutputstream.c:551 +#: gio/glocalfile.c:1211 gio/glocalfile.c:2317 gio/glocalfile.c:2345 +#: gio/glocalfile.c:2502 gio/glocalfileoutputstream.c:646 msgid "Invalid filename" msgstr "Ugyldigt filnavn" -#: gio/glocalfile.c:1374 gio/glocalfile.c:1389 +#: gio/glocalfile.c:1379 gio/glocalfile.c:1394 #, c-format msgid "Error opening file %s: %s" msgstr "Fejl ved åbning af filen %s: %s" -#: gio/glocalfile.c:1514 +#: gio/glocalfile.c:1519 #, c-format msgid "Error removing file %s: %s" msgstr "Fejl under fjernelse af filen %s: %s" -#: gio/glocalfile.c:1925 +#: gio/glocalfile.c:1958 #, c-format msgid "Error trashing file %s: %s" msgstr "Fejl ved flytning af filen %s til papirkurv: %s" -#: gio/glocalfile.c:1948 +#: gio/glocalfile.c:1999 #, c-format msgid "Unable to create trash dir %s: %s" msgstr "Kan ikke oprette papirkurvskatalog %s: %s" -#: gio/glocalfile.c:1970 +#: gio/glocalfile.c:2020 #, c-format msgid "Unable to find toplevel directory to trash %s" msgstr "Kan ikke finde topniveau-katalog til papirkurv %s" -#: gio/glocalfile.c:1979 +#: gio/glocalfile.c:2029 #, c-format msgid "Trashing on system internal mounts is not supported" msgstr "Papirkurv understøttes ikke på interne systemmonteringer" -#: gio/glocalfile.c:2063 gio/glocalfile.c:2083 +#: gio/glocalfile.c:2113 gio/glocalfile.c:2133 #, c-format msgid "Unable to find or create trash directory for %s" msgstr "Kan ikke finde eller oprette papirkurvskatalog for %s" -#: gio/glocalfile.c:2118 +#: gio/glocalfile.c:2168 #, c-format msgid "Unable to create trashing info file for %s: %s" msgstr "Kan ikke oprette papirkurvs-infofil for %s: %s" -#: gio/glocalfile.c:2178 +#: gio/glocalfile.c:2228 #, c-format msgid "Unable to trash file %s across filesystem boundaries" msgstr "Kan ikke smide filen %s ud på andet filsystem" -#: gio/glocalfile.c:2182 gio/glocalfile.c:2238 +#: gio/glocalfile.c:2232 gio/glocalfile.c:2288 #, c-format msgid "Unable to trash file %s: %s" msgstr "Kan ikke smide filen %s ud: %s" -#: gio/glocalfile.c:2244 +#: gio/glocalfile.c:2294 #, c-format msgid "Unable to trash file %s" msgstr "Kan ikke smide filen %s ud" -#: gio/glocalfile.c:2270 +#: gio/glocalfile.c:2320 #, c-format msgid "Error creating directory %s: %s" msgstr "Fejl ved oprettelse af mappen %s: %s" -#: gio/glocalfile.c:2299 +#: gio/glocalfile.c:2349 #, c-format msgid "Filesystem does not support symbolic links" -msgstr "Filsystemet understøtter ikke symbolske henvisninger" +msgstr "Filsystemet understøtter ikke symbolske links" -#: gio/glocalfile.c:2302 +#: gio/glocalfile.c:2352 #, c-format msgid "Error making symbolic link %s: %s" msgstr "Fejl under oprettelse af symbolsk link %s: %s" -#: gio/glocalfile.c:2308 glib/gfileutils.c:2138 +#: gio/glocalfile.c:2358 glib/gfileutils.c:2138 msgid "Symbolic links not supported" -msgstr "Symbolske henvisninger er ikke understøttet" +msgstr "Symbolske links er ikke understøttet" -#: gio/glocalfile.c:2363 gio/glocalfile.c:2398 gio/glocalfile.c:2455 +#: gio/glocalfile.c:2413 gio/glocalfile.c:2448 gio/glocalfile.c:2505 #, c-format msgid "Error moving file %s: %s" msgstr "Fejl ved flytning af filen %s: %s" -#: gio/glocalfile.c:2386 +#: gio/glocalfile.c:2436 msgid "Can’t move directory over directory" msgstr "Kan ikke flytte mappe over mappe" -#: gio/glocalfile.c:2412 gio/glocalfileoutputstream.c:935 -#: gio/glocalfileoutputstream.c:949 gio/glocalfileoutputstream.c:964 -#: gio/glocalfileoutputstream.c:981 gio/glocalfileoutputstream.c:995 +#: gio/glocalfile.c:2462 gio/glocalfileoutputstream.c:1030 +#: gio/glocalfileoutputstream.c:1044 gio/glocalfileoutputstream.c:1059 +#: gio/glocalfileoutputstream.c:1076 gio/glocalfileoutputstream.c:1090 msgid "Backup file creation failed" msgstr "Oprettelse af sikkerhedskopi mislykkedes" -#: gio/glocalfile.c:2431 +#: gio/glocalfile.c:2481 #, c-format msgid "Error removing target file: %s" msgstr "Fejl ved fjernelse af målfil: %s" -#: gio/glocalfile.c:2445 +#: gio/glocalfile.c:2495 msgid "Move between mounts not supported" msgstr "Flytning mellem monteringer understøttes ikke" -#: gio/glocalfile.c:2636 +#: gio/glocalfile.c:2686 #, c-format msgid "Could not determine the disk usage of %s: %s" msgstr "Kunne ikke bestemme diskforbruget af %s: %s" @@ -2964,152 +2991,150 @@ msgid "Error setting extended attribute “%s”: %s" msgstr "Fejl ved indstilling af udvidet attribut “%s”: %s" -#: gio/glocalfileinfo.c:1619 +#: gio/glocalfileinfo.c:1625 msgid " (invalid encoding)" msgstr " (ugyldig kodning)" -#: gio/glocalfileinfo.c:1783 gio/glocalfileoutputstream.c:813 +#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:908 #, c-format msgid "Error when getting information for file “%s”: %s" msgstr "Fejl ved indhentning af oplysninger om filen “%s”: %s" -#: gio/glocalfileinfo.c:2045 +#: gio/glocalfileinfo.c:2059 #, c-format msgid "Error when getting information for file descriptor: %s" msgstr "Fejl ved indhentning af oplysninger om fildeskriptor: %s" -#: gio/glocalfileinfo.c:2090 +#: gio/glocalfileinfo.c:2104 msgid "Invalid attribute type (uint32 expected)" msgstr "Ugyldig attributtype (uint32 forventet)" -#: gio/glocalfileinfo.c:2108 +#: gio/glocalfileinfo.c:2122 msgid "Invalid attribute type (uint64 expected)" msgstr "Ugyldig attributtype (uint64 forventet)" -#: gio/glocalfileinfo.c:2127 gio/glocalfileinfo.c:2146 +#: gio/glocalfileinfo.c:2141 gio/glocalfileinfo.c:2160 msgid "Invalid attribute type (byte string expected)" msgstr "Ugyldig attributtype (byte-streng forventet)" -#: gio/glocalfileinfo.c:2191 +#: gio/glocalfileinfo.c:2207 msgid "Cannot set permissions on symlinks" -msgstr "Kan ikke ændre rettigheder på symlænker" +msgstr "Kan ikke ændre rettigheder på symlinks" -#: gio/glocalfileinfo.c:2207 +#: gio/glocalfileinfo.c:2223 #, c-format msgid "Error setting permissions: %s" msgstr "Fejl ved ændring af rettigheder: %s" -#: gio/glocalfileinfo.c:2258 +#: gio/glocalfileinfo.c:2274 #, c-format msgid "Error setting owner: %s" msgstr "Fejl ved ændring af ejer: %s" -#: gio/glocalfileinfo.c:2281 +#: gio/glocalfileinfo.c:2297 msgid "symlink must be non-NULL" -msgstr "symbolsk henvisning må ikke være NULL" +msgstr "symlink må ikke være NULL" -#: gio/glocalfileinfo.c:2291 gio/glocalfileinfo.c:2310 -#: gio/glocalfileinfo.c:2321 +#: gio/glocalfileinfo.c:2307 gio/glocalfileinfo.c:2326 +#: gio/glocalfileinfo.c:2337 #, c-format msgid "Error setting symlink: %s" -msgstr "Fejl ved manipulation af symbolsk henvisning: %s" +msgstr "Fejl ved manipulation af symlink: %s" -#: gio/glocalfileinfo.c:2300 +#: gio/glocalfileinfo.c:2316 msgid "Error setting symlink: file is not a symlink" -msgstr "" -"Fejl ved manipulation af symbolsk henvisning: filen er ikke en symbolsk " -"henvisning" +msgstr "Fejl ved manipulation af symlink: filen er ikke et symlink" -#: gio/glocalfileinfo.c:2426 +#: gio/glocalfileinfo.c:2442 #, c-format msgid "Error setting modification or access time: %s" msgstr "Fejl ved ændring af tidspunkt for ændring eller tilgang: %s" -#: gio/glocalfileinfo.c:2449 +#: gio/glocalfileinfo.c:2465 msgid "SELinux context must be non-NULL" msgstr "SELinux-kontekst skal være forskellig fra NULL" -#: gio/glocalfileinfo.c:2464 +#: gio/glocalfileinfo.c:2480 #, c-format msgid "Error setting SELinux context: %s" msgstr "Fejl ved ændring af SELinux-kontekst: %s" -#: gio/glocalfileinfo.c:2471 +#: gio/glocalfileinfo.c:2487 msgid "SELinux is not enabled on this system" msgstr "SELinux er ikke aktiveret på dette system" -#: gio/glocalfileinfo.c:2563 +#: gio/glocalfileinfo.c:2579 #, c-format msgid "Setting attribute %s not supported" msgstr "Indstilling af attributten %s understøttes ikke" -#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:696 +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:791 #, c-format msgid "Error reading from file: %s" msgstr "Fejl ved læsning fra filen: %s" #: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 #: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 -#: gio/glocalfileoutputstream.c:458 gio/glocalfileoutputstream.c:1013 +#: gio/glocalfileoutputstream.c:553 gio/glocalfileoutputstream.c:1108 #, c-format msgid "Error seeking in file: %s" msgstr "Fejl under søgning i filen: %s" -#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:248 -#: gio/glocalfileoutputstream.c:342 +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:343 +#: gio/glocalfileoutputstream.c:437 #, c-format msgid "Error closing file: %s" msgstr "Fejl ved lukning af filen: %s" -#: gio/glocalfilemonitor.c:854 +#: gio/glocalfilemonitor.c:856 msgid "Unable to find default local file monitor type" msgstr "Kan ikke finde standardmonitortype for lokal fil" -#: gio/glocalfileoutputstream.c:196 gio/glocalfileoutputstream.c:228 -#: gio/glocalfileoutputstream.c:717 +#: gio/glocalfileoutputstream.c:208 gio/glocalfileoutputstream.c:286 +#: gio/glocalfileoutputstream.c:323 gio/glocalfileoutputstream.c:812 #, c-format msgid "Error writing to file: %s" msgstr "Fejl under skrivning til filen: %s" -#: gio/glocalfileoutputstream.c:275 +#: gio/glocalfileoutputstream.c:370 #, c-format msgid "Error removing old backup link: %s" -msgstr "Fejl under fjernelse af gammel sikkerhedskopi-henvisning: %s" +msgstr "Fejl under fjernelse af gammelt link til sikkerhedskopi: %s" -#: gio/glocalfileoutputstream.c:289 gio/glocalfileoutputstream.c:302 +#: gio/glocalfileoutputstream.c:384 gio/glocalfileoutputstream.c:397 #, c-format msgid "Error creating backup copy: %s" msgstr "Fejl under oprettelse af sikkerhedskopi: %s" -#: gio/glocalfileoutputstream.c:320 +#: gio/glocalfileoutputstream.c:415 #, c-format msgid "Error renaming temporary file: %s" msgstr "Fejl under omdøbning af midlertidig fil: %s" -#: gio/glocalfileoutputstream.c:504 gio/glocalfileoutputstream.c:1064 +#: gio/glocalfileoutputstream.c:599 gio/glocalfileoutputstream.c:1159 #, c-format msgid "Error truncating file: %s" msgstr "Fejl ved beskæring af filen: %s" -#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:795 -#: gio/glocalfileoutputstream.c:1045 gio/gsubprocess.c:380 +#: gio/glocalfileoutputstream.c:652 gio/glocalfileoutputstream.c:890 +#: gio/glocalfileoutputstream.c:1140 gio/gsubprocess.c:380 #, c-format msgid "Error opening file “%s”: %s" msgstr "Fejl ved åbning af filen “%s”: %s" -#: gio/glocalfileoutputstream.c:826 +#: gio/glocalfileoutputstream.c:921 msgid "Target file is a directory" msgstr "Målfilen er en mappe" -#: gio/glocalfileoutputstream.c:831 +#: gio/glocalfileoutputstream.c:926 msgid "Target file is not a regular file" msgstr "Målfilen er ikke en almindelig fil" -#: gio/glocalfileoutputstream.c:843 +#: gio/glocalfileoutputstream.c:938 msgid "The file was externally modified" msgstr "Filen blev modificeret eksternt" -#: gio/glocalfileoutputstream.c:1029 +#: gio/glocalfileoutputstream.c:1124 #, c-format msgid "Error removing old file: %s" msgstr "Fejl under fjernelse af gammel fil: %s" @@ -3201,7 +3226,7 @@ msgid "mount doesn’t implement synchronous content type guessing" msgstr "monteringsobjekt implementerer ikke synkrone gæt på indholdstype" -#: gio/gnetworkaddress.c:378 +#: gio/gnetworkaddress.c:384 #, c-format msgid "Hostname “%s” contains “[” but not “]”" msgstr "Værtsnavnet “%s” indeholder “[”, men ikke “]”" @@ -3214,51 +3239,67 @@ msgid "Host unreachable" msgstr "Vært kan ikke nås" -#: gio/gnetworkmonitornetlink.c:97 gio/gnetworkmonitornetlink.c:109 -#: gio/gnetworkmonitornetlink.c:128 +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 #, c-format msgid "Could not create network monitor: %s" msgstr "Kunne ikke oprette netværksovervågning: %s" -#: gio/gnetworkmonitornetlink.c:118 +#: gio/gnetworkmonitornetlink.c:120 msgid "Could not create network monitor: " msgstr "Kunne ikke oprette netværksovervågning: " -#: gio/gnetworkmonitornetlink.c:176 +#: gio/gnetworkmonitornetlink.c:183 msgid "Could not get network status: " msgstr "Kunne ikke finde netværksstatus: " -#: gio/gnetworkmonitornm.c:322 +#: gio/gnetworkmonitornm.c:313 +#, c-format +msgid "NetworkManager not running" +msgstr "Netværkshåndtering kører ikke" + +#: gio/gnetworkmonitornm.c:324 #, c-format msgid "NetworkManager version too old" msgstr "Versionen af NetværksHåndtering er for gammel" -#: gio/goutputstream.c:212 gio/goutputstream.c:560 +#: gio/goutputstream.c:232 gio/goutputstream.c:775 msgid "Output stream doesn’t implement write" msgstr "Uddatastrøm implementerer ikke write" -#: gio/goutputstream.c:521 gio/goutputstream.c:1224 +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Summen af vektorer givet til %s er for stor" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 msgid "Source stream is already closed" msgstr "Kildestrømmen er allerede lukket" -#: gio/gresolver.c:342 gio/gthreadedresolver.c:116 gio/gthreadedresolver.c:126 +#: gio/gresolver.c:344 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:160 #, c-format msgid "Error resolving “%s”: %s" msgstr "Fejl ved opløsning af “%s”: %s" -#: gio/gresolver.c:729 gio/gresolver.c:781 +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:389 gio/gresolver.c:547 +#, c-format +msgid "%s not implemented" +msgstr "%s er ikke implementeret" + +#: gio/gresolver.c:915 gio/gresolver.c:967 msgid "Invalid domain" msgstr "Ugyldigt domæne" -#: gio/gresource.c:622 gio/gresource.c:881 gio/gresource.c:920 -#: gio/gresource.c:1044 gio/gresource.c:1116 gio/gresource.c:1189 -#: gio/gresource.c:1259 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 #: gio/gresourcefile.c:736 #, c-format msgid "The resource at “%s” does not exist" msgstr "Ressourcen på “%s” findes ikke" -#: gio/gresource.c:787 +#: gio/gresource.c:830 #, c-format msgid "The resource at “%s” failed to decompress" msgstr "Ressourcen på “%s” kunne ikke afkomprimeres" @@ -3272,11 +3313,11 @@ msgid "Input stream doesn’t implement seek" msgstr "Inputstrømmen implementerer ikke søgning" -#: gio/gresource-tool.c:494 +#: gio/gresource-tool.c:501 msgid "List sections containing resources in an elf FILE" msgstr "Vis sektioner, der indeholder ressourcer, i en elf-FIL" -#: gio/gresource-tool.c:500 +#: gio/gresource-tool.c:507 msgid "" "List resources\n" "If SECTION is given, only list resources in this section\n" @@ -3286,15 +3327,15 @@ "Hvis SEKTION er givet, så vis kun ressourcer i denne sektion\n" "Hvis STI er givet, så vis kun matchende ressourcer" -#: gio/gresource-tool.c:503 gio/gresource-tool.c:513 +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 msgid "FILE [PATH]" msgstr "FIL [STI]" -#: gio/gresource-tool.c:504 gio/gresource-tool.c:514 gio/gresource-tool.c:521 +#: gio/gresource-tool.c:511 gio/gresource-tool.c:521 gio/gresource-tool.c:528 msgid "SECTION" msgstr "SEKTION" -#: gio/gresource-tool.c:509 +#: gio/gresource-tool.c:516 msgid "" "List resources with details\n" "If SECTION is given, only list resources in this section\n" @@ -3306,15 +3347,15 @@ "Hvis STI er givet, så vis kun matchende ressourcer\n" "Detaljerne inkluderer sektion, størrelse og komprimering" -#: gio/gresource-tool.c:519 +#: gio/gresource-tool.c:526 msgid "Extract a resource file to stdout" msgstr "Udskriv en ressourcefil til stdout" -#: gio/gresource-tool.c:520 +#: gio/gresource-tool.c:527 msgid "FILE PATH" msgstr "FILSTI" -#: gio/gresource-tool.c:534 +#: gio/gresource-tool.c:541 msgid "" "Usage:\n" " gresource [--section SECTION] COMMAND [ARGS…]\n" @@ -3342,7 +3383,7 @@ "Brug “gresource help KOMMANDO” til at få uddybende hjælp.\n" "\n" -#: gio/gresource-tool.c:548 +#: gio/gresource-tool.c:555 #, c-format msgid "" "Usage:\n" @@ -3357,19 +3398,19 @@ "%s\n" "\n" -#: gio/gresource-tool.c:555 +#: gio/gresource-tool.c:562 msgid " SECTION An (optional) elf section name\n" msgstr " SEKTION Navn på elf-sektion (valgfri)\n" -#: gio/gresource-tool.c:559 gio/gsettings-tool.c:703 +#: gio/gresource-tool.c:566 gio/gsettings-tool.c:703 msgid " COMMAND The (optional) command to explain\n" msgstr " KOMMANDO Den kommandoen der skal forklares (valgfri)\n" -#: gio/gresource-tool.c:565 +#: gio/gresource-tool.c:572 msgid " FILE An elf file (a binary or a shared library)\n" msgstr " FIL En elf-fil (et binært eller delt bibliotek)\n" -#: gio/gresource-tool.c:568 +#: gio/gresource-tool.c:575 msgid "" " FILE An elf file (a binary or a shared library)\n" " or a compiled resource file\n" @@ -3377,19 +3418,19 @@ " FIL En elf-fil (et binært eller delt bibliotek)\n" " eller en kompileret ressourcefil\n" -#: gio/gresource-tool.c:572 +#: gio/gresource-tool.c:579 msgid "[PATH]" msgstr "[STI]" -#: gio/gresource-tool.c:574 +#: gio/gresource-tool.c:581 msgid " PATH An (optional) resource path (may be partial)\n" msgstr " STI En eventuelt delvis ressourcesti (valgfri)\n" -#: gio/gresource-tool.c:575 +#: gio/gresource-tool.c:582 msgid "PATH" msgstr "STI" -#: gio/gresource-tool.c:577 +#: gio/gresource-tool.c:584 msgid " PATH A resource path\n" msgstr " STI En ressourcesti\n" @@ -3620,143 +3661,143 @@ msgid "No such key “%s”\n" msgstr "Ingen sådan nøgle “%s”\n" -#: gio/gsocket.c:384 +#: gio/gsocket.c:373 msgid "Invalid socket, not initialized" msgstr "Ugyldig sokkel, ikke initialiseret" -#: gio/gsocket.c:391 +#: gio/gsocket.c:380 #, c-format msgid "Invalid socket, initialization failed due to: %s" msgstr "Ugyldig sokkel, initialisering mislykkedes på grund af: %s" -#: gio/gsocket.c:399 +#: gio/gsocket.c:388 msgid "Socket is already closed" msgstr "Soklen er allerede lukket" -#: gio/gsocket.c:414 gio/gsocket.c:3034 gio/gsocket.c:4244 gio/gsocket.c:4302 +#: gio/gsocket.c:403 gio/gsocket.c:3027 gio/gsocket.c:4244 gio/gsocket.c:4302 msgid "Socket I/O timed out" msgstr "Tidsudløb for sokkel-I/O" -#: gio/gsocket.c:549 +#: gio/gsocket.c:538 #, c-format msgid "creating GSocket from fd: %s" msgstr "opretter GSocket fra fd: %s" -#: gio/gsocket.c:578 gio/gsocket.c:632 gio/gsocket.c:639 +#: gio/gsocket.c:567 gio/gsocket.c:621 gio/gsocket.c:628 #, c-format msgid "Unable to create socket: %s" msgstr "Kan ikke oprette sokkel: %s" -#: gio/gsocket.c:632 +#: gio/gsocket.c:621 msgid "Unknown family was specified" msgstr "Der blev angivet en ukendt familie" -#: gio/gsocket.c:639 +#: gio/gsocket.c:628 msgid "Unknown protocol was specified" msgstr "Der blev angivet en ukendt protokol" -#: gio/gsocket.c:1130 +#: gio/gsocket.c:1119 #, c-format msgid "Cannot use datagram operations on a non-datagram socket." msgstr "Kan ikke bruge datagramoperationer på en ikke-datagram-sokkel." -#: gio/gsocket.c:1147 +#: gio/gsocket.c:1136 #, c-format msgid "Cannot use datagram operations on a socket with a timeout set." msgstr "Kan ikke bruge datagramoperationer på en sokkel med angivet udløbstid." -#: gio/gsocket.c:1954 +#: gio/gsocket.c:1943 #, c-format msgid "could not get local address: %s" msgstr "kunne ikke finde lokal adresse: %s" -#: gio/gsocket.c:2000 +#: gio/gsocket.c:1989 #, c-format msgid "could not get remote address: %s" msgstr "kunne ikke finde fjern adresse: %s" -#: gio/gsocket.c:2066 +#: gio/gsocket.c:2055 #, c-format msgid "could not listen: %s" msgstr "kunne ikke lytte: %s" -#: gio/gsocket.c:2168 +#: gio/gsocket.c:2157 #, c-format msgid "Error binding to address: %s" msgstr "Fejl ved binding til adresse: %s" -#: gio/gsocket.c:2226 gio/gsocket.c:2263 gio/gsocket.c:2373 gio/gsocket.c:2398 -#: gio/gsocket.c:2471 gio/gsocket.c:2529 gio/gsocket.c:2547 +#: gio/gsocket.c:2215 gio/gsocket.c:2252 gio/gsocket.c:2362 gio/gsocket.c:2387 +#: gio/gsocket.c:2460 gio/gsocket.c:2518 gio/gsocket.c:2536 #, c-format msgid "Error joining multicast group: %s" msgstr "Fejl ved deltagelse i multicastgruppe: %s" -#: gio/gsocket.c:2227 gio/gsocket.c:2264 gio/gsocket.c:2374 gio/gsocket.c:2399 -#: gio/gsocket.c:2472 gio/gsocket.c:2530 gio/gsocket.c:2548 +#: gio/gsocket.c:2216 gio/gsocket.c:2253 gio/gsocket.c:2363 gio/gsocket.c:2388 +#: gio/gsocket.c:2461 gio/gsocket.c:2519 gio/gsocket.c:2537 #, c-format msgid "Error leaving multicast group: %s" msgstr "Fejl ved fratræden fra multicastgruppe: %s" -#: gio/gsocket.c:2228 +#: gio/gsocket.c:2217 msgid "No support for source-specific multicast" msgstr "Ingen understøttelse for kildespecifik multicast" -#: gio/gsocket.c:2375 +#: gio/gsocket.c:2364 msgid "Unsupported socket family" msgstr "Sokkelfamilie understøttes ikke" # ? -#: gio/gsocket.c:2400 +#: gio/gsocket.c:2389 msgid "source-specific not an IPv4 address" msgstr "kildespecifik er ikke en IPv4-adresse" -#: gio/gsocket.c:2418 gio/gsocket.c:2447 gio/gsocket.c:2497 +#: gio/gsocket.c:2407 gio/gsocket.c:2436 gio/gsocket.c:2486 #, c-format msgid "Interface not found: %s" msgstr "Grænseflade ikke fundet: %s" -#: gio/gsocket.c:2434 +#: gio/gsocket.c:2423 #, c-format msgid "Interface name too long" msgstr "Grænsefladenavnet er for langt" -#: gio/gsocket.c:2473 +#: gio/gsocket.c:2462 msgid "No support for IPv4 source-specific multicast" msgstr "Ingen understøttelse for kildespecifik multicast med IPv4" -#: gio/gsocket.c:2531 +#: gio/gsocket.c:2520 msgid "No support for IPv6 source-specific multicast" msgstr "Ingen understøttelse for kildespecifik multicast med IPv6" -#: gio/gsocket.c:2740 +#: gio/gsocket.c:2729 #, c-format msgid "Error accepting connection: %s" msgstr "Fejl ved accept af forbindelse: %s" -#: gio/gsocket.c:2864 +#: gio/gsocket.c:2855 msgid "Connection in progress" msgstr "Forbinder" -#: gio/gsocket.c:2913 +#: gio/gsocket.c:2906 msgid "Unable to get pending error: " msgstr "Kan ikke hente verserende fejl: " -#: gio/gsocket.c:3097 +#: gio/gsocket.c:3092 #, c-format msgid "Error receiving data: %s" msgstr "Fejl ved modtagelse af data: %s" -#: gio/gsocket.c:3292 +#: gio/gsocket.c:3289 #, c-format msgid "Error sending data: %s" msgstr "Fejl ved afsendelse af data: %s" -#: gio/gsocket.c:3479 +#: gio/gsocket.c:3476 #, c-format msgid "Unable to shutdown socket: %s" msgstr "Kan ikke nedlukke sokkel: %s" -#: gio/gsocket.c:3560 +#: gio/gsocket.c:3557 #, c-format msgid "Error closing socket: %s" msgstr "Fejl ved lukning af sokkel: %s" @@ -3766,52 +3807,53 @@ msgid "Waiting for socket condition: %s" msgstr "Venter på sokkelbetingelse: %s" -#: gio/gsocket.c:4711 gio/gsocket.c:4791 gio/gsocket.c:4969 +#: gio/gsocket.c:4612 gio/gsocket.c:4756 gio/gsocket.c:4841 gio/gsocket.c:5021 +#: gio/gsocket.c:5059 #, c-format msgid "Error sending message: %s" msgstr "Fejl ved afsendelse af meddelelse: %s" -#: gio/gsocket.c:4735 +#: gio/gsocket.c:4783 msgid "GSocketControlMessage not supported on Windows" msgstr "GSocketControlMessage understøttes ikke af Windows" -#: gio/gsocket.c:5188 gio/gsocket.c:5261 gio/gsocket.c:5487 +#: gio/gsocket.c:5248 gio/gsocket.c:5321 gio/gsocket.c:5548 #, c-format msgid "Error receiving message: %s" msgstr "Fejl ved modtagelse af meddelelse: %s" -#: gio/gsocket.c:5759 +#: gio/gsocket.c:5820 #, c-format msgid "Unable to read socket credentials: %s" msgstr "Kan ikke læse sokkelakkreditiver: %s" -#: gio/gsocket.c:5768 +#: gio/gsocket.c:5829 msgid "g_socket_get_credentials not implemented for this OS" msgstr "g_socket_get_credentials ikke implementeret på dette operativsystem" -#: gio/gsocketclient.c:176 +#: gio/gsocketclient.c:181 #, c-format msgid "Could not connect to proxy server %s: " msgstr "Kunne ikke forbinde til proxyserver %s: " -#: gio/gsocketclient.c:190 +#: gio/gsocketclient.c:195 #, c-format msgid "Could not connect to %s: " msgstr "Kunne ikke forbinde til %s: " -#: gio/gsocketclient.c:192 +#: gio/gsocketclient.c:197 msgid "Could not connect: " msgstr "Kunne ikke forbinde: " -#: gio/gsocketclient.c:1027 gio/gsocketclient.c:1599 +#: gio/gsocketclient.c:1032 gio/gsocketclient.c:1714 msgid "Unknown error on connect" msgstr "Ukendt forbindelsesfejl" -#: gio/gsocketclient.c:1081 gio/gsocketclient.c:1535 +#: gio/gsocketclient.c:1086 gio/gsocketclient.c:1626 msgid "Proxying over a non-TCP connection is not supported." msgstr "Brug af proxy over ikke-TCP-forbindelse understøttes ikke." -#: gio/gsocketclient.c:1110 gio/gsocketclient.c:1561 +#: gio/gsocketclient.c:1115 gio/gsocketclient.c:1652 #, c-format msgid "Proxy protocol “%s” is not supported." msgstr "Proxyprotokollen “%s” understøttes ikke." @@ -3911,54 +3953,54 @@ msgid "Unknown SOCKSv5 proxy error." msgstr "Ukendt SOCKSv5-proxyfejl." -#: gio/gthemedicon.c:518 +#: gio/gthemedicon.c:595 #, c-format msgid "Can’t handle version %d of GThemedIcon encoding" msgstr "Kan ikke håndtere version %d af GThemedIcon-kodningen" -#: gio/gthreadedresolver.c:118 +#: gio/gthreadedresolver.c:152 msgid "No valid addresses were found" msgstr "Der blev ikke fundet nogen gyldige adresser" -#: gio/gthreadedresolver.c:213 +#: gio/gthreadedresolver.c:317 #, c-format msgid "Error reverse-resolving “%s”: %s" msgstr "Fejl ved baglæns opløsning af “%s”: %s" -#: gio/gthreadedresolver.c:549 gio/gthreadedresolver.c:628 -#: gio/gthreadedresolver.c:726 gio/gthreadedresolver.c:776 +#: gio/gthreadedresolver.c:653 gio/gthreadedresolver.c:732 +#: gio/gthreadedresolver.c:830 gio/gthreadedresolver.c:880 #, c-format msgid "No DNS record of the requested type for “%s”" msgstr "Ingen DNS-post af den forespurgte type for “%s”" -#: gio/gthreadedresolver.c:554 gio/gthreadedresolver.c:731 +#: gio/gthreadedresolver.c:658 gio/gthreadedresolver.c:835 #, c-format msgid "Temporarily unable to resolve “%s”" msgstr "Midlertidigt ude af stand til at opløse “%s”" -#: gio/gthreadedresolver.c:559 gio/gthreadedresolver.c:736 -#: gio/gthreadedresolver.c:844 +#: gio/gthreadedresolver.c:663 gio/gthreadedresolver.c:840 +#: gio/gthreadedresolver.c:948 #, c-format msgid "Error resolving “%s”" msgstr "Fejl ved opløsning af “%s”" -#: gio/gtlscertificate.c:250 -msgid "Cannot decrypt PEM-encoded private key" -msgstr "Kan ikke dekryptere PEM-kodet privat nøgle" - -#: gio/gtlscertificate.c:255 +#: gio/gtlscertificate.c:243 msgid "No PEM-encoded private key found" msgstr "Intet privat, PEM-kodet nøgle fundet" -#: gio/gtlscertificate.c:265 +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Kan ikke dekryptere PEM-kodet privat nøgle" + +#: gio/gtlscertificate.c:264 msgid "Could not parse PEM-encoded private key" msgstr "Kunne ikke fortolke PEM-kodet privat nøgle" -#: gio/gtlscertificate.c:290 +#: gio/gtlscertificate.c:291 msgid "No PEM-encoded certificate found" msgstr "Intet PEM-kodet certifikat fundet" -#: gio/gtlscertificate.c:299 +#: gio/gtlscertificate.c:300 msgid "Could not parse PEM-encoded certificate" msgstr "Kunne ikke fortolke PEM-kodet certifikat" @@ -4042,17 +4084,19 @@ msgid "Error reading from file descriptor: %s" msgstr "Fejl ved læsning fra fildeskriptor: %s" -#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:411 +#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:534 #: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 #, c-format msgid "Error closing file descriptor: %s" msgstr "Fejl ved lukning af fildeskriptor: %s" -#: gio/gunixmounts.c:2589 gio/gunixmounts.c:2642 +#: gio/gunixmounts.c:2650 gio/gunixmounts.c:2703 msgid "Filesystem root" msgstr "Filsystemets rod" -#: gio/gunixoutputstream.c:358 gio/gunixoutputstream.c:378 +#: gio/gunixoutputstream.c:371 gio/gunixoutputstream.c:391 +#: gio/gunixoutputstream.c:478 gio/gunixoutputstream.c:498 +#: gio/gunixoutputstream.c:675 #, c-format msgid "Error writing to file descriptor: %s" msgstr "Fejl under skrivning til fildeskriptor: %s" @@ -4136,143 +4180,143 @@ msgstr "Uventet attribut “%s” for elementet “%s”" #: glib/gbookmarkfile.c:765 glib/gbookmarkfile.c:836 glib/gbookmarkfile.c:846 -#: glib/gbookmarkfile.c:953 +#: glib/gbookmarkfile.c:955 #, c-format msgid "Attribute “%s” of element “%s” not found" msgstr "Attributten “%s” for elementet “%s” blev ikke fundet" -#: glib/gbookmarkfile.c:1123 glib/gbookmarkfile.c:1188 -#: glib/gbookmarkfile.c:1252 glib/gbookmarkfile.c:1262 +#: glib/gbookmarkfile.c:1164 glib/gbookmarkfile.c:1229 +#: glib/gbookmarkfile.c:1293 glib/gbookmarkfile.c:1303 #, c-format msgid "Unexpected tag “%s”, tag “%s” expected" msgstr "Uventet mærke “%s”, forventede mærket “%s”" -#: glib/gbookmarkfile.c:1148 glib/gbookmarkfile.c:1162 -#: glib/gbookmarkfile.c:1230 +#: glib/gbookmarkfile.c:1189 glib/gbookmarkfile.c:1203 +#: glib/gbookmarkfile.c:1271 glib/gbookmarkfile.c:1317 #, c-format msgid "Unexpected tag “%s” inside “%s”" msgstr "Uventet mærke “%s” inden i “%s”" -#: glib/gbookmarkfile.c:1757 +#: glib/gbookmarkfile.c:1813 msgid "No valid bookmark file found in data dirs" msgstr "Ingen gyldig bogmærkefil blev fundet i datakatalogerne" -#: glib/gbookmarkfile.c:1958 +#: glib/gbookmarkfile.c:2014 #, c-format msgid "A bookmark for URI “%s” already exists" msgstr "Et bogmærke for URI'en “%s” findes allerede" -#: glib/gbookmarkfile.c:2004 glib/gbookmarkfile.c:2162 -#: glib/gbookmarkfile.c:2247 glib/gbookmarkfile.c:2327 -#: glib/gbookmarkfile.c:2412 glib/gbookmarkfile.c:2495 -#: glib/gbookmarkfile.c:2573 glib/gbookmarkfile.c:2652 -#: glib/gbookmarkfile.c:2694 glib/gbookmarkfile.c:2791 -#: glib/gbookmarkfile.c:2912 glib/gbookmarkfile.c:3102 -#: glib/gbookmarkfile.c:3178 glib/gbookmarkfile.c:3346 -#: glib/gbookmarkfile.c:3435 glib/gbookmarkfile.c:3524 -#: glib/gbookmarkfile.c:3640 +#: glib/gbookmarkfile.c:2060 glib/gbookmarkfile.c:2218 +#: glib/gbookmarkfile.c:2303 glib/gbookmarkfile.c:2383 +#: glib/gbookmarkfile.c:2468 glib/gbookmarkfile.c:2551 +#: glib/gbookmarkfile.c:2629 glib/gbookmarkfile.c:2708 +#: glib/gbookmarkfile.c:2750 glib/gbookmarkfile.c:2847 +#: glib/gbookmarkfile.c:2968 glib/gbookmarkfile.c:3158 +#: glib/gbookmarkfile.c:3234 glib/gbookmarkfile.c:3402 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3580 +#: glib/gbookmarkfile.c:3699 #, c-format msgid "No bookmark found for URI “%s”" msgstr "Der blev intet bogmærke fundet for URI'en “%s”" -#: glib/gbookmarkfile.c:2336 +#: glib/gbookmarkfile.c:2392 #, c-format msgid "No MIME type defined in the bookmark for URI “%s”" msgstr "Ingen MIME-type er defineret i bogmærket for URI'en “%s”" -#: glib/gbookmarkfile.c:2421 +#: glib/gbookmarkfile.c:2477 #, c-format msgid "No private flag has been defined in bookmark for URI “%s”" msgstr "Intet privat flag er defineret i bogmærket for URI'en “%s”" -#: glib/gbookmarkfile.c:2800 +#: glib/gbookmarkfile.c:2856 #, c-format msgid "No groups set in bookmark for URI “%s”" msgstr "Ingen grupper er sat i bogmærket for URI'en “%s”" -#: glib/gbookmarkfile.c:3199 glib/gbookmarkfile.c:3356 +#: glib/gbookmarkfile.c:3255 glib/gbookmarkfile.c:3412 #, c-format msgid "No application with name “%s” registered a bookmark for “%s”" msgstr "Intet program med navnet “%s” har registreret et bogmærke for “%s”" -#: glib/gbookmarkfile.c:3379 +#: glib/gbookmarkfile.c:3435 #, c-format msgid "Failed to expand exec line “%s” with URI “%s”" msgstr "Kunne ikke udvide eksekveringslinjen “%s” med URI'en “%s”" -#: glib/gconvert.c:473 +#: glib/gconvert.c:474 msgid "Unrepresentable character in conversion input" msgstr "Konverteringsinddata indeholder et tegn, som ikke kan repræsenteres" -#: glib/gconvert.c:500 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 +#: glib/gconvert.c:501 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 #: glib/gutf8.c:1318 msgid "Partial character sequence at end of input" msgstr "Delvis tegnsekvens ved slutningen af inddata" -#: glib/gconvert.c:769 +#: glib/gconvert.c:770 #, c-format msgid "Cannot convert fallback “%s” to codeset “%s”" msgstr "Kan ikke konvertere tilbagefaldet “%s” til tegnsæt “%s”" -#: glib/gconvert.c:940 +#: glib/gconvert.c:942 msgid "Embedded NUL byte in conversion input" msgstr "Indlejret NUL-byte i konverteringsinddata" -#: glib/gconvert.c:961 +#: glib/gconvert.c:963 msgid "Embedded NUL byte in conversion output" msgstr "Indlejret NUL-byte i konverteringsuddata" -#: glib/gconvert.c:1649 +#: glib/gconvert.c:1648 #, c-format msgid "The URI “%s” is not an absolute URI using the “file” scheme" msgstr "URI'en “%s” er ikke en absolut URI, ved brug af “fil”-metoden" -#: glib/gconvert.c:1659 +#: glib/gconvert.c:1658 #, c-format msgid "The local file URI “%s” may not include a “#”" msgstr "Den lokale fil-URI “%s” må ikke indeholde en “#”" -#: glib/gconvert.c:1676 +#: glib/gconvert.c:1675 #, c-format msgid "The URI “%s” is invalid" msgstr "URI'en “%s” er ugyldig" -#: glib/gconvert.c:1688 +#: glib/gconvert.c:1687 #, c-format msgid "The hostname of the URI “%s” is invalid" msgstr "Værtsnavnet for URI'en “%s” er ugyldig" -#: glib/gconvert.c:1704 +#: glib/gconvert.c:1703 #, c-format msgid "The URI “%s” contains invalidly escaped characters" msgstr "URI'en “%s” indeholder ugyldigt beskyttede tegn" -#: glib/gconvert.c:1776 +#: glib/gconvert.c:1775 #, c-format msgid "The pathname “%s” is not an absolute path" msgstr "Stinavnet “%s” er ikke en absolut sti" #. Translators: this is the preferred format for expressing the date and the time -#: glib/gdatetime.c:213 +#: glib/gdatetime.c:214 msgctxt "GDateTime" msgid "%a %b %e %H:%M:%S %Y" msgstr "%a %d %b %Y %T %Z" #. Translators: this is the preferred format for expressing the date -#: glib/gdatetime.c:216 +#: glib/gdatetime.c:217 msgctxt "GDateTime" msgid "%m/%d/%y" msgstr "%d/%m-%y" #. Translators: this is the preferred format for expressing the time -#: glib/gdatetime.c:219 +#: glib/gdatetime.c:220 msgctxt "GDateTime" msgid "%H:%M:%S" msgstr "%H:%M:%S" # Læg mærke til programmørkommentaren. Selvom vi ikke bruger AM/PM %p må det jo stadig være den foretrukne måde at udtrykke 12-timers tid. #. Translators: this is the preferred format for expressing 12 hour time -#: glib/gdatetime.c:222 +#: glib/gdatetime.c:223 msgctxt "GDateTime" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" @@ -4293,62 +4337,62 @@ #. * non-European) there is no difference between the standalone and #. * complete date form. #. -#: glib/gdatetime.c:261 +#: glib/gdatetime.c:262 msgctxt "full month name" msgid "January" msgstr "januar" -#: glib/gdatetime.c:263 +#: glib/gdatetime.c:264 msgctxt "full month name" msgid "February" msgstr "februar" -#: glib/gdatetime.c:265 +#: glib/gdatetime.c:266 msgctxt "full month name" msgid "March" msgstr "marts" -#: glib/gdatetime.c:267 +#: glib/gdatetime.c:268 msgctxt "full month name" msgid "April" msgstr "april" -#: glib/gdatetime.c:269 +#: glib/gdatetime.c:270 msgctxt "full month name" msgid "May" msgstr "maj" -#: glib/gdatetime.c:271 +#: glib/gdatetime.c:272 msgctxt "full month name" msgid "June" msgstr "juni" -#: glib/gdatetime.c:273 +#: glib/gdatetime.c:274 msgctxt "full month name" msgid "July" msgstr "juli" -#: glib/gdatetime.c:275 +#: glib/gdatetime.c:276 msgctxt "full month name" msgid "August" msgstr "august" -#: glib/gdatetime.c:277 +#: glib/gdatetime.c:278 msgctxt "full month name" msgid "September" msgstr "september" -#: glib/gdatetime.c:279 +#: glib/gdatetime.c:280 msgctxt "full month name" msgid "October" msgstr "oktober" -#: glib/gdatetime.c:281 +#: glib/gdatetime.c:282 msgctxt "full month name" msgid "November" msgstr "november" -#: glib/gdatetime.c:283 +#: glib/gdatetime.c:284 msgctxt "full month name" msgid "December" msgstr "december" @@ -4370,132 +4414,132 @@ #. * other platform. Here are abbreviated month names in a form #. * appropriate when they are used standalone. #. -#: glib/gdatetime.c:315 +#: glib/gdatetime.c:316 msgctxt "abbreviated month name" msgid "Jan" msgstr "jan" -#: glib/gdatetime.c:317 +#: glib/gdatetime.c:318 msgctxt "abbreviated month name" msgid "Feb" msgstr "feb" -#: glib/gdatetime.c:319 +#: glib/gdatetime.c:320 msgctxt "abbreviated month name" msgid "Mar" msgstr "mar" -#: glib/gdatetime.c:321 +#: glib/gdatetime.c:322 msgctxt "abbreviated month name" msgid "Apr" msgstr "apr" -#: glib/gdatetime.c:323 +#: glib/gdatetime.c:324 msgctxt "abbreviated month name" msgid "May" msgstr "maj" -#: glib/gdatetime.c:325 +#: glib/gdatetime.c:326 msgctxt "abbreviated month name" msgid "Jun" msgstr "jun" -#: glib/gdatetime.c:327 +#: glib/gdatetime.c:328 msgctxt "abbreviated month name" msgid "Jul" msgstr "jul" -#: glib/gdatetime.c:329 +#: glib/gdatetime.c:330 msgctxt "abbreviated month name" msgid "Aug" msgstr "aug" -#: glib/gdatetime.c:331 +#: glib/gdatetime.c:332 msgctxt "abbreviated month name" msgid "Sep" msgstr "sep" -#: glib/gdatetime.c:333 +#: glib/gdatetime.c:334 msgctxt "abbreviated month name" msgid "Oct" msgstr "okt" -#: glib/gdatetime.c:335 +#: glib/gdatetime.c:336 msgctxt "abbreviated month name" msgid "Nov" msgstr "nov" -#: glib/gdatetime.c:337 +#: glib/gdatetime.c:338 msgctxt "abbreviated month name" msgid "Dec" msgstr "dec" -#: glib/gdatetime.c:352 +#: glib/gdatetime.c:353 msgctxt "full weekday name" msgid "Monday" msgstr "mandag" -#: glib/gdatetime.c:354 +#: glib/gdatetime.c:355 msgctxt "full weekday name" msgid "Tuesday" msgstr "tirsdag" -#: glib/gdatetime.c:356 +#: glib/gdatetime.c:357 msgctxt "full weekday name" msgid "Wednesday" msgstr "onsdag" -#: glib/gdatetime.c:358 +#: glib/gdatetime.c:359 msgctxt "full weekday name" msgid "Thursday" msgstr "torsdag" -#: glib/gdatetime.c:360 +#: glib/gdatetime.c:361 msgctxt "full weekday name" msgid "Friday" msgstr "fredag" -#: glib/gdatetime.c:362 +#: glib/gdatetime.c:363 msgctxt "full weekday name" msgid "Saturday" msgstr "lørdag" -#: glib/gdatetime.c:364 +#: glib/gdatetime.c:365 msgctxt "full weekday name" msgid "Sunday" msgstr "søndag" -#: glib/gdatetime.c:379 +#: glib/gdatetime.c:380 msgctxt "abbreviated weekday name" msgid "Mon" msgstr "man" -#: glib/gdatetime.c:381 +#: glib/gdatetime.c:382 msgctxt "abbreviated weekday name" msgid "Tue" msgstr "tir" -#: glib/gdatetime.c:383 +#: glib/gdatetime.c:384 msgctxt "abbreviated weekday name" msgid "Wed" msgstr "ons" -#: glib/gdatetime.c:385 +#: glib/gdatetime.c:386 msgctxt "abbreviated weekday name" msgid "Thu" msgstr "tor" -#: glib/gdatetime.c:387 +#: glib/gdatetime.c:388 msgctxt "abbreviated weekday name" msgid "Fri" msgstr "fre" -#: glib/gdatetime.c:389 +#: glib/gdatetime.c:390 msgctxt "abbreviated weekday name" msgid "Sat" msgstr "lør" -#: glib/gdatetime.c:391 +#: glib/gdatetime.c:392 msgctxt "abbreviated weekday name" msgid "Sun" msgstr "søn" @@ -4517,62 +4561,62 @@ #. * (western European, non-European) there is no difference between the #. * standalone and complete date form. #. -#: glib/gdatetime.c:455 +#: glib/gdatetime.c:456 msgctxt "full month name with day" msgid "January" msgstr "januar" -#: glib/gdatetime.c:457 +#: glib/gdatetime.c:458 msgctxt "full month name with day" msgid "February" msgstr "februar" -#: glib/gdatetime.c:459 +#: glib/gdatetime.c:460 msgctxt "full month name with day" msgid "March" msgstr "marts" -#: glib/gdatetime.c:461 +#: glib/gdatetime.c:462 msgctxt "full month name with day" msgid "April" msgstr "april" -#: glib/gdatetime.c:463 +#: glib/gdatetime.c:464 msgctxt "full month name with day" msgid "May" msgstr "maj" -#: glib/gdatetime.c:465 +#: glib/gdatetime.c:466 msgctxt "full month name with day" msgid "June" msgstr "juni" -#: glib/gdatetime.c:467 +#: glib/gdatetime.c:468 msgctxt "full month name with day" msgid "July" msgstr "juli" -#: glib/gdatetime.c:469 +#: glib/gdatetime.c:470 msgctxt "full month name with day" msgid "August" msgstr "august" -#: glib/gdatetime.c:471 +#: glib/gdatetime.c:472 msgctxt "full month name with day" msgid "September" msgstr "september" -#: glib/gdatetime.c:473 +#: glib/gdatetime.c:474 msgctxt "full month name with day" msgid "October" msgstr "oktober" -#: glib/gdatetime.c:475 +#: glib/gdatetime.c:476 msgctxt "full month name with day" msgid "November" msgstr "november" -#: glib/gdatetime.c:477 +#: glib/gdatetime.c:478 msgctxt "full month name with day" msgid "December" msgstr "december" @@ -4594,79 +4638,79 @@ #. * month names almost ready to copy and paste here. In other systems #. * due to a bug the result is incorrect in some languages. #. -#: glib/gdatetime.c:542 +#: glib/gdatetime.c:543 msgctxt "abbreviated month name with day" msgid "Jan" msgstr "jan" -#: glib/gdatetime.c:544 +#: glib/gdatetime.c:545 msgctxt "abbreviated month name with day" msgid "Feb" msgstr "feb" -#: glib/gdatetime.c:546 +#: glib/gdatetime.c:547 msgctxt "abbreviated month name with day" msgid "Mar" msgstr "mar" -#: glib/gdatetime.c:548 +#: glib/gdatetime.c:549 msgctxt "abbreviated month name with day" msgid "Apr" msgstr "apr" -#: glib/gdatetime.c:550 +#: glib/gdatetime.c:551 msgctxt "abbreviated month name with day" msgid "May" msgstr "maj" -#: glib/gdatetime.c:552 +#: glib/gdatetime.c:553 msgctxt "abbreviated month name with day" msgid "Jun" msgstr "jun" -#: glib/gdatetime.c:554 +#: glib/gdatetime.c:555 msgctxt "abbreviated month name with day" msgid "Jul" msgstr "jul" -#: glib/gdatetime.c:556 +#: glib/gdatetime.c:557 msgctxt "abbreviated month name with day" msgid "Aug" msgstr "aug" -#: glib/gdatetime.c:558 +#: glib/gdatetime.c:559 msgctxt "abbreviated month name with day" msgid "Sep" msgstr "sep" -#: glib/gdatetime.c:560 +#: glib/gdatetime.c:561 msgctxt "abbreviated month name with day" msgid "Oct" msgstr "okt" -#: glib/gdatetime.c:562 +#: glib/gdatetime.c:563 msgctxt "abbreviated month name with day" msgid "Nov" msgstr "nov" -#: glib/gdatetime.c:564 +#: glib/gdatetime.c:565 msgctxt "abbreviated month name with day" msgid "Dec" msgstr "dec" #. Translators: 'before midday' indicator -#: glib/gdatetime.c:581 +#: glib/gdatetime.c:582 msgctxt "GDateTime" msgid "AM" msgstr "AM" #. Translators: 'after midday' indicator -#: glib/gdatetime.c:584 +#: glib/gdatetime.c:585 msgctxt "GDateTime" msgid "PM" msgstr "PM" -#: glib/gdir.c:155 +#: glib/gdir.c:154 #, c-format msgid "Error opening directory “%s”: %s" msgstr "Fejl ved åbning af mappen “%s”: %s" @@ -4747,7 +4791,7 @@ #: glib/gfileutils.c:2116 #, c-format msgid "Failed to read the symbolic link “%s”: %s" -msgstr "Kunne ikke læse den symbolske henvisning “%s”: %s" +msgstr "Kunne ikke læse den symbolske link “%s”: %s" #: glib/giochannel.c:1389 #, c-format @@ -4770,15 +4814,15 @@ msgid "Can’t do a raw read in g_io_channel_read_to_end" msgstr "Kan ikke foretage en rå læsning i g_io_channel_read_to_end" -#: glib/gkeyfile.c:788 +#: glib/gkeyfile.c:789 msgid "Valid key file could not be found in search dirs" msgstr "Gyldig nøglefil blev ikke fundet i søgekatalogerne" -#: glib/gkeyfile.c:825 +#: glib/gkeyfile.c:826 msgid "Not a regular file" msgstr "Ikke en almindelig fil" -#: glib/gkeyfile.c:1270 +#: glib/gkeyfile.c:1275 #, c-format msgid "" "Key file contains line “%s” which is not a key-value pair, group, or comment" @@ -4786,50 +4830,50 @@ "Nøglefilen indeholder linjen “%s” hvilken ikke er et nøgle-værdi-par, en " "gruppe eller en kommentar" -#: glib/gkeyfile.c:1327 +#: glib/gkeyfile.c:1332 #, c-format msgid "Invalid group name: %s" msgstr "Ugyldigt gruppenavn: %s" -#: glib/gkeyfile.c:1349 +#: glib/gkeyfile.c:1354 msgid "Key file does not start with a group" msgstr "Nøglefilen starter ikke med en gruppe" -#: glib/gkeyfile.c:1375 +#: glib/gkeyfile.c:1380 #, c-format msgid "Invalid key name: %s" msgstr "Ugyldigt nøglenavn: %s" -#: glib/gkeyfile.c:1402 +#: glib/gkeyfile.c:1407 #, c-format msgid "Key file contains unsupported encoding “%s”" msgstr "Nøglefilen indeholder kodningen “%s”, der ikke understøttes" -#: glib/gkeyfile.c:1645 glib/gkeyfile.c:1818 glib/gkeyfile.c:3271 -#: glib/gkeyfile.c:3334 glib/gkeyfile.c:3464 glib/gkeyfile.c:3594 -#: glib/gkeyfile.c:3738 glib/gkeyfile.c:3967 glib/gkeyfile.c:4034 +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3339 glib/gkeyfile.c:3469 glib/gkeyfile.c:3601 +#: glib/gkeyfile.c:3747 glib/gkeyfile.c:3976 glib/gkeyfile.c:4043 #, c-format msgid "Key file does not have group “%s”" msgstr "Nøglefilen indeholder ikke gruppen “%s”" -#: glib/gkeyfile.c:1773 +#: glib/gkeyfile.c:1778 #, c-format msgid "Key file does not have key “%s” in group “%s”" msgstr "Nøglefilen har ikke nøglen “%s” i gruppen “%s”" -#: glib/gkeyfile.c:1935 glib/gkeyfile.c:2051 +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 #, c-format msgid "Key file contains key “%s” with value “%s” which is not UTF-8" msgstr "Nøglefilen indeholder nøglen “%s” med værdien “%s” der ikke er UTF-8" -#: glib/gkeyfile.c:1955 glib/gkeyfile.c:2071 glib/gkeyfile.c:2513 +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 #, c-format msgid "" "Key file contains key “%s” which has a value that cannot be interpreted." msgstr "" "Nøglefilen indeholder nøglen “%s”, som har en værdi, der ikke kan fortolkes." -#: glib/gkeyfile.c:2731 glib/gkeyfile.c:3100 +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 #, c-format msgid "" "Key file contains key “%s” in group “%s” which has a value that cannot be " @@ -4838,36 +4882,36 @@ "Nøglefilen indeholder nøglen “%s” i gruppen “%s”, som har en værdi der ikke " "kan fortolkes." -#: glib/gkeyfile.c:2809 glib/gkeyfile.c:2886 +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 #, c-format msgid "Key “%s” in group “%s” has value “%s” where %s was expected" msgstr "Nøglen “%s” i gruppen “%s” har værdien “%s”, mens %s blev forventet" -#: glib/gkeyfile.c:4274 +#: glib/gkeyfile.c:4283 msgid "Key file contains escape character at end of line" msgstr "Nøglefilen indeholder beskyttede tegn for enden af linjen" -#: glib/gkeyfile.c:4296 +#: glib/gkeyfile.c:4305 #, c-format msgid "Key file contains invalid escape sequence “%s”" msgstr "Nøglefilen indeholder en ugyldig undvigesekvens “%s”" -#: glib/gkeyfile.c:4440 +#: glib/gkeyfile.c:4449 #, c-format msgid "Value “%s” cannot be interpreted as a number." msgstr "Værdien “%s” kan ikke fortolkes som et nummer." -#: glib/gkeyfile.c:4454 +#: glib/gkeyfile.c:4463 #, c-format msgid "Integer value “%s” out of range" msgstr "Heltalsværdien “%s” er ikke i gyldigt interval" -#: glib/gkeyfile.c:4487 +#: glib/gkeyfile.c:4496 #, c-format msgid "Value “%s” cannot be interpreted as a float number." msgstr "Værdien “%s” kan ikke fortolkes som en float." -#: glib/gkeyfile.c:4526 +#: glib/gkeyfile.c:4535 #, c-format msgid "Value “%s” cannot be interpreted as a boolean." msgstr "Værdien “%s” kan ikke fortolkes som en sandhedsværdi." @@ -4888,72 +4932,80 @@ msgid "Failed to open file “%s”: open() failed: %s" msgstr "Kunne ikke åbne filen “%s”: open() mislykkedes: %s" -#: glib/gmarkup.c:397 glib/gmarkup.c:439 +#: glib/gmarkup.c:398 glib/gmarkup.c:440 #, c-format msgid "Error on line %d char %d: " msgstr "Fejl på linje %d tegn %d: " -#: glib/gmarkup.c:461 glib/gmarkup.c:544 +#: glib/gmarkup.c:462 glib/gmarkup.c:545 #, c-format msgid "Invalid UTF-8 encoded text in name — not valid “%s”" msgstr "Ugyldig UTF-8-kodet tekst i navnet — ugyldig “%s”" -#: glib/gmarkup.c:472 +#: glib/gmarkup.c:473 #, c-format msgid "“%s” is not a valid name" msgstr "“%s” er ikke et gyldigt navn" -#: glib/gmarkup.c:488 +#: glib/gmarkup.c:489 #, c-format msgid "“%s” is not a valid name: “%c”" msgstr "“%s” er ikke et gyldigt navn: “%c”" -#: glib/gmarkup.c:610 +#: glib/gmarkup.c:613 #, c-format msgid "Error on line %d: %s" msgstr "Fejl på linje %d: %s" -#: glib/gmarkup.c:687 +#: glib/gmarkup.c:690 #, c-format msgid "" "Failed to parse “%-.*s”, which should have been a digit inside a character " "reference (ê for example) — perhaps the digit is too large" -msgstr "Fejl ved fortolkning af “%-.*s” som skulle have været et ciffer i en tegnreference (ê for eksempel) — måske er cifret for stort" +msgstr "" +"Fejl ved fortolkning af “%-.*s” som skulle have været et ciffer i en " +"tegnreference (ê for eksempel) — måske er cifret for stort" -#: glib/gmarkup.c:699 +#: glib/gmarkup.c:702 msgid "" "Character reference did not end with a semicolon; most likely you used an " "ampersand character without intending to start an entity — escape ampersand " "as &" -msgstr "Tegnreferencen sluttede ikke med et semikolon; du har sandsynligvis brugt et og-tegn uden at det var beregnet på at starte en entitet — undgå dette ved at bruge & i stedet" +msgstr "" +"Tegnreferencen sluttede ikke med et semikolon; du har sandsynligvis brugt et " +"og-tegn uden at det var beregnet på at starte en entitet — undgå dette ved " +"at bruge & i stedet" -#: glib/gmarkup.c:725 +#: glib/gmarkup.c:728 #, c-format msgid "Character reference “%-.*s” does not encode a permitted character" msgstr "Tegnreferencen “%-.*s” koder ikke et tilladt tegn" -#: glib/gmarkup.c:763 +#: glib/gmarkup.c:766 msgid "" "Empty entity “&;” seen; valid entities are: & " < > '" msgstr "" "Tom entitet “&;” fundet; gyldige entiteter er: & " < > '" -#: glib/gmarkup.c:771 +#: glib/gmarkup.c:774 #, c-format msgid "Entity name “%-.*s” is not known" msgstr "Entitetsnavnet “%-.*s” er ukendt" -#: glib/gmarkup.c:776 +#: glib/gmarkup.c:779 msgid "" "Entity did not end with a semicolon; most likely you used an ampersand " "character without intending to start an entity — escape ampersand as &" -msgstr "Entiteten sluttede ikke med et semikolon; du har sandsynligvis brugt et og-tegn uden at det var beregnet på at starte en entitet — dette undgås ved at bruge & i stedet" +msgstr "" +"Entiteten sluttede ikke med et semikolon; du har sandsynligvis brugt et og-" +"tegn uden at det var beregnet på at starte en entitet — dette undgås ved at " +"bruge & i stedet" -#: glib/gmarkup.c:1182 +#: glib/gmarkup.c:1187 msgid "Document must begin with an element (e.g. )" msgstr "Dokumentet skal begynde med et element (f.eks )" -#: glib/gmarkup.c:1222 +#: glib/gmarkup.c:1227 #, c-format msgid "" "“%s” is not a valid character following a “<” character; it may not begin an " @@ -4962,7 +5014,7 @@ "“%s” er ikke et gyldigt tegn efter et “<”-tegn; det kan ikke være " "begyndelsen på et elementnavn" -#: glib/gmarkup.c:1264 +#: glib/gmarkup.c:1270 #, c-format msgid "" "Odd character “%s”, expected a “>” character to end the empty-element tag " @@ -4971,7 +5023,7 @@ "Mærkeligt tegn “%s”, forventede et “>”-tegn for at afslutte det tomme " "elementmærke “%s”" -#: glib/gmarkup.c:1345 +#: glib/gmarkup.c:1352 #, c-format msgid "" "Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”" @@ -4979,7 +5031,7 @@ "Mærkeligt tegn “%s”, forventede et “=” efter attributnavn “%s” for elementet " "“%s”" -#: glib/gmarkup.c:1386 +#: glib/gmarkup.c:1394 #, c-format msgid "" "Odd character “%s”, expected a “>” or “/” character to end the start tag of " @@ -4990,7 +5042,7 @@ "begyndelsesmærket til elementet “%s” eller alternativt en attribut; måske " "brugte du et ugyldigt tegn i attributnavnet" -#: glib/gmarkup.c:1430 +#: glib/gmarkup.c:1439 #, c-format msgid "" "Odd character “%s”, expected an open quote mark after the equals sign when " @@ -4999,7 +5051,7 @@ "Mærkeligt tegn “%s”, forventede et åbningsanførselstegn efter lighedstegnet " "når værdien for egenskaben “%s” for attributten “%s” angives" -#: glib/gmarkup.c:1563 +#: glib/gmarkup.c:1573 #, c-format msgid "" "“%s” is not a valid character following the characters “”" -#: glib/gmarkup.c:1610 +#: glib/gmarkup.c:1623 #, c-format msgid "Element “%s” was closed, no element is currently open" msgstr "Element “%s” blev lukket, ingen åbne elementer nu" -#: glib/gmarkup.c:1619 +#: glib/gmarkup.c:1632 #, c-format msgid "Element “%s” was closed, but the currently open element is “%s”" msgstr "Element “%s” blev lukket, men aktivt åbent element er “%s”" -#: glib/gmarkup.c:1772 +#: glib/gmarkup.c:1785 msgid "Document was empty or contained only whitespace" msgstr "Dokumentet var tomt eller indeholdt kun blanke tegn" -#: glib/gmarkup.c:1786 +#: glib/gmarkup.c:1799 msgid "Document ended unexpectedly just after an open angle bracket “<”" msgstr "Dokumentet sluttede uventet lige efter en åben vinkelparantes “<”" -#: glib/gmarkup.c:1794 glib/gmarkup.c:1839 +#: glib/gmarkup.c:1807 glib/gmarkup.c:1852 #, c-format msgid "" "Document ended unexpectedly with elements still open — “%s” was the last " "element opened" -msgstr "Dokumentet sluttede uventet med åbne elementer — “%s” var sidste åbne element" +msgstr "" +"Dokumentet sluttede uventet med åbne elementer — “%s” var sidste åbne element" -#: glib/gmarkup.c:1802 +#: glib/gmarkup.c:1815 #, c-format msgid "" "Document ended unexpectedly, expected to see a close angle bracket ending " @@ -5051,19 +5104,19 @@ "Dokumentet sluttede uventet, forventede at se en vinkelparantes for at " "afslutte det sidste mærke <%s/>" -#: glib/gmarkup.c:1808 +#: glib/gmarkup.c:1821 msgid "Document ended unexpectedly inside an element name" msgstr "Dokumentet sluttede uventet inden i et elementnavn" -#: glib/gmarkup.c:1814 +#: glib/gmarkup.c:1827 msgid "Document ended unexpectedly inside an attribute name" msgstr "Dokumentet sluttede uventet inden i et attributnavn" -#: glib/gmarkup.c:1819 +#: glib/gmarkup.c:1832 msgid "Document ended unexpectedly inside an element-opening tag." msgstr "Dokumentet sluttede uventet inden i et element-åbnende mærke." -#: glib/gmarkup.c:1825 +#: glib/gmarkup.c:1838 msgid "" "Document ended unexpectedly after the equals sign following an attribute " "name; no attribute value" @@ -5071,21 +5124,22 @@ "Dokumentet sluttede uventet efter lighedstegnet efter et attributnavn; ingen " "attributværdi" -#: glib/gmarkup.c:1832 +#: glib/gmarkup.c:1845 msgid "Document ended unexpectedly while inside an attribute value" msgstr "Dokumentet sluttede uventet inden i en attributværdi" -#: glib/gmarkup.c:1849 +#: glib/gmarkup.c:1862 #, c-format msgid "Document ended unexpectedly inside the close tag for element “%s”" msgstr "Dokumentet sluttede uventet inden i lukningsmærket for elementet “%s”" -#: glib/gmarkup.c:1853 +#: glib/gmarkup.c:1866 msgid "" "Document ended unexpectedly inside the close tag for an unopened element" -msgstr "Dokumentet sluttede uventet inden i lukningsmærket for et uåbnet element" +msgstr "" +"Dokumentet sluttede uventet inden i lukningsmærket for et uåbnet element" -#: glib/gmarkup.c:1859 +#: glib/gmarkup.c:1872 msgid "Document ended unexpectedly inside a comment or processing instruction" msgstr "" "Dokumentet sluttede uventet inden i en kommentar eller behandlingsinstruktion" @@ -5511,15 +5565,15 @@ msgid "illegal symbolic reference" msgstr "ugyldig symbolsk reference" -#: glib/gregex.c:2582 +#: glib/gregex.c:2583 msgid "stray final “\\”" msgstr "løst afsluttende “\\”" -#: glib/gregex.c:2586 +#: glib/gregex.c:2587 msgid "unknown escape sequence" msgstr "ukendt undvigesekvens" -#: glib/gregex.c:2596 +#: glib/gregex.c:2597 #, c-format msgid "Error while parsing replacement text “%s” at char %lu: %s" msgstr "Fejl under fortolkning af erstatningstekst “%s” ved tegn %lu: %s" @@ -5549,127 +5603,127 @@ msgid "Text was empty (or contained only whitespace)" msgstr "Tekst var tom (eller indeholdt kun blanke tegn)" -#: glib/gspawn.c:302 +#: glib/gspawn.c:315 #, c-format msgid "Failed to read data from child process (%s)" msgstr "Fejl ved læsning af data fra underprocess (%s)" -#: glib/gspawn.c:450 +#: glib/gspawn.c:463 #, c-format msgid "Unexpected error in select() reading data from a child process (%s)" msgstr "Uventet fejl i select() ved læsning af data fra underprocess (%s)" -#: glib/gspawn.c:535 +#: glib/gspawn.c:548 #, c-format msgid "Unexpected error in waitpid() (%s)" msgstr "Uventet fejl i waitpid() (%s)" -#: glib/gspawn.c:1043 glib/gspawn-win32.c:1318 +#: glib/gspawn.c:1056 glib/gspawn-win32.c:1329 #, c-format msgid "Child process exited with code %ld" msgstr "Underproces afsluttede med kode %ld" -#: glib/gspawn.c:1051 +#: glib/gspawn.c:1064 #, c-format msgid "Child process killed by signal %ld" msgstr "Underproces dræbt med signal %ld" -#: glib/gspawn.c:1058 +#: glib/gspawn.c:1071 #, c-format msgid "Child process stopped by signal %ld" msgstr "Underproces stoppet med signal %ld" -#: glib/gspawn.c:1065 +#: glib/gspawn.c:1078 #, c-format msgid "Child process exited abnormally" msgstr "Underproces afsluttede fejlagtigt" -#: glib/gspawn.c:1360 glib/gspawn-win32.c:339 glib/gspawn-win32.c:347 +#: glib/gspawn.c:1405 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 #, c-format msgid "Failed to read from child pipe (%s)" msgstr "Fejl under læsning fra barnedatakanal (%s)" -#: glib/gspawn.c:1596 +#: glib/gspawn.c:1653 #, c-format msgid "Failed to spawn child process “%s” (%s)" msgstr "Fejl under kørsel af underprocessen “%s” (%s)" -#: glib/gspawn.c:1635 +#: glib/gspawn.c:1692 #, c-format msgid "Failed to fork (%s)" msgstr "Fejl under fraspaltning af proces (%s)" -#: glib/gspawn.c:1784 glib/gspawn-win32.c:370 +#: glib/gspawn.c:1841 glib/gspawn-win32.c:381 #, c-format msgid "Failed to change to directory “%s” (%s)" msgstr "Fejl ved skift til mappen “%s” (%s)" -#: glib/gspawn.c:1794 +#: glib/gspawn.c:1851 #, c-format msgid "Failed to execute child process “%s” (%s)" msgstr "Fejl under kørsel af underprocessen “%s” (%s)" -#: glib/gspawn.c:1804 +#: glib/gspawn.c:1861 #, c-format msgid "Failed to redirect output or input of child process (%s)" msgstr "Fejl under omdirigering af uddata eller inddata for underprocess (%s)" -#: glib/gspawn.c:1813 +#: glib/gspawn.c:1870 #, c-format msgid "Failed to fork child process (%s)" msgstr "Fejl ved fraspaltning af underprocess (%s)" -#: glib/gspawn.c:1821 +#: glib/gspawn.c:1878 #, c-format msgid "Unknown error executing child process “%s”" msgstr "Ukendt fejl under kørsel af underprocessen “%s”" -#: glib/gspawn.c:1845 +#: glib/gspawn.c:1902 #, c-format msgid "Failed to read enough data from child pid pipe (%s)" msgstr "" "Kunne ikke læse tilstrækkelig mængde data fra underprocessens pid-kanal (%s)" -#: glib/gspawn-win32.c:283 +#: glib/gspawn-win32.c:294 msgid "Failed to read data from child process" msgstr "Fejl under læsning af data fra underprocess" -#: glib/gspawn-win32.c:300 +#: glib/gspawn-win32.c:311 #, c-format msgid "Failed to create pipe for communicating with child process (%s)" msgstr "Fejl under oprettelse af kommunikationskanal til underproces (%s)" -#: glib/gspawn-win32.c:376 glib/gspawn-win32.c:381 glib/gspawn-win32.c:500 +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 #, c-format msgid "Failed to execute child process (%s)" msgstr "Fejl under kørsel af underprocess (%s)" -#: glib/gspawn-win32.c:450 +#: glib/gspawn-win32.c:461 #, c-format msgid "Invalid program name: %s" msgstr "Ugyldigt programnavn: %s" -#: glib/gspawn-win32.c:460 glib/gspawn-win32.c:714 +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 #, c-format msgid "Invalid string in argument vector at %d: %s" msgstr "Ugyldig streng i argumentvektor på %d: %s" -#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:729 +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 #, c-format msgid "Invalid string in environment: %s" msgstr "Ugyldig streng i miljø: %s" -#: glib/gspawn-win32.c:710 +#: glib/gspawn-win32.c:721 #, c-format msgid "Invalid working directory: %s" msgstr "Ugyldigt arbejdskatalog: %s" -#: glib/gspawn-win32.c:772 +#: glib/gspawn-win32.c:783 #, c-format msgid "Failed to execute helper program (%s)" msgstr "Fejl under kørsel af hjælpeprogram (%s)" -#: glib/gspawn-win32.c:1045 +#: glib/gspawn-win32.c:1056 msgid "" "Unexpected error in g_io_channel_win32_poll() reading data from a child " "process" @@ -5677,21 +5731,21 @@ "Uventet fejl i g_io_channel_win32_poll() under læsning af data fra en " "underprocess" -#: glib/gstrfuncs.c:3247 glib/gstrfuncs.c:3348 +#: glib/gstrfuncs.c:3286 glib/gstrfuncs.c:3388 msgid "Empty string is not a number" msgstr "Tom streng er ikke et tal" -#: glib/gstrfuncs.c:3271 +#: glib/gstrfuncs.c:3310 #, c-format msgid "“%s” is not a signed number" msgstr "“%s” er ikke et tal med fortegn" -#: glib/gstrfuncs.c:3281 glib/gstrfuncs.c:3384 +#: glib/gstrfuncs.c:3320 glib/gstrfuncs.c:3424 #, c-format msgid "Number “%s” is out of bounds [%s, %s]" msgstr "Tallet “%s” er uden for det gyldige interval [%s, %s]" -#: glib/gstrfuncs.c:3374 +#: glib/gstrfuncs.c:3414 #, c-format msgid "“%s” is not an unsigned number" msgstr "“%s” er ikke et tal uden fortegn" @@ -5713,134 +5767,180 @@ msgid "Character out of range for UTF-16" msgstr "Tegn uden for gyldigt interval for UTF-16" -#: glib/gutils.c:2244 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2384 #, c-format -msgid "%.1f kB" -msgstr "%.1f kB" +#| msgid "%.1f kB" +msgid "%.1f kB" +msgstr "%.1f kB" -#: glib/gutils.c:2245 glib/gutils.c:2451 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2386 #, c-format -msgid "%.1f MB" +msgid "%.1f MB" msgstr "%.1f MB" -#: glib/gutils.c:2246 glib/gutils.c:2456 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2388 #, c-format -msgid "%.1f GB" +msgid "%.1f GB" msgstr "%.1f GB" -#: glib/gutils.c:2247 glib/gutils.c:2461 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2390 #, c-format -msgid "%.1f TB" -msgstr "%.1f TB" +#| msgid "%.1f TB" +msgid "%.1f TB" +msgstr "%.1f TB" -#: glib/gutils.c:2248 glib/gutils.c:2466 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2392 #, c-format -msgid "%.1f PB" -msgstr "%.1f PB" +#| msgid "%.1f PB" +msgid "%.1f PB" +msgstr "%.1f PB" -#: glib/gutils.c:2249 glib/gutils.c:2471 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2394 #, c-format -msgid "%.1f EB" -msgstr "%.1f EB" +#| msgid "%.1f EB" +msgid "%.1f EB" +msgstr "%.1f EB" -#: glib/gutils.c:2252 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2398 #, c-format -msgid "%.1f KiB" -msgstr "%.1f KiB" +#| msgid "%.1f KiB" +msgid "%.1f KiB" +msgstr "%.1f KiB" -#: glib/gutils.c:2253 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2400 #, c-format -msgid "%.1f MiB" -msgstr "%.1f MiB" +#| msgid "%.1f MiB" +msgid "%.1f MiB" +msgstr "%.1f MiB" -#: glib/gutils.c:2254 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2402 #, c-format -msgid "%.1f GiB" -msgstr "%.1f GiB" +#| msgid "%.1f GiB" +msgid "%.1f GiB" +msgstr "%.1f GiB" -#: glib/gutils.c:2255 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2404 #, c-format -msgid "%.1f TiB" -msgstr "%.1f TiB" +#| msgid "%.1f TiB" +msgid "%.1f TiB" +msgstr "%.1f TiB" -#: glib/gutils.c:2256 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2406 #, c-format -msgid "%.1f PiB" -msgstr "%.1f PiB" +#| msgid "%.1f PiB" +msgid "%.1f PiB" +msgstr "%.1f PiB" -#: glib/gutils.c:2257 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2408 #, c-format -msgid "%.1f EiB" -msgstr "%.1f EiB" +#| msgid "%.1f EiB" +msgid "%.1f EiB" +msgstr "%.1f EiB" -#: glib/gutils.c:2260 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2412 #, c-format -msgid "%.1f kb" -msgstr "%.1f kb" +#| msgid "%.1f kb" +msgid "%.1f kb" +msgstr "%.1f kb" -#: glib/gutils.c:2261 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2414 #, c-format -msgid "%.1f Mb" -msgstr "%.1f Mb" +#| msgid "%.1f Mb" +msgid "%.1f Mb" +msgstr "%.1f Mb" -#: glib/gutils.c:2262 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2416 #, c-format -msgid "%.1f Gb" -msgstr "%.1f Gb" +#| msgid "%.1f Gb" +msgid "%.1f Gb" +msgstr "%.1f Gb" -#: glib/gutils.c:2263 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2418 #, c-format -msgid "%.1f Tb" -msgstr "%.1f Tb" +#| msgid "%.1f Tb" +msgid "%.1f Tb" +msgstr "%.1f Tb" -#: glib/gutils.c:2264 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2420 #, c-format -msgid "%.1f Pb" -msgstr "%.1f Pb" +#| msgid "%.1f Pb" +msgid "%.1f Pb" +msgstr "%.1f Pb" -#: glib/gutils.c:2265 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2422 #, c-format -msgid "%.1f Eb" -msgstr "%.1f Eb" +#| msgid "%.1f Eb" +msgid "%.1f Eb" +msgstr "%.1f Eb" -#: glib/gutils.c:2268 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2426 #, c-format -msgid "%.1f Kib" -msgstr "%.1f Kib" +#| msgid "%.1f Kib" +msgid "%.1f Kib" +msgstr "%.1f Kib" -#: glib/gutils.c:2269 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2428 #, c-format -msgid "%.1f Mib" -msgstr "%.1f Mib" +#| msgid "%.1f Mib" +msgid "%.1f Mib" +msgstr "%.1f Mib" -#: glib/gutils.c:2270 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2430 #, c-format -msgid "%.1f Gib" -msgstr "%.1f Gib" +#| msgid "%.1f Gib" +msgid "%.1f Gib" +msgstr "%.1f Gib" -#: glib/gutils.c:2271 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2432 #, c-format -msgid "%.1f Tib" -msgstr "%.1f Tib" +#| msgid "%.1f Tib" +msgid "%.1f Tib" +msgstr "%.1f Tib" -#: glib/gutils.c:2272 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2434 #, c-format -msgid "%.1f Pib" -msgstr "%.1f Pib" +#| msgid "%.1f Pib" +msgid "%.1f Pib" +msgstr "%.1f Pib" -#: glib/gutils.c:2273 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2436 #, c-format -msgid "%.1f Eib" -msgstr "%.1f Eib" +#| msgid "%.1f Eib" +msgid "%.1f Eib" +msgstr "%.1f Eib" -#: glib/gutils.c:2307 glib/gutils.c:2433 +#: glib/gutils.c:2470 glib/gutils.c:2596 #, c-format msgid "%u byte" msgid_plural "%u bytes" msgstr[0] "%u byte" msgstr[1] "%u byte" -#: glib/gutils.c:2311 +#: glib/gutils.c:2474 #, c-format msgid "%u bit" msgid_plural "%u bits" @@ -5848,7 +5948,7 @@ msgstr[1] "%u bit" #. Translators: the %s in "%s bytes" will always be replaced by a number. -#: glib/gutils.c:2378 +#: glib/gutils.c:2541 #, c-format msgid "%s byte" msgid_plural "%s bytes" @@ -5856,7 +5956,7 @@ msgstr[1] "%s bytes" #. Translators: the %s in "%s bits" will always be replaced by a number. -#: glib/gutils.c:2383 +#: glib/gutils.c:2546 #, c-format msgid "%s bit" msgid_plural "%s bits" @@ -5868,11 +5968,36 @@ #. * compatibility. Users will not see this string unless a program is using this deprecated function. #. * Please translate as literally as possible. #. -#: glib/gutils.c:2446 +#: glib/gutils.c:2609 #, c-format msgid "%.1f KB" msgstr "%.1f KB" +#: glib/gutils.c:2614 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2619 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2624 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2629 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2634 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + #~ msgid "No such method '%s'" #~ msgstr "Ingen sådan metode “%s”" diff -Nru glib2.0-2.59.2/po/fr.po glib2.0-2.59.3/po/fr.po --- glib2.0-2.59.2/po/fr.po 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/fr.po 2019-03-04 09:01:42.000000000 +0000 @@ -11,21 +11,22 @@ # Bruno Brouard , 2010-2012. # Gérard Baylard , 2010. # Alexandre Franke , 2012. -# Charles Monzat , 2016. +# Charles Monzat , 2016-2018. # msgid "" msgstr "" "Project-Id-Version: glib master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" -"POT-Creation-Date: 2018-08-09 00:27+0000\n" -"PO-Revision-Date: 2018-08-12 13:47+0200\n" -"Last-Translator: Claude Paroz \n" -"Language-Team: GNOME French Team \n" +"POT-Creation-Date: 2019-01-18 15:16+0000\n" +"PO-Revision-Date: 2018-11-20 09:47+0100\n" +"Last-Translator: Charles Monzat \n" +"Language-Team: français \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n>1;\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Gtranslator 3.30.0\n" #: gio/gapplication.c:496 msgid "GApplication options" @@ -307,13 +308,13 @@ #: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 #: gio/gdatainputstream.c:1261 glib/gconvert.c:454 glib/gconvert.c:883 -#: glib/giochannel.c:1557 glib/giochannel.c:1599 glib/giochannel.c:2443 -#: glib/gutf8.c:869 glib/gutf8.c:1322 +#: glib/giochannel.c:1558 glib/giochannel.c:1600 glib/giochannel.c:2444 +#: glib/gutf8.c:870 glib/gutf8.c:1323 msgid "Invalid byte sequence in conversion input" msgstr "Séquence d’octets incorrecte en entrée du convertisseur" #: gio/gcharsetconverter.c:347 glib/gconvert.c:462 glib/gconvert.c:797 -#: glib/giochannel.c:1564 glib/giochannel.c:2455 +#: glib/giochannel.c:1565 glib/giochannel.c:2456 #, c-format msgid "Error during conversion: %s" msgstr "Erreur lors de la conversion : %s" @@ -322,7 +323,7 @@ msgid "Cancellable initialization not supported" msgstr "Initialisation annulable non prise en charge" -#: gio/gcharsetconverter.c:456 glib/gconvert.c:327 glib/giochannel.c:1385 +#: gio/gcharsetconverter.c:456 glib/gconvert.c:327 glib/giochannel.c:1386 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported" msgstr "" @@ -735,7 +736,7 @@ #: gio/gdbusconnection.c:5384 #, c-format msgid "Unable to retrieve property %s.%s" -msgstr "Impossible d’obtenir le propriété %s.%s" +msgstr "Impossible d’obtenir la propriété %s.%s" #: gio/gdbusconnection.c:5440 #, c-format @@ -759,27 +760,27 @@ msgid "A subtree is already exported for %s" msgstr "Une sous-arborescence est déjà exportée pour « %s »" -#: gio/gdbusmessage.c:1248 +#: gio/gdbusmessage.c:1251 msgid "type is INVALID" msgstr "le type est « INVALID »" -#: gio/gdbusmessage.c:1259 +#: gio/gdbusmessage.c:1262 msgid "METHOD_CALL message: PATH or MEMBER header field is missing" msgstr "Message de METHOD_CALL : champ d’en-tête PATH ou MEMBER manquant" -#: gio/gdbusmessage.c:1270 +#: gio/gdbusmessage.c:1273 msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" msgstr "Message de METHOD_RETURN : champ d’en-tête REPLY_SERIAL manquant" -#: gio/gdbusmessage.c:1282 +#: gio/gdbusmessage.c:1285 msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" msgstr "Message d’ERREUR : champ d’en-tête REPLY_SERIAL ou ERROR_NAME manquant" -#: gio/gdbusmessage.c:1295 +#: gio/gdbusmessage.c:1298 msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" msgstr "Message de SIGNAL : champ d’en-tête PATH, INTERFACE ou MEMBER manquant" -#: gio/gdbusmessage.c:1303 +#: gio/gdbusmessage.c:1306 msgid "" "SIGNAL message: The PATH header field is using the reserved value /org/" "freedesktop/DBus/Local" @@ -787,7 +788,7 @@ "Message de SIGNAL : le champ d’en-tête PATH utilise la valeur réservée /org/" "freedesktop/DBus/Local" -#: gio/gdbusmessage.c:1311 +#: gio/gdbusmessage.c:1314 msgid "" "SIGNAL message: The INTERFACE header field is using the reserved value org." "freedesktop.DBus.Local" @@ -795,21 +796,21 @@ "Message de SIGNAL : le champ d’en-tête INTERFACE utilise la valeur réservée " "org.freedesktop.DBus.Local" -#: gio/gdbusmessage.c:1359 gio/gdbusmessage.c:1419 +#: gio/gdbusmessage.c:1362 gio/gdbusmessage.c:1422 #, c-format msgid "Wanted to read %lu byte but only got %lu" msgid_plural "Wanted to read %lu bytes but only got %lu" msgstr[0] "Lecture de %lu octet demandée, mais seulement %lu reçu(s)" msgstr[1] "Lecture de %lu octets demandée, mais seulement %lu reçu(s)" -#: gio/gdbusmessage.c:1373 +#: gio/gdbusmessage.c:1376 #, c-format msgid "Expected NUL byte after the string “%s” but found byte %d" msgstr "" "Octet 00 (NUL) attendu à la fin de la chaîne « %s » mais un octet %d a été " "trouvé" -#: gio/gdbusmessage.c:1392 +#: gio/gdbusmessage.c:1395 #, c-format msgid "" "Expected valid UTF-8 string but found invalid bytes at byte offset %d " @@ -819,19 +820,19 @@ "rencontrés à la position %d (longueur de la chaîne : %d octets). La chaîne " "UTF-8 valide jusqu’à cet endroit est « %s »" -#: gio/gdbusmessage.c:1595 +#: gio/gdbusmessage.c:1598 #, c-format msgid "Parsed value “%s” is not a valid D-Bus object path" msgstr "" "La valeur analysée « %s » n’est pas un chemin vers un objet D-Bus valide" -#: gio/gdbusmessage.c:1617 +#: gio/gdbusmessage.c:1620 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature" msgstr "La valeur analysée « %s » n’est pas une signature D-Bus valide" # 2<<26 donne 128 Mo, 2^26 donne 64 Mo, 1<<26 donne 64 Mo -#: gio/gdbusmessage.c:1664 +#: gio/gdbusmessage.c:1667 #, c-format msgid "" "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." @@ -839,12 +840,12 @@ "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." msgstr[0] "" "Un tableau de %u octet de long a été trouvé. La longueur maximale est de " -"2<<26 octets (64 Mo)." +"2<<26 octets (64 Mo)." msgstr[1] "" "Un tableau de %u octets de long a été trouvé. La longueur maximale est de " -"2<<26 octets (64 Mo)." +"2<<26 octets (64 Mo)." -#: gio/gdbusmessage.c:1684 +#: gio/gdbusmessage.c:1687 #, c-format msgid "" "Encountered array of type “a%c”, expected to have a length a multiple of %u " @@ -853,14 +854,14 @@ "Un tableau de type « a%c » a été trouvé, avec une longueur attendue multiple " "de %u octets, mais la longueur réelle est de %u octets" -#: gio/gdbusmessage.c:1851 +#: gio/gdbusmessage.c:1857 #, c-format msgid "Parsed value “%s” for variant is not a valid D-Bus signature" msgstr "" "La valeur « %s » analysée en tant que variant n’est pas une signature valide " "de D-Bus" -#: gio/gdbusmessage.c:1875 +#: gio/gdbusmessage.c:1881 #, c-format msgid "" "Error deserializing GVariant with type string “%s” from the D-Bus wire format" @@ -868,7 +869,7 @@ "Erreur en désérialisant le GVariant en chaîne de type « %s » à partir du " "format de transmission D-Bus" -#: gio/gdbusmessage.c:2057 +#: gio/gdbusmessage.c:2066 #, c-format msgid "" "Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value " @@ -877,26 +878,30 @@ "Valeur de boutisme non valide. 0x6c (« l ») ou 0x42 (« B ») attendus, mais 0x" "%02x trouvé" -#: gio/gdbusmessage.c:2070 +#: gio/gdbusmessage.c:2079 #, c-format msgid "Invalid major protocol version. Expected 1 but found %d" msgstr "Version majeure du protocole non valide. 1 attendu, %d trouvé" -#: gio/gdbusmessage.c:2126 +#: gio/gdbusmessage.c:2132 gio/gdbusmessage.c:2722 +msgid "Signature header found but is not of type signature" +msgstr "En-tête de signature trouvé mais n’est pas de type signature" + +#: gio/gdbusmessage.c:2144 #, c-format msgid "Signature header with signature “%s” found but message body is empty" msgstr "" "En-tête de signature trouvé avec la signature « %s », mais le corps du " "message est vide" -#: gio/gdbusmessage.c:2140 +#: gio/gdbusmessage.c:2158 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature (for body)" msgstr "" "La valeur analysée « %s » n’est pas une signature valide de D-Bus (pour le " "corps)" -#: gio/gdbusmessage.c:2170 +#: gio/gdbusmessage.c:2188 #, c-format msgid "No signature header in message but the message body is %u byte" msgid_plural "No signature header in message but the message body is %u bytes" @@ -907,11 +912,11 @@ "Pas de signature d’en-tête dans le message, mais le corps du message est de " "%u octets" -#: gio/gdbusmessage.c:2180 +#: gio/gdbusmessage.c:2198 msgid "Cannot deserialize message: " msgstr "Impossible de désérialiser le message : " -#: gio/gdbusmessage.c:2521 +#: gio/gdbusmessage.c:2539 #, c-format msgid "" "Error serializing GVariant with type string “%s” to the D-Bus wire format" @@ -919,7 +924,7 @@ "Erreur en sérialisant le GVariant en chaîne de type « %s » dans le format de " "transmission D-Bus" -#: gio/gdbusmessage.c:2658 +#: gio/gdbusmessage.c:2676 #, c-format msgid "" "Number of file descriptors in message (%d) differs from header field (%d)" @@ -927,18 +932,18 @@ "Le nombre de descripteurs de fichiers dans le message (%d) diffère de celui " "du champ d’en-tête (%d)" -#: gio/gdbusmessage.c:2666 +#: gio/gdbusmessage.c:2684 msgid "Cannot serialize message: " msgstr "Impossible de sérialiser le message : " -#: gio/gdbusmessage.c:2710 +#: gio/gdbusmessage.c:2738 #, c-format msgid "Message body has signature “%s” but there is no signature header" msgstr "" "Le corps du message a la signature « %s », mais il n’y a pas d’en-tête de " "signature" -#: gio/gdbusmessage.c:2720 +#: gio/gdbusmessage.c:2748 #, c-format msgid "" "Message body has type signature “%s” but signature in the header field is " @@ -947,19 +952,19 @@ "Le corps du message a une signature de type « %s », mais celle dans le champ " "d’en-tête est « %s »" -#: gio/gdbusmessage.c:2736 +#: gio/gdbusmessage.c:2764 #, c-format msgid "Message body is empty but signature in the header field is “(%s)”" msgstr "" "Le corps du message est vide mais sa signature dans le champ d’en-tête est " "« (%s) »" -#: gio/gdbusmessage.c:3289 +#: gio/gdbusmessage.c:3317 #, c-format msgid "Error return with body of type “%s”" msgstr "Retour d’erreur avec un corps de type « %s »" -#: gio/gdbusmessage.c:3297 +#: gio/gdbusmessage.c:3325 msgid "Error return with empty body" msgstr "Retour d’erreur avec un corps vide" @@ -1412,7 +1417,7 @@ msgid "Containing mount does not exist" msgstr "Le point de montage conteneur n’existe pas" -#: gio/gfile.c:2622 gio/glocalfile.c:2391 +#: gio/gfile.c:2622 gio/glocalfile.c:2441 msgid "Can’t copy over directory" msgstr "Impossible d’écraser un répertoire" @@ -1549,38 +1554,38 @@ msgstr "" "Le serveur mandataire HTTP a terminé la connexion de manière inattendue." -#: gio/gicon.c:290 +#: gio/gicon.c:298 #, c-format msgid "Wrong number of tokens (%d)" msgstr "Nombre de jetons incorrect (%d)" -#: gio/gicon.c:310 +#: gio/gicon.c:318 #, c-format msgid "No type for class name %s" msgstr "Aucun type pour le nom de classe %s" -#: gio/gicon.c:320 +#: gio/gicon.c:328 #, c-format msgid "Type %s does not implement the GIcon interface" msgstr "Le type %s n’implémente pas l’interface GIcon" -#: gio/gicon.c:331 +#: gio/gicon.c:339 #, c-format msgid "Type %s is not classed" msgstr "Le type %s n’est pas classé" -#: gio/gicon.c:345 +#: gio/gicon.c:353 #, c-format msgid "Malformed version number: %s" msgstr "Numéro de version incorrect : %s" -#: gio/gicon.c:359 +#: gio/gicon.c:367 #, c-format msgid "Type %s does not implement from_tokens() on the GIcon interface" msgstr "" "Le type %s n’implémente pas la fonction from_tokens() de l’interface GIcon" -#: gio/gicon.c:461 +#: gio/gicon.c:469 msgid "Can’t handle the supplied version of the icon encoding" msgstr "Impossible de gérer la version fournie du codage de l’icône" @@ -1667,7 +1672,7 @@ #: gio/gio-tool.c:233 msgid "Get or set the handler for a mimetype" -msgstr "Obtenir ou définir le gestionaire d’un type MIME" +msgstr "Obtenir ou définir le gestionnaire d’un type MIME" #: gio/gio-tool.c:234 msgid "Create directories" @@ -2040,7 +2045,7 @@ #: gio/gio-tool-monitor.c:47 msgid "Watch for mount events" -msgstr "Surveille les événements de montage" +msgstr "Surveille les évènements de montage" #: gio/gio-tool-monitor.c:208 msgid "Monitor files or directories for changes." @@ -2182,7 +2187,7 @@ #: gio/gio-tool-rename.c:50 msgid "Rename a file." -msgstr "Renommmer un fichier." +msgstr "Renommer un fichier." #: gio/gio-tool-rename.c:70 msgid "Missing argument" @@ -2338,7 +2343,7 @@ #, c-format msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" msgstr "" -"Un prétraitement %s a été demandé, mais %s n'est pas défini et %s n’est pas " +"Un prétraitement %s a été demandé, mais %s n’est pas défini et %s n’est pas " "dans le chemin PATH" #: gio/glib-compile-resources.c:460 @@ -2356,7 +2361,7 @@ msgid "text may not appear inside <%s>" msgstr "<%s> ne peut pas contenir du texte" -#: gio/glib-compile-resources.c:736 gio/glib-compile-schemas.c:2138 +#: gio/glib-compile-resources.c:736 gio/glib-compile-schemas.c:2139 msgid "Show program version and exit" msgstr "Affiche la version du programme et quitte" @@ -2372,8 +2377,8 @@ "Les répertoires à partir desquels charger les fichiers référencés dans " "FICHIER (par défaut le répertoire actuel)" -#: gio/glib-compile-resources.c:738 gio/glib-compile-schemas.c:2139 -#: gio/glib-compile-schemas.c:2168 +#: gio/glib-compile-resources.c:738 gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-schemas.c:2169 msgid "DIRECTORY" msgstr "RÉPERTOIRE" @@ -2577,12 +2582,12 @@ #: gio/glib-compile-schemas.c:607 #, c-format msgid "alias target “%s” is not in enumerated type" -msgstr "la cible d'alias « %s » n’est pas dans le type énuméré" +msgstr "la cible d’alias « %s » n’est pas dans le type énuméré" #: gio/glib-compile-schemas.c:608 #, c-format msgid "alias target “%s” is not in " -msgstr "la cible d'alias « %s » n’est pas dans " +msgstr "la cible d’alias « %s » n’est pas dans " #: gio/glib-compile-schemas.c:623 #, c-format @@ -2772,7 +2777,7 @@ #: gio/glib-compile-schemas.c:1695 #, c-format msgid "Warning: undefined reference to " -msgstr "Attention : reférence indéfinie vers " +msgstr "Attention : référence indéfinie vers " #. Translators: Do not translate "--strict". #: gio/glib-compile-schemas.c:1834 gio/glib-compile-schemas.c:1910 @@ -2850,23 +2855,23 @@ "la redéfinition de la clé « %s » dans le schéma « %s » du fichier de " "redéfinition « %s » n’est pas dans la liste des choix valides" -#: gio/glib-compile-schemas.c:2139 +#: gio/glib-compile-schemas.c:2140 msgid "where to store the gschemas.compiled file" msgstr "endroit où enregistrer le fichier gschemas.compiled" -#: gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-schemas.c:2141 msgid "Abort on any errors in schemas" msgstr "Annulation en cas d’erreurs dans des schémas" -#: gio/glib-compile-schemas.c:2141 +#: gio/glib-compile-schemas.c:2142 msgid "Do not write the gschema.compiled file" msgstr "Ne pas écrire de fichier gschema.compiled" -#: gio/glib-compile-schemas.c:2142 +#: gio/glib-compile-schemas.c:2143 msgid "Do not enforce key name restrictions" msgstr "Ne pas appliquer les limitations de nom de clé" -#: gio/glib-compile-schemas.c:2171 +#: gio/glib-compile-schemas.c:2172 msgid "" "Compile all GSettings schema files into a schema cache.\n" "Schema files are required to have the extension .gschema.xml,\n" @@ -2876,22 +2881,22 @@ "L’extension .gschema.xml est requise pour les fichiers schémas,\n" "et le fichier cache est nommé gschemas.compiled." -#: gio/glib-compile-schemas.c:2192 +#: gio/glib-compile-schemas.c:2193 #, c-format msgid "You should give exactly one directory name\n" msgstr "Vous devez indiquer un et un seul nom de répertoire\n" -#: gio/glib-compile-schemas.c:2234 +#: gio/glib-compile-schemas.c:2235 #, c-format msgid "No schema files found: " msgstr "Aucun fichier schéma trouvé : " -#: gio/glib-compile-schemas.c:2237 +#: gio/glib-compile-schemas.c:2238 #, c-format msgid "doing nothing.\n" msgstr "aucune action effectuée.\n" -#: gio/glib-compile-schemas.c:2240 +#: gio/glib-compile-schemas.c:2241 #, c-format msgid "removed existing output file.\n" msgstr "fichier de sortie existant supprimé.\n" @@ -2901,7 +2906,7 @@ msgid "Invalid filename %s" msgstr "Nom de fichier non valide : %s" -#: gio/glocalfile.c:1006 +#: gio/glocalfile.c:1011 #, c-format msgid "Error getting filesystem info for %s: %s" msgstr "" @@ -2911,135 +2916,135 @@ #. * the enclosing (user visible) mount of a file, but none #. * exists. #. -#: gio/glocalfile.c:1145 +#: gio/glocalfile.c:1150 #, c-format msgid "Containing mount for file %s not found" msgstr "Le point de montage conteneur pour le fichier %s est introuvable" -#: gio/glocalfile.c:1168 +#: gio/glocalfile.c:1173 msgid "Can’t rename root directory" msgstr "Impossible de renommer le répertoire racine" -#: gio/glocalfile.c:1186 gio/glocalfile.c:1209 +#: gio/glocalfile.c:1191 gio/glocalfile.c:1214 #, c-format msgid "Error renaming file %s: %s" msgstr "Erreur de renommage du fichier %s : %s" -#: gio/glocalfile.c:1193 +#: gio/glocalfile.c:1198 msgid "Can’t rename file, filename already exists" msgstr "Impossible de renommer le fichier car ce nom est déjà utilisé" -#: gio/glocalfile.c:1206 gio/glocalfile.c:2267 gio/glocalfile.c:2295 -#: gio/glocalfile.c:2452 gio/glocalfileoutputstream.c:551 +#: gio/glocalfile.c:1211 gio/glocalfile.c:2317 gio/glocalfile.c:2345 +#: gio/glocalfile.c:2502 gio/glocalfileoutputstream.c:551 msgid "Invalid filename" msgstr "Nom de fichier non valide" -#: gio/glocalfile.c:1374 gio/glocalfile.c:1389 +#: gio/glocalfile.c:1379 gio/glocalfile.c:1394 #, c-format msgid "Error opening file %s: %s" msgstr "Erreur lors de l’ouverture du fichier %s : %s" -#: gio/glocalfile.c:1514 +#: gio/glocalfile.c:1519 #, c-format msgid "Error removing file %s: %s" msgstr "Erreur lors de la suppression du fichier %s : %s" -#: gio/glocalfile.c:1925 +#: gio/glocalfile.c:1958 #, c-format msgid "Error trashing file %s: %s" msgstr "Erreur lors de la mise à la corbeille du fichier %s : %s" -#: gio/glocalfile.c:1948 +#: gio/glocalfile.c:1999 #, c-format msgid "Unable to create trash dir %s: %s" msgstr "Impossible de créer le répertoire de la corbeille %s : %s" -#: gio/glocalfile.c:1970 +#: gio/glocalfile.c:2020 #, c-format msgid "Unable to find toplevel directory to trash %s" msgstr "" "Impossible de trouver le répertoire racine pour mettre %s à la corbeille" -#: gio/glocalfile.c:1979 +#: gio/glocalfile.c:2029 #, c-format msgid "Trashing on system internal mounts is not supported" msgstr "" "La mise à la corbeille sur des montages systèmes internes n’est pas prise en " "charge" -#: gio/glocalfile.c:2063 gio/glocalfile.c:2083 +#: gio/glocalfile.c:2113 gio/glocalfile.c:2133 #, c-format msgid "Unable to find or create trash directory for %s" msgstr "Impossible de trouver ou créer le répertoire de la corbeille pour %s" -#: gio/glocalfile.c:2118 +#: gio/glocalfile.c:2168 #, c-format msgid "Unable to create trashing info file for %s: %s" msgstr "" "Impossible de créer le fichier d’informations de mise à la corbeille pour " "%s : %s" -#: gio/glocalfile.c:2178 +#: gio/glocalfile.c:2228 #, c-format msgid "Unable to trash file %s across filesystem boundaries" msgstr "" "Impossible de mettre à la corbeille le fichier %s au-delà des limites du " "système de fichiers" -#: gio/glocalfile.c:2182 gio/glocalfile.c:2238 +#: gio/glocalfile.c:2232 gio/glocalfile.c:2288 #, c-format msgid "Unable to trash file %s: %s" msgstr "Impossible de mettre à la corbeille le fichier %s : %s" -#: gio/glocalfile.c:2244 +#: gio/glocalfile.c:2294 #, c-format msgid "Unable to trash file %s" msgstr "Impossible de mettre à la corbeille le fichier %s" -#: gio/glocalfile.c:2270 +#: gio/glocalfile.c:2320 #, c-format msgid "Error creating directory %s: %s" msgstr "Erreur lors de la création du répertoire %s : %s" -#: gio/glocalfile.c:2299 +#: gio/glocalfile.c:2349 #, c-format msgid "Filesystem does not support symbolic links" msgstr "Le système de fichiers ne gère pas les liens symboliques" -#: gio/glocalfile.c:2302 +#: gio/glocalfile.c:2352 #, c-format msgid "Error making symbolic link %s: %s" msgstr "Erreur lors de la création du lien symbolique %s : %s" -#: gio/glocalfile.c:2308 glib/gfileutils.c:2138 +#: gio/glocalfile.c:2358 glib/gfileutils.c:2138 msgid "Symbolic links not supported" msgstr "Liens symboliques non pris en charge" -#: gio/glocalfile.c:2363 gio/glocalfile.c:2398 gio/glocalfile.c:2455 +#: gio/glocalfile.c:2413 gio/glocalfile.c:2448 gio/glocalfile.c:2505 #, c-format msgid "Error moving file %s: %s" msgstr "Erreur lors du déplacement du fichier %s : %s" -#: gio/glocalfile.c:2386 +#: gio/glocalfile.c:2436 msgid "Can’t move directory over directory" msgstr "Impossible de déplacer un répertoire par dessus un autre" -#: gio/glocalfile.c:2412 gio/glocalfileoutputstream.c:935 +#: gio/glocalfile.c:2462 gio/glocalfileoutputstream.c:935 #: gio/glocalfileoutputstream.c:949 gio/glocalfileoutputstream.c:964 #: gio/glocalfileoutputstream.c:981 gio/glocalfileoutputstream.c:995 msgid "Backup file creation failed" msgstr "La création du fichier de sauvegarde a échoué" -#: gio/glocalfile.c:2431 +#: gio/glocalfile.c:2481 #, c-format msgid "Error removing target file: %s" msgstr "Erreur lors de la suppression du fichier cible : %s" -#: gio/glocalfile.c:2445 +#: gio/glocalfile.c:2495 msgid "Move between mounts not supported" msgstr "Le déplacement entre points de montage n’est pas pris en charge" -#: gio/glocalfile.c:2636 +#: gio/glocalfile.c:2686 #, c-format msgid "Could not determine the disk usage of %s: %s" msgstr "Impossible de déterminer l’utilisation disque de %s : %s" @@ -3061,83 +3066,83 @@ msgid "Error setting extended attribute “%s”: %s" msgstr "Erreur lors de la définition de l’attribut étendu « %s » : %s" -#: gio/glocalfileinfo.c:1629 +#: gio/glocalfileinfo.c:1625 msgid " (invalid encoding)" msgstr " (codage non valide)" -#: gio/glocalfileinfo.c:1793 gio/glocalfileoutputstream.c:813 +#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:813 #, c-format msgid "Error when getting information for file “%s”: %s" msgstr "Erreur lors de l’obtention des informations du fichier « %s » : %s" -#: gio/glocalfileinfo.c:2057 +#: gio/glocalfileinfo.c:2053 #, c-format msgid "Error when getting information for file descriptor: %s" msgstr "" "Erreur lors de l’obtention des informations du descripteur de fichier : %s" -#: gio/glocalfileinfo.c:2102 +#: gio/glocalfileinfo.c:2098 msgid "Invalid attribute type (uint32 expected)" msgstr "Type d’attribut non valide (uint32 attendu)" -#: gio/glocalfileinfo.c:2120 +#: gio/glocalfileinfo.c:2116 msgid "Invalid attribute type (uint64 expected)" msgstr "Type d’attribut non valide (uint64 attendu)" -#: gio/glocalfileinfo.c:2139 gio/glocalfileinfo.c:2158 +#: gio/glocalfileinfo.c:2135 gio/glocalfileinfo.c:2154 msgid "Invalid attribute type (byte string expected)" msgstr "Type d’attribut non valide (chaîne d’octets attendue)" -#: gio/glocalfileinfo.c:2205 +#: gio/glocalfileinfo.c:2201 msgid "Cannot set permissions on symlinks" msgstr "Impossible de définir des permissions sur les liens symboliques" -#: gio/glocalfileinfo.c:2221 +#: gio/glocalfileinfo.c:2217 #, c-format msgid "Error setting permissions: %s" msgstr "Erreur lors de la définition des permissions : %s" -#: gio/glocalfileinfo.c:2272 +#: gio/glocalfileinfo.c:2268 #, c-format msgid "Error setting owner: %s" msgstr "Erreur lors de la définition du propriétaire : %s" -#: gio/glocalfileinfo.c:2295 +#: gio/glocalfileinfo.c:2291 msgid "symlink must be non-NULL" msgstr "un lien symbolique ne doit pas être « NULL »" -#: gio/glocalfileinfo.c:2305 gio/glocalfileinfo.c:2324 -#: gio/glocalfileinfo.c:2335 +#: gio/glocalfileinfo.c:2301 gio/glocalfileinfo.c:2320 +#: gio/glocalfileinfo.c:2331 #, c-format msgid "Error setting symlink: %s" msgstr "Erreur lors de la définition du lien symbolique : %s" -#: gio/glocalfileinfo.c:2314 +#: gio/glocalfileinfo.c:2310 msgid "Error setting symlink: file is not a symlink" msgstr "" "Erreur lors de la définition du lien symbolique : le fichier n’est pas un " "lien symbolique" -#: gio/glocalfileinfo.c:2440 +#: gio/glocalfileinfo.c:2436 #, c-format msgid "Error setting modification or access time: %s" msgstr "" "Erreur lors de la définition de l’heure de modification ou d’accès : %s" -#: gio/glocalfileinfo.c:2463 +#: gio/glocalfileinfo.c:2459 msgid "SELinux context must be non-NULL" msgstr "Le contexte SELinux ne doit pas être « NULL »" -#: gio/glocalfileinfo.c:2478 +#: gio/glocalfileinfo.c:2474 #, c-format msgid "Error setting SELinux context: %s" msgstr "Erreur lors de la définition du contexte SELinux : %s" -#: gio/glocalfileinfo.c:2485 +#: gio/glocalfileinfo.c:2481 msgid "SELinux is not enabled on this system" msgstr "SELinux n’est pas activé sur ce système" -#: gio/glocalfileinfo.c:2577 +#: gio/glocalfileinfo.c:2573 #, c-format msgid "Setting attribute %s not supported" msgstr "La définition de l’attribut %s n’est pas prise en charge" @@ -3350,15 +3355,15 @@ msgid "Invalid domain" msgstr "Domaine non valide" -#: gio/gresource.c:622 gio/gresource.c:881 gio/gresource.c:920 -#: gio/gresource.c:1044 gio/gresource.c:1116 gio/gresource.c:1189 -#: gio/gresource.c:1259 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresource.c:644 gio/gresource.c:903 gio/gresource.c:942 +#: gio/gresource.c:1066 gio/gresource.c:1138 gio/gresource.c:1211 +#: gio/gresource.c:1281 gio/gresourcefile.c:476 gio/gresourcefile.c:599 #: gio/gresourcefile.c:736 #, c-format msgid "The resource at “%s” does not exist" msgstr "La ressource dans « %s » n’existe pas" -#: gio/gresource.c:787 +#: gio/gresource.c:809 #, c-format msgid "The resource at “%s” failed to decompress" msgstr "La décompression de la ressource dans « %s » n’a pas réussi" @@ -4029,7 +4034,7 @@ msgid "Unknown SOCKSv5 proxy error." msgstr "Erreur inconnue du serveur mandataire SOCKSv5." -#: gio/gthemedicon.c:518 +#: gio/gthemedicon.c:595 #, c-format msgid "Can’t handle version %d of GThemedIcon encoding" msgstr "Impossible de gérer la version %d du codage GThemedIcon" @@ -4168,7 +4173,7 @@ msgid "Error closing file descriptor: %s" msgstr "Erreur de fermeture du descripteur de fichier : %s" -#: gio/gunixmounts.c:2589 gio/gunixmounts.c:2642 +#: gio/gunixmounts.c:2606 gio/gunixmounts.c:2659 msgid "Filesystem root" msgstr "Racine du système de fichiers" @@ -4293,7 +4298,7 @@ #: glib/gbookmarkfile.c:2968 glib/gbookmarkfile.c:3158 #: glib/gbookmarkfile.c:3234 glib/gbookmarkfile.c:3402 #: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3580 -#: glib/gbookmarkfile.c:3696 +#: glib/gbookmarkfile.c:3699 #, c-format msgid "No bookmark found for URI “%s”" msgstr "Aucun signet trouvé pour l’URI « %s »" @@ -4328,8 +4333,8 @@ msgid "Unrepresentable character in conversion input" msgstr "Caractère non affichable dans l’entrée du convertisseur" -#: glib/gconvert.c:500 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 -#: glib/gutf8.c:1318 +#: glib/gconvert.c:500 glib/gutf8.c:866 glib/gutf8.c:1078 glib/gutf8.c:1215 +#: glib/gutf8.c:1319 msgid "Partial character sequence at end of input" msgstr "Séquence de caractères incomplète en fin d’entrée" @@ -4351,7 +4356,7 @@ #: glib/gconvert.c:1649 #, c-format msgid "The URI “%s” is not an absolute URI using the “file” scheme" -msgstr "L’URI « %s » n’est pas une URI absolue utilisant le protocole « file »" +msgstr "L’URI « %s » n’est pas un URI absolu utilisant le protocole « file »" #: glib/gconvert.c:1659 #, c-format @@ -4379,25 +4384,25 @@ msgstr "Le nom de chemin « %s » n’est pas un chemin absolu" #. Translators: this is the preferred format for expressing the date and the time -#: glib/gdatetime.c:213 +#: glib/gdatetime.c:214 msgctxt "GDateTime" msgid "%a %b %e %H:%M:%S %Y" msgstr "%a %d %b %Y %T %Z" #. Translators: this is the preferred format for expressing the date -#: glib/gdatetime.c:216 +#: glib/gdatetime.c:217 msgctxt "GDateTime" msgid "%m/%d/%y" msgstr "%d/%m/%y" #. Translators: this is the preferred format for expressing the time -#: glib/gdatetime.c:219 +#: glib/gdatetime.c:220 msgctxt "GDateTime" msgid "%H:%M:%S" msgstr "%H:%M:%S" #. Translators: this is the preferred format for expressing 12 hour time -#: glib/gdatetime.c:222 +#: glib/gdatetime.c:223 msgctxt "GDateTime" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" @@ -4418,62 +4423,62 @@ #. * non-European) there is no difference between the standalone and #. * complete date form. #. -#: glib/gdatetime.c:261 +#: glib/gdatetime.c:262 msgctxt "full month name" msgid "January" msgstr "janvier" -#: glib/gdatetime.c:263 +#: glib/gdatetime.c:264 msgctxt "full month name" msgid "February" msgstr "février" -#: glib/gdatetime.c:265 +#: glib/gdatetime.c:266 msgctxt "full month name" msgid "March" msgstr "mars" -#: glib/gdatetime.c:267 +#: glib/gdatetime.c:268 msgctxt "full month name" msgid "April" msgstr "avril" -#: glib/gdatetime.c:269 +#: glib/gdatetime.c:270 msgctxt "full month name" msgid "May" msgstr "mai" -#: glib/gdatetime.c:271 +#: glib/gdatetime.c:272 msgctxt "full month name" msgid "June" msgstr "juin" -#: glib/gdatetime.c:273 +#: glib/gdatetime.c:274 msgctxt "full month name" msgid "July" msgstr "juillet" -#: glib/gdatetime.c:275 +#: glib/gdatetime.c:276 msgctxt "full month name" msgid "August" msgstr "août" -#: glib/gdatetime.c:277 +#: glib/gdatetime.c:278 msgctxt "full month name" msgid "September" msgstr "septembre" -#: glib/gdatetime.c:279 +#: glib/gdatetime.c:280 msgctxt "full month name" msgid "October" msgstr "octobre" -#: glib/gdatetime.c:281 +#: glib/gdatetime.c:282 msgctxt "full month name" msgid "November" msgstr "novembre" -#: glib/gdatetime.c:283 +#: glib/gdatetime.c:284 msgctxt "full month name" msgid "December" msgstr "décembre" @@ -4495,132 +4500,132 @@ #. * other platform. Here are abbreviated month names in a form #. * appropriate when they are used standalone. #. -#: glib/gdatetime.c:315 +#: glib/gdatetime.c:316 msgctxt "abbreviated month name" msgid "Jan" msgstr "janv." -#: glib/gdatetime.c:317 +#: glib/gdatetime.c:318 msgctxt "abbreviated month name" msgid "Feb" msgstr "févr." -#: glib/gdatetime.c:319 +#: glib/gdatetime.c:320 msgctxt "abbreviated month name" msgid "Mar" msgstr "mars" -#: glib/gdatetime.c:321 +#: glib/gdatetime.c:322 msgctxt "abbreviated month name" msgid "Apr" msgstr "avril" -#: glib/gdatetime.c:323 +#: glib/gdatetime.c:324 msgctxt "abbreviated month name" msgid "May" msgstr "mai" -#: glib/gdatetime.c:325 +#: glib/gdatetime.c:326 msgctxt "abbreviated month name" msgid "Jun" msgstr "juin" -#: glib/gdatetime.c:327 +#: glib/gdatetime.c:328 msgctxt "abbreviated month name" msgid "Jul" msgstr "juil." -#: glib/gdatetime.c:329 +#: glib/gdatetime.c:330 msgctxt "abbreviated month name" msgid "Aug" msgstr "août" -#: glib/gdatetime.c:331 +#: glib/gdatetime.c:332 msgctxt "abbreviated month name" msgid "Sep" msgstr "sept." -#: glib/gdatetime.c:333 +#: glib/gdatetime.c:334 msgctxt "abbreviated month name" msgid "Oct" msgstr "oct." -#: glib/gdatetime.c:335 +#: glib/gdatetime.c:336 msgctxt "abbreviated month name" msgid "Nov" msgstr "nov." -#: glib/gdatetime.c:337 +#: glib/gdatetime.c:338 msgctxt "abbreviated month name" msgid "Dec" msgstr "déc." -#: glib/gdatetime.c:352 +#: glib/gdatetime.c:353 msgctxt "full weekday name" msgid "Monday" msgstr "lundi" -#: glib/gdatetime.c:354 +#: glib/gdatetime.c:355 msgctxt "full weekday name" msgid "Tuesday" msgstr "mardi" -#: glib/gdatetime.c:356 +#: glib/gdatetime.c:357 msgctxt "full weekday name" msgid "Wednesday" msgstr "mercredi" -#: glib/gdatetime.c:358 +#: glib/gdatetime.c:359 msgctxt "full weekday name" msgid "Thursday" msgstr "jeudi" -#: glib/gdatetime.c:360 +#: glib/gdatetime.c:361 msgctxt "full weekday name" msgid "Friday" msgstr "vendredi" -#: glib/gdatetime.c:362 +#: glib/gdatetime.c:363 msgctxt "full weekday name" msgid "Saturday" msgstr "samedi" -#: glib/gdatetime.c:364 +#: glib/gdatetime.c:365 msgctxt "full weekday name" msgid "Sunday" msgstr "dimanche" -#: glib/gdatetime.c:379 +#: glib/gdatetime.c:380 msgctxt "abbreviated weekday name" msgid "Mon" msgstr "lun." -#: glib/gdatetime.c:381 +#: glib/gdatetime.c:382 msgctxt "abbreviated weekday name" msgid "Tue" msgstr "mar." -#: glib/gdatetime.c:383 +#: glib/gdatetime.c:384 msgctxt "abbreviated weekday name" msgid "Wed" msgstr "mer." -#: glib/gdatetime.c:385 +#: glib/gdatetime.c:386 msgctxt "abbreviated weekday name" msgid "Thu" msgstr "jeu." -#: glib/gdatetime.c:387 +#: glib/gdatetime.c:388 msgctxt "abbreviated weekday name" msgid "Fri" msgstr "ven." -#: glib/gdatetime.c:389 +#: glib/gdatetime.c:390 msgctxt "abbreviated weekday name" msgid "Sat" msgstr "sam." -#: glib/gdatetime.c:391 +#: glib/gdatetime.c:392 msgctxt "abbreviated weekday name" msgid "Sun" msgstr "dim." @@ -4642,62 +4647,62 @@ #. * (western European, non-European) there is no difference between the #. * standalone and complete date form. #. -#: glib/gdatetime.c:455 +#: glib/gdatetime.c:456 msgctxt "full month name with day" msgid "January" msgstr "janvier" -#: glib/gdatetime.c:457 +#: glib/gdatetime.c:458 msgctxt "full month name with day" msgid "February" msgstr "février" -#: glib/gdatetime.c:459 +#: glib/gdatetime.c:460 msgctxt "full month name with day" msgid "March" msgstr "mars" -#: glib/gdatetime.c:461 +#: glib/gdatetime.c:462 msgctxt "full month name with day" msgid "April" msgstr "avril" -#: glib/gdatetime.c:463 +#: glib/gdatetime.c:464 msgctxt "full month name with day" msgid "May" msgstr "mai" -#: glib/gdatetime.c:465 +#: glib/gdatetime.c:466 msgctxt "full month name with day" msgid "June" msgstr "juin" -#: glib/gdatetime.c:467 +#: glib/gdatetime.c:468 msgctxt "full month name with day" msgid "July" msgstr "juillet" -#: glib/gdatetime.c:469 +#: glib/gdatetime.c:470 msgctxt "full month name with day" msgid "August" msgstr "août" -#: glib/gdatetime.c:471 +#: glib/gdatetime.c:472 msgctxt "full month name with day" msgid "September" msgstr "septembre" -#: glib/gdatetime.c:473 +#: glib/gdatetime.c:474 msgctxt "full month name with day" msgid "October" msgstr "octobre" -#: glib/gdatetime.c:475 +#: glib/gdatetime.c:476 msgctxt "full month name with day" msgid "November" msgstr "novembre" -#: glib/gdatetime.c:477 +#: glib/gdatetime.c:478 msgctxt "full month name with day" msgid "December" msgstr "décembre" @@ -4719,74 +4724,74 @@ #. * month names almost ready to copy and paste here. In other systems #. * due to a bug the result is incorrect in some languages. #. -#: glib/gdatetime.c:542 +#: glib/gdatetime.c:543 msgctxt "abbreviated month name with day" msgid "Jan" msgstr "janv." -#: glib/gdatetime.c:544 +#: glib/gdatetime.c:545 msgctxt "abbreviated month name with day" msgid "Feb" msgstr "févr." -#: glib/gdatetime.c:546 +#: glib/gdatetime.c:547 msgctxt "abbreviated month name with day" msgid "Mar" msgstr "mars" -#: glib/gdatetime.c:548 +#: glib/gdatetime.c:549 msgctxt "abbreviated month name with day" msgid "Apr" msgstr "avril" -#: glib/gdatetime.c:550 +#: glib/gdatetime.c:551 msgctxt "abbreviated month name with day" msgid "May" msgstr "mai" -#: glib/gdatetime.c:552 +#: glib/gdatetime.c:553 msgctxt "abbreviated month name with day" msgid "Jun" msgstr "juin" -#: glib/gdatetime.c:554 +#: glib/gdatetime.c:555 msgctxt "abbreviated month name with day" msgid "Jul" msgstr "juil." -#: glib/gdatetime.c:556 +#: glib/gdatetime.c:557 msgctxt "abbreviated month name with day" msgid "Aug" msgstr "août" -#: glib/gdatetime.c:558 +#: glib/gdatetime.c:559 msgctxt "abbreviated month name with day" msgid "Sep" msgstr "sept." -#: glib/gdatetime.c:560 +#: glib/gdatetime.c:561 msgctxt "abbreviated month name with day" msgid "Oct" msgstr "oct." -#: glib/gdatetime.c:562 +#: glib/gdatetime.c:563 msgctxt "abbreviated month name with day" msgid "Nov" msgstr "nov." -#: glib/gdatetime.c:564 +#: glib/gdatetime.c:565 msgctxt "abbreviated month name with day" msgid "Dec" msgstr "déc." #. Translators: 'before midday' indicator -#: glib/gdatetime.c:581 +#: glib/gdatetime.c:582 msgctxt "GDateTime" msgid "AM" msgstr "AM" #. Translators: 'after midday' indicator -#: glib/gdatetime.c:584 +#: glib/gdatetime.c:585 msgctxt "GDateTime" msgid "PM" msgstr "PM" @@ -4879,25 +4884,25 @@ msgid "Failed to read the symbolic link “%s”: %s" msgstr "La lecture du lien symbolique « %s » a échoué : %s" -#: glib/giochannel.c:1389 +#: glib/giochannel.c:1390 #, c-format msgid "Could not open converter from “%s” to “%s”: %s" msgstr "Impossible d’ouvrir le convertisseur de « %s » vers « %s » : %s" -#: glib/giochannel.c:1734 +#: glib/giochannel.c:1735 msgid "Can’t do a raw read in g_io_channel_read_line_string" msgstr "" "Lecture de données brutes impossible dans g_io_channel_read_line_string" -#: glib/giochannel.c:1781 glib/giochannel.c:2039 glib/giochannel.c:2126 +#: glib/giochannel.c:1782 glib/giochannel.c:2040 glib/giochannel.c:2127 msgid "Leftover unconverted data in read buffer" msgstr "Données restantes non converties dans le tampon de lecture" -#: glib/giochannel.c:1862 glib/giochannel.c:1939 +#: glib/giochannel.c:1863 glib/giochannel.c:1940 msgid "Channel terminates in a partial character" msgstr "La canal se termine avec un caractère partiel" -#: glib/giochannel.c:1925 +#: glib/giochannel.c:1926 msgid "Can’t do a raw read in g_io_channel_read_to_end" msgstr "Lecture de données brutes impossible dans g_io_channel_read_to_end" @@ -4911,7 +4916,7 @@ msgid "Not a regular file" msgstr "N’est pas un fichier standard" -#: glib/gkeyfile.c:1270 +#: glib/gkeyfile.c:1274 #, c-format msgid "" "Key file contains line “%s” which is not a key-value pair, group, or comment" @@ -4919,46 +4924,46 @@ "Le fichier de clés contient la ligne « %s » qui n’est ni une paire de " "valeurs de clé, ni un groupe, ni un commentaire" -#: glib/gkeyfile.c:1327 +#: glib/gkeyfile.c:1331 #, c-format msgid "Invalid group name: %s" msgstr "Nom de groupe non valide : %s" -#: glib/gkeyfile.c:1349 +#: glib/gkeyfile.c:1353 msgid "Key file does not start with a group" msgstr "Le fichier de clés ne débute pas par un groupe" -#: glib/gkeyfile.c:1375 +#: glib/gkeyfile.c:1379 #, c-format msgid "Invalid key name: %s" msgstr "Nom de clé non valide : %s" -#: glib/gkeyfile.c:1402 +#: glib/gkeyfile.c:1406 #, c-format msgid "Key file contains unsupported encoding “%s”" msgstr "" "Le fichier de clés contient un codage de caractères non pris en charge « %s »" -#: glib/gkeyfile.c:1645 glib/gkeyfile.c:1818 glib/gkeyfile.c:3271 -#: glib/gkeyfile.c:3334 glib/gkeyfile.c:3464 glib/gkeyfile.c:3594 -#: glib/gkeyfile.c:3738 glib/gkeyfile.c:3967 glib/gkeyfile.c:4034 +#: glib/gkeyfile.c:1649 glib/gkeyfile.c:1822 glib/gkeyfile.c:3275 +#: glib/gkeyfile.c:3338 glib/gkeyfile.c:3468 glib/gkeyfile.c:3598 +#: glib/gkeyfile.c:3742 glib/gkeyfile.c:3971 glib/gkeyfile.c:4038 #, c-format msgid "Key file does not have group “%s”" msgstr "Le fichier de clés n’a pas de groupe « %s »" -#: glib/gkeyfile.c:1773 +#: glib/gkeyfile.c:1777 #, c-format msgid "Key file does not have key “%s” in group “%s”" msgstr "Le fichier de clés ne contient pas de clé « %s » dans le groupe « %s »" -#: glib/gkeyfile.c:1935 glib/gkeyfile.c:2051 +#: glib/gkeyfile.c:1939 glib/gkeyfile.c:2055 #, c-format msgid "Key file contains key “%s” with value “%s” which is not UTF-8" msgstr "" "Le fichier de clés contient la clé « %s » avec la valeur « %s » qui n’est " "pas codé en UTF-8" -#: glib/gkeyfile.c:1955 glib/gkeyfile.c:2071 glib/gkeyfile.c:2513 +#: glib/gkeyfile.c:1959 glib/gkeyfile.c:2075 glib/gkeyfile.c:2517 #, c-format msgid "" "Key file contains key “%s” which has a value that cannot be interpreted." @@ -4966,7 +4971,7 @@ "Le fichier de clés contient la clé « %s » dont une valeur est impossible à " "interpréter." -#: glib/gkeyfile.c:2731 glib/gkeyfile.c:3100 +#: glib/gkeyfile.c:2735 glib/gkeyfile.c:3104 #, c-format msgid "" "Key file contains key “%s” in group “%s” which has a value that cannot be " @@ -4975,41 +4980,41 @@ "Le fichier de clés contient la clé « %s » dans le groupe « %s » qui a une " "valeur impossible à interpréter." -#: glib/gkeyfile.c:2809 glib/gkeyfile.c:2886 +#: glib/gkeyfile.c:2813 glib/gkeyfile.c:2890 #, c-format msgid "Key “%s” in group “%s” has value “%s” where %s was expected" msgstr "" "La clé « %s » dans le groupe « %s » a une valeur « %s » alors que %s était " "attendu" -#: glib/gkeyfile.c:4274 +#: glib/gkeyfile.c:4278 msgid "Key file contains escape character at end of line" msgstr "Le fichier de clés contient un caractère d’échappement en fin de ligne" -#: glib/gkeyfile.c:4296 +#: glib/gkeyfile.c:4300 #, c-format msgid "Key file contains invalid escape sequence “%s”" msgstr "" "Le fichier de clés contient une séquence d’échappement non valide « %s »" -#: glib/gkeyfile.c:4440 +#: glib/gkeyfile.c:4444 #, c-format msgid "Value “%s” cannot be interpreted as a number." msgstr "La valeur « %s » ne peut pas être interprétée comme un nombre." -#: glib/gkeyfile.c:4454 +#: glib/gkeyfile.c:4458 #, c-format msgid "Integer value “%s” out of range" msgstr "La valeur entière « %s » est hors plage" -#: glib/gkeyfile.c:4487 +#: glib/gkeyfile.c:4491 #, c-format msgid "Value “%s” cannot be interpreted as a float number." msgstr "" "La valeur « %s » ne peut pas être interprétée comme un nombre à virgule " "flottante." -#: glib/gkeyfile.c:4526 +#: glib/gkeyfile.c:4530 #, c-format msgid "Value “%s” cannot be interpreted as a boolean." msgstr "La valeur « %s » ne peut pas être interprétée comme un booléen." @@ -5031,32 +5036,32 @@ msgid "Failed to open file “%s”: open() failed: %s" msgstr "L’ouverture du fichier « %s » a échoué : échec de open() : %s" -#: glib/gmarkup.c:397 glib/gmarkup.c:439 +#: glib/gmarkup.c:398 glib/gmarkup.c:440 #, c-format msgid "Error on line %d char %d: " msgstr "Erreur à la ligne %d, caractère %d : " -#: glib/gmarkup.c:461 glib/gmarkup.c:544 +#: glib/gmarkup.c:462 glib/gmarkup.c:545 #, c-format msgid "Invalid UTF-8 encoded text in name — not valid “%s”" msgstr "Codage UTF-8 non valide dans le nom — « %s » n’est pas valide" -#: glib/gmarkup.c:472 +#: glib/gmarkup.c:473 #, c-format msgid "“%s” is not a valid name" msgstr "« %s » n’est pas un nom valide" -#: glib/gmarkup.c:488 +#: glib/gmarkup.c:489 #, c-format msgid "“%s” is not a valid name: “%c”" msgstr "« %s » n’est pas un nom valide : « %c »" -#: glib/gmarkup.c:610 +#: glib/gmarkup.c:613 #, c-format msgid "Error on line %d: %s" msgstr "Erreur à la ligne %d : %s" -#: glib/gmarkup.c:687 +#: glib/gmarkup.c:690 #, c-format msgid "" "Failed to parse “%-.*s”, which should have been a digit inside a character " @@ -5066,7 +5071,7 @@ "référence des caractères (ê par exemple) — peut-être que le nombre est " "trop grand" -#: glib/gmarkup.c:699 +#: glib/gmarkup.c:702 msgid "" "Character reference did not end with a semicolon; most likely you used an " "ampersand character without intending to start an entity — escape ampersand " @@ -5076,24 +5081,24 @@ "vraisemblablement utilisé une esperluette sans intention d’écrire une entité " "— échappez l’esperluette avec &" -#: glib/gmarkup.c:725 +#: glib/gmarkup.c:728 #, c-format msgid "Character reference “%-.*s” does not encode a permitted character" msgstr "La référence au caractère « %-.*s » ne code pas un caractère autorisé" -#: glib/gmarkup.c:763 +#: glib/gmarkup.c:766 msgid "" "Empty entity “&;” seen; valid entities are: & " < > '" msgstr "" "Entité vide « &; » rencontrée ; les entités valides sont : & " < " "> '" -#: glib/gmarkup.c:771 +#: glib/gmarkup.c:774 #, c-format msgid "Entity name “%-.*s” is not known" msgstr "L’entité nommée « %-.*s » est inconnue" -#: glib/gmarkup.c:776 +#: glib/gmarkup.c:779 msgid "" "Entity did not end with a semicolon; most likely you used an ampersand " "character without intending to start an entity — escape ampersand as &" @@ -5102,11 +5107,11 @@ "utilisé une esperluette sans intention d’écrire une entité — échappez " "l’esperluette avec &" -#: glib/gmarkup.c:1182 +#: glib/gmarkup.c:1187 msgid "Document must begin with an element (e.g. )" msgstr "Le document doit commencer avec un élément (par ex. )" -#: glib/gmarkup.c:1222 +#: glib/gmarkup.c:1227 #, c-format msgid "" "“%s” is not a valid character following a “<” character; it may not begin an " @@ -5115,7 +5120,7 @@ "« %s » n’est pas un caractère valide à la suite du caractère « < » ; il ne " "semble pas commencer un nom d’élément" -#: glib/gmarkup.c:1264 +#: glib/gmarkup.c:1270 #, c-format msgid "" "Odd character “%s”, expected a “>” character to end the empty-element tag " @@ -5124,7 +5129,7 @@ "Caractère anormal « %s », un caractère « > » est requis pour terminer la " "balise d’élément vide « %s »" -#: glib/gmarkup.c:1345 +#: glib/gmarkup.c:1352 #, c-format msgid "" "Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”" @@ -5132,7 +5137,7 @@ "Caractère anormal « %s », un caractère « = » est requis après le nom de " "l’attribut « %s » de l’élément « %s »" -#: glib/gmarkup.c:1386 +#: glib/gmarkup.c:1394 #, c-format msgid "" "Odd character “%s”, expected a “>” or “/” character to end the start tag of " @@ -5144,7 +5149,7 @@ "« %s » ; peut-être avez-vous utilisé un caractère non valide dans un nom " "d’attribut" -#: glib/gmarkup.c:1430 +#: glib/gmarkup.c:1439 #, c-format msgid "" "Odd character “%s”, expected an open quote mark after the equals sign when " @@ -5153,7 +5158,7 @@ "Caractère anormal « %s », un guillemet d’ouverture après le signe égal est " "requis quand on affecte une valeur à l’attribut « %s » de l’élément « %s »" -#: glib/gmarkup.c:1563 +#: glib/gmarkup.c:1573 #, c-format msgid "" "“%s” is not a valid character following the characters “ »" -#: glib/gmarkup.c:1610 +#: glib/gmarkup.c:1623 #, c-format msgid "Element “%s” was closed, no element is currently open" msgstr "L’élément « %s » a été fermé, aucun élément n’est actuellement ouvert" -#: glib/gmarkup.c:1619 +#: glib/gmarkup.c:1632 #, c-format msgid "Element “%s” was closed, but the currently open element is “%s”" msgstr "" "L’élément « %s » a été fermé, mais l’élément actuellement ouvert est « %s »" -#: glib/gmarkup.c:1772 +#: glib/gmarkup.c:1785 msgid "Document was empty or contained only whitespace" msgstr "Le document était vide ou ne contenait que des espaces" -#: glib/gmarkup.c:1786 +#: glib/gmarkup.c:1799 msgid "Document ended unexpectedly just after an open angle bracket “<”" msgstr "" "Le document s’est terminé de manière inattendue juste après un crochet " "ouvrant « < »" -#: glib/gmarkup.c:1794 glib/gmarkup.c:1839 +#: glib/gmarkup.c:1807 glib/gmarkup.c:1852 #, c-format msgid "" "Document ended unexpectedly with elements still open — “%s” was the last " @@ -5201,7 +5206,7 @@ "Le document s’est terminé de manière inattendue avec des éléments encore " "ouverts — « %s » était le dernier élément ouvert" -#: glib/gmarkup.c:1802 +#: glib/gmarkup.c:1815 #, c-format msgid "" "Document ended unexpectedly, expected to see a close angle bracket ending " @@ -5210,25 +5215,25 @@ "Le document s’est terminé de manière inattendue, un crochet fermant pour la " "balise <%s/> est requis" -#: glib/gmarkup.c:1808 +#: glib/gmarkup.c:1821 msgid "Document ended unexpectedly inside an element name" msgstr "" "Le document s’est terminé de manière inattendue à l’intérieur d’un nom " "d’élément" -#: glib/gmarkup.c:1814 +#: glib/gmarkup.c:1827 msgid "Document ended unexpectedly inside an attribute name" msgstr "" "Le document s’est terminé de manière inattendue à l’intérieur d’un nom " "d’attribut" -#: glib/gmarkup.c:1819 +#: glib/gmarkup.c:1832 msgid "Document ended unexpectedly inside an element-opening tag." msgstr "" "Le document s’est terminé de manière inattendue à l’intérieur d’une balise " "d’ouverture d’élément." -#: glib/gmarkup.c:1825 +#: glib/gmarkup.c:1838 msgid "" "Document ended unexpectedly after the equals sign following an attribute " "name; no attribute value" @@ -5236,27 +5241,27 @@ "Le document s’est terminé de manière inattendue après le signe égal suivant " "un nom d’attribut ; aucune valeur d’attribut" -#: glib/gmarkup.c:1832 +#: glib/gmarkup.c:1845 msgid "Document ended unexpectedly while inside an attribute value" msgstr "" "Le document s’est terminé de manière inattendue alors qu’il était à " "l’intérieur d’une valeur d’attribut" -#: glib/gmarkup.c:1849 +#: glib/gmarkup.c:1862 #, c-format msgid "Document ended unexpectedly inside the close tag for element “%s”" msgstr "" "Le document s’est terminé de manière inattendue à l’intérieur de la balise " "de fermeture pour l’élément « %s »" -#: glib/gmarkup.c:1853 +#: glib/gmarkup.c:1866 msgid "" "Document ended unexpectedly inside the close tag for an unopened element" msgstr "" "Le document s’est terminé de manière inattendue à l’intérieur de la balise " "de fermeture pour un élément non ouvert" -#: glib/gmarkup.c:1859 +#: glib/gmarkup.c:1872 msgid "Document ended unexpectedly inside a comment or processing instruction" msgstr "" "Le document s’est terminé de manière inattendue à l’intérieur d’un " @@ -5492,7 +5497,7 @@ #: glib/gregex.c:418 msgid "character value in \\x{...} sequence is too large" -msgstr "la valeur du caractère dans la séquence \\x{...} est trop grande" +msgstr "la valeur du caractère dans la séquence \\x{…} est trop grande" #: glib/gregex.c:421 msgid "invalid condition (?(0)" @@ -5594,7 +5599,7 @@ #: glib/gregex.c:498 msgid "] is an invalid data character in JavaScript compatibility mode" msgstr "" -"] est un caractère de données invalide en mode de compatibilité JavaScript" +"] est un caractère de données non valide en mode de compatibilité JavaScript" #: glib/gregex.c:501 msgid "different names for subpatterns of the same number are not allowed" @@ -5732,85 +5737,85 @@ msgid "Text was empty (or contained only whitespace)" msgstr "Le texte était vide (ou ne contenait que des espaces)" -#: glib/gspawn.c:302 +#: glib/gspawn.c:315 #, c-format msgid "Failed to read data from child process (%s)" msgstr "La lecture des données depuis le processus fils a échoué (%s)" -#: glib/gspawn.c:450 +#: glib/gspawn.c:463 #, c-format msgid "Unexpected error in select() reading data from a child process (%s)" msgstr "" "Erreur inattendue dans select() à la lecture des données depuis un processus " "fils (%s)" -#: glib/gspawn.c:535 +#: glib/gspawn.c:548 #, c-format msgid "Unexpected error in waitpid() (%s)" msgstr "Erreur inattendue dans waitpid() (%s)" -#: glib/gspawn.c:1043 glib/gspawn-win32.c:1318 +#: glib/gspawn.c:1056 glib/gspawn-win32.c:1318 #, c-format msgid "Child process exited with code %ld" msgstr "Le processus fils s’est terminé avec le code %ld" -#: glib/gspawn.c:1051 +#: glib/gspawn.c:1064 #, c-format msgid "Child process killed by signal %ld" msgstr "Le processus fils a été tué par le signal %ld" -#: glib/gspawn.c:1058 +#: glib/gspawn.c:1071 #, c-format msgid "Child process stopped by signal %ld" msgstr "Le processus fils a été arrêté par le signal %ld" -#: glib/gspawn.c:1065 +#: glib/gspawn.c:1078 #, c-format msgid "Child process exited abnormally" msgstr "Le processus fils s’est terminé anormalement" -#: glib/gspawn.c:1360 glib/gspawn-win32.c:339 glib/gspawn-win32.c:347 +#: glib/gspawn.c:1405 glib/gspawn-win32.c:339 glib/gspawn-win32.c:347 #, c-format msgid "Failed to read from child pipe (%s)" msgstr "La lecture depuis un tube fils a échoué (%s)" -#: glib/gspawn.c:1596 +#: glib/gspawn.c:1653 #, c-format msgid "Failed to spawn child process “%s” (%s)" msgstr "L’exécution du processus fils « %s » a échoué (%s)" -#: glib/gspawn.c:1635 +#: glib/gspawn.c:1692 #, c-format msgid "Failed to fork (%s)" msgstr "Le clonage a échoué (%s)" -#: glib/gspawn.c:1784 glib/gspawn-win32.c:370 +#: glib/gspawn.c:1841 glib/gspawn-win32.c:370 #, c-format msgid "Failed to change to directory “%s” (%s)" msgstr "Le changement de répertoire « %s » a échoué (%s)" -#: glib/gspawn.c:1794 +#: glib/gspawn.c:1851 #, c-format msgid "Failed to execute child process “%s” (%s)" msgstr "L’exécution du processus fils « %s » a échoué (%s)" -#: glib/gspawn.c:1804 +#: glib/gspawn.c:1861 #, c-format msgid "Failed to redirect output or input of child process (%s)" msgstr "" "La redirection de la sortie ou de l’entrée du processus fils a échoué (%s)" -#: glib/gspawn.c:1813 +#: glib/gspawn.c:1870 #, c-format msgid "Failed to fork child process (%s)" msgstr "Le clonage du processus fils a échoué (%s)" -#: glib/gspawn.c:1821 +#: glib/gspawn.c:1878 #, c-format msgid "Unknown error executing child process “%s”" msgstr "Erreur inconnue à l’exécution du processus fils « %s »" -#: glib/gspawn.c:1845 +#: glib/gspawn.c:1902 #, c-format msgid "Failed to read enough data from child pid pipe (%s)" msgstr "" @@ -5884,20 +5889,20 @@ msgid "“%s” is not an unsigned number" msgstr "« %s » n’est pas un nombre non signé" -#: glib/gutf8.c:811 +#: glib/gutf8.c:812 msgid "Failed to allocate memory" msgstr "Impossible d’allouer de la mémoire" -#: glib/gutf8.c:944 +#: glib/gutf8.c:945 msgid "Character out of range for UTF-8" msgstr "Caractère hors plage pour UTF-8" -#: glib/gutf8.c:1045 glib/gutf8.c:1054 glib/gutf8.c:1184 glib/gutf8.c:1193 -#: glib/gutf8.c:1332 glib/gutf8.c:1429 +#: glib/gutf8.c:1046 glib/gutf8.c:1055 glib/gutf8.c:1185 glib/gutf8.c:1194 +#: glib/gutf8.c:1333 glib/gutf8.c:1430 msgid "Invalid sequence in conversion input" msgstr "Séquence non valide dans l’entrée du convertisseur" -#: glib/gutf8.c:1343 glib/gutf8.c:1440 +#: glib/gutf8.c:1344 glib/gutf8.c:1441 msgid "Character out of range for UTF-16" msgstr "Caractère hors plage pour UTF-16" diff -Nru glib2.0-2.59.2/po/.gitignore glib2.0-2.59.3/po/.gitignore --- glib2.0-2.59.2/po/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -POTFILES -*.gmo -glib20.pot diff -Nru glib2.0-2.59.2/po/id.po glib2.0-2.59.3/po/id.po --- glib2.0-2.59.2/po/id.po 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/id.po 2019-03-04 09:01:42.000000000 +0000 @@ -9,33 +9,37 @@ msgstr "" "Project-Id-Version: glib master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" -"POT-Creation-Date: 2018-08-17 12:52+0000\n" -"PO-Revision-Date: 2018-08-22 14:25+0700\n" +"POT-Creation-Date: 2019-02-12 14:26+0000\n" +"PO-Revision-Date: 2019-02-14 22:06+0700\n" "Last-Translator: Kukuh Syafaat \n" "Language-Team: Indonesian \n" "Language: id\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 2.0.6\n" +"Plural-Forms: nplurals=2; plural= n!=1;\n" +"X-Generator: Poedit 2.2.1\n" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "GApplication options" msgstr "Opsi GApplication" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "Show GApplication options" msgstr "Tunjukkan opsi GApplication" -#: gio/gapplication.c:541 +#: gio/gapplication.c:544 msgid "Enter GApplication service mode (use from D-Bus service files)" msgstr "Masuk mode layanan GApplication (pakai dari berkas layanan D-Bus)" -#: gio/gapplication.c:553 +#: gio/gapplication.c:556 msgid "Override the application’s ID" msgstr "Timpa ID aplikasi" +#: gio/gapplication.c:568 +msgid "Replace the running instance" +msgstr "Ganti instance yang berjalan" + #: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 #: gio/gresource-tool.c:495 gio/gsettings-tool.c:569 msgid "Print help" @@ -112,8 +116,8 @@ msgid "Application identifier in D-Bus format (eg: org.example.viewer)" msgstr "Identifier aplikasi dalam format D-Bus (mis: org.example.viewer)" -#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:737 -#: gio/glib-compile-resources.c:743 gio/glib-compile-resources.c:770 +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 #: gio/gresource-tool.c:502 gio/gresource-tool.c:568 msgid "FILE" msgstr "BERKAS" @@ -251,8 +255,8 @@ #: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 #: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 -#: gio/ginputstream.c:1019 gio/goutputstream.c:203 gio/goutputstream.c:834 -#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:209 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 #, c-format msgid "Too large count value passed to %s" msgstr "Nilai cacah yang dilewatkan ke %s terlalu besar" @@ -267,7 +271,7 @@ msgstr "Tak bisa memenggal GBufferedInputStream" #: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 -#: gio/goutputstream.c:1661 +#: gio/goutputstream.c:2198 msgid "Stream is already closed" msgstr "Stream telah ditutup" @@ -275,7 +279,7 @@ msgid "Truncate not supported on base stream" msgstr "Pemenggalan tak didukung pada stream basis" -#: gio/gcancellable.c:317 gio/gdbusconnection.c:1840 gio/gdbusprivate.c:1402 +#: gio/gcancellable.c:317 gio/gdbusconnection.c:1867 gio/gdbusprivate.c:1402 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 #, c-format msgid "Operation was cancelled" @@ -294,33 +298,33 @@ msgstr "Tak cukup ruang di tujuan" #: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 -#: gio/gdatainputstream.c:1261 glib/gconvert.c:454 glib/gconvert.c:883 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:455 glib/gconvert.c:885 #: glib/giochannel.c:1557 glib/giochannel.c:1599 glib/giochannel.c:2443 #: glib/gutf8.c:869 glib/gutf8.c:1322 msgid "Invalid byte sequence in conversion input" msgstr "Rangkaian bita dalam input konversi tidak benar" -#: gio/gcharsetconverter.c:347 glib/gconvert.c:462 glib/gconvert.c:797 +#: gio/gcharsetconverter.c:347 glib/gconvert.c:463 glib/gconvert.c:799 #: glib/giochannel.c:1564 glib/giochannel.c:2455 #, c-format msgid "Error during conversion: %s" msgstr "Galat ketika konversi: %s" -#: gio/gcharsetconverter.c:445 gio/gsocket.c:1104 +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1093 msgid "Cancellable initialization not supported" msgstr "Inisialisasi yang dapat dibatalkan tak didukung" -#: gio/gcharsetconverter.c:456 glib/gconvert.c:327 glib/giochannel.c:1385 +#: gio/gcharsetconverter.c:456 glib/gconvert.c:328 glib/giochannel.c:1385 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported" msgstr "Konversi dari gugus karakter \"%s\" ke \"%s\" tak didukung" -#: gio/gcharsetconverter.c:460 glib/gconvert.c:331 +#: gio/gcharsetconverter.c:460 glib/gconvert.c:332 #, c-format msgid "Could not open converter from “%s” to “%s”" msgstr "Tidak dapat membuka pengubah dari \"%s\" ke \"%s\"" -#: gio/gcontenttype.c:358 +#: gio/gcontenttype.c:452 #, c-format msgid "%s type" msgstr "tipe %s" @@ -451,7 +455,7 @@ #: gio/gdbusaddress.c:746 #, c-format msgid "Error reading from nonce file “%s”, expected 16 bytes, got %d" -msgstr "Galat saat membaca berkas nonce \"%s\", berharap 16 byte, mendapat %d" +msgstr "Galat saat membaca berkas nonce \"%s\", berharap 16 bita, mendapat %d" #: gio/gdbusaddress.c:764 #, c-format @@ -497,7 +501,7 @@ msgstr "" "Tidak bisa menentukan alamat bus sesi (tidak diimplementasi bagi OS ini)" -#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7142 +#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7174 #, c-format msgid "" "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " @@ -506,7 +510,7 @@ "Tak bisa menentukan alamat bus dari variabel lingkungan " "DBUS_STARTER_BUS_TYPE — nilai tak dikenal \"%s\"" -#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7151 +#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7183 msgid "" "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " "variable is not set" @@ -618,21 +622,21 @@ msgid "(Additionally, releasing the lock for “%s” also failed: %s) " msgstr "(Selain itu, melepas kunci bagi \"%s\" juga gagal: %s) " -#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2369 +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2396 msgid "The connection is closed" msgstr "Sambungan tertutup" -#: gio/gdbusconnection.c:1870 +#: gio/gdbusconnection.c:1897 msgid "Timeout was reached" msgstr "Kehabisan waktu" -#: gio/gdbusconnection.c:2491 +#: gio/gdbusconnection.c:2518 msgid "" "Unsupported flags encountered when constructing a client-side connection" msgstr "" "Ditemui flag yang tak didukung ketika membangun sambungan di sisi klien" -#: gio/gdbusconnection.c:4115 gio/gdbusconnection.c:4462 +#: gio/gdbusconnection.c:4147 gio/gdbusconnection.c:4494 #, c-format msgid "" "No such interface “org.freedesktop.DBus.Properties” on object at path %s" @@ -640,101 +644,101 @@ "Tidak ada antarmuka \"org.freedesktop.DBus.Properties\" pada objek pada path " "%s" -#: gio/gdbusconnection.c:4257 +#: gio/gdbusconnection.c:4289 #, c-format msgid "No such property “%s”" msgstr "Tak ada properti \"%s\"" -#: gio/gdbusconnection.c:4269 +#: gio/gdbusconnection.c:4301 #, c-format msgid "Property “%s” is not readable" msgstr "Properti \"%s\" tidak dapat dibaca" -#: gio/gdbusconnection.c:4280 +#: gio/gdbusconnection.c:4312 #, c-format msgid "Property “%s” is not writable" msgstr "Properti \"%s\" tidak dapat ditulisi" -#: gio/gdbusconnection.c:4300 +#: gio/gdbusconnection.c:4332 #, c-format msgid "Error setting property “%s”: Expected type “%s” but got “%s”" msgstr "" "Galat menata properti \"%s\": Tipe yang diharapkan \"%s\" tapi diperoleh \"%s" "\"" -#: gio/gdbusconnection.c:4405 gio/gdbusconnection.c:4613 -#: gio/gdbusconnection.c:6582 +#: gio/gdbusconnection.c:4437 gio/gdbusconnection.c:4645 +#: gio/gdbusconnection.c:6614 #, c-format msgid "No such interface “%s”" msgstr "Tak ada antarmuka \"%s\"" -#: gio/gdbusconnection.c:4831 gio/gdbusconnection.c:7091 +#: gio/gdbusconnection.c:4863 gio/gdbusconnection.c:7123 #, c-format msgid "No such interface “%s” on object at path %s" msgstr "Tak ada antarmuka \"%s\" pada objek di lokasi %s" -#: gio/gdbusconnection.c:4929 +#: gio/gdbusconnection.c:4961 #, c-format msgid "No such method “%s”" msgstr "Tidak ada metode seperti \"%s\"" -#: gio/gdbusconnection.c:4960 +#: gio/gdbusconnection.c:4992 #, c-format msgid "Type of message, “%s”, does not match expected type “%s”" msgstr "Tipe pesan \"%s\" tak cocok dengan tipe yang diharapkan \"%s\"" -#: gio/gdbusconnection.c:5158 +#: gio/gdbusconnection.c:5190 #, c-format msgid "An object is already exported for the interface %s at %s" msgstr "Suatu objek telah diekspor bagi antar muka %s pada %s" -#: gio/gdbusconnection.c:5384 +#: gio/gdbusconnection.c:5416 #, c-format msgid "Unable to retrieve property %s.%s" msgstr "Tak bisa mengambil properti %s.%s" -#: gio/gdbusconnection.c:5440 +#: gio/gdbusconnection.c:5472 #, c-format msgid "Unable to set property %s.%s" msgstr "Tak bisa menata properti %s.%s" -#: gio/gdbusconnection.c:5618 +#: gio/gdbusconnection.c:5650 #, c-format msgid "Method “%s” returned type “%s”, but expected “%s”" msgstr "Metoda \"%s\" mengembalikan tipe \"%s\", tapi yang diharapkan \"%s\"" -#: gio/gdbusconnection.c:6693 +#: gio/gdbusconnection.c:6725 #, c-format msgid "Method “%s” on interface “%s” with signature “%s” does not exist" msgstr "" "Metoda \"%s\" pada antar muka \"%s\" dengan tanda tangan \"%s\"' tak ada" -#: gio/gdbusconnection.c:6814 +#: gio/gdbusconnection.c:6846 #, c-format msgid "A subtree is already exported for %s" msgstr "Subtree telah diekspor bagi %s" -#: gio/gdbusmessage.c:1248 +#: gio/gdbusmessage.c:1251 msgid "type is INVALID" msgstr "jenisnya INVALID" -#: gio/gdbusmessage.c:1259 +#: gio/gdbusmessage.c:1262 msgid "METHOD_CALL message: PATH or MEMBER header field is missing" msgstr "Pesan METHOD_CALL: ruas header PATH atau MEMBER hilang" -#: gio/gdbusmessage.c:1270 +#: gio/gdbusmessage.c:1273 msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" msgstr "Pesan METHOD_RETURN: ruas header REPLY_SERIAL hilang" -#: gio/gdbusmessage.c:1282 +#: gio/gdbusmessage.c:1285 msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" msgstr "Pesan ERROR: ruas header REPLY_SERIAL atau ERRORN_NAME hilang" -#: gio/gdbusmessage.c:1295 +#: gio/gdbusmessage.c:1298 msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" msgstr "Pesan SIGNAL: ruas header PATH, INTERFACE, atau MEMBER hilang" -#: gio/gdbusmessage.c:1303 +#: gio/gdbusmessage.c:1306 msgid "" "SIGNAL message: The PATH header field is using the reserved value /org/" "freedesktop/DBus/Local" @@ -742,7 +746,7 @@ "Pesan SIGNAL: ruas header PATH memakai nilai khusus /org/freedesktop/DBus/" "Local" -#: gio/gdbusmessage.c:1311 +#: gio/gdbusmessage.c:1314 msgid "" "SIGNAL message: The INTERFACE header field is using the reserved value org." "freedesktop.DBus.Local" @@ -750,38 +754,39 @@ "Pesan SIGNAL: ruas header INTERFACE memakai nilai khusus org.freedesktop." "DBus.Local" -#: gio/gdbusmessage.c:1359 gio/gdbusmessage.c:1419 +#: gio/gdbusmessage.c:1362 gio/gdbusmessage.c:1422 #, c-format msgid "Wanted to read %lu byte but only got %lu" msgid_plural "Wanted to read %lu bytes but only got %lu" msgstr[0] "Ingin membaca %lu bita tapi hanya memperoleh %lu" +msgstr[1] "Ingin membaca %lu bita tapi hanya memperoleh %lu" -#: gio/gdbusmessage.c:1373 +#: gio/gdbusmessage.c:1376 #, c-format msgid "Expected NUL byte after the string “%s” but found byte %d" -msgstr "Mengharapkan byte NUL setelah string \"%s\" tapi menemui byte %d" +msgstr "Mengharapkan bita NUL setelah string \"%s\" tapi menemui bita %d" -#: gio/gdbusmessage.c:1392 +#: gio/gdbusmessage.c:1395 #, c-format msgid "" "Expected valid UTF-8 string but found invalid bytes at byte offset %d " "(length of string is %d). The valid UTF-8 string up until that point was “%s”" msgstr "" -"Berharap string UTF-8 yang valid tapi menjumpai byte tak valid pada lokasi " +"Berharap string UTF-8 yang valid tapi menjumpai bita tak valid pada lokasi " "%d (panjang string adalah %d). String UTF-8 yang valid sampai titik itu " "adalah \"%s\"" -#: gio/gdbusmessage.c:1595 +#: gio/gdbusmessage.c:1598 #, c-format msgid "Parsed value “%s” is not a valid D-Bus object path" msgstr "Nilai terurai \"%s\" bukan lokasi objek D-Bus yang valid" -#: gio/gdbusmessage.c:1617 +#: gio/gdbusmessage.c:1620 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature" msgstr "Nilai terurai \"%s\" bukan tanda tangan D-Bus yang valid" -#: gio/gdbusmessage.c:1664 +#: gio/gdbusmessage.c:1667 #, c-format msgid "" "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." @@ -790,22 +795,25 @@ msgstr[0] "" "Menjumpai larik dengan panjang %u bita. Panjang maksimal adalah 2<<26 bita " "(64 MiB)." +msgstr[1] "" +"Menjumpai larik dengan panjang %u bita. Panjang maksimal adalah 2<<26 bita " +"(64 MiB)." -#: gio/gdbusmessage.c:1684 +#: gio/gdbusmessage.c:1687 #, c-format msgid "" "Encountered array of type “a%c”, expected to have a length a multiple of %u " "bytes, but found to be %u bytes in length" msgstr "" -"Menemui larik bertipe \"a%c\", mengharapkan punya panjang kelipatan %u byte, " -"tapi menemui panjang %u byte" +"Menemui larik bertipe \"a%c\", mengharapkan punya panjang kelipatan %u bita, " +"tapi menemui panjang %u bita" -#: gio/gdbusmessage.c:1851 +#: gio/gdbusmessage.c:1857 #, c-format msgid "Parsed value “%s” for variant is not a valid D-Bus signature" msgstr "Nilai terurai \"%s\" bagi varian bukan tanda tangan D-Bus yang valid" -#: gio/gdbusmessage.c:1875 +#: gio/gdbusmessage.c:1881 #, c-format msgid "" "Error deserializing GVariant with type string “%s” from the D-Bus wire format" @@ -813,7 +821,7 @@ "Galat saat deserialisasi GVariant dengan type string \"%s\" dari format " "kabel D-Bus" -#: gio/gdbusmessage.c:2057 +#: gio/gdbusmessage.c:2066 #, c-format msgid "" "Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value " @@ -822,36 +830,43 @@ "Nilai ke-endian-an tak valid. Berharap 0x6c (\"l\") atau (0x42) \"B\" tapi " "menemui 0x%02x" -#: gio/gdbusmessage.c:2070 +#: gio/gdbusmessage.c:2079 #, c-format msgid "Invalid major protocol version. Expected 1 but found %d" msgstr "Versi protokol mayor tak valid. Berharap 1 tapi menemui %d" -#: gio/gdbusmessage.c:2126 +#: gio/gdbusmessage.c:2132 gio/gdbusmessage.c:2724 +msgid "Signature header found but is not of type signature" +msgstr "Tajuk tanda tangan ditemukan tetapi bukan tipe tanda tangan" + +#: gio/gdbusmessage.c:2144 #, c-format msgid "Signature header with signature “%s” found but message body is empty" msgstr "" "Header tanda tangan dengan tanda tangan \"%s\" ditemukan tapi body pesan " "kosong" -#: gio/gdbusmessage.c:2140 +#: gio/gdbusmessage.c:2159 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature (for body)" msgstr "Nilai terurai \"%s\" bukan tanda tangan D-Bus yang valid (bagi body)" -#: gio/gdbusmessage.c:2170 +#: gio/gdbusmessage.c:2190 #, c-format msgid "No signature header in message but the message body is %u byte" msgid_plural "No signature header in message but the message body is %u bytes" msgstr[0] "" "Tidak terdapat tajuk tanda tangan pada pesan, tetapi panjang badan pesan " "adalah %u bita" +msgstr[1] "" +"Tidak terdapat tajuk tanda tangan pada pesan, tetapi panjang badan pesan " +"adalah %u bita" -#: gio/gdbusmessage.c:2180 +#: gio/gdbusmessage.c:2200 msgid "Cannot deserialize message: " msgstr "Tidak bisa men-deserialisasi pesan: " -#: gio/gdbusmessage.c:2521 +#: gio/gdbusmessage.c:2541 #, c-format msgid "" "Error serializing GVariant with type string “%s” to the D-Bus wire format" @@ -859,23 +874,23 @@ "Kesalahan serialisasi GVariant dengan type string \"%s\" ke format kabel D-" "Bus" -#: gio/gdbusmessage.c:2658 +#: gio/gdbusmessage.c:2678 #, c-format msgid "" "Number of file descriptors in message (%d) differs from header field (%d)" msgstr "" "Jumlah deskriptor berkas dalam pesan (%d) berbeda dari field header (%d)" -#: gio/gdbusmessage.c:2666 +#: gio/gdbusmessage.c:2686 msgid "Cannot serialize message: " msgstr "Tidak bisa men-serialisasi pesan: " -#: gio/gdbusmessage.c:2710 +#: gio/gdbusmessage.c:2739 #, c-format msgid "Message body has signature “%s” but there is no signature header" msgstr "Body pesan punya tanda tangan \"%s\" tapi tak ada header tanda tangan" -#: gio/gdbusmessage.c:2720 +#: gio/gdbusmessage.c:2749 #, c-format msgid "" "Message body has type signature “%s” but signature in the header field is " @@ -884,46 +899,47 @@ "Tubuh pesan memiliki tanda tangan tipe \"%s\" tapi tanda tangan di ruas " "header adalah \"(%s)\"" -#: gio/gdbusmessage.c:2736 +#: gio/gdbusmessage.c:2765 #, c-format msgid "Message body is empty but signature in the header field is “(%s)”" msgstr "Tubuh pesan kosong tapi tanda tangan pada ruas header adalah \"(%s)\"" -#: gio/gdbusmessage.c:3289 +#: gio/gdbusmessage.c:3318 #, c-format msgid "Error return with body of type “%s”" msgstr "Galat balikan dengan tubuh bertipe \"%s\"" -#: gio/gdbusmessage.c:3297 +#: gio/gdbusmessage.c:3326 msgid "Error return with empty body" msgstr "Galat balikan dengan body kosong" -#: gio/gdbusprivate.c:2066 +#: gio/gdbusprivate.c:2075 #, c-format msgid "Unable to get Hardware profile: %s" msgstr "Tak bisa mendapat profil perangkat keras: %s" -#: gio/gdbusprivate.c:2111 +#: gio/gdbusprivate.c:2120 msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " msgstr "Tak bisa memuat /var/lib/dbus/machine-id ata /etc/machine-id: " -#: gio/gdbusproxy.c:1612 +#: gio/gdbusproxy.c:1617 #, c-format msgid "Error calling StartServiceByName for %s: " msgstr "Galat sewaktu memanggil StartServiceByName untuk %s: " -#: gio/gdbusproxy.c:1635 +#: gio/gdbusproxy.c:1640 #, c-format msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" msgstr "Balasan tak diharapkan %d dari metode StartServiceByName(\"%s\")" -#: gio/gdbusproxy.c:2726 gio/gdbusproxy.c:2860 +#: gio/gdbusproxy.c:2740 gio/gdbusproxy.c:2875 +#, c-format msgid "" -"Cannot invoke method; proxy is for a well-known name without an owner and " -"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" msgstr "" -"Tidak bisa menjalankan metoda; proksi adalah nama terkenal tanpa pemilik dan " -"proksi dibangun dengan flag G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" +"Tidak bisa menjalankan metoda; proksi adalah nama terkenal %s tanpa pemilik " +"dan proksi dibangun dengan flag G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" #: gio/gdbusserver.c:708 msgid "Abstract name space not supported" @@ -1223,39 +1239,39 @@ msgid "Error: %s is not a valid well-known bus name.\n" msgstr "Galat: %s bukan nama bus yang dikenal baik dan valid\n" -#: gio/gdesktopappinfo.c:2023 gio/gdesktopappinfo.c:4633 +#: gio/gdesktopappinfo.c:2041 gio/gdesktopappinfo.c:4822 msgid "Unnamed" msgstr "Tanpa nama" -#: gio/gdesktopappinfo.c:2433 +#: gio/gdesktopappinfo.c:2451 msgid "Desktop file didn’t specify Exec field" msgstr "Berkas desktop tak menyatakan ruas Exec" -#: gio/gdesktopappinfo.c:2692 +#: gio/gdesktopappinfo.c:2710 msgid "Unable to find terminal required for application" msgstr "Tak bisa temukan terminal yang diperlukan bagi aplikasi" -#: gio/gdesktopappinfo.c:3202 +#: gio/gdesktopappinfo.c:3362 #, c-format msgid "Can’t create user application configuration folder %s: %s" msgstr "" "Tak bisa membuat folder %s untuk konfigurasi aplikasi bagi pengguna: %s" -#: gio/gdesktopappinfo.c:3206 +#: gio/gdesktopappinfo.c:3366 #, c-format msgid "Can’t create user MIME configuration folder %s: %s" msgstr "Tak bisa membuat folder %s untuk konfigurasi MIME bagi pengguna: %s" -#: gio/gdesktopappinfo.c:3446 gio/gdesktopappinfo.c:3470 +#: gio/gdesktopappinfo.c:3606 gio/gdesktopappinfo.c:3630 msgid "Application information lacks an identifier" msgstr "Informasi aplikasi tak punya identifier" -#: gio/gdesktopappinfo.c:3704 +#: gio/gdesktopappinfo.c:3864 #, c-format msgid "Can’t create user desktop file %s" msgstr "Tak bisa membuat berkas desktop pengguna %s" -#: gio/gdesktopappinfo.c:3838 +#: gio/gdesktopappinfo.c:3998 #, c-format msgid "Custom definition for %s" msgstr "Definisi gubahan bagi %s" @@ -1321,7 +1337,7 @@ #: gio/gfile.c:2008 gio/gfile.c:2063 gio/gfile.c:3738 gio/gfile.c:3793 #: gio/gfile.c:4029 gio/gfile.c:4071 gio/gfile.c:4539 gio/gfile.c:4950 #: gio/gfile.c:5035 gio/gfile.c:5125 gio/gfile.c:5222 gio/gfile.c:5309 -#: gio/gfile.c:5410 gio/gfile.c:7988 gio/gfile.c:8078 gio/gfile.c:8162 +#: gio/gfile.c:5410 gio/gfile.c:8113 gio/gfile.c:8203 gio/gfile.c:8287 #: gio/win32/gwinhttpfile.c:437 msgid "Operation not supported" msgstr "Operasi tak didukung" @@ -1334,7 +1350,7 @@ msgid "Containing mount does not exist" msgstr "Kait yang memuat tak ada" -#: gio/gfile.c:2622 gio/glocalfile.c:2399 +#: gio/gfile.c:2622 gio/glocalfile.c:2446 msgid "Can’t copy over directory" msgstr "Tak bisa menyalin direktori atas direktori" @@ -1392,7 +1408,7 @@ msgid "volume doesn’t implement mount" msgstr "volume tak mengimplementasi pengaitan" -#: gio/gfile.c:6882 +#: gio/gfile.c:6884 gio/gfile.c:6930 msgid "No application is registered as handling this file" msgstr "Tak ada aplikasi terdaftar yang menangani berkas ini" @@ -1437,8 +1453,8 @@ msgid "Truncate not supported on stream" msgstr "Pemenggalan tak didukung pada stream" -#: gio/ghttpproxy.c:91 gio/gresolver.c:410 gio/gresolver.c:476 -#: glib/gconvert.c:1786 +#: gio/ghttpproxy.c:91 gio/gresolver.c:377 gio/gresolver.c:529 +#: glib/gconvert.c:1785 msgid "Invalid hostname" msgstr "Nama host salah" @@ -1467,37 +1483,37 @@ msgid "HTTP proxy server closed connection unexpectedly." msgstr "Server proksi HTTP menutup koneksi secara tak terduga." -#: gio/gicon.c:290 +#: gio/gicon.c:298 #, c-format msgid "Wrong number of tokens (%d)" msgstr "Cacah token yang salah (%d)" -#: gio/gicon.c:310 +#: gio/gicon.c:318 #, c-format msgid "No type for class name %s" msgstr "Tak ada tipe bagi nama kelas %s" -#: gio/gicon.c:320 +#: gio/gicon.c:328 #, c-format msgid "Type %s does not implement the GIcon interface" msgstr "Tipe %s tak mengimplementasi antar muka GIcon" -#: gio/gicon.c:331 +#: gio/gicon.c:339 #, c-format msgid "Type %s is not classed" msgstr "Tipe %s tak dikelaskan" -#: gio/gicon.c:345 +#: gio/gicon.c:353 #, c-format msgid "Malformed version number: %s" msgstr "Nomor versi salah bentuk: %s" -#: gio/gicon.c:359 +#: gio/gicon.c:367 #, c-format msgid "Type %s does not implement from_tokens() on the GIcon interface" msgstr "Tipe %s tak mengimplementasi from_tokens() pada antar muka GIcon" -#: gio/gicon.c:461 +#: gio/gicon.c:469 msgid "Can’t handle the supplied version of the icon encoding" msgstr "Tak bisa menangani versi pengkodean ikon yang diberikan" @@ -1538,7 +1554,7 @@ #. Translators: This is an error you get if there is #. * already an operation running against this stream when #. * you try to start one -#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:1671 +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 msgid "Stream has outstanding operation" msgstr "Stream memiliki operasi tertunda" @@ -1643,7 +1659,7 @@ #: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:282 gio/gio-tool-list.c:165 #: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 #: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 -#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:113 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:70 #: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 #: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 msgid "LOCATION" @@ -1664,7 +1680,7 @@ "seperti smb://server/sumberdaya/berkas.txt sebagai lokasi." #: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:313 gio/gio-tool-mkdir.c:76 -#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:139 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:96 #: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 msgid "No locations given" msgstr "Tidak ada lokasi yang diberikan" @@ -2074,7 +2090,7 @@ msgid "Target %s is not a directory" msgstr "Target %s bukan suatu direktori" -#: gio/gio-tool-open.c:118 +#: gio/gio-tool-open.c:75 msgid "" "Open files with the default application that\n" "is registered to handle files of this type." @@ -2266,15 +2282,15 @@ msgid "text may not appear inside <%s>" msgstr "teks tidak boleh muncul di dalam <%s>" -#: gio/glib-compile-resources.c:736 gio/glib-compile-schemas.c:2139 +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2139 msgid "Show program version and exit" msgstr "Tampilkan versi program dan keluar" -#: gio/glib-compile-resources.c:737 +#: gio/glib-compile-resources.c:738 msgid "Name of the output file" msgstr "Nama berkas keluaran" -#: gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:739 msgid "" "The directories to load files referenced in FILE from (default: current " "directory)" @@ -2282,52 +2298,60 @@ "Direktori untuk memuat berkas yang direferensikan dalam FILE darinya " "(bawaan: direktori saat ini)" -#: gio/glib-compile-resources.c:738 gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2140 #: gio/glib-compile-schemas.c:2169 msgid "DIRECTORY" msgstr "DIREKTORI" -#: gio/glib-compile-resources.c:739 +#: gio/glib-compile-resources.c:740 msgid "" "Generate output in the format selected for by the target filename extension" msgstr "" "Buat keluaran dalam format yang dipilih bagi ekstensi nama berkas target" -#: gio/glib-compile-resources.c:740 +#: gio/glib-compile-resources.c:741 msgid "Generate source header" msgstr "Buat tajuk sumber" -#: gio/glib-compile-resources.c:741 +#: gio/glib-compile-resources.c:742 msgid "Generate source code used to link in the resource file into your code" msgstr "" "Buat kode sumber yang dipakai untutk menaut berkas sumber daya ke dalam kode " "Anda" -#: gio/glib-compile-resources.c:742 +#: gio/glib-compile-resources.c:743 msgid "Generate dependency list" msgstr "Buat daftar kebergantungan" -#: gio/glib-compile-resources.c:743 +#: gio/glib-compile-resources.c:744 msgid "Name of the dependency file to generate" msgstr "Nama berkas kebergantungan yang akan dibuat" -#: gio/glib-compile-resources.c:744 +#: gio/glib-compile-resources.c:745 msgid "Include phony targets in the generated dependency file" msgstr "Sertakan target palsu pada berkas dependensi yang dihasilkan" -#: gio/glib-compile-resources.c:745 +#: gio/glib-compile-resources.c:746 msgid "Don’t automatically create and register resource" msgstr "Jangan buat dan daftarkan sumber daya secara otomatis" -#: gio/glib-compile-resources.c:746 +#: gio/glib-compile-resources.c:747 msgid "Don’t export functions; declare them G_GNUC_INTERNAL" msgstr "Jangan ekspor fungsi; deklarasikan mereka G_GNUC_INTERNAL" -#: gio/glib-compile-resources.c:747 +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Jangan menyematkan data sumber daya dalam berkas C; anggap itu terhubung " +"secara eksternal sebagai gantinya" + +#: gio/glib-compile-resources.c:749 msgid "C identifier name used for the generated source code" msgstr "Nama identifier C yang dipakai bagi kode sumber yang dibuat" -#: gio/glib-compile-resources.c:773 +#: gio/glib-compile-resources.c:775 msgid "" "Compile a resource specification into a resource file.\n" "Resource specification files have the extension .gresource.xml,\n" @@ -2337,7 +2361,7 @@ "Berkas spesifikasi sumber daya memiliki ekstensi .gresource.xml,\n" "dan berkas sumber daya memiliki ekstensi bernama .gresource." -#: gio/glib-compile-resources.c:795 +#: gio/glib-compile-resources.c:797 msgid "You should give exactly one file name\n" msgstr "Anda mesti memberikan hanya satu nama berkas\n" @@ -2799,12 +2823,12 @@ msgid "removed existing output file.\n" msgstr "menghapus berkas keluaran yang telah ada.\n" -#: gio/glocalfile.c:544 gio/win32/gwinhttpfile.c:420 +#: gio/glocalfile.c:546 gio/win32/gwinhttpfile.c:420 #, c-format msgid "Invalid filename %s" msgstr "Nama berkas tak valid: %s" -#: gio/glocalfile.c:1011 +#: gio/glocalfile.c:1013 #, c-format msgid "Error getting filesystem info for %s: %s" msgstr "Galat saat mengambil info sistem berkas bagi %s: %s" @@ -2813,130 +2837,130 @@ #. * the enclosing (user visible) mount of a file, but none #. * exists. #. -#: gio/glocalfile.c:1150 +#: gio/glocalfile.c:1152 #, c-format msgid "Containing mount for file %s not found" msgstr "Kait wadah bagi berkas %s tak ditemukan" -#: gio/glocalfile.c:1173 +#: gio/glocalfile.c:1175 msgid "Can’t rename root directory" msgstr "Tidak bisa mengubah nama direktori root" -#: gio/glocalfile.c:1191 gio/glocalfile.c:1214 +#: gio/glocalfile.c:1193 gio/glocalfile.c:1216 #, c-format msgid "Error renaming file %s: %s" msgstr "Galat saat mengubah nama berkas %s: %s" -#: gio/glocalfile.c:1198 +#: gio/glocalfile.c:1200 msgid "Can’t rename file, filename already exists" msgstr "Tidak bisa mengubah nama berkas, nama telah dipakai" -#: gio/glocalfile.c:1211 gio/glocalfile.c:2275 gio/glocalfile.c:2303 -#: gio/glocalfile.c:2460 gio/glocalfileoutputstream.c:551 +#: gio/glocalfile.c:1213 gio/glocalfile.c:2322 gio/glocalfile.c:2350 +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:646 msgid "Invalid filename" msgstr "Nama berkas tak valid" -#: gio/glocalfile.c:1379 gio/glocalfile.c:1394 +#: gio/glocalfile.c:1381 gio/glocalfile.c:1396 #, c-format msgid "Error opening file %s: %s" msgstr "Galat saat membuka berkas %s: %s" -#: gio/glocalfile.c:1519 +#: gio/glocalfile.c:1521 #, c-format msgid "Error removing file %s: %s" msgstr "Galat saat menghapus berkas %s: %s" -#: gio/glocalfile.c:1916 +#: gio/glocalfile.c:1963 #, c-format msgid "Error trashing file %s: %s" msgstr "Galat saat memindah berkas %s ke tong sampah: %s" -#: gio/glocalfile.c:1957 +#: gio/glocalfile.c:2004 #, c-format msgid "Unable to create trash dir %s: %s" msgstr "Tak bisa membuat direktori tong sampah %s: %s" -#: gio/glocalfile.c:1978 +#: gio/glocalfile.c:2025 #, c-format msgid "Unable to find toplevel directory to trash %s" msgstr "" "Tidak bisa menemukan direktori puncak %s yang akan dibuang ke tong sampah" -#: gio/glocalfile.c:1987 +#: gio/glocalfile.c:2034 #, c-format msgid "Trashing on system internal mounts is not supported" msgstr "Penyampahan pada kandar internal sistem tidak didukung" -#: gio/glocalfile.c:2071 gio/glocalfile.c:2091 +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 #, c-format msgid "Unable to find or create trash directory for %s" msgstr "Tidak bisa menemukan atau membuat direktori tong sampah bagi %s" -#: gio/glocalfile.c:2126 +#: gio/glocalfile.c:2173 #, c-format msgid "Unable to create trashing info file for %s: %s" msgstr "Tidak bisa membuat berkas info pembuangan ke tong sampah bagi %s: %s" -#: gio/glocalfile.c:2186 +#: gio/glocalfile.c:2233 #, c-format msgid "Unable to trash file %s across filesystem boundaries" msgstr "" "Tidak bisa membuang berkas %s ke tong sampah menyeberang batas sistem berkas" -#: gio/glocalfile.c:2190 gio/glocalfile.c:2246 +#: gio/glocalfile.c:2237 gio/glocalfile.c:2293 #, c-format msgid "Unable to trash file %s: %s" msgstr "Tak bisa membuang berkas %s ke tong sampah: %s" -#: gio/glocalfile.c:2252 +#: gio/glocalfile.c:2299 #, c-format msgid "Unable to trash file %s" msgstr "Tak bisa membuang berkas ke tong sampah %s" -#: gio/glocalfile.c:2278 +#: gio/glocalfile.c:2325 #, c-format msgid "Error creating directory %s: %s" msgstr "Galat saat membuat direktori %s: %s" -#: gio/glocalfile.c:2307 +#: gio/glocalfile.c:2354 #, c-format msgid "Filesystem does not support symbolic links" msgstr "Sistem berkas tak mendukung taut simbolik" -#: gio/glocalfile.c:2310 +#: gio/glocalfile.c:2357 #, c-format msgid "Error making symbolic link %s: %s" msgstr "Galat saat membuat taut simbolis %s: %s" -#: gio/glocalfile.c:2316 glib/gfileutils.c:2138 +#: gio/glocalfile.c:2363 glib/gfileutils.c:2138 msgid "Symbolic links not supported" msgstr "Taut simbolik tidak didukung" -#: gio/glocalfile.c:2371 gio/glocalfile.c:2406 gio/glocalfile.c:2463 +#: gio/glocalfile.c:2418 gio/glocalfile.c:2453 gio/glocalfile.c:2510 #, c-format msgid "Error moving file %s: %s" msgstr "Galat saat memindah berkas %s: %s" -#: gio/glocalfile.c:2394 +#: gio/glocalfile.c:2441 msgid "Can’t move directory over directory" msgstr "Tidak bisa memindah direktori atas direktori" -#: gio/glocalfile.c:2420 gio/glocalfileoutputstream.c:935 -#: gio/glocalfileoutputstream.c:949 gio/glocalfileoutputstream.c:964 -#: gio/glocalfileoutputstream.c:981 gio/glocalfileoutputstream.c:995 +#: gio/glocalfile.c:2467 gio/glocalfileoutputstream.c:1030 +#: gio/glocalfileoutputstream.c:1044 gio/glocalfileoutputstream.c:1059 +#: gio/glocalfileoutputstream.c:1076 gio/glocalfileoutputstream.c:1090 msgid "Backup file creation failed" msgstr "Pembuatan berkas cadangan gagal" -#: gio/glocalfile.c:2439 +#: gio/glocalfile.c:2486 #, c-format msgid "Error removing target file: %s" msgstr "Galat saat menghapus berkas tujuan: %s" -#: gio/glocalfile.c:2453 +#: gio/glocalfile.c:2500 msgid "Move between mounts not supported" msgstr "Perpindahan antar kait tak didukung" -#: gio/glocalfile.c:2644 +#: gio/glocalfile.c:2691 #, c-format msgid "Could not determine the disk usage of %s: %s" msgstr "Tak bisa menentukan penggunaan diska dari %s: %s" @@ -2962,146 +2986,146 @@ msgid " (invalid encoding)" msgstr " (pengkodean tak valid)" -#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:813 +#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:908 #, c-format msgid "Error when getting information for file “%s”: %s" msgstr "Galat saat mengambil informasi bagi berkas \"%s\": %s" -#: gio/glocalfileinfo.c:2053 +#: gio/glocalfileinfo.c:2059 #, c-format msgid "Error when getting information for file descriptor: %s" msgstr "Galat saat mengambil informasi bagi descriptor berkas: %s" -#: gio/glocalfileinfo.c:2098 +#: gio/glocalfileinfo.c:2104 msgid "Invalid attribute type (uint32 expected)" msgstr "Tipe atribut tak valid (diharapkan uint32)" -#: gio/glocalfileinfo.c:2116 +#: gio/glocalfileinfo.c:2122 msgid "Invalid attribute type (uint64 expected)" msgstr "Tipe atribut tak valid (diharapkan uint64)" -#: gio/glocalfileinfo.c:2135 gio/glocalfileinfo.c:2154 +#: gio/glocalfileinfo.c:2141 gio/glocalfileinfo.c:2160 msgid "Invalid attribute type (byte string expected)" msgstr "Jenis atribut tidak sah (diharapkan bita berjenis string)" -#: gio/glocalfileinfo.c:2201 +#: gio/glocalfileinfo.c:2207 msgid "Cannot set permissions on symlinks" msgstr "Tak bisa menata ijin pada taut simbolik" -#: gio/glocalfileinfo.c:2217 +#: gio/glocalfileinfo.c:2223 #, c-format msgid "Error setting permissions: %s" msgstr "Galat saat menata ijin: %s" -#: gio/glocalfileinfo.c:2268 +#: gio/glocalfileinfo.c:2274 #, c-format msgid "Error setting owner: %s" msgstr "Galat saat menata pemilik: %s" -#: gio/glocalfileinfo.c:2291 +#: gio/glocalfileinfo.c:2297 msgid "symlink must be non-NULL" msgstr "symlink tak boleh NULL" -#: gio/glocalfileinfo.c:2301 gio/glocalfileinfo.c:2320 -#: gio/glocalfileinfo.c:2331 +#: gio/glocalfileinfo.c:2307 gio/glocalfileinfo.c:2326 +#: gio/glocalfileinfo.c:2337 #, c-format msgid "Error setting symlink: %s" msgstr "Galat saat menata taut simbolis: %s" -#: gio/glocalfileinfo.c:2310 +#: gio/glocalfileinfo.c:2316 msgid "Error setting symlink: file is not a symlink" msgstr "Galat saat menata symlink: berkas bukan suatu link simbolik" -#: gio/glocalfileinfo.c:2436 +#: gio/glocalfileinfo.c:2442 #, c-format msgid "Error setting modification or access time: %s" msgstr "Galat saat menata waktu modifikasi atau akses: %s" -#: gio/glocalfileinfo.c:2459 +#: gio/glocalfileinfo.c:2465 msgid "SELinux context must be non-NULL" msgstr "Konteks SELinux tak boleh NULL" -#: gio/glocalfileinfo.c:2474 +#: gio/glocalfileinfo.c:2480 #, c-format msgid "Error setting SELinux context: %s" msgstr "Galat saat menata konteks SELinux: %s" -#: gio/glocalfileinfo.c:2481 +#: gio/glocalfileinfo.c:2487 msgid "SELinux is not enabled on this system" msgstr "SELinux tak diaktifkan di sistem ini" -#: gio/glocalfileinfo.c:2573 +#: gio/glocalfileinfo.c:2579 #, c-format msgid "Setting attribute %s not supported" msgstr "Penataan atribut %s tak didukung" -#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:696 +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:791 #, c-format msgid "Error reading from file: %s" msgstr "Galat saat membaca dari berkas: %s" #: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 #: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 -#: gio/glocalfileoutputstream.c:458 gio/glocalfileoutputstream.c:1013 +#: gio/glocalfileoutputstream.c:553 gio/glocalfileoutputstream.c:1108 #, c-format msgid "Error seeking in file: %s" msgstr "Galat saat men-seek di berkas: %s" -#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:248 -#: gio/glocalfileoutputstream.c:342 +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:343 +#: gio/glocalfileoutputstream.c:437 #, c-format msgid "Error closing file: %s" msgstr "Galat saat menutup berkas: %s" -#: gio/glocalfilemonitor.c:854 +#: gio/glocalfilemonitor.c:856 msgid "Unable to find default local file monitor type" msgstr "Tak bisa temukan tipe pemantauan berkas lokal baku" -#: gio/glocalfileoutputstream.c:196 gio/glocalfileoutputstream.c:228 -#: gio/glocalfileoutputstream.c:717 +#: gio/glocalfileoutputstream.c:208 gio/glocalfileoutputstream.c:286 +#: gio/glocalfileoutputstream.c:323 gio/glocalfileoutputstream.c:812 #, c-format msgid "Error writing to file: %s" msgstr "Galat saat menulis ke berkas: %s" -#: gio/glocalfileoutputstream.c:275 +#: gio/glocalfileoutputstream.c:370 #, c-format msgid "Error removing old backup link: %s" msgstr "Galat saat menghapus taut cadangan lama: %s" -#: gio/glocalfileoutputstream.c:289 gio/glocalfileoutputstream.c:302 +#: gio/glocalfileoutputstream.c:384 gio/glocalfileoutputstream.c:397 #, c-format msgid "Error creating backup copy: %s" msgstr "Galat saat membuat salinan cadangan: %s" -#: gio/glocalfileoutputstream.c:320 +#: gio/glocalfileoutputstream.c:415 #, c-format msgid "Error renaming temporary file: %s" msgstr "Galat saat mengubah nama berkas sementara: %s" -#: gio/glocalfileoutputstream.c:504 gio/glocalfileoutputstream.c:1064 +#: gio/glocalfileoutputstream.c:599 gio/glocalfileoutputstream.c:1159 #, c-format msgid "Error truncating file: %s" msgstr "Galat saat memenggal berkas: %s" -#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:795 -#: gio/glocalfileoutputstream.c:1045 gio/gsubprocess.c:380 +#: gio/glocalfileoutputstream.c:652 gio/glocalfileoutputstream.c:890 +#: gio/glocalfileoutputstream.c:1140 gio/gsubprocess.c:380 #, c-format msgid "Error opening file “%s”: %s" msgstr "Galat saat membuka berkas \"%s\": %s" -#: gio/glocalfileoutputstream.c:826 +#: gio/glocalfileoutputstream.c:921 msgid "Target file is a directory" msgstr "Berkas tujuan adalah suatu direktori" -#: gio/glocalfileoutputstream.c:831 +#: gio/glocalfileoutputstream.c:926 msgid "Target file is not a regular file" msgstr "Berkas tujuan bukan berkas biasa" -#: gio/glocalfileoutputstream.c:843 +#: gio/glocalfileoutputstream.c:938 msgid "The file was externally modified" msgstr "Berkas telah diubah secara eksternal" -#: gio/glocalfileoutputstream.c:1029 +#: gio/glocalfileoutputstream.c:1124 #, c-format msgid "Error removing old file: %s" msgstr "Galat saat menghapus berkas lama: %s" @@ -3191,7 +3215,7 @@ msgid "mount doesn’t implement synchronous content type guessing" msgstr "mount tak mengimplementasi penebakan sinkron jenis isi" -#: gio/gnetworkaddress.c:378 +#: gio/gnetworkaddress.c:388 #, c-format msgid "Hostname “%s” contains “[” but not “]”" msgstr "Nama host \"%s\" mengandung \"[\" tapi tanpa \"]\"" @@ -3204,51 +3228,67 @@ msgid "Host unreachable" msgstr "Host tak dapat dihubungi" -#: gio/gnetworkmonitornetlink.c:97 gio/gnetworkmonitornetlink.c:109 -#: gio/gnetworkmonitornetlink.c:128 +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 #, c-format msgid "Could not create network monitor: %s" msgstr "Tak bisa membuat pemantau jaringan: %s" -#: gio/gnetworkmonitornetlink.c:118 +#: gio/gnetworkmonitornetlink.c:120 msgid "Could not create network monitor: " msgstr "Tak bisa membuat pemantau jaringan: " -#: gio/gnetworkmonitornetlink.c:176 +#: gio/gnetworkmonitornetlink.c:183 msgid "Could not get network status: " msgstr "Tak bisa mendapat status jaringan: " -#: gio/gnetworkmonitornm.c:322 +#: gio/gnetworkmonitornm.c:313 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager tidak berjalan" + +#: gio/gnetworkmonitornm.c:324 #, c-format msgid "NetworkManager version too old" msgstr "Versi NetworkManager terlalu tua" -#: gio/goutputstream.c:212 gio/goutputstream.c:560 +#: gio/goutputstream.c:232 gio/goutputstream.c:775 msgid "Output stream doesn’t implement write" msgstr "Stream keluaran tidak mengimplementasikan penulisan" -#: gio/goutputstream.c:521 gio/goutputstream.c:1224 +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Jumlah vektor yang dilewatkan ke %s terlalu besar" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 msgid "Source stream is already closed" msgstr "Stream sumber telah ditutup" -#: gio/gresolver.c:342 gio/gthreadedresolver.c:116 gio/gthreadedresolver.c:126 +#: gio/gresolver.c:344 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:160 #, c-format msgid "Error resolving “%s”: %s" msgstr "Galat saat mengurai \"%s\": %s" -#: gio/gresolver.c:729 gio/gresolver.c:781 +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:389 gio/gresolver.c:547 +#, c-format +msgid "%s not implemented" +msgstr "%s tidak diterapkan" + +#: gio/gresolver.c:915 gio/gresolver.c:967 msgid "Invalid domain" msgstr "Domain tidak valid" -#: gio/gresource.c:644 gio/gresource.c:903 gio/gresource.c:942 -#: gio/gresource.c:1066 gio/gresource.c:1138 gio/gresource.c:1211 -#: gio/gresource.c:1281 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 #: gio/gresourcefile.c:736 #, c-format msgid "The resource at “%s” does not exist" msgstr "Sumber daya pada \"%s\" tidak ada" -#: gio/gresource.c:809 +#: gio/gresource.c:830 #, c-format msgid "The resource at “%s” failed to decompress" msgstr "Sumber daya di \"%s\" gagal didekompresi" @@ -3610,144 +3650,144 @@ msgid "No such key “%s”\n" msgstr "Tidak ada kunci seperti \"%s\"\n" -#: gio/gsocket.c:384 +#: gio/gsocket.c:373 msgid "Invalid socket, not initialized" msgstr "Soket tak valid, tak diinisialisasi" -#: gio/gsocket.c:391 +#: gio/gsocket.c:380 #, c-format msgid "Invalid socket, initialization failed due to: %s" msgstr "Soket tak valid, inisialisasi gagal karena: %s" -#: gio/gsocket.c:399 +#: gio/gsocket.c:388 msgid "Socket is already closed" msgstr "Soket telah ditutup" -#: gio/gsocket.c:414 gio/gsocket.c:3034 gio/gsocket.c:4244 gio/gsocket.c:4302 +#: gio/gsocket.c:403 gio/gsocket.c:3027 gio/gsocket.c:4244 gio/gsocket.c:4302 msgid "Socket I/O timed out" msgstr "I/O soket kehabisan waktu" -#: gio/gsocket.c:549 +#: gio/gsocket.c:538 #, c-format msgid "creating GSocket from fd: %s" msgstr "membuat GSocket dari fd: %s" -#: gio/gsocket.c:578 gio/gsocket.c:632 gio/gsocket.c:639 +#: gio/gsocket.c:567 gio/gsocket.c:621 gio/gsocket.c:628 #, c-format msgid "Unable to create socket: %s" msgstr "Tak bisa membuat soket: %s" -#: gio/gsocket.c:632 +#: gio/gsocket.c:621 msgid "Unknown family was specified" msgstr "Famili tak dikenal dinyatakan" -#: gio/gsocket.c:639 +#: gio/gsocket.c:628 msgid "Unknown protocol was specified" msgstr "Protokol tak dikenal dinyatakan" -#: gio/gsocket.c:1130 +#: gio/gsocket.c:1119 #, c-format msgid "Cannot use datagram operations on a non-datagram socket." msgstr "Tidak bisa memakai operasi datagram pada suatu soket bukan datagram." -#: gio/gsocket.c:1147 +#: gio/gsocket.c:1136 #, c-format msgid "Cannot use datagram operations on a socket with a timeout set." msgstr "" "Tidak bisa memakai operasi datagram pada suatu soket yang tenggang waktunya " "ditata." -#: gio/gsocket.c:1954 +#: gio/gsocket.c:1943 #, c-format msgid "could not get local address: %s" msgstr "tak bisa mendapat alamat lokal: %s" -#: gio/gsocket.c:2000 +#: gio/gsocket.c:1989 #, c-format msgid "could not get remote address: %s" msgstr "tak bisa mendapat alamat jauh: %s" -#: gio/gsocket.c:2066 +#: gio/gsocket.c:2055 #, c-format msgid "could not listen: %s" msgstr "tak bisa mendengarkan: %s" -#: gio/gsocket.c:2168 +#: gio/gsocket.c:2157 #, c-format msgid "Error binding to address: %s" msgstr "Galat saat mengikat ke alamat: %s" -#: gio/gsocket.c:2226 gio/gsocket.c:2263 gio/gsocket.c:2373 gio/gsocket.c:2398 -#: gio/gsocket.c:2471 gio/gsocket.c:2529 gio/gsocket.c:2547 +#: gio/gsocket.c:2215 gio/gsocket.c:2252 gio/gsocket.c:2362 gio/gsocket.c:2387 +#: gio/gsocket.c:2460 gio/gsocket.c:2518 gio/gsocket.c:2536 #, c-format msgid "Error joining multicast group: %s" msgstr "Galat saat bergabung dengan grup multicast: %s" -#: gio/gsocket.c:2227 gio/gsocket.c:2264 gio/gsocket.c:2374 gio/gsocket.c:2399 -#: gio/gsocket.c:2472 gio/gsocket.c:2530 gio/gsocket.c:2548 +#: gio/gsocket.c:2216 gio/gsocket.c:2253 gio/gsocket.c:2363 gio/gsocket.c:2388 +#: gio/gsocket.c:2461 gio/gsocket.c:2519 gio/gsocket.c:2537 #, c-format msgid "Error leaving multicast group: %s" msgstr "Galat saat meninggalkan grup multicast: %s" -#: gio/gsocket.c:2228 +#: gio/gsocket.c:2217 msgid "No support for source-specific multicast" msgstr "Tak ada dukungan bagi multicast spesifik sumber" -#: gio/gsocket.c:2375 +#: gio/gsocket.c:2364 msgid "Unsupported socket family" msgstr "Keluarga soket tak didukung" -#: gio/gsocket.c:2400 +#: gio/gsocket.c:2389 msgid "source-specific not an IPv4 address" msgstr "spesifik sumber bukan alamat IPv4" -#: gio/gsocket.c:2418 gio/gsocket.c:2447 gio/gsocket.c:2497 +#: gio/gsocket.c:2407 gio/gsocket.c:2436 gio/gsocket.c:2486 #, c-format msgid "Interface not found: %s" msgstr "Antarmuka tidak ditemukan: %s" -#: gio/gsocket.c:2434 +#: gio/gsocket.c:2423 #, c-format msgid "Interface name too long" msgstr "Nama antarmuka terlalu panjang" -#: gio/gsocket.c:2473 +#: gio/gsocket.c:2462 msgid "No support for IPv4 source-specific multicast" msgstr "Tak ada dukungan bagi multicast spesifik sumber IPV4" -#: gio/gsocket.c:2531 +#: gio/gsocket.c:2520 msgid "No support for IPv6 source-specific multicast" msgstr "Tak ada dukungan bagi multicast spesifik sumber IPV6" -#: gio/gsocket.c:2740 +#: gio/gsocket.c:2729 #, c-format msgid "Error accepting connection: %s" msgstr "Galat saat menerima sambungan: %s" -#: gio/gsocket.c:2864 +#: gio/gsocket.c:2855 msgid "Connection in progress" msgstr "Penyambungan tengah berlangsung" -#: gio/gsocket.c:2913 +#: gio/gsocket.c:2906 msgid "Unable to get pending error: " msgstr "Tak bisa mendapat kesalahan yang tertunda: " -#: gio/gsocket.c:3097 +#: gio/gsocket.c:3092 #, c-format msgid "Error receiving data: %s" msgstr "Galat saat menerima data: %s" -#: gio/gsocket.c:3292 +#: gio/gsocket.c:3289 #, c-format msgid "Error sending data: %s" msgstr "Galat saat mengirim data: %s" -#: gio/gsocket.c:3479 +#: gio/gsocket.c:3476 #, c-format msgid "Unable to shutdown socket: %s" msgstr "Tak bisa mematikan soket: %s" -#: gio/gsocket.c:3560 +#: gio/gsocket.c:3557 #, c-format msgid "Error closing socket: %s" msgstr "Galat saat menutup soket: %s" @@ -3757,52 +3797,53 @@ msgid "Waiting for socket condition: %s" msgstr "Menunggu kondisi soket: %s" -#: gio/gsocket.c:4711 gio/gsocket.c:4791 gio/gsocket.c:4969 +#: gio/gsocket.c:4614 gio/gsocket.c:4616 gio/gsocket.c:4762 gio/gsocket.c:4847 +#: gio/gsocket.c:5027 gio/gsocket.c:5067 gio/gsocket.c:5069 #, c-format msgid "Error sending message: %s" msgstr "Galat saat menerima pesan: %s" -#: gio/gsocket.c:4735 +#: gio/gsocket.c:4789 msgid "GSocketControlMessage not supported on Windows" msgstr "GSocketControlMessage tak didukung pada Windows" -#: gio/gsocket.c:5188 gio/gsocket.c:5261 gio/gsocket.c:5487 +#: gio/gsocket.c:5260 gio/gsocket.c:5333 gio/gsocket.c:5560 #, c-format msgid "Error receiving message: %s" msgstr "Galat saat menerima pesan: %s" -#: gio/gsocket.c:5759 +#: gio/gsocket.c:5832 #, c-format msgid "Unable to read socket credentials: %s" msgstr "Tak bisa membaca kredensial soket: %s" -#: gio/gsocket.c:5768 +#: gio/gsocket.c:5841 msgid "g_socket_get_credentials not implemented for this OS" msgstr "g_socket_get_credentials tidak diimplementasikan untuk OS ini" -#: gio/gsocketclient.c:176 +#: gio/gsocketclient.c:181 #, c-format msgid "Could not connect to proxy server %s: " msgstr "Tak bisa menyambung ke server proxi %s: " -#: gio/gsocketclient.c:190 +#: gio/gsocketclient.c:195 #, c-format msgid "Could not connect to %s: " msgstr "Tak bisa menyambung ke %s: " -#: gio/gsocketclient.c:192 +#: gio/gsocketclient.c:197 msgid "Could not connect: " msgstr "Tak bisa menyambung: " -#: gio/gsocketclient.c:1027 gio/gsocketclient.c:1599 +#: gio/gsocketclient.c:1032 gio/gsocketclient.c:1731 msgid "Unknown error on connect" msgstr "Galat tak dikenal saat hubungan" -#: gio/gsocketclient.c:1081 gio/gsocketclient.c:1535 +#: gio/gsocketclient.c:1086 gio/gsocketclient.c:1640 msgid "Proxying over a non-TCP connection is not supported." msgstr "Proksi melalui koneksi bukan TCP tidak didukung." -#: gio/gsocketclient.c:1110 gio/gsocketclient.c:1561 +#: gio/gsocketclient.c:1115 gio/gsocketclient.c:1666 #, c-format msgid "Proxy protocol “%s” is not supported." msgstr "Protokol proksi \"%s\" tidak didukung." @@ -3905,49 +3946,49 @@ msgid "Can’t handle version %d of GThemedIcon encoding" msgstr "Tidak bisa menangani pengkodean versi %d dari GThemedIcon" -#: gio/gthreadedresolver.c:118 +#: gio/gthreadedresolver.c:152 msgid "No valid addresses were found" msgstr "Tak ada alamat valid yang ditemukan" -#: gio/gthreadedresolver.c:213 +#: gio/gthreadedresolver.c:317 #, c-format msgid "Error reverse-resolving “%s”: %s" msgstr "Galat saat mengurai balik \"%s\": %s" -#: gio/gthreadedresolver.c:549 gio/gthreadedresolver.c:628 -#: gio/gthreadedresolver.c:726 gio/gthreadedresolver.c:776 +#: gio/gthreadedresolver.c:653 gio/gthreadedresolver.c:732 +#: gio/gthreadedresolver.c:830 gio/gthreadedresolver.c:880 #, c-format msgid "No DNS record of the requested type for “%s”" msgstr "Tidak ada record DNS dengan tipe yang diminta bagi \"%s\"" -#: gio/gthreadedresolver.c:554 gio/gthreadedresolver.c:731 +#: gio/gthreadedresolver.c:658 gio/gthreadedresolver.c:835 #, c-format msgid "Temporarily unable to resolve “%s”" msgstr "Sementara tidak dapat mengurai \"%s\"" -#: gio/gthreadedresolver.c:559 gio/gthreadedresolver.c:736 -#: gio/gthreadedresolver.c:844 +#: gio/gthreadedresolver.c:663 gio/gthreadedresolver.c:840 +#: gio/gthreadedresolver.c:948 #, c-format msgid "Error resolving “%s”" msgstr "Galat saat mengurai \"%s\"" -#: gio/gtlscertificate.c:250 -msgid "Cannot decrypt PEM-encoded private key" -msgstr "Tak bisa mendekripsi kunci privat terenkode-PEM" - -#: gio/gtlscertificate.c:255 +#: gio/gtlscertificate.c:243 msgid "No PEM-encoded private key found" msgstr "Tak ditemukan sertifikat terenkode-PEM" -#: gio/gtlscertificate.c:265 +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Tak bisa mendekripsi kunci privat terenkode-PEM" + +#: gio/gtlscertificate.c:264 msgid "Could not parse PEM-encoded private key" msgstr "Tak bisa mengurai kunci privat terenkode-PEM" -#: gio/gtlscertificate.c:290 +#: gio/gtlscertificate.c:291 msgid "No PEM-encoded certificate found" msgstr "Tak ditemukan sertifika terenkode-PEM" -#: gio/gtlscertificate.c:299 +#: gio/gtlscertificate.c:300 msgid "Could not parse PEM-encoded certificate" msgstr "Tak bisa mengurai sertifikat terenkode-PEM" @@ -3978,6 +4019,7 @@ msgid "Expecting 1 control message, got %d" msgid_plural "Expecting 1 control message, got %d" msgstr[0] "Mengharapkan 1 pesan kendali, memperoleh %d" +msgstr[1] "Mengharapkan 1 pesan kendali, memperoleh %d" #: gio/gunixconnection.c:182 gio/gunixconnection.c:575 msgid "Unexpected type of ancillary data" @@ -3988,6 +4030,7 @@ msgid "Expecting one fd, but got %d\n" msgid_plural "Expecting one fd, but got %d\n" msgstr[0] "Mengharapkan satu fd, tapi mendapat %d\n" +msgstr[1] "Mengharapkan satu fd, tapi mendapat %d\n" #: gio/gunixconnection.c:219 msgid "Received invalid fd" @@ -4011,8 +4054,8 @@ msgid "" "Expecting to read a single byte for receiving credentials but read zero bytes" msgstr "" -"Berharap membaca byte tunggal untuk penerimaan kredensial tapi membaca nol " -"byte" +"Berharap membaca bita tunggal untuk penerimaan kredensial tapi membaca nol " +"bita" #: gio/gunixconnection.c:589 #, c-format @@ -4029,17 +4072,19 @@ msgid "Error reading from file descriptor: %s" msgstr "Galat saat membaca dari descriptor berkas: %s" -#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:411 +#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:534 #: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 #, c-format msgid "Error closing file descriptor: %s" msgstr "Galat saat menutup descriptor berkas: %s" -#: gio/gunixmounts.c:2589 gio/gunixmounts.c:2642 +#: gio/gunixmounts.c:2650 gio/gunixmounts.c:2703 msgid "Filesystem root" msgstr "Akar sistem berkas" -#: gio/gunixoutputstream.c:358 gio/gunixoutputstream.c:378 +#: gio/gunixoutputstream.c:371 gio/gunixoutputstream.c:391 +#: gio/gunixoutputstream.c:478 gio/gunixoutputstream.c:498 +#: gio/gunixoutputstream.c:675 #, c-format msgid "Error writing to file descriptor: %s" msgstr "Galat saat menulis ke descriptor berkas: %s" @@ -4155,7 +4200,7 @@ #: glib/gbookmarkfile.c:2968 glib/gbookmarkfile.c:3158 #: glib/gbookmarkfile.c:3234 glib/gbookmarkfile.c:3402 #: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3580 -#: glib/gbookmarkfile.c:3696 +#: glib/gbookmarkfile.c:3699 #, c-format msgid "No bookmark found for URI “%s”" msgstr "Tak ditemukan penanda taut untuk URI \"%s\"" @@ -4188,78 +4233,78 @@ msgid "Failed to expand exec line “%s” with URI “%s”" msgstr "Gagal mengembangkan baris eksekusi \"%s\" dengan URI \"%s\"" -#: glib/gconvert.c:473 +#: glib/gconvert.c:474 msgid "Unrepresentable character in conversion input" msgstr "Karakter yang tidak dapat diterima dalam masukan konversi" -#: glib/gconvert.c:500 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 +#: glib/gconvert.c:501 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 #: glib/gutf8.c:1318 msgid "Partial character sequence at end of input" msgstr "Rangkaian karakter sebagian pada akhir input" -#: glib/gconvert.c:769 +#: glib/gconvert.c:770 #, c-format msgid "Cannot convert fallback “%s” to codeset “%s”" msgstr "Tidak dapat mengonversi fallback \"%s\" menjadi codeset \"%s\"" -#: glib/gconvert.c:940 +#: glib/gconvert.c:942 msgid "Embedded NUL byte in conversion input" msgstr "NUL bita tertanam dalam masukan konversi" -#: glib/gconvert.c:961 +#: glib/gconvert.c:963 msgid "Embedded NUL byte in conversion output" msgstr "NUL bita tertanam dalam keluaran konversi" -#: glib/gconvert.c:1649 +#: glib/gconvert.c:1648 #, c-format msgid "The URI “%s” is not an absolute URI using the “file” scheme" msgstr "URI \"%s\" bukanlah URI absolut dengan menggunakan skema \"file\"" -#: glib/gconvert.c:1659 +#: glib/gconvert.c:1658 #, c-format msgid "The local file URI “%s” may not include a “#”" msgstr "URI berkas lokal \"%s\" tak boleh mengandung \"#\"" -#: glib/gconvert.c:1676 +#: glib/gconvert.c:1675 #, c-format msgid "The URI “%s” is invalid" msgstr "URI \"%s\" tidak valid" -#: glib/gconvert.c:1688 +#: glib/gconvert.c:1687 #, c-format msgid "The hostname of the URI “%s” is invalid" msgstr "Nama host dari URI \"%s\" tidak valid" -#: glib/gconvert.c:1704 +#: glib/gconvert.c:1703 #, c-format msgid "The URI “%s” contains invalidly escaped characters" msgstr "URI \"%s\" mengandung karakter yang di-escape secara tidak valid" -#: glib/gconvert.c:1776 +#: glib/gconvert.c:1775 #, c-format msgid "The pathname “%s” is not an absolute path" msgstr "Nama path \"%s\" bukan lokasi absolut" #. Translators: this is the preferred format for expressing the date and the time -#: glib/gdatetime.c:213 +#: glib/gdatetime.c:214 msgctxt "GDateTime" msgid "%a %b %e %H:%M:%S %Y" msgstr "%a %d %b %Y %r %Z" #. Translators: this is the preferred format for expressing the date -#: glib/gdatetime.c:216 +#: glib/gdatetime.c:217 msgctxt "GDateTime" msgid "%m/%d/%y" msgstr "%d/%m/%y" #. Translators: this is the preferred format for expressing the time -#: glib/gdatetime.c:219 +#: glib/gdatetime.c:220 msgctxt "GDateTime" msgid "%H:%M:%S" msgstr "%H:%M:%S" #. Translators: this is the preferred format for expressing 12 hour time -#: glib/gdatetime.c:222 +#: glib/gdatetime.c:223 msgctxt "GDateTime" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" @@ -4280,62 +4325,62 @@ #. * non-European) there is no difference between the standalone and #. * complete date form. #. -#: glib/gdatetime.c:261 +#: glib/gdatetime.c:262 msgctxt "full month name" msgid "January" msgstr "Januari" -#: glib/gdatetime.c:263 +#: glib/gdatetime.c:264 msgctxt "full month name" msgid "February" msgstr "Februari" -#: glib/gdatetime.c:265 +#: glib/gdatetime.c:266 msgctxt "full month name" msgid "March" msgstr "Maret" -#: glib/gdatetime.c:267 +#: glib/gdatetime.c:268 msgctxt "full month name" msgid "April" msgstr "April" -#: glib/gdatetime.c:269 +#: glib/gdatetime.c:270 msgctxt "full month name" msgid "May" msgstr "Mei" -#: glib/gdatetime.c:271 +#: glib/gdatetime.c:272 msgctxt "full month name" msgid "June" msgstr "Juni" -#: glib/gdatetime.c:273 +#: glib/gdatetime.c:274 msgctxt "full month name" msgid "July" msgstr "Juli" -#: glib/gdatetime.c:275 +#: glib/gdatetime.c:276 msgctxt "full month name" msgid "August" msgstr "Agustus" -#: glib/gdatetime.c:277 +#: glib/gdatetime.c:278 msgctxt "full month name" msgid "September" msgstr "September" -#: glib/gdatetime.c:279 +#: glib/gdatetime.c:280 msgctxt "full month name" msgid "October" msgstr "Oktober" -#: glib/gdatetime.c:281 +#: glib/gdatetime.c:282 msgctxt "full month name" msgid "November" msgstr "November" -#: glib/gdatetime.c:283 +#: glib/gdatetime.c:284 msgctxt "full month name" msgid "December" msgstr "Desember" @@ -4357,132 +4402,132 @@ #. * other platform. Here are abbreviated month names in a form #. * appropriate when they are used standalone. #. -#: glib/gdatetime.c:315 +#: glib/gdatetime.c:316 msgctxt "abbreviated month name" msgid "Jan" msgstr "Jan" -#: glib/gdatetime.c:317 +#: glib/gdatetime.c:318 msgctxt "abbreviated month name" msgid "Feb" msgstr "Feb" -#: glib/gdatetime.c:319 +#: glib/gdatetime.c:320 msgctxt "abbreviated month name" msgid "Mar" msgstr "Mar" -#: glib/gdatetime.c:321 +#: glib/gdatetime.c:322 msgctxt "abbreviated month name" msgid "Apr" msgstr "Apr" -#: glib/gdatetime.c:323 +#: glib/gdatetime.c:324 msgctxt "abbreviated month name" msgid "May" msgstr "Mei" -#: glib/gdatetime.c:325 +#: glib/gdatetime.c:326 msgctxt "abbreviated month name" msgid "Jun" msgstr "Jun" -#: glib/gdatetime.c:327 +#: glib/gdatetime.c:328 msgctxt "abbreviated month name" msgid "Jul" msgstr "Jul" -#: glib/gdatetime.c:329 +#: glib/gdatetime.c:330 msgctxt "abbreviated month name" msgid "Aug" msgstr "Ags" -#: glib/gdatetime.c:331 +#: glib/gdatetime.c:332 msgctxt "abbreviated month name" msgid "Sep" msgstr "Sep" -#: glib/gdatetime.c:333 +#: glib/gdatetime.c:334 msgctxt "abbreviated month name" msgid "Oct" msgstr "Okt" -#: glib/gdatetime.c:335 +#: glib/gdatetime.c:336 msgctxt "abbreviated month name" msgid "Nov" msgstr "Nov" -#: glib/gdatetime.c:337 +#: glib/gdatetime.c:338 msgctxt "abbreviated month name" msgid "Dec" msgstr "Des" -#: glib/gdatetime.c:352 +#: glib/gdatetime.c:353 msgctxt "full weekday name" msgid "Monday" msgstr "Senin" -#: glib/gdatetime.c:354 +#: glib/gdatetime.c:355 msgctxt "full weekday name" msgid "Tuesday" msgstr "Selasa" -#: glib/gdatetime.c:356 +#: glib/gdatetime.c:357 msgctxt "full weekday name" msgid "Wednesday" msgstr "Rabu" -#: glib/gdatetime.c:358 +#: glib/gdatetime.c:359 msgctxt "full weekday name" msgid "Thursday" msgstr "Kamis" -#: glib/gdatetime.c:360 +#: glib/gdatetime.c:361 msgctxt "full weekday name" msgid "Friday" msgstr "Jumat" -#: glib/gdatetime.c:362 +#: glib/gdatetime.c:363 msgctxt "full weekday name" msgid "Saturday" msgstr "Sabtu" -#: glib/gdatetime.c:364 +#: glib/gdatetime.c:365 msgctxt "full weekday name" msgid "Sunday" msgstr "Minggu" -#: glib/gdatetime.c:379 +#: glib/gdatetime.c:380 msgctxt "abbreviated weekday name" msgid "Mon" msgstr "Sen" -#: glib/gdatetime.c:381 +#: glib/gdatetime.c:382 msgctxt "abbreviated weekday name" msgid "Tue" msgstr "Sel" -#: glib/gdatetime.c:383 +#: glib/gdatetime.c:384 msgctxt "abbreviated weekday name" msgid "Wed" msgstr "Rab" -#: glib/gdatetime.c:385 +#: glib/gdatetime.c:386 msgctxt "abbreviated weekday name" msgid "Thu" msgstr "Kam" -#: glib/gdatetime.c:387 +#: glib/gdatetime.c:388 msgctxt "abbreviated weekday name" msgid "Fri" msgstr "Jum" -#: glib/gdatetime.c:389 +#: glib/gdatetime.c:390 msgctxt "abbreviated weekday name" msgid "Sat" msgstr "Sab" -#: glib/gdatetime.c:391 +#: glib/gdatetime.c:392 msgctxt "abbreviated weekday name" msgid "Sun" msgstr "Min" @@ -4504,62 +4549,62 @@ #. * (western European, non-European) there is no difference between the #. * standalone and complete date form. #. -#: glib/gdatetime.c:455 +#: glib/gdatetime.c:456 msgctxt "full month name with day" msgid "January" msgstr "Januari" -#: glib/gdatetime.c:457 +#: glib/gdatetime.c:458 msgctxt "full month name with day" msgid "February" msgstr "Februari" -#: glib/gdatetime.c:459 +#: glib/gdatetime.c:460 msgctxt "full month name with day" msgid "March" msgstr "Maret" -#: glib/gdatetime.c:461 +#: glib/gdatetime.c:462 msgctxt "full month name with day" msgid "April" msgstr "April" -#: glib/gdatetime.c:463 +#: glib/gdatetime.c:464 msgctxt "full month name with day" msgid "May" msgstr "Mei" -#: glib/gdatetime.c:465 +#: glib/gdatetime.c:466 msgctxt "full month name with day" msgid "June" msgstr "Juni" -#: glib/gdatetime.c:467 +#: glib/gdatetime.c:468 msgctxt "full month name with day" msgid "July" msgstr "Juli" -#: glib/gdatetime.c:469 +#: glib/gdatetime.c:470 msgctxt "full month name with day" msgid "August" msgstr "Agustus" -#: glib/gdatetime.c:471 +#: glib/gdatetime.c:472 msgctxt "full month name with day" msgid "September" msgstr "September" -#: glib/gdatetime.c:473 +#: glib/gdatetime.c:474 msgctxt "full month name with day" msgid "October" msgstr "Oktober" -#: glib/gdatetime.c:475 +#: glib/gdatetime.c:476 msgctxt "full month name with day" msgid "November" msgstr "November" -#: glib/gdatetime.c:477 +#: glib/gdatetime.c:478 msgctxt "full month name with day" msgid "December" msgstr "Desember" @@ -4581,79 +4626,79 @@ #. * month names almost ready to copy and paste here. In other systems #. * due to a bug the result is incorrect in some languages. #. -#: glib/gdatetime.c:542 +#: glib/gdatetime.c:543 msgctxt "abbreviated month name with day" msgid "Jan" msgstr "Jan" -#: glib/gdatetime.c:544 +#: glib/gdatetime.c:545 msgctxt "abbreviated month name with day" msgid "Feb" msgstr "Feb" -#: glib/gdatetime.c:546 +#: glib/gdatetime.c:547 msgctxt "abbreviated month name with day" msgid "Mar" msgstr "Mar" -#: glib/gdatetime.c:548 +#: glib/gdatetime.c:549 msgctxt "abbreviated month name with day" msgid "Apr" msgstr "Apr" -#: glib/gdatetime.c:550 +#: glib/gdatetime.c:551 msgctxt "abbreviated month name with day" msgid "May" msgstr "Mei" -#: glib/gdatetime.c:552 +#: glib/gdatetime.c:553 msgctxt "abbreviated month name with day" msgid "Jun" msgstr "Jun" -#: glib/gdatetime.c:554 +#: glib/gdatetime.c:555 msgctxt "abbreviated month name with day" msgid "Jul" msgstr "Jul" -#: glib/gdatetime.c:556 +#: glib/gdatetime.c:557 msgctxt "abbreviated month name with day" msgid "Aug" msgstr "Ags" -#: glib/gdatetime.c:558 +#: glib/gdatetime.c:559 msgctxt "abbreviated month name with day" msgid "Sep" msgstr "Sep" -#: glib/gdatetime.c:560 +#: glib/gdatetime.c:561 msgctxt "abbreviated month name with day" msgid "Oct" msgstr "Okt" -#: glib/gdatetime.c:562 +#: glib/gdatetime.c:563 msgctxt "abbreviated month name with day" msgid "Nov" msgstr "Nov" -#: glib/gdatetime.c:564 +#: glib/gdatetime.c:565 msgctxt "abbreviated month name with day" msgid "Dec" msgstr "Des" #. Translators: 'before midday' indicator -#: glib/gdatetime.c:581 +#: glib/gdatetime.c:582 msgctxt "GDateTime" msgid "AM" msgstr "AM" #. Translators: 'after midday' indicator -#: glib/gdatetime.c:584 +#: glib/gdatetime.c:585 msgctxt "GDateTime" msgid "PM" msgstr "PM" -#: glib/gdir.c:155 +#: glib/gdir.c:154 #, c-format msgid "Error opening directory “%s”: %s" msgstr "Galat saat membuka direktori \"%s\": %s" @@ -4662,7 +4707,8 @@ #, c-format msgid "Could not allocate %lu byte to read file “%s”" msgid_plural "Could not allocate %lu bytes to read file “%s”" -msgstr[0] "Tidak dapat mengalokasikan %lu byte untuk membaca berkas \"%s\"" +msgstr[0] "Tidak dapat mengalokasikan %lu bita untuk membaca berkas \"%s\"" +msgstr[1] "Tidak dapat mengalokasikan %lu bita untuk membaca berkas \"%s\"" #: glib/gfileutils.c:733 #, c-format @@ -4756,15 +4802,15 @@ msgid "Can’t do a raw read in g_io_channel_read_to_end" msgstr "Tidak dapat melakukan pembacaan mentah dalam g_io_channel_read_to_end" -#: glib/gkeyfile.c:788 +#: glib/gkeyfile.c:789 msgid "Valid key file could not be found in search dirs" msgstr "Berkas kunci yang valid tak ditemukan pada direktori yang dicari" -#: glib/gkeyfile.c:825 +#: glib/gkeyfile.c:826 msgid "Not a regular file" msgstr "Bukan berkas biasa" -#: glib/gkeyfile.c:1270 +#: glib/gkeyfile.c:1275 #, c-format msgid "" "Key file contains line “%s” which is not a key-value pair, group, or comment" @@ -4772,51 +4818,51 @@ "Berkas kunci mengandung baris \"%s\" yang bukan suatu pasangan kunci-nilai, " "kelompok, atau komentar" -#: glib/gkeyfile.c:1327 +#: glib/gkeyfile.c:1332 #, c-format msgid "Invalid group name: %s" msgstr "Nama grup tak valid: %s" -#: glib/gkeyfile.c:1349 +#: glib/gkeyfile.c:1354 msgid "Key file does not start with a group" msgstr "Berkas kunci tidak mulai dengan sebuah kelompok" -#: glib/gkeyfile.c:1375 +#: glib/gkeyfile.c:1380 #, c-format msgid "Invalid key name: %s" msgstr "Nama kunci tak valid: %s" -#: glib/gkeyfile.c:1402 +#: glib/gkeyfile.c:1407 #, c-format msgid "Key file contains unsupported encoding “%s”" msgstr "Berkas kunci mengandung enkoding \"%s\" yang tidak didukung" -#: glib/gkeyfile.c:1645 glib/gkeyfile.c:1818 glib/gkeyfile.c:3271 -#: glib/gkeyfile.c:3334 glib/gkeyfile.c:3464 glib/gkeyfile.c:3594 -#: glib/gkeyfile.c:3738 glib/gkeyfile.c:3967 glib/gkeyfile.c:4034 +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3339 glib/gkeyfile.c:3469 glib/gkeyfile.c:3601 +#: glib/gkeyfile.c:3747 glib/gkeyfile.c:3976 glib/gkeyfile.c:4043 #, c-format msgid "Key file does not have group “%s”" msgstr "Berkas kunci tidak memiliki grup \"%s\"" -#: glib/gkeyfile.c:1773 +#: glib/gkeyfile.c:1778 #, c-format msgid "Key file does not have key “%s” in group “%s”" msgstr "Berkas kunci tidak memiliki kunci \"%s\" dalam kelompok \"%s\"" -#: glib/gkeyfile.c:1935 glib/gkeyfile.c:2051 +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 #, c-format msgid "Key file contains key “%s” with value “%s” which is not UTF-8" msgstr "" "Berkas kunci mengandung kunci \"%s\" dengan nilai \"%s\" yang bukan UTF-8" -#: glib/gkeyfile.c:1955 glib/gkeyfile.c:2071 glib/gkeyfile.c:2513 +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 #, c-format msgid "" "Key file contains key “%s” which has a value that cannot be interpreted." msgstr "" "Berkas kunci mengandung kunci \"%s\" yang nilainya tidak dapat diterjemahkan." -#: glib/gkeyfile.c:2731 glib/gkeyfile.c:3100 +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 #, c-format msgid "" "Key file contains key “%s” in group “%s” which has a value that cannot be " @@ -4825,36 +4871,36 @@ "Berkas kunci mengandung kunci \"%s\" dalam grup \"%s\" yang nilainya tidak " "dapat diterjemahkan." -#: glib/gkeyfile.c:2809 glib/gkeyfile.c:2886 +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 #, c-format msgid "Key “%s” in group “%s” has value “%s” where %s was expected" msgstr "Kunci \"%s\" dalam grup \"%s\" bernilai \"%s\" padahal diharapkan %s" -#: glib/gkeyfile.c:4274 +#: glib/gkeyfile.c:4283 msgid "Key file contains escape character at end of line" msgstr "Berkas kunci mengandung karakter escape pada akhir baris" -#: glib/gkeyfile.c:4296 +#: glib/gkeyfile.c:4305 #, c-format msgid "Key file contains invalid escape sequence “%s”" msgstr "Berkas kunci memuat urutan escape \"%s\" yang tidak valid" -#: glib/gkeyfile.c:4440 +#: glib/gkeyfile.c:4449 #, c-format msgid "Value “%s” cannot be interpreted as a number." msgstr "Nilai \"%s\" tidak bisa diterjemahkan sebagai sebuah bilangan." -#: glib/gkeyfile.c:4454 +#: glib/gkeyfile.c:4463 #, c-format msgid "Integer value “%s” out of range" msgstr "Nilai bilangan bulat \"%s\" di luar jangkauan" -#: glib/gkeyfile.c:4487 +#: glib/gkeyfile.c:4496 #, c-format msgid "Value “%s” cannot be interpreted as a float number." msgstr "Nilai \"%s\" tidak dapat diterjemahkan sebagai sebuah bilangan float." -#: glib/gkeyfile.c:4526 +#: glib/gkeyfile.c:4535 #, c-format msgid "Value “%s” cannot be interpreted as a boolean." msgstr "Nilai \"%s\" tidak dapat diterjemahkan sebagai sebuah boolean." @@ -4874,32 +4920,32 @@ msgid "Failed to open file “%s”: open() failed: %s" msgstr "Gagal membuka berkas \"%s\": open() gagal: %s" -#: glib/gmarkup.c:397 glib/gmarkup.c:439 +#: glib/gmarkup.c:398 glib/gmarkup.c:440 #, c-format msgid "Error on line %d char %d: " msgstr "Galat pada baris %d karakter ke-%d: " -#: glib/gmarkup.c:461 glib/gmarkup.c:544 +#: glib/gmarkup.c:462 glib/gmarkup.c:545 #, c-format msgid "Invalid UTF-8 encoded text in name — not valid “%s”" msgstr "Teks UTF-8 dalam nama tak valid — bukan “%s” yang valid" -#: glib/gmarkup.c:472 +#: glib/gmarkup.c:473 #, c-format msgid "“%s” is not a valid name" msgstr "“%s” bukan suatu nama yang valid" -#: glib/gmarkup.c:488 +#: glib/gmarkup.c:489 #, c-format msgid "“%s” is not a valid name: “%c”" msgstr "“%s” bukan suatu nama yang valid: \"%c\"" -#: glib/gmarkup.c:610 +#: glib/gmarkup.c:613 #, c-format msgid "Error on line %d: %s" msgstr "Galat pada baris ke-%d: %s" -#: glib/gmarkup.c:687 +#: glib/gmarkup.c:690 #, c-format msgid "" "Failed to parse “%-.*s”, which should have been a digit inside a character " @@ -4908,7 +4954,7 @@ "Gagal saat mengurai \"%-.*s\", yang seharusnya sebuah digit dalam referensi " "karakter (misalnya ê) — mungkin digitnya terlalu besar" -#: glib/gmarkup.c:699 +#: glib/gmarkup.c:702 msgid "" "Character reference did not end with a semicolon; most likely you used an " "ampersand character without intending to start an entity — escape ampersand " @@ -4918,25 +4964,25 @@ "menggunakan karakter ampersand tanpa bermaksud menjadikannya sebagai entitas " "— silakan gunakan & saja" -#: glib/gmarkup.c:725 +#: glib/gmarkup.c:728 #, c-format msgid "Character reference “%-.*s” does not encode a permitted character" msgstr "" "Referensi karakter \"%-.*s\" tidak mengenkode karakter yang diperbolehkan" -#: glib/gmarkup.c:763 +#: glib/gmarkup.c:766 msgid "" "Empty entity “&;” seen; valid entities are: & " < > '" msgstr "" "Ada entitas \"&;\" yang kosong; entitas yang benar antara lain adalah: & " "" < > '" -#: glib/gmarkup.c:771 +#: glib/gmarkup.c:774 #, c-format msgid "Entity name “%-.*s” is not known" msgstr "Nama entitas \"%-.*s\" tak dikenal" -#: glib/gmarkup.c:776 +#: glib/gmarkup.c:779 msgid "" "Entity did not end with a semicolon; most likely you used an ampersand " "character without intending to start an entity — escape ampersand as &" @@ -4945,11 +4991,11 @@ "ampersand tanpa bermaksud menjadikannya sebagai entitas — silakan pakai " "& saja" -#: glib/gmarkup.c:1182 +#: glib/gmarkup.c:1187 msgid "Document must begin with an element (e.g. )" msgstr "Dokumen harus dimulai dengan elemen (misalnya )" -#: glib/gmarkup.c:1222 +#: glib/gmarkup.c:1227 #, c-format msgid "" "“%s” is not a valid character following a “<” character; it may not begin an " @@ -4958,7 +5004,7 @@ "“%s” bukanlah karakter yang benar bila diikuti dengan karakter \"<\". Ini " "tidak boleh menjadi nama elemen" -#: glib/gmarkup.c:1264 +#: glib/gmarkup.c:1270 #, c-format msgid "" "Odd character “%s”, expected a “>” character to end the empty-element tag " @@ -4967,7 +5013,7 @@ "Ada karakter aneh “%s”, seharusnya ada \">\" untuk mengakhiri tag elemen " "kosong “%s”" -#: glib/gmarkup.c:1345 +#: glib/gmarkup.c:1352 #, c-format msgid "" "Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”" @@ -4975,7 +5021,7 @@ "Ada karakter aneh “%s”. Seharusnya ada karakter '=' setelah nama atribut " "“%s” pada elemen “%s”" -#: glib/gmarkup.c:1386 +#: glib/gmarkup.c:1394 #, c-format msgid "" "Odd character “%s”, expected a “>” or “/” character to end the start tag of " @@ -4986,7 +5032,7 @@ "padaelemen “%s”, atau bisa juga ada atribut lain. Mungkin Anda menggunakan " "karakter yang tidak diperbolehkan pada nama atribut" -#: glib/gmarkup.c:1430 +#: glib/gmarkup.c:1439 #, c-format msgid "" "Odd character “%s”, expected an open quote mark after the equals sign when " @@ -4995,7 +5041,7 @@ "Ada karakter aneh “%s”. Seharusnya ada tanda kutip buka setelah tanda sama " "dengan saat memberikan nilai atribut “%s” pada elemen “%s”" -#: glib/gmarkup.c:1563 +#: glib/gmarkup.c:1573 #, c-format msgid "" "“%s” is not a valid character following the characters “\"" -#: glib/gmarkup.c:1610 +#: glib/gmarkup.c:1623 #, c-format msgid "Element “%s” was closed, no element is currently open" msgstr "Elemen “%s” sudah ditutup, tidak ada elemen yang masih terbuka" -#: glib/gmarkup.c:1619 +#: glib/gmarkup.c:1632 #, c-format msgid "Element “%s” was closed, but the currently open element is “%s”" msgstr "Elemen “%s” sudah ditutup, tapi elemen yang masih terbuka adalah “%s”" -#: glib/gmarkup.c:1772 +#: glib/gmarkup.c:1785 msgid "Document was empty or contained only whitespace" msgstr "Dokumen kosong atau berisi whitespace saja" -#: glib/gmarkup.c:1786 +#: glib/gmarkup.c:1799 msgid "Document ended unexpectedly just after an open angle bracket “<”" msgstr "" "Dokumen terpotong tidak sempurna sesaat setelah membuka kurung siku \"<\"" -#: glib/gmarkup.c:1794 glib/gmarkup.c:1839 +#: glib/gmarkup.c:1807 glib/gmarkup.c:1852 #, c-format msgid "" "Document ended unexpectedly with elements still open — “%s” was the last " @@ -5041,7 +5087,7 @@ "Dokumen terpotong tidak sempurna dengan elemen yang masih terbuka — “%s” " "adalah elemen terakhir yang dibuka" -#: glib/gmarkup.c:1802 +#: glib/gmarkup.c:1815 #, c-format msgid "" "Document ended unexpectedly, expected to see a close angle bracket ending " @@ -5050,19 +5096,19 @@ "Dokumen terpotong tidak sempurna, seharusnya ada kurung siku penutup untuk " "mengakhiri tag <%s/>" -#: glib/gmarkup.c:1808 +#: glib/gmarkup.c:1821 msgid "Document ended unexpectedly inside an element name" msgstr "Dokumen terpotong tidak sempurna pada dalam nama elemen" -#: glib/gmarkup.c:1814 +#: glib/gmarkup.c:1827 msgid "Document ended unexpectedly inside an attribute name" msgstr "Dokumen terpotong tidak sempurna di dalam nama atribut" -#: glib/gmarkup.c:1819 +#: glib/gmarkup.c:1832 msgid "Document ended unexpectedly inside an element-opening tag." msgstr "Dokumen terpotong tidak sempurna di dalam tag pembukaan elemen." -#: glib/gmarkup.c:1825 +#: glib/gmarkup.c:1838 msgid "" "Document ended unexpectedly after the equals sign following an attribute " "name; no attribute value" @@ -5070,23 +5116,23 @@ "Dokumen terpotong tidak sempurna setelah tanda sama dengan mengikuti nama " "atribut. Tidak ada nilai atribut yang diperoleh" -#: glib/gmarkup.c:1832 +#: glib/gmarkup.c:1845 msgid "Document ended unexpectedly while inside an attribute value" msgstr "Dokumen tidak sempura saat ada dalam nilai atribut" -#: glib/gmarkup.c:1849 +#: glib/gmarkup.c:1862 #, c-format msgid "Document ended unexpectedly inside the close tag for element “%s”" msgstr "Dokumen terpotong tidak sempurna di dalam tag penutup elemen “%s”" -#: glib/gmarkup.c:1853 +#: glib/gmarkup.c:1866 msgid "" "Document ended unexpectedly inside the close tag for an unopened element" msgstr "" "Dokumen terpotong tidak sempurna di dalam tag penutup untuk elemen yang " "belum dibuka" -#: glib/gmarkup.c:1859 +#: glib/gmarkup.c:1872 msgid "Document ended unexpectedly inside a comment or processing instruction" msgstr "" "Dokumen terpotong tidak sempurna di dalam keterangan atau instruksi " @@ -5507,15 +5553,15 @@ msgid "illegal symbolic reference" msgstr "acuan simbolis yang tak legal" -#: glib/gregex.c:2582 +#: glib/gregex.c:2583 msgid "stray final “\\”" msgstr "\"\\\" akhir yang tersesat" -#: glib/gregex.c:2586 +#: glib/gregex.c:2587 msgid "unknown escape sequence" msgstr "urutan escape tak dikenal" -#: glib/gregex.c:2596 +#: glib/gregex.c:2597 #, c-format msgid "Error while parsing replacement text “%s” at char %lu: %s" msgstr "Galat saat mengurai teks pengganti \"%s\" pada karakter %lu: %s" @@ -5546,128 +5592,128 @@ msgid "Text was empty (or contained only whitespace)" msgstr "Teksnya kosong (atau hanya berisi whitespace)" -#: glib/gspawn.c:308 +#: glib/gspawn.c:315 #, c-format msgid "Failed to read data from child process (%s)" msgstr "Gagal saat membaca data dari proses child (%s)" -#: glib/gspawn.c:456 +#: glib/gspawn.c:463 #, c-format msgid "Unexpected error in select() reading data from a child process (%s)" msgstr "" "Terjadi galat pada fungsi select() ketika membaca data dari anak proses (%s)" -#: glib/gspawn.c:541 +#: glib/gspawn.c:548 #, c-format msgid "Unexpected error in waitpid() (%s)" msgstr "Terjadi galat pada fungsi waitpid() (%s)" -#: glib/gspawn.c:1049 glib/gspawn-win32.c:1318 +#: glib/gspawn.c:1056 glib/gspawn-win32.c:1329 #, c-format msgid "Child process exited with code %ld" msgstr "Proses anak keluar dengan kode %ld" -#: glib/gspawn.c:1057 +#: glib/gspawn.c:1064 #, c-format msgid "Child process killed by signal %ld" msgstr "Proses anak dimatikan oleh sinyal %ld" -#: glib/gspawn.c:1064 +#: glib/gspawn.c:1071 #, c-format msgid "Child process stopped by signal %ld" msgstr "Proses anak dihentikan oleh sinyal %ld" -#: glib/gspawn.c:1071 +#: glib/gspawn.c:1078 #, c-format msgid "Child process exited abnormally" msgstr "Proses anak keluar secara tak normal" -#: glib/gspawn.c:1366 glib/gspawn-win32.c:339 glib/gspawn-win32.c:347 +#: glib/gspawn.c:1405 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 #, c-format msgid "Failed to read from child pipe (%s)" msgstr "Gagal saat membaca dari pipe child (%s)" -#: glib/gspawn.c:1614 +#: glib/gspawn.c:1653 #, c-format msgid "Failed to spawn child process “%s” (%s)" msgstr "Gagal menelurkan proses anak \"%s\" (%s)" -#: glib/gspawn.c:1653 +#: glib/gspawn.c:1692 #, c-format msgid "Failed to fork (%s)" msgstr "Gagal saat fork (%s)" -#: glib/gspawn.c:1802 glib/gspawn-win32.c:370 +#: glib/gspawn.c:1841 glib/gspawn-win32.c:381 #, c-format msgid "Failed to change to directory “%s” (%s)" msgstr "Gagal pindah ke direktori \"%s\" (%s)" -#: glib/gspawn.c:1812 +#: glib/gspawn.c:1851 #, c-format msgid "Failed to execute child process “%s” (%s)" msgstr "Gagal menjalankan proses anak \"%s\" (%s)" -#: glib/gspawn.c:1822 +#: glib/gspawn.c:1861 #, c-format msgid "Failed to redirect output or input of child process (%s)" msgstr "Gagal mengarahkan output atau input pada proses child (%s)" -#: glib/gspawn.c:1831 +#: glib/gspawn.c:1870 #, c-format msgid "Failed to fork child process (%s)" msgstr "Gagal saat fork proses child (%s)" -#: glib/gspawn.c:1839 +#: glib/gspawn.c:1878 #, c-format msgid "Unknown error executing child process “%s”" msgstr "Galat tak dikenal ketika menjalankan proses anak \"%s\"" -#: glib/gspawn.c:1863 +#: glib/gspawn.c:1902 #, c-format msgid "Failed to read enough data from child pid pipe (%s)" msgstr "Gagal saat membaca data yang dibutuhkan dai pipe pid child (%s)" -#: glib/gspawn-win32.c:283 +#: glib/gspawn-win32.c:294 msgid "Failed to read data from child process" msgstr "Gagal untuk membaca data dari proses child" -#: glib/gspawn-win32.c:300 +#: glib/gspawn-win32.c:311 #, c-format msgid "Failed to create pipe for communicating with child process (%s)" msgstr "" "Gagal saat membuat pipe untuk sarana komunikasi dengan proses child (%s)" -#: glib/gspawn-win32.c:376 glib/gspawn-win32.c:381 glib/gspawn-win32.c:500 +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 #, c-format msgid "Failed to execute child process (%s)" msgstr "Gagal saat menjalankan proses child (%s)" -#: glib/gspawn-win32.c:450 +#: glib/gspawn-win32.c:461 #, c-format msgid "Invalid program name: %s" msgstr "Nama program salah: %s" -#: glib/gspawn-win32.c:460 glib/gspawn-win32.c:714 +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 #, c-format msgid "Invalid string in argument vector at %d: %s" msgstr "String tidak benar pada vektor argumen pada %d: %s" -#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:729 +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 #, c-format msgid "Invalid string in environment: %s" msgstr "String tidak benar pada variabel lingkungan: %s" -#: glib/gspawn-win32.c:710 +#: glib/gspawn-win32.c:721 #, c-format msgid "Invalid working directory: %s" msgstr "Direktori aktif salah: %s" -#: glib/gspawn-win32.c:772 +#: glib/gspawn-win32.c:783 #, c-format msgid "Failed to execute helper program (%s)" msgstr "Gagal saat menjalankan program bantuan (%s)" -#: glib/gspawn-win32.c:1045 +#: glib/gspawn-win32.c:1056 msgid "" "Unexpected error in g_io_channel_win32_poll() reading data from a child " "process" @@ -5675,21 +5721,21 @@ "Terjadi galat pada g_io_channel_win32_poll() ketika membaca data dari anak " "proses" -#: glib/gstrfuncs.c:3247 glib/gstrfuncs.c:3348 +#: glib/gstrfuncs.c:3286 glib/gstrfuncs.c:3388 msgid "Empty string is not a number" msgstr "String kosong bukan angka" -#: glib/gstrfuncs.c:3271 +#: glib/gstrfuncs.c:3310 #, c-format msgid "“%s” is not a signed number" msgstr "\"%s\" bukan bilangan bertanda" -#: glib/gstrfuncs.c:3281 glib/gstrfuncs.c:3384 +#: glib/gstrfuncs.c:3320 glib/gstrfuncs.c:3424 #, c-format msgid "Number “%s” is out of bounds [%s, %s]" msgstr "Nomor \"%s\" berada di luar batas [%s, %s]" -#: glib/gstrfuncs.c:3374 +#: glib/gstrfuncs.c:3414 #, c-format msgid "“%s” is not an unsigned number" msgstr "\"%s\" bukan bilangan tak bertanda" @@ -5711,162 +5757,215 @@ msgid "Character out of range for UTF-16" msgstr "Karakter di luar jangkauan UTF-16" -#: glib/gutils.c:2244 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2339 #, c-format -msgid "%.1f kB" -msgstr "%.1f kB" +msgid "%.1f kB" +msgstr "%.1f kB" -#: glib/gutils.c:2245 glib/gutils.c:2451 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2341 #, c-format -msgid "%.1f MB" -msgstr "%.1f MB" +msgid "%.1f MB" +msgstr "%.1f MB" -#: glib/gutils.c:2246 glib/gutils.c:2456 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2343 #, c-format -msgid "%.1f GB" -msgstr "%.1f GB" +msgid "%.1f GB" +msgstr "%.1f GB" -#: glib/gutils.c:2247 glib/gutils.c:2461 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2345 #, c-format -msgid "%.1f TB" -msgstr "%.1f TB" +msgid "%.1f TB" +msgstr "%.1f TB" -#: glib/gutils.c:2248 glib/gutils.c:2466 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2347 #, c-format -msgid "%.1f PB" -msgstr "%.1f PB" +msgid "%.1f PB" +msgstr "%.1f PB" -#: glib/gutils.c:2249 glib/gutils.c:2471 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2349 #, c-format -msgid "%.1f EB" -msgstr "%.1f EB" +msgid "%.1f EB" +msgstr "%.1f EB" -#: glib/gutils.c:2252 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2353 #, c-format -msgid "%.1f KiB" -msgstr "%.1f KiB" +msgid "%.1f KiB" +msgstr "%.1f KiB" -#: glib/gutils.c:2253 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2355 #, c-format -msgid "%.1f MiB" -msgstr "%.1f MiB" +msgid "%.1f MiB" +msgstr "%.1f MiB" -#: glib/gutils.c:2254 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2357 #, c-format -msgid "%.1f GiB" -msgstr "%.1f GiB" +msgid "%.1f GiB" +msgstr "%.1f GiB" -#: glib/gutils.c:2255 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2359 #, c-format -msgid "%.1f TiB" -msgstr "%.1f TiB" +msgid "%.1f TiB" +msgstr "%.1f TiB" -#: glib/gutils.c:2256 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2361 #, c-format -msgid "%.1f PiB" -msgstr "%.1f PiB" +msgid "%.1f PiB" +msgstr "%.1f PiB" -#: glib/gutils.c:2257 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2363 #, c-format -msgid "%.1f EiB" -msgstr "%.1f EiB" +msgid "%.1f EiB" +msgstr "%.1f EiB" -#: glib/gutils.c:2260 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2367 #, c-format -msgid "%.1f kb" -msgstr "%.1f kb" +msgid "%.1f kb" +msgstr "%.1f kb" -#: glib/gutils.c:2261 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2369 #, c-format -msgid "%.1f Mb" -msgstr "%.1f Mb" +msgid "%.1f Mb" +msgstr "%.1f Mb" -#: glib/gutils.c:2262 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2371 #, c-format -msgid "%.1f Gb" -msgstr "%.1f Gb" +msgid "%.1f Gb" +msgstr "%.1f Gb" -#: glib/gutils.c:2263 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2373 #, c-format -msgid "%.1f Tb" -msgstr "%.1f Tb" +msgid "%.1f Tb" +msgstr "%.1f Tb" -#: glib/gutils.c:2264 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2375 #, c-format -msgid "%.1f Pb" -msgstr "%.1f Pb" +msgid "%.1f Pb" +msgstr "%.1f Pb" -#: glib/gutils.c:2265 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2377 #, c-format -msgid "%.1f Eb" -msgstr "%.1f Eb" +msgid "%.1f Eb" +msgstr "%.1f Eb" -#: glib/gutils.c:2268 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2381 #, c-format -msgid "%.1f Kib" -msgstr "%.1f Kib" +msgid "%.1f Kib" +msgstr "%.1f Kib" -#: glib/gutils.c:2269 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2383 #, c-format -msgid "%.1f Mib" -msgstr "%.1f Mib" +msgid "%.1f Mib" +msgstr "%.1f Mib" -#: glib/gutils.c:2270 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2385 #, c-format -msgid "%.1f Gib" -msgstr "%.1f Gib" +msgid "%.1f Gib" +msgstr "%.1f Gib" -#: glib/gutils.c:2271 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2387 #, c-format -msgid "%.1f Tib" -msgstr "%.1f Tib" +msgid "%.1f Tib" +msgstr "%.1f Tib" -#: glib/gutils.c:2272 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2389 #, c-format -msgid "%.1f Pib" -msgstr "%.1f Pib" +msgid "%.1f Pib" +msgstr "%.1f Pib" -#: glib/gutils.c:2273 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2391 #, c-format -msgid "%.1f Eib" -msgstr "%.1f Eib" +msgid "%.1f Eib" +msgstr "%.1f Eib" -#: glib/gutils.c:2307 glib/gutils.c:2433 +#: glib/gutils.c:2425 glib/gutils.c:2551 #, c-format msgid "%u byte" msgid_plural "%u bytes" msgstr[0] "%u bita" +msgstr[1] "%u bita" -#: glib/gutils.c:2311 +#: glib/gutils.c:2429 #, c-format msgid "%u bit" msgid_plural "%u bits" msgstr[0] "%u bita" +msgstr[1] "%u bita" #. Translators: the %s in "%s bytes" will always be replaced by a number. -#: glib/gutils.c:2378 +#: glib/gutils.c:2496 #, c-format msgid "%s byte" msgid_plural "%s bytes" msgstr[0] "%s bita" +msgstr[1] "%s bita" #. Translators: the %s in "%s bits" will always be replaced by a number. -#: glib/gutils.c:2383 +#: glib/gutils.c:2501 #, c-format msgid "%s bit" msgid_plural "%s bits" msgstr[0] "%s bita" +msgstr[1] "%s bita" #. Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to #. * mean 1024 bytes. I am aware that 'KB' is not correct, but it has been preserved for reasons of #. * compatibility. Users will not see this string unless a program is using this deprecated function. #. * Please translate as literally as possible. #. -#: glib/gutils.c:2446 +#: glib/gutils.c:2564 #, c-format msgid "%.1f KB" msgstr "%.1f KB" +#: glib/gutils.c:2569 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2574 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2579 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2584 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2589 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + #~ msgid "No such method '%s'" #~ msgstr "Tak ada metoda '%s'" diff -Nru glib2.0-2.59.2/po/kk.po glib2.0-2.59.3/po/kk.po --- glib2.0-2.59.2/po/kk.po 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/kk.po 2019-03-04 09:01:42.000000000 +0000 @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" -"POT-Creation-Date: 2018-07-30 18:46+0000\n" -"PO-Revision-Date: 2018-08-25 22:32+0500\n" +"POT-Creation-Date: 2019-02-12 14:26+0000\n" +"PO-Revision-Date: 2019-02-16 17:15+0500\n" "Last-Translator: Baurzhan Muftakhidinov \n" "Language-Team: Kazakh \n" "Language: kk\n" @@ -16,30 +16,34 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 2.1.1\n" +"X-Generator: Poedit 2.2.1\n" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "GApplication options" msgstr "GApplication опциялары" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "Show GApplication options" msgstr "GApplication опцияларын көрсету" -#: gio/gapplication.c:541 +#: gio/gapplication.c:544 msgid "Enter GApplication service mode (use from D-Bus service files)" msgstr "" -#: gio/gapplication.c:553 +#: gio/gapplication.c:556 msgid "Override the application’s ID" msgstr "" +#: gio/gapplication.c:568 +msgid "Replace the running instance" +msgstr "" + #: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 -#: gio/gresource-tool.c:488 gio/gsettings-tool.c:569 +#: gio/gresource-tool.c:495 gio/gsettings-tool.c:569 msgid "Print help" msgstr "Көмекті шығару" -#: gio/gapplication-tool.c:47 gio/gresource-tool.c:489 gio/gresource-tool.c:557 +#: gio/gapplication-tool.c:47 gio/gresource-tool.c:496 gio/gresource-tool.c:564 msgid "[COMMAND]" msgstr "[КОМАНДА]" @@ -108,9 +112,9 @@ msgid "Application identifier in D-Bus format (eg: org.example.viewer)" msgstr "" -#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:737 -#: gio/glib-compile-resources.c:743 gio/glib-compile-resources.c:770 -#: gio/gresource-tool.c:495 gio/gresource-tool.c:561 +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 +#: gio/gresource-tool.c:502 gio/gresource-tool.c:568 msgid "FILE" msgstr "ФАЙЛ" @@ -134,7 +138,7 @@ msgid "Optional parameter to the action invocation, in GVariant format" msgstr "" -#: gio/gapplication-tool.c:96 gio/gresource-tool.c:526 gio/gsettings-tool.c:661 +#: gio/gapplication-tool.c:96 gio/gresource-tool.c:533 gio/gsettings-tool.c:661 #, c-format msgid "" "Unknown command %s\n" @@ -145,7 +149,7 @@ msgid "Usage:\n" msgstr "Қолданылуы:\n" -#: gio/gapplication-tool.c:114 gio/gresource-tool.c:551 +#: gio/gapplication-tool.c:114 gio/gresource-tool.c:558 #: gio/gsettings-tool.c:696 msgid "Arguments:\n" msgstr "Аргументтер:\n" @@ -239,8 +243,8 @@ #: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 #: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 -#: gio/ginputstream.c:1019 gio/goutputstream.c:203 gio/goutputstream.c:834 -#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:209 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 #, c-format msgid "Too large count value passed to %s" msgstr "" @@ -255,7 +259,7 @@ msgstr "" #: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 -#: gio/goutputstream.c:1661 +#: gio/goutputstream.c:2198 msgid "Stream is already closed" msgstr "" @@ -263,7 +267,7 @@ msgid "Truncate not supported on base stream" msgstr "" -#: gio/gcancellable.c:317 gio/gdbusconnection.c:1840 gio/gdbusprivate.c:1402 +#: gio/gcancellable.c:317 gio/gdbusconnection.c:1867 gio/gdbusprivate.c:1402 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 #, c-format msgid "Operation was cancelled" @@ -282,33 +286,33 @@ msgstr "" #: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 -#: gio/gdatainputstream.c:1261 glib/gconvert.c:454 glib/gconvert.c:883 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:455 glib/gconvert.c:885 #: glib/giochannel.c:1557 glib/giochannel.c:1599 glib/giochannel.c:2443 #: glib/gutf8.c:869 glib/gutf8.c:1322 msgid "Invalid byte sequence in conversion input" msgstr "" -#: gio/gcharsetconverter.c:347 glib/gconvert.c:462 glib/gconvert.c:797 +#: gio/gcharsetconverter.c:347 glib/gconvert.c:463 glib/gconvert.c:799 #: glib/giochannel.c:1564 glib/giochannel.c:2455 #, c-format msgid "Error during conversion: %s" msgstr "" -#: gio/gcharsetconverter.c:445 gio/gsocket.c:1104 +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1093 msgid "Cancellable initialization not supported" msgstr "Бас тартуға болатын инициализацияға қолдау жоқ" -#: gio/gcharsetconverter.c:456 glib/gconvert.c:327 glib/giochannel.c:1385 +#: gio/gcharsetconverter.c:456 glib/gconvert.c:328 glib/giochannel.c:1385 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported" msgstr "" -#: gio/gcharsetconverter.c:460 glib/gconvert.c:331 +#: gio/gcharsetconverter.c:460 glib/gconvert.c:332 #, c-format msgid "Could not open converter from “%s” to “%s”" msgstr "" -#: gio/gcontenttype.c:358 +#: gio/gcontenttype.c:452 #, c-format msgid "%s type" msgstr "%s түрі" @@ -476,14 +480,14 @@ msgid "Cannot determine session bus address (not implemented for this OS)" msgstr "" -#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7142 +#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7174 #, c-format msgid "" "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " "— unknown value “%s”" msgstr "" -#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7151 +#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7183 msgid "" "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " "variable is not set" @@ -585,157 +589,157 @@ msgid "(Additionally, releasing the lock for “%s” also failed: %s) " msgstr "" -#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2369 +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2396 msgid "The connection is closed" msgstr "Байланыс жабылған" -#: gio/gdbusconnection.c:1870 +#: gio/gdbusconnection.c:1897 msgid "Timeout was reached" msgstr "" -#: gio/gdbusconnection.c:2491 +#: gio/gdbusconnection.c:2518 msgid "" "Unsupported flags encountered when constructing a client-side connection" msgstr "" -#: gio/gdbusconnection.c:4115 gio/gdbusconnection.c:4462 +#: gio/gdbusconnection.c:4147 gio/gdbusconnection.c:4494 #, c-format msgid "" "No such interface “org.freedesktop.DBus.Properties” on object at path %s" msgstr "" -#: gio/gdbusconnection.c:4257 +#: gio/gdbusconnection.c:4289 #, c-format msgid "No such property “%s”" msgstr "\"%s\" қасиеті табылмады" -#: gio/gdbusconnection.c:4269 +#: gio/gdbusconnection.c:4301 #, c-format msgid "Property “%s” is not readable" msgstr "\"%s\" қасиетін оқу мүмкін емес" -#: gio/gdbusconnection.c:4280 +#: gio/gdbusconnection.c:4312 #, c-format msgid "Property “%s” is not writable" msgstr "\"%s\" қасиетін жазу мүмкін емес" -#: gio/gdbusconnection.c:4300 +#: gio/gdbusconnection.c:4332 #, c-format msgid "Error setting property “%s”: Expected type “%s” but got “%s”" msgstr "" -#: gio/gdbusconnection.c:4405 gio/gdbusconnection.c:4613 -#: gio/gdbusconnection.c:6582 +#: gio/gdbusconnection.c:4437 gio/gdbusconnection.c:4645 +#: gio/gdbusconnection.c:6614 #, c-format msgid "No such interface “%s”" msgstr "" -#: gio/gdbusconnection.c:4831 gio/gdbusconnection.c:7091 +#: gio/gdbusconnection.c:4863 gio/gdbusconnection.c:7123 #, c-format msgid "No such interface “%s” on object at path %s" msgstr "" -#: gio/gdbusconnection.c:4929 +#: gio/gdbusconnection.c:4961 #, c-format msgid "No such method “%s”" msgstr "" -#: gio/gdbusconnection.c:4960 +#: gio/gdbusconnection.c:4992 #, c-format msgid "Type of message, “%s”, does not match expected type “%s”" msgstr "" -#: gio/gdbusconnection.c:5158 +#: gio/gdbusconnection.c:5190 #, c-format msgid "An object is already exported for the interface %s at %s" msgstr "" -#: gio/gdbusconnection.c:5384 +#: gio/gdbusconnection.c:5416 #, c-format msgid "Unable to retrieve property %s.%s" msgstr "" -#: gio/gdbusconnection.c:5440 +#: gio/gdbusconnection.c:5472 #, c-format msgid "Unable to set property %s.%s" msgstr "%s қасиетін орнату мүмкін емес.%s" -#: gio/gdbusconnection.c:5618 +#: gio/gdbusconnection.c:5650 #, c-format msgid "Method “%s” returned type “%s”, but expected “%s”" msgstr "" -#: gio/gdbusconnection.c:6693 +#: gio/gdbusconnection.c:6725 #, c-format msgid "Method “%s” on interface “%s” with signature “%s” does not exist" msgstr "" -#: gio/gdbusconnection.c:6814 +#: gio/gdbusconnection.c:6846 #, c-format msgid "A subtree is already exported for %s" msgstr "" -#: gio/gdbusmessage.c:1248 +#: gio/gdbusmessage.c:1251 msgid "type is INVALID" msgstr "" -#: gio/gdbusmessage.c:1259 +#: gio/gdbusmessage.c:1262 msgid "METHOD_CALL message: PATH or MEMBER header field is missing" msgstr "" -#: gio/gdbusmessage.c:1270 +#: gio/gdbusmessage.c:1273 msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" msgstr "" -#: gio/gdbusmessage.c:1282 +#: gio/gdbusmessage.c:1285 msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" msgstr "" -#: gio/gdbusmessage.c:1295 +#: gio/gdbusmessage.c:1298 msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" msgstr "" -#: gio/gdbusmessage.c:1303 +#: gio/gdbusmessage.c:1306 msgid "" "SIGNAL message: The PATH header field is using the reserved value /org/" "freedesktop/DBus/Local" msgstr "" -#: gio/gdbusmessage.c:1311 +#: gio/gdbusmessage.c:1314 msgid "" "SIGNAL message: The INTERFACE header field is using the reserved value org." "freedesktop.DBus.Local" msgstr "" -#: gio/gdbusmessage.c:1359 gio/gdbusmessage.c:1419 +#: gio/gdbusmessage.c:1362 gio/gdbusmessage.c:1422 #, c-format msgid "Wanted to read %lu byte but only got %lu" msgid_plural "Wanted to read %lu bytes but only got %lu" msgstr[0] "" -#: gio/gdbusmessage.c:1373 +#: gio/gdbusmessage.c:1376 #, c-format msgid "Expected NUL byte after the string “%s” but found byte %d" msgstr "" -#: gio/gdbusmessage.c:1392 +#: gio/gdbusmessage.c:1395 #, c-format msgid "" "Expected valid UTF-8 string but found invalid bytes at byte offset %d " "(length of string is %d). The valid UTF-8 string up until that point was “%s”" msgstr "" -#: gio/gdbusmessage.c:1595 +#: gio/gdbusmessage.c:1598 #, c-format msgid "Parsed value “%s” is not a valid D-Bus object path" msgstr "" -#: gio/gdbusmessage.c:1617 +#: gio/gdbusmessage.c:1620 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature" msgstr "" -#: gio/gdbusmessage.c:1664 +#: gio/gdbusmessage.c:1667 #, c-format msgid "" "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." @@ -743,121 +747,126 @@ "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." msgstr[0] "" -#: gio/gdbusmessage.c:1684 +#: gio/gdbusmessage.c:1687 #, c-format msgid "" "Encountered array of type “a%c”, expected to have a length a multiple of %u " "bytes, but found to be %u bytes in length" msgstr "" -#: gio/gdbusmessage.c:1851 +#: gio/gdbusmessage.c:1857 #, c-format msgid "Parsed value “%s” for variant is not a valid D-Bus signature" msgstr "" -#: gio/gdbusmessage.c:1875 +#: gio/gdbusmessage.c:1881 #, c-format msgid "" "Error deserializing GVariant with type string “%s” from the D-Bus wire format" msgstr "" -#: gio/gdbusmessage.c:2057 +#: gio/gdbusmessage.c:2066 #, c-format msgid "" "Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value " "0x%02x" msgstr "" -#: gio/gdbusmessage.c:2070 +#: gio/gdbusmessage.c:2079 #, c-format msgid "Invalid major protocol version. Expected 1 but found %d" msgstr "" -#: gio/gdbusmessage.c:2126 +#: gio/gdbusmessage.c:2132 gio/gdbusmessage.c:2724 +msgid "Signature header found but is not of type signature" +msgstr "" + +#: gio/gdbusmessage.c:2144 #, c-format msgid "Signature header with signature “%s” found but message body is empty" msgstr "" -#: gio/gdbusmessage.c:2140 +#: gio/gdbusmessage.c:2159 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature (for body)" msgstr "" -#: gio/gdbusmessage.c:2170 +#: gio/gdbusmessage.c:2190 #, c-format msgid "No signature header in message but the message body is %u byte" msgid_plural "No signature header in message but the message body is %u bytes" msgstr[0] "" -#: gio/gdbusmessage.c:2180 +#: gio/gdbusmessage.c:2200 msgid "Cannot deserialize message: " msgstr "" -#: gio/gdbusmessage.c:2521 +#: gio/gdbusmessage.c:2541 #, c-format msgid "" "Error serializing GVariant with type string “%s” to the D-Bus wire format" msgstr "" -#: gio/gdbusmessage.c:2658 +#: gio/gdbusmessage.c:2678 #, c-format msgid "" "Number of file descriptors in message (%d) differs from header field (%d)" msgstr "" -#: gio/gdbusmessage.c:2666 +#: gio/gdbusmessage.c:2686 msgid "Cannot serialize message: " msgstr "" -#: gio/gdbusmessage.c:2710 +#: gio/gdbusmessage.c:2739 #, c-format msgid "Message body has signature “%s” but there is no signature header" msgstr "" -#: gio/gdbusmessage.c:2720 +#: gio/gdbusmessage.c:2749 #, c-format msgid "" "Message body has type signature “%s” but signature in the header field is " "“%s”" msgstr "" -#: gio/gdbusmessage.c:2736 +#: gio/gdbusmessage.c:2765 #, c-format msgid "Message body is empty but signature in the header field is “(%s)”" msgstr "" -#: gio/gdbusmessage.c:3289 +#: gio/gdbusmessage.c:3318 #, c-format msgid "Error return with body of type “%s”" msgstr "" -#: gio/gdbusmessage.c:3297 +#: gio/gdbusmessage.c:3326 msgid "Error return with empty body" msgstr "" -#: gio/gdbusprivate.c:2066 +#: gio/gdbusprivate.c:2075 #, c-format msgid "Unable to get Hardware profile: %s" msgstr "" -#: gio/gdbusprivate.c:2111 +#: gio/gdbusprivate.c:2120 msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " msgstr "" -#: gio/gdbusproxy.c:1612 +#: gio/gdbusproxy.c:1617 #, c-format msgid "Error calling StartServiceByName for %s: " msgstr "" -#: gio/gdbusproxy.c:1635 +#: gio/gdbusproxy.c:1640 #, c-format msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" msgstr "" -#: gio/gdbusproxy.c:2726 gio/gdbusproxy.c:2860 +#: gio/gdbusproxy.c:2740 gio/gdbusproxy.c:2875 +#, c-format msgid "" -"Cannot invoke method; proxy is for a well-known name without an owner and " -"proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" msgstr "" #: gio/gdbusserver.c:708 @@ -1142,38 +1151,38 @@ msgid "Error: %s is not a valid well-known bus name.\n" msgstr "Қате: \"%s\" - кеңінен белгілі шина аты емес.\n" -#: gio/gdesktopappinfo.c:2023 gio/gdesktopappinfo.c:4633 +#: gio/gdesktopappinfo.c:2041 gio/gdesktopappinfo.c:4822 msgid "Unnamed" msgstr "Атаусыз" -#: gio/gdesktopappinfo.c:2433 +#: gio/gdesktopappinfo.c:2451 msgid "Desktop file didn’t specify Exec field" msgstr "" -#: gio/gdesktopappinfo.c:2692 +#: gio/gdesktopappinfo.c:2710 msgid "Unable to find terminal required for application" msgstr "" -#: gio/gdesktopappinfo.c:3202 +#: gio/gdesktopappinfo.c:3362 #, c-format msgid "Can’t create user application configuration folder %s: %s" msgstr "" -#: gio/gdesktopappinfo.c:3206 +#: gio/gdesktopappinfo.c:3366 #, c-format msgid "Can’t create user MIME configuration folder %s: %s" msgstr "" -#: gio/gdesktopappinfo.c:3446 gio/gdesktopappinfo.c:3470 +#: gio/gdesktopappinfo.c:3606 gio/gdesktopappinfo.c:3630 msgid "Application information lacks an identifier" msgstr "" -#: gio/gdesktopappinfo.c:3704 +#: gio/gdesktopappinfo.c:3864 #, c-format msgid "Can’t create user desktop file %s" msgstr "%s пайдаланушы жұмыс үстел файлын жасау мүмкін емес" -#: gio/gdesktopappinfo.c:3838 +#: gio/gdesktopappinfo.c:3998 #, c-format msgid "Custom definition for %s" msgstr "" @@ -1239,7 +1248,7 @@ #: gio/gfile.c:2008 gio/gfile.c:2063 gio/gfile.c:3738 gio/gfile.c:3793 #: gio/gfile.c:4029 gio/gfile.c:4071 gio/gfile.c:4539 gio/gfile.c:4950 #: gio/gfile.c:5035 gio/gfile.c:5125 gio/gfile.c:5222 gio/gfile.c:5309 -#: gio/gfile.c:5410 gio/gfile.c:7988 gio/gfile.c:8078 gio/gfile.c:8162 +#: gio/gfile.c:5410 gio/gfile.c:8113 gio/gfile.c:8203 gio/gfile.c:8287 #: gio/win32/gwinhttpfile.c:437 msgid "Operation not supported" msgstr "Әрекетке қолдау жоқ" @@ -1252,7 +1261,7 @@ msgid "Containing mount does not exist" msgstr "" -#: gio/gfile.c:2622 gio/glocalfile.c:2391 +#: gio/gfile.c:2622 gio/glocalfile.c:2446 msgid "Can’t copy over directory" msgstr "Бума үстіне көшіру мүмкін емес" @@ -1310,7 +1319,7 @@ msgid "volume doesn’t implement mount" msgstr "" -#: gio/gfile.c:6882 +#: gio/gfile.c:6884 gio/gfile.c:6930 msgid "No application is registered as handling this file" msgstr "" @@ -1355,8 +1364,8 @@ msgid "Truncate not supported on stream" msgstr "" -#: gio/ghttpproxy.c:91 gio/gresolver.c:410 gio/gresolver.c:476 -#: glib/gconvert.c:1786 +#: gio/ghttpproxy.c:91 gio/gresolver.c:377 gio/gresolver.c:529 +#: glib/gconvert.c:1785 msgid "Invalid hostname" msgstr "Хост аты қате" @@ -1385,37 +1394,37 @@ msgid "HTTP proxy server closed connection unexpectedly." msgstr "" -#: gio/gicon.c:290 +#: gio/gicon.c:298 #, c-format msgid "Wrong number of tokens (%d)" msgstr "" -#: gio/gicon.c:310 +#: gio/gicon.c:318 #, c-format msgid "No type for class name %s" msgstr "" -#: gio/gicon.c:320 +#: gio/gicon.c:328 #, c-format msgid "Type %s does not implement the GIcon interface" msgstr "" -#: gio/gicon.c:331 +#: gio/gicon.c:339 #, c-format msgid "Type %s is not classed" msgstr "" -#: gio/gicon.c:345 +#: gio/gicon.c:353 #, c-format msgid "Malformed version number: %s" msgstr "" -#: gio/gicon.c:359 +#: gio/gicon.c:367 #, c-format msgid "Type %s does not implement from_tokens() on the GIcon interface" msgstr "" -#: gio/gicon.c:461 +#: gio/gicon.c:469 msgid "Can’t handle the supplied version of the icon encoding" msgstr "" @@ -1456,7 +1465,7 @@ #. Translators: This is an error you get if there is #. * already an operation running against this stream when #. * you try to start one -#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:1671 +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 msgid "Stream has outstanding operation" msgstr "" @@ -1561,7 +1570,7 @@ #: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:282 gio/gio-tool-list.c:165 #: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 #: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 -#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1235 gio/gio-tool-open.c:113 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:70 #: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 #: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 msgid "LOCATION" @@ -1579,7 +1588,7 @@ msgstr "" #: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:313 gio/gio-tool-mkdir.c:76 -#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1285 gio/gio-tool-open.c:139 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:96 #: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 msgid "No locations given" msgstr "" @@ -1851,95 +1860,93 @@ msgid "Monitor files or directories for changes." msgstr "" -#: gio/gio-tool-mount.c:62 +#: gio/gio-tool-mount.c:63 msgid "Mount as mountable" msgstr "Тіркелетін ретінде тіркеу" -#: gio/gio-tool-mount.c:63 +#: gio/gio-tool-mount.c:64 msgid "Mount volume with device file" msgstr "" -#: gio/gio-tool-mount.c:63 gio/gio-tool-mount.c:66 +#: gio/gio-tool-mount.c:64 gio/gio-tool-mount.c:67 msgid "DEVICE" msgstr "ҚҰРЫЛҒЫ" -#: gio/gio-tool-mount.c:64 +#: gio/gio-tool-mount.c:65 msgid "Unmount" msgstr "Тіркеуден босату" -#: gio/gio-tool-mount.c:65 +#: gio/gio-tool-mount.c:66 msgid "Eject" msgstr "Шығару" -#: gio/gio-tool-mount.c:66 +#: gio/gio-tool-mount.c:67 msgid "Stop drive with device file" msgstr "" -#: gio/gio-tool-mount.c:67 +#: gio/gio-tool-mount.c:68 msgid "Unmount all mounts with the given scheme" msgstr "" -#: gio/gio-tool-mount.c:67 +#: gio/gio-tool-mount.c:68 msgid "SCHEME" msgstr "СХЕМА" -#: gio/gio-tool-mount.c:68 +#: gio/gio-tool-mount.c:69 msgid "Ignore outstanding file operations when unmounting or ejecting" msgstr "" -#: gio/gio-tool-mount.c:69 +#: gio/gio-tool-mount.c:70 msgid "Use an anonymous user when authenticating" msgstr "" #. Translator: List here is a verb as in 'List all mounts' -#: gio/gio-tool-mount.c:71 +#: gio/gio-tool-mount.c:72 msgid "List" msgstr "Тізім" -#: gio/gio-tool-mount.c:72 +#: gio/gio-tool-mount.c:73 msgid "Monitor events" msgstr "Оқиғаларды бақылау" -#: gio/gio-tool-mount.c:73 +#: gio/gio-tool-mount.c:74 msgid "Show extra information" msgstr "Қосымша ақпаратты көрсету" -#: gio/gio-tool-mount.c:74 +#: gio/gio-tool-mount.c:75 msgid "The numeric PIM when unlocking a VeraCrypt volume" msgstr "" -#: gio/gio-tool-mount.c:74 -#| msgctxt "GDateTime" -#| msgid "PM" +#: gio/gio-tool-mount.c:75 msgid "PIM" msgstr "" -#: gio/gio-tool-mount.c:75 +#: gio/gio-tool-mount.c:76 msgid "Mount a TCRYPT hidden volume" msgstr "" -#: gio/gio-tool-mount.c:76 +#: gio/gio-tool-mount.c:77 msgid "Mount a TCRYPT system volume" msgstr "" -#: gio/gio-tool-mount.c:264 gio/gio-tool-mount.c:296 +#: gio/gio-tool-mount.c:265 gio/gio-tool-mount.c:297 msgid "Anonymous access denied" msgstr "" -#: gio/gio-tool-mount.c:524 +#: gio/gio-tool-mount.c:522 msgid "No drive for device file" msgstr "" -#: gio/gio-tool-mount.c:989 +#: gio/gio-tool-mount.c:975 #, c-format msgid "Mounted %s at %s\n" msgstr "" -#: gio/gio-tool-mount.c:1044 +#: gio/gio-tool-mount.c:1027 msgid "No volume for device file" msgstr "" -#: gio/gio-tool-mount.c:1239 +#: gio/gio-tool-mount.c:1216 msgid "Mount or unmount the locations." msgstr "Орналасуларды тіркеу немесе тіркеуден шығару." @@ -1963,7 +1970,7 @@ msgid "Target %s is not a directory" msgstr "%s мақсаты бума емес болып тұр" -#: gio/gio-tool-open.c:118 +#: gio/gio-tool-open.c:75 msgid "" "Open files with the default application that\n" "is registered to handle files of this type." @@ -2153,70 +2160,76 @@ msgid "text may not appear inside <%s>" msgstr "мәтін <%s> ішінде болмауы мүмкін" -#: gio/glib-compile-resources.c:736 gio/glib-compile-schemas.c:2138 +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2139 msgid "Show program version and exit" msgstr "" -#: gio/glib-compile-resources.c:737 +#: gio/glib-compile-resources.c:738 msgid "Name of the output file" msgstr "" -#: gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:739 msgid "" "The directories to load files referenced in FILE from (default: current " "directory)" msgstr "" -#: gio/glib-compile-resources.c:738 gio/glib-compile-schemas.c:2139 -#: gio/glib-compile-schemas.c:2168 +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-schemas.c:2169 msgid "DIRECTORY" msgstr "БУМА" -#: gio/glib-compile-resources.c:739 +#: gio/glib-compile-resources.c:740 msgid "" "Generate output in the format selected for by the target filename extension" msgstr "" -#: gio/glib-compile-resources.c:740 +#: gio/glib-compile-resources.c:741 msgid "Generate source header" msgstr "" -#: gio/glib-compile-resources.c:741 +#: gio/glib-compile-resources.c:742 msgid "Generate source code used to link in the resource file into your code" msgstr "" -#: gio/glib-compile-resources.c:742 +#: gio/glib-compile-resources.c:743 msgid "Generate dependency list" msgstr "" -#: gio/glib-compile-resources.c:743 +#: gio/glib-compile-resources.c:744 msgid "Name of the dependency file to generate" msgstr "" -#: gio/glib-compile-resources.c:744 +#: gio/glib-compile-resources.c:745 msgid "Include phony targets in the generated dependency file" msgstr "" -#: gio/glib-compile-resources.c:745 +#: gio/glib-compile-resources.c:746 msgid "Don’t automatically create and register resource" msgstr "" -#: gio/glib-compile-resources.c:746 +#: gio/glib-compile-resources.c:747 msgid "Don’t export functions; declare them G_GNUC_INTERNAL" msgstr "" -#: gio/glib-compile-resources.c:747 +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" + +#: gio/glib-compile-resources.c:749 msgid "C identifier name used for the generated source code" msgstr "" -#: gio/glib-compile-resources.c:773 +#: gio/glib-compile-resources.c:775 msgid "" "Compile a resource specification into a resource file.\n" "Resource specification files have the extension .gresource.xml,\n" "and the resource file have the extension called .gresource." msgstr "" -#: gio/glib-compile-resources.c:795 +#: gio/glib-compile-resources.c:797 msgid "You should give exactly one file name\n" msgstr "" @@ -2601,55 +2614,55 @@ "list of valid choices" msgstr "" -#: gio/glib-compile-schemas.c:2139 +#: gio/glib-compile-schemas.c:2140 msgid "where to store the gschemas.compiled file" msgstr "" -#: gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-schemas.c:2141 msgid "Abort on any errors in schemas" msgstr "" -#: gio/glib-compile-schemas.c:2141 +#: gio/glib-compile-schemas.c:2142 msgid "Do not write the gschema.compiled file" msgstr "" -#: gio/glib-compile-schemas.c:2142 +#: gio/glib-compile-schemas.c:2143 msgid "Do not enforce key name restrictions" msgstr "" -#: gio/glib-compile-schemas.c:2171 +#: gio/glib-compile-schemas.c:2172 msgid "" "Compile all GSettings schema files into a schema cache.\n" "Schema files are required to have the extension .gschema.xml,\n" "and the cache file is called gschemas.compiled." msgstr "" -#: gio/glib-compile-schemas.c:2192 +#: gio/glib-compile-schemas.c:2193 #, c-format msgid "You should give exactly one directory name\n" msgstr "" -#: gio/glib-compile-schemas.c:2234 +#: gio/glib-compile-schemas.c:2235 #, c-format msgid "No schema files found: " msgstr "" -#: gio/glib-compile-schemas.c:2237 +#: gio/glib-compile-schemas.c:2238 #, c-format msgid "doing nothing.\n" msgstr "" -#: gio/glib-compile-schemas.c:2240 +#: gio/glib-compile-schemas.c:2241 #, c-format msgid "removed existing output file.\n" msgstr "" -#: gio/glocalfile.c:544 gio/win32/gwinhttpfile.c:420 +#: gio/glocalfile.c:546 gio/win32/gwinhttpfile.c:420 #, c-format msgid "Invalid filename %s" msgstr "Қате файл аты %s" -#: gio/glocalfile.c:1006 +#: gio/glocalfile.c:1013 #, c-format msgid "Error getting filesystem info for %s: %s" msgstr "%s үшін файлдық жүйе ақпаратын алу қатесі: %s" @@ -2658,128 +2671,128 @@ #. * the enclosing (user visible) mount of a file, but none #. * exists. #. -#: gio/glocalfile.c:1145 +#: gio/glocalfile.c:1152 #, c-format msgid "Containing mount for file %s not found" msgstr "" -#: gio/glocalfile.c:1168 +#: gio/glocalfile.c:1175 msgid "Can’t rename root directory" msgstr "Түбірлік буманың атын ауыстыру мүмкін емес" -#: gio/glocalfile.c:1186 gio/glocalfile.c:1209 +#: gio/glocalfile.c:1193 gio/glocalfile.c:1216 #, c-format msgid "Error renaming file %s: %s" msgstr "%s файл атын ауыстыру қатесі: %s" -#: gio/glocalfile.c:1193 +#: gio/glocalfile.c:1200 msgid "Can’t rename file, filename already exists" msgstr "Файл атын ауыстыру мүмкін емес, ондай файл бар болып тұр" -#: gio/glocalfile.c:1206 gio/glocalfile.c:2267 gio/glocalfile.c:2295 -#: gio/glocalfile.c:2452 gio/glocalfileoutputstream.c:551 +#: gio/glocalfile.c:1213 gio/glocalfile.c:2322 gio/glocalfile.c:2350 +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:646 msgid "Invalid filename" msgstr "Файл аты қате" -#: gio/glocalfile.c:1374 gio/glocalfile.c:1389 +#: gio/glocalfile.c:1381 gio/glocalfile.c:1396 #, c-format msgid "Error opening file %s: %s" msgstr "%s файлын ашу қатесі: %s" -#: gio/glocalfile.c:1514 +#: gio/glocalfile.c:1521 #, c-format msgid "Error removing file %s: %s" msgstr "%s файлын өшіру қатесі: %s" -#: gio/glocalfile.c:1925 +#: gio/glocalfile.c:1963 #, c-format msgid "Error trashing file %s: %s" msgstr "%s файлын қоқысқа тастау қатесі: %s" -#: gio/glocalfile.c:1948 +#: gio/glocalfile.c:2004 #, c-format msgid "Unable to create trash dir %s: %s" msgstr "" -#: gio/glocalfile.c:1970 +#: gio/glocalfile.c:2025 #, c-format msgid "Unable to find toplevel directory to trash %s" msgstr "" -#: gio/glocalfile.c:1979 +#: gio/glocalfile.c:2034 #, c-format msgid "Trashing on system internal mounts is not supported" msgstr "" -#: gio/glocalfile.c:2063 gio/glocalfile.c:2083 +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 #, c-format msgid "Unable to find or create trash directory for %s" msgstr "" -#: gio/glocalfile.c:2118 +#: gio/glocalfile.c:2173 #, c-format msgid "Unable to create trashing info file for %s: %s" msgstr "" -#: gio/glocalfile.c:2178 +#: gio/glocalfile.c:2233 #, c-format msgid "Unable to trash file %s across filesystem boundaries" msgstr "" -#: gio/glocalfile.c:2182 gio/glocalfile.c:2238 +#: gio/glocalfile.c:2237 gio/glocalfile.c:2293 #, c-format msgid "Unable to trash file %s: %s" msgstr "%s файлын қоқысқа тастау мүмкін емес: %s" -#: gio/glocalfile.c:2244 +#: gio/glocalfile.c:2299 #, c-format msgid "Unable to trash file %s" msgstr "%s файлын қоқысқа тастау мүмкін емес" -#: gio/glocalfile.c:2270 +#: gio/glocalfile.c:2325 #, c-format msgid "Error creating directory %s: %s" msgstr "%s бумасын жасау қатесі: %s" -#: gio/glocalfile.c:2299 +#: gio/glocalfile.c:2354 #, c-format msgid "Filesystem does not support symbolic links" msgstr "" -#: gio/glocalfile.c:2302 +#: gio/glocalfile.c:2357 #, c-format msgid "Error making symbolic link %s: %s" msgstr "%s символдық сілтемесін жасау қатесі: %s" -#: gio/glocalfile.c:2308 glib/gfileutils.c:2138 +#: gio/glocalfile.c:2363 glib/gfileutils.c:2138 msgid "Symbolic links not supported" msgstr "Символдық сілтемелерге қолдау жоқ" -#: gio/glocalfile.c:2363 gio/glocalfile.c:2398 gio/glocalfile.c:2455 +#: gio/glocalfile.c:2418 gio/glocalfile.c:2453 gio/glocalfile.c:2510 #, c-format msgid "Error moving file %s: %s" msgstr "%s файлын жылжыту қатесі: %s" -#: gio/glocalfile.c:2386 +#: gio/glocalfile.c:2441 msgid "Can’t move directory over directory" msgstr "Буманы бума үстіне жылжыту мүмкін емес" -#: gio/glocalfile.c:2412 gio/glocalfileoutputstream.c:935 -#: gio/glocalfileoutputstream.c:949 gio/glocalfileoutputstream.c:964 -#: gio/glocalfileoutputstream.c:981 gio/glocalfileoutputstream.c:995 +#: gio/glocalfile.c:2467 gio/glocalfileoutputstream.c:1030 +#: gio/glocalfileoutputstream.c:1044 gio/glocalfileoutputstream.c:1059 +#: gio/glocalfileoutputstream.c:1076 gio/glocalfileoutputstream.c:1090 msgid "Backup file creation failed" msgstr "" -#: gio/glocalfile.c:2431 +#: gio/glocalfile.c:2486 #, c-format msgid "Error removing target file: %s" msgstr "Мақсат файлын өшіру қатесі: %s" -#: gio/glocalfile.c:2445 +#: gio/glocalfile.c:2500 msgid "Move between mounts not supported" msgstr "" -#: gio/glocalfile.c:2636 +#: gio/glocalfile.c:2691 #, c-format msgid "Could not determine the disk usage of %s: %s" msgstr "" @@ -2801,150 +2814,150 @@ msgid "Error setting extended attribute “%s”: %s" msgstr "\"%s\" кеңейтілген атрибутын орнату қатесі: %s" -#: gio/glocalfileinfo.c:1619 +#: gio/glocalfileinfo.c:1625 msgid " (invalid encoding)" msgstr " (кодталуы қате)" -#: gio/glocalfileinfo.c:1783 gio/glocalfileoutputstream.c:813 +#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:908 #, c-format msgid "Error when getting information for file “%s”: %s" msgstr "\"%s\" файлы ақпаратын алу қатесі: %s" -#: gio/glocalfileinfo.c:2045 +#: gio/glocalfileinfo.c:2059 #, c-format msgid "Error when getting information for file descriptor: %s" msgstr "" -#: gio/glocalfileinfo.c:2090 +#: gio/glocalfileinfo.c:2104 msgid "Invalid attribute type (uint32 expected)" msgstr "" -#: gio/glocalfileinfo.c:2108 +#: gio/glocalfileinfo.c:2122 msgid "Invalid attribute type (uint64 expected)" msgstr "" -#: gio/glocalfileinfo.c:2127 gio/glocalfileinfo.c:2146 +#: gio/glocalfileinfo.c:2141 gio/glocalfileinfo.c:2160 msgid "Invalid attribute type (byte string expected)" msgstr "" -#: gio/glocalfileinfo.c:2191 +#: gio/glocalfileinfo.c:2207 msgid "Cannot set permissions on symlinks" msgstr "" -#: gio/glocalfileinfo.c:2207 +#: gio/glocalfileinfo.c:2223 #, c-format msgid "Error setting permissions: %s" msgstr "Рұқсаттарды орнату қатесі: %s" -#: gio/glocalfileinfo.c:2258 +#: gio/glocalfileinfo.c:2274 #, c-format msgid "Error setting owner: %s" msgstr "Иесін орнату қатесі: %s" -#: gio/glocalfileinfo.c:2281 +#: gio/glocalfileinfo.c:2297 msgid "symlink must be non-NULL" msgstr "" -#: gio/glocalfileinfo.c:2291 gio/glocalfileinfo.c:2310 -#: gio/glocalfileinfo.c:2321 +#: gio/glocalfileinfo.c:2307 gio/glocalfileinfo.c:2326 +#: gio/glocalfileinfo.c:2337 #, c-format msgid "Error setting symlink: %s" msgstr "" -#: gio/glocalfileinfo.c:2300 +#: gio/glocalfileinfo.c:2316 msgid "Error setting symlink: file is not a symlink" msgstr "" -#: gio/glocalfileinfo.c:2426 +#: gio/glocalfileinfo.c:2442 #, c-format msgid "Error setting modification or access time: %s" msgstr "" -#: gio/glocalfileinfo.c:2449 +#: gio/glocalfileinfo.c:2465 msgid "SELinux context must be non-NULL" msgstr "" -#: gio/glocalfileinfo.c:2464 +#: gio/glocalfileinfo.c:2480 #, c-format msgid "Error setting SELinux context: %s" msgstr "" -#: gio/glocalfileinfo.c:2471 +#: gio/glocalfileinfo.c:2487 msgid "SELinux is not enabled on this system" msgstr "" -#: gio/glocalfileinfo.c:2563 +#: gio/glocalfileinfo.c:2579 #, c-format msgid "Setting attribute %s not supported" msgstr "" -#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:696 +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:791 #, c-format msgid "Error reading from file: %s" msgstr "Файлдан оқу қатесі: %s" #: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 #: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 -#: gio/glocalfileoutputstream.c:458 gio/glocalfileoutputstream.c:1013 +#: gio/glocalfileoutputstream.c:553 gio/glocalfileoutputstream.c:1108 #, c-format msgid "Error seeking in file: %s" msgstr "Файлдан іздеу қатесі: %s" -#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:248 -#: gio/glocalfileoutputstream.c:342 +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:343 +#: gio/glocalfileoutputstream.c:437 #, c-format msgid "Error closing file: %s" msgstr "Файлды жабу қатесі: %s" -#: gio/glocalfilemonitor.c:854 +#: gio/glocalfilemonitor.c:856 msgid "Unable to find default local file monitor type" msgstr "" -#: gio/glocalfileoutputstream.c:196 gio/glocalfileoutputstream.c:228 -#: gio/glocalfileoutputstream.c:717 +#: gio/glocalfileoutputstream.c:208 gio/glocalfileoutputstream.c:286 +#: gio/glocalfileoutputstream.c:323 gio/glocalfileoutputstream.c:812 #, c-format msgid "Error writing to file: %s" msgstr "Файлға жазу қатесі: %s" -#: gio/glocalfileoutputstream.c:275 +#: gio/glocalfileoutputstream.c:370 #, c-format msgid "Error removing old backup link: %s" msgstr "" -#: gio/glocalfileoutputstream.c:289 gio/glocalfileoutputstream.c:302 +#: gio/glocalfileoutputstream.c:384 gio/glocalfileoutputstream.c:397 #, c-format msgid "Error creating backup copy: %s" msgstr "" -#: gio/glocalfileoutputstream.c:320 +#: gio/glocalfileoutputstream.c:415 #, c-format msgid "Error renaming temporary file: %s" msgstr "" -#: gio/glocalfileoutputstream.c:504 gio/glocalfileoutputstream.c:1064 +#: gio/glocalfileoutputstream.c:599 gio/glocalfileoutputstream.c:1159 #, c-format msgid "Error truncating file: %s" msgstr "" -#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:795 -#: gio/glocalfileoutputstream.c:1045 gio/gsubprocess.c:380 +#: gio/glocalfileoutputstream.c:652 gio/glocalfileoutputstream.c:890 +#: gio/glocalfileoutputstream.c:1140 gio/gsubprocess.c:380 #, c-format msgid "Error opening file “%s”: %s" msgstr "\"%s\" файлын ашу қатесі: %s" -#: gio/glocalfileoutputstream.c:826 +#: gio/glocalfileoutputstream.c:921 msgid "Target file is a directory" msgstr "Мақсат файлы бума болып тұр" -#: gio/glocalfileoutputstream.c:831 +#: gio/glocalfileoutputstream.c:926 msgid "Target file is not a regular file" msgstr "Мақсат файлы қалыпты файл емес болып тұр" -#: gio/glocalfileoutputstream.c:843 +#: gio/glocalfileoutputstream.c:938 msgid "The file was externally modified" msgstr "" -#: gio/glocalfileoutputstream.c:1029 +#: gio/glocalfileoutputstream.c:1124 #, c-format msgid "Error removing old file: %s" msgstr "Ескі файлды өшіру қатесі: %s" @@ -3032,7 +3045,7 @@ msgid "mount doesn’t implement synchronous content type guessing" msgstr "" -#: gio/gnetworkaddress.c:378 +#: gio/gnetworkaddress.c:388 #, c-format msgid "Hostname “%s” contains “[” but not “]”" msgstr "" @@ -3045,51 +3058,67 @@ msgid "Host unreachable" msgstr "Хост қолжетерсіз" -#: gio/gnetworkmonitornetlink.c:97 gio/gnetworkmonitornetlink.c:109 -#: gio/gnetworkmonitornetlink.c:128 +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 #, c-format msgid "Could not create network monitor: %s" msgstr "" -#: gio/gnetworkmonitornetlink.c:118 +#: gio/gnetworkmonitornetlink.c:120 msgid "Could not create network monitor: " msgstr "" -#: gio/gnetworkmonitornetlink.c:176 +#: gio/gnetworkmonitornetlink.c:183 msgid "Could not get network status: " msgstr "" -#: gio/gnetworkmonitornm.c:322 +#: gio/gnetworkmonitornm.c:313 +#, c-format +msgid "NetworkManager not running" +msgstr "NetworkManager орындалы тұрған жоқ" + +#: gio/gnetworkmonitornm.c:324 #, c-format msgid "NetworkManager version too old" msgstr "NetworkManager нұсқасы тым ескі" -#: gio/goutputstream.c:212 gio/goutputstream.c:560 +#: gio/goutputstream.c:232 gio/goutputstream.c:775 msgid "Output stream doesn’t implement write" msgstr "" -#: gio/goutputstream.c:521 gio/goutputstream.c:1224 +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 msgid "Source stream is already closed" msgstr "" -#: gio/gresolver.c:342 gio/gthreadedresolver.c:116 gio/gthreadedresolver.c:126 +#: gio/gresolver.c:344 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:160 #, c-format msgid "Error resolving “%s”: %s" msgstr "" -#: gio/gresolver.c:729 gio/gresolver.c:781 +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:389 gio/gresolver.c:547 +#, c-format +msgid "%s not implemented" +msgstr "" + +#: gio/gresolver.c:915 gio/gresolver.c:967 msgid "Invalid domain" msgstr "Хост аты қате" -#: gio/gresource.c:622 gio/gresource.c:881 gio/gresource.c:920 -#: gio/gresource.c:1044 gio/gresource.c:1116 gio/gresource.c:1189 -#: gio/gresource.c:1259 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 #: gio/gresourcefile.c:736 #, c-format msgid "The resource at “%s” does not exist" msgstr "" -#: gio/gresource.c:787 +#: gio/gresource.c:830 #, c-format msgid "The resource at “%s” failed to decompress" msgstr "" @@ -3103,26 +3132,26 @@ msgid "Input stream doesn’t implement seek" msgstr "" -#: gio/gresource-tool.c:494 +#: gio/gresource-tool.c:501 msgid "List sections containing resources in an elf FILE" msgstr "" -#: gio/gresource-tool.c:500 +#: gio/gresource-tool.c:507 msgid "" "List resources\n" "If SECTION is given, only list resources in this section\n" "If PATH is given, only list matching resources" msgstr "" -#: gio/gresource-tool.c:503 gio/gresource-tool.c:513 +#: gio/gresource-tool.c:510 gio/gresource-tool.c:520 msgid "FILE [PATH]" msgstr "" -#: gio/gresource-tool.c:504 gio/gresource-tool.c:514 gio/gresource-tool.c:521 +#: gio/gresource-tool.c:511 gio/gresource-tool.c:521 gio/gresource-tool.c:528 msgid "SECTION" msgstr "" -#: gio/gresource-tool.c:509 +#: gio/gresource-tool.c:516 msgid "" "List resources with details\n" "If SECTION is given, only list resources in this section\n" @@ -3130,15 +3159,15 @@ "Details include the section, size and compression" msgstr "" -#: gio/gresource-tool.c:519 +#: gio/gresource-tool.c:526 msgid "Extract a resource file to stdout" msgstr "" -#: gio/gresource-tool.c:520 +#: gio/gresource-tool.c:527 msgid "FILE PATH" msgstr "" -#: gio/gresource-tool.c:534 +#: gio/gresource-tool.c:541 msgid "" "Usage:\n" " gresource [--section SECTION] COMMAND [ARGS…]\n" @@ -3154,7 +3183,7 @@ "\n" msgstr "" -#: gio/gresource-tool.c:548 +#: gio/gresource-tool.c:555 #, c-format msgid "" "Usage:\n" @@ -3164,37 +3193,37 @@ "\n" msgstr "" -#: gio/gresource-tool.c:555 +#: gio/gresource-tool.c:562 msgid " SECTION An (optional) elf section name\n" msgstr "" -#: gio/gresource-tool.c:559 gio/gsettings-tool.c:703 +#: gio/gresource-tool.c:566 gio/gsettings-tool.c:703 msgid " COMMAND The (optional) command to explain\n" msgstr "" -#: gio/gresource-tool.c:565 +#: gio/gresource-tool.c:572 msgid " FILE An elf file (a binary or a shared library)\n" msgstr "" -#: gio/gresource-tool.c:568 +#: gio/gresource-tool.c:575 msgid "" " FILE An elf file (a binary or a shared library)\n" " or a compiled resource file\n" msgstr "" -#: gio/gresource-tool.c:572 +#: gio/gresource-tool.c:579 msgid "[PATH]" msgstr "" -#: gio/gresource-tool.c:574 +#: gio/gresource-tool.c:581 msgid " PATH An (optional) resource path (may be partial)\n" msgstr "" -#: gio/gresource-tool.c:575 +#: gio/gresource-tool.c:582 msgid "PATH" msgstr "ЖОЛ" -#: gio/gresource-tool.c:577 +#: gio/gresource-tool.c:584 msgid " PATH A resource path\n" msgstr "" @@ -3391,142 +3420,142 @@ msgid "No such key “%s”\n" msgstr "" -#: gio/gsocket.c:384 +#: gio/gsocket.c:373 msgid "Invalid socket, not initialized" msgstr "" -#: gio/gsocket.c:391 +#: gio/gsocket.c:380 #, c-format msgid "Invalid socket, initialization failed due to: %s" msgstr "" -#: gio/gsocket.c:399 +#: gio/gsocket.c:388 msgid "Socket is already closed" msgstr "" -#: gio/gsocket.c:414 gio/gsocket.c:3034 gio/gsocket.c:4244 gio/gsocket.c:4302 +#: gio/gsocket.c:403 gio/gsocket.c:3027 gio/gsocket.c:4244 gio/gsocket.c:4302 msgid "Socket I/O timed out" msgstr "" -#: gio/gsocket.c:549 +#: gio/gsocket.c:538 #, c-format msgid "creating GSocket from fd: %s" msgstr "" -#: gio/gsocket.c:578 gio/gsocket.c:632 gio/gsocket.c:639 +#: gio/gsocket.c:567 gio/gsocket.c:621 gio/gsocket.c:628 #, c-format msgid "Unable to create socket: %s" msgstr "" -#: gio/gsocket.c:632 +#: gio/gsocket.c:621 msgid "Unknown family was specified" msgstr "" -#: gio/gsocket.c:639 +#: gio/gsocket.c:628 msgid "Unknown protocol was specified" msgstr "" -#: gio/gsocket.c:1130 +#: gio/gsocket.c:1119 #, c-format msgid "Cannot use datagram operations on a non-datagram socket." msgstr "" -#: gio/gsocket.c:1147 +#: gio/gsocket.c:1136 #, c-format msgid "Cannot use datagram operations on a socket with a timeout set." msgstr "" -#: gio/gsocket.c:1954 +#: gio/gsocket.c:1943 #, c-format msgid "could not get local address: %s" msgstr "" -#: gio/gsocket.c:2000 +#: gio/gsocket.c:1989 #, c-format msgid "could not get remote address: %s" msgstr "" -#: gio/gsocket.c:2066 +#: gio/gsocket.c:2055 #, c-format msgid "could not listen: %s" msgstr "" -#: gio/gsocket.c:2168 +#: gio/gsocket.c:2157 #, c-format msgid "Error binding to address: %s" msgstr "" -#: gio/gsocket.c:2226 gio/gsocket.c:2263 gio/gsocket.c:2373 gio/gsocket.c:2398 -#: gio/gsocket.c:2471 gio/gsocket.c:2529 gio/gsocket.c:2547 +#: gio/gsocket.c:2215 gio/gsocket.c:2252 gio/gsocket.c:2362 gio/gsocket.c:2387 +#: gio/gsocket.c:2460 gio/gsocket.c:2518 gio/gsocket.c:2536 #, c-format msgid "Error joining multicast group: %s" msgstr "" -#: gio/gsocket.c:2227 gio/gsocket.c:2264 gio/gsocket.c:2374 gio/gsocket.c:2399 -#: gio/gsocket.c:2472 gio/gsocket.c:2530 gio/gsocket.c:2548 +#: gio/gsocket.c:2216 gio/gsocket.c:2253 gio/gsocket.c:2363 gio/gsocket.c:2388 +#: gio/gsocket.c:2461 gio/gsocket.c:2519 gio/gsocket.c:2537 #, c-format msgid "Error leaving multicast group: %s" msgstr "" -#: gio/gsocket.c:2228 +#: gio/gsocket.c:2217 msgid "No support for source-specific multicast" msgstr "" -#: gio/gsocket.c:2375 +#: gio/gsocket.c:2364 msgid "Unsupported socket family" msgstr "" -#: gio/gsocket.c:2400 +#: gio/gsocket.c:2389 msgid "source-specific not an IPv4 address" msgstr "" -#: gio/gsocket.c:2418 gio/gsocket.c:2447 gio/gsocket.c:2497 +#: gio/gsocket.c:2407 gio/gsocket.c:2436 gio/gsocket.c:2486 #, c-format msgid "Interface not found: %s" msgstr "" -#: gio/gsocket.c:2434 +#: gio/gsocket.c:2423 #, c-format msgid "Interface name too long" msgstr "" -#: gio/gsocket.c:2473 +#: gio/gsocket.c:2462 msgid "No support for IPv4 source-specific multicast" msgstr "" -#: gio/gsocket.c:2531 +#: gio/gsocket.c:2520 msgid "No support for IPv6 source-specific multicast" msgstr "" -#: gio/gsocket.c:2740 +#: gio/gsocket.c:2729 #, c-format msgid "Error accepting connection: %s" msgstr "" -#: gio/gsocket.c:2864 +#: gio/gsocket.c:2855 msgid "Connection in progress" msgstr "" -#: gio/gsocket.c:2913 +#: gio/gsocket.c:2906 msgid "Unable to get pending error: " msgstr "" -#: gio/gsocket.c:3097 +#: gio/gsocket.c:3092 #, c-format msgid "Error receiving data: %s" msgstr "" -#: gio/gsocket.c:3292 +#: gio/gsocket.c:3289 #, c-format msgid "Error sending data: %s" msgstr "" -#: gio/gsocket.c:3479 +#: gio/gsocket.c:3476 #, c-format msgid "Unable to shutdown socket: %s" msgstr "" -#: gio/gsocket.c:3560 +#: gio/gsocket.c:3557 #, c-format msgid "Error closing socket: %s" msgstr "" @@ -3536,52 +3565,53 @@ msgid "Waiting for socket condition: %s" msgstr "" -#: gio/gsocket.c:4711 gio/gsocket.c:4791 gio/gsocket.c:4969 +#: gio/gsocket.c:4614 gio/gsocket.c:4616 gio/gsocket.c:4762 gio/gsocket.c:4847 +#: gio/gsocket.c:5027 gio/gsocket.c:5067 gio/gsocket.c:5069 #, c-format msgid "Error sending message: %s" msgstr "Хабарламаны жіберу сәтсіз: %s" -#: gio/gsocket.c:4735 +#: gio/gsocket.c:4789 msgid "GSocketControlMessage not supported on Windows" msgstr "" -#: gio/gsocket.c:5188 gio/gsocket.c:5261 gio/gsocket.c:5487 +#: gio/gsocket.c:5260 gio/gsocket.c:5333 gio/gsocket.c:5560 #, c-format msgid "Error receiving message: %s" msgstr "" -#: gio/gsocket.c:5759 +#: gio/gsocket.c:5832 #, c-format msgid "Unable to read socket credentials: %s" msgstr "" -#: gio/gsocket.c:5768 +#: gio/gsocket.c:5841 msgid "g_socket_get_credentials not implemented for this OS" msgstr "" -#: gio/gsocketclient.c:176 +#: gio/gsocketclient.c:181 #, c-format msgid "Could not connect to proxy server %s: " msgstr "" -#: gio/gsocketclient.c:190 +#: gio/gsocketclient.c:195 #, c-format msgid "Could not connect to %s: " msgstr "" -#: gio/gsocketclient.c:192 +#: gio/gsocketclient.c:197 msgid "Could not connect: " msgstr "Байланысу мүмкін емес: " -#: gio/gsocketclient.c:1027 gio/gsocketclient.c:1599 +#: gio/gsocketclient.c:1032 gio/gsocketclient.c:1731 msgid "Unknown error on connect" msgstr "Байланысты орнату кезіндегі белгісіз қате" -#: gio/gsocketclient.c:1081 gio/gsocketclient.c:1535 +#: gio/gsocketclient.c:1086 gio/gsocketclient.c:1640 msgid "Proxying over a non-TCP connection is not supported." msgstr "" -#: gio/gsocketclient.c:1110 gio/gsocketclient.c:1561 +#: gio/gsocketclient.c:1115 gio/gsocketclient.c:1666 #, c-format msgid "Proxy protocol “%s” is not supported." msgstr "" @@ -3679,54 +3709,54 @@ msgid "Unknown SOCKSv5 proxy error." msgstr "" -#: gio/gthemedicon.c:518 +#: gio/gthemedicon.c:595 #, c-format msgid "Can’t handle version %d of GThemedIcon encoding" msgstr "" -#: gio/gthreadedresolver.c:118 +#: gio/gthreadedresolver.c:152 msgid "No valid addresses were found" msgstr "" -#: gio/gthreadedresolver.c:213 +#: gio/gthreadedresolver.c:317 #, c-format msgid "Error reverse-resolving “%s”: %s" msgstr "" -#: gio/gthreadedresolver.c:549 gio/gthreadedresolver.c:628 -#: gio/gthreadedresolver.c:726 gio/gthreadedresolver.c:776 +#: gio/gthreadedresolver.c:653 gio/gthreadedresolver.c:732 +#: gio/gthreadedresolver.c:830 gio/gthreadedresolver.c:880 #, c-format msgid "No DNS record of the requested type for “%s”" msgstr "" -#: gio/gthreadedresolver.c:554 gio/gthreadedresolver.c:731 +#: gio/gthreadedresolver.c:658 gio/gthreadedresolver.c:835 #, c-format msgid "Temporarily unable to resolve “%s”" msgstr "" -#: gio/gthreadedresolver.c:559 gio/gthreadedresolver.c:736 -#: gio/gthreadedresolver.c:844 +#: gio/gthreadedresolver.c:663 gio/gthreadedresolver.c:840 +#: gio/gthreadedresolver.c:948 #, c-format msgid "Error resolving “%s”" msgstr "" -#: gio/gtlscertificate.c:250 -msgid "Cannot decrypt PEM-encoded private key" +#: gio/gtlscertificate.c:243 +msgid "No PEM-encoded private key found" msgstr "" -#: gio/gtlscertificate.c:255 -msgid "No PEM-encoded private key found" +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" msgstr "" -#: gio/gtlscertificate.c:265 +#: gio/gtlscertificate.c:264 msgid "Could not parse PEM-encoded private key" msgstr "" -#: gio/gtlscertificate.c:290 +#: gio/gtlscertificate.c:291 msgid "No PEM-encoded certificate found" msgstr "" -#: gio/gtlscertificate.c:299 +#: gio/gtlscertificate.c:300 msgid "Could not parse PEM-encoded certificate" msgstr "" @@ -3805,17 +3835,19 @@ msgid "Error reading from file descriptor: %s" msgstr "" -#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:411 +#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:534 #: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 #, c-format msgid "Error closing file descriptor: %s" msgstr "" -#: gio/gunixmounts.c:2589 gio/gunixmounts.c:2642 +#: gio/gunixmounts.c:2650 gio/gunixmounts.c:2703 msgid "Filesystem root" msgstr "Файлдық жүйе түбірі" -#: gio/gunixoutputstream.c:358 gio/gunixoutputstream.c:378 +#: gio/gunixoutputstream.c:371 gio/gunixoutputstream.c:391 +#: gio/gunixoutputstream.c:478 gio/gunixoutputstream.c:498 +#: gio/gunixoutputstream.c:675 #, c-format msgid "Error writing to file descriptor: %s" msgstr "" @@ -3897,142 +3929,142 @@ msgstr "" #: glib/gbookmarkfile.c:765 glib/gbookmarkfile.c:836 glib/gbookmarkfile.c:846 -#: glib/gbookmarkfile.c:953 +#: glib/gbookmarkfile.c:955 #, c-format msgid "Attribute “%s” of element “%s” not found" msgstr "" -#: glib/gbookmarkfile.c:1123 glib/gbookmarkfile.c:1188 -#: glib/gbookmarkfile.c:1252 glib/gbookmarkfile.c:1262 +#: glib/gbookmarkfile.c:1164 glib/gbookmarkfile.c:1229 +#: glib/gbookmarkfile.c:1293 glib/gbookmarkfile.c:1303 #, c-format msgid "Unexpected tag “%s”, tag “%s” expected" msgstr "" -#: glib/gbookmarkfile.c:1148 glib/gbookmarkfile.c:1162 -#: glib/gbookmarkfile.c:1230 +#: glib/gbookmarkfile.c:1189 glib/gbookmarkfile.c:1203 +#: glib/gbookmarkfile.c:1271 glib/gbookmarkfile.c:1317 #, c-format msgid "Unexpected tag “%s” inside “%s”" msgstr "" -#: glib/gbookmarkfile.c:1757 +#: glib/gbookmarkfile.c:1813 msgid "No valid bookmark file found in data dirs" msgstr "" -#: glib/gbookmarkfile.c:1958 +#: glib/gbookmarkfile.c:2014 #, c-format msgid "A bookmark for URI “%s” already exists" msgstr "" -#: glib/gbookmarkfile.c:2004 glib/gbookmarkfile.c:2162 -#: glib/gbookmarkfile.c:2247 glib/gbookmarkfile.c:2327 -#: glib/gbookmarkfile.c:2412 glib/gbookmarkfile.c:2495 -#: glib/gbookmarkfile.c:2573 glib/gbookmarkfile.c:2652 -#: glib/gbookmarkfile.c:2694 glib/gbookmarkfile.c:2791 -#: glib/gbookmarkfile.c:2912 glib/gbookmarkfile.c:3102 -#: glib/gbookmarkfile.c:3178 glib/gbookmarkfile.c:3346 -#: glib/gbookmarkfile.c:3435 glib/gbookmarkfile.c:3524 -#: glib/gbookmarkfile.c:3640 +#: glib/gbookmarkfile.c:2060 glib/gbookmarkfile.c:2218 +#: glib/gbookmarkfile.c:2303 glib/gbookmarkfile.c:2383 +#: glib/gbookmarkfile.c:2468 glib/gbookmarkfile.c:2551 +#: glib/gbookmarkfile.c:2629 glib/gbookmarkfile.c:2708 +#: glib/gbookmarkfile.c:2750 glib/gbookmarkfile.c:2847 +#: glib/gbookmarkfile.c:2968 glib/gbookmarkfile.c:3158 +#: glib/gbookmarkfile.c:3234 glib/gbookmarkfile.c:3402 +#: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3580 +#: glib/gbookmarkfile.c:3699 #, c-format msgid "No bookmark found for URI “%s”" msgstr "" -#: glib/gbookmarkfile.c:2336 +#: glib/gbookmarkfile.c:2392 #, c-format msgid "No MIME type defined in the bookmark for URI “%s”" msgstr "" -#: glib/gbookmarkfile.c:2421 +#: glib/gbookmarkfile.c:2477 #, c-format msgid "No private flag has been defined in bookmark for URI “%s”" msgstr "" -#: glib/gbookmarkfile.c:2800 +#: glib/gbookmarkfile.c:2856 #, c-format msgid "No groups set in bookmark for URI “%s”" msgstr "" -#: glib/gbookmarkfile.c:3199 glib/gbookmarkfile.c:3356 +#: glib/gbookmarkfile.c:3255 glib/gbookmarkfile.c:3412 #, c-format msgid "No application with name “%s” registered a bookmark for “%s”" msgstr "" -#: glib/gbookmarkfile.c:3379 +#: glib/gbookmarkfile.c:3435 #, c-format msgid "Failed to expand exec line “%s” with URI “%s”" msgstr "" -#: glib/gconvert.c:473 +#: glib/gconvert.c:474 msgid "Unrepresentable character in conversion input" msgstr "" -#: glib/gconvert.c:500 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 +#: glib/gconvert.c:501 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 #: glib/gutf8.c:1318 msgid "Partial character sequence at end of input" msgstr "" -#: glib/gconvert.c:769 +#: glib/gconvert.c:770 #, c-format msgid "Cannot convert fallback “%s” to codeset “%s”" msgstr "" -#: glib/gconvert.c:940 +#: glib/gconvert.c:942 msgid "Embedded NUL byte in conversion input" msgstr "" -#: glib/gconvert.c:961 +#: glib/gconvert.c:963 msgid "Embedded NUL byte in conversion output" msgstr "" -#: glib/gconvert.c:1649 +#: glib/gconvert.c:1648 #, c-format msgid "The URI “%s” is not an absolute URI using the “file” scheme" msgstr "" -#: glib/gconvert.c:1659 +#: glib/gconvert.c:1658 #, c-format msgid "The local file URI “%s” may not include a “#”" msgstr "" -#: glib/gconvert.c:1676 +#: glib/gconvert.c:1675 #, c-format msgid "The URI “%s” is invalid" msgstr "URI \"%s\" қате" -#: glib/gconvert.c:1688 +#: glib/gconvert.c:1687 #, c-format msgid "The hostname of the URI “%s” is invalid" msgstr "" -#: glib/gconvert.c:1704 +#: glib/gconvert.c:1703 #, c-format msgid "The URI “%s” contains invalidly escaped characters" msgstr "" -#: glib/gconvert.c:1776 +#: glib/gconvert.c:1775 #, c-format msgid "The pathname “%s” is not an absolute path" msgstr "" #. Translators: this is the preferred format for expressing the date and the time -#: glib/gdatetime.c:213 +#: glib/gdatetime.c:214 msgctxt "GDateTime" msgid "%a %b %e %H:%M:%S %Y" msgstr "%a %d %b %Y %T" #. Translators: this is the preferred format for expressing the date -#: glib/gdatetime.c:216 +#: glib/gdatetime.c:217 msgctxt "GDateTime" msgid "%m/%d/%y" msgstr "%d.%m.%Y" #. Translators: this is the preferred format for expressing the time -#: glib/gdatetime.c:219 +#: glib/gdatetime.c:220 msgctxt "GDateTime" msgid "%H:%M:%S" msgstr "%T" #. Translators: this is the preferred format for expressing 12 hour time -#: glib/gdatetime.c:222 +#: glib/gdatetime.c:223 msgctxt "GDateTime" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" @@ -4053,62 +4085,62 @@ #. * non-European) there is no difference between the standalone and #. * complete date form. #. -#: glib/gdatetime.c:261 +#: glib/gdatetime.c:262 msgctxt "full month name" msgid "January" msgstr "Қаңтар" -#: glib/gdatetime.c:263 +#: glib/gdatetime.c:264 msgctxt "full month name" msgid "February" msgstr "Ақпан" -#: glib/gdatetime.c:265 +#: glib/gdatetime.c:266 msgctxt "full month name" msgid "March" msgstr "Наурыз" -#: glib/gdatetime.c:267 +#: glib/gdatetime.c:268 msgctxt "full month name" msgid "April" msgstr "Сәуір" -#: glib/gdatetime.c:269 +#: glib/gdatetime.c:270 msgctxt "full month name" msgid "May" msgstr "Мамыр" -#: glib/gdatetime.c:271 +#: glib/gdatetime.c:272 msgctxt "full month name" msgid "June" msgstr "Маусым" -#: glib/gdatetime.c:273 +#: glib/gdatetime.c:274 msgctxt "full month name" msgid "July" msgstr "Шілде" -#: glib/gdatetime.c:275 +#: glib/gdatetime.c:276 msgctxt "full month name" msgid "August" msgstr "Тамыз" -#: glib/gdatetime.c:277 +#: glib/gdatetime.c:278 msgctxt "full month name" msgid "September" msgstr "Қыркүйек" -#: glib/gdatetime.c:279 +#: glib/gdatetime.c:280 msgctxt "full month name" msgid "October" msgstr "Қазан" -#: glib/gdatetime.c:281 +#: glib/gdatetime.c:282 msgctxt "full month name" msgid "November" msgstr "Қараша" -#: glib/gdatetime.c:283 +#: glib/gdatetime.c:284 msgctxt "full month name" msgid "December" msgstr "Желтоқсан" @@ -4130,132 +4162,132 @@ #. * other platform. Here are abbreviated month names in a form #. * appropriate when they are used standalone. #. -#: glib/gdatetime.c:315 +#: glib/gdatetime.c:316 msgctxt "abbreviated month name" msgid "Jan" msgstr "Қаң" -#: glib/gdatetime.c:317 +#: glib/gdatetime.c:318 msgctxt "abbreviated month name" msgid "Feb" msgstr "Ақп" -#: glib/gdatetime.c:319 +#: glib/gdatetime.c:320 msgctxt "abbreviated month name" msgid "Mar" msgstr "Нау" -#: glib/gdatetime.c:321 +#: glib/gdatetime.c:322 msgctxt "abbreviated month name" msgid "Apr" msgstr "Сәу" -#: glib/gdatetime.c:323 +#: glib/gdatetime.c:324 msgctxt "abbreviated month name" msgid "May" msgstr "Мам" -#: glib/gdatetime.c:325 +#: glib/gdatetime.c:326 msgctxt "abbreviated month name" msgid "Jun" msgstr "Мау" -#: glib/gdatetime.c:327 +#: glib/gdatetime.c:328 msgctxt "abbreviated month name" msgid "Jul" msgstr "Шіл" -#: glib/gdatetime.c:329 +#: glib/gdatetime.c:330 msgctxt "abbreviated month name" msgid "Aug" msgstr "Там" -#: glib/gdatetime.c:331 +#: glib/gdatetime.c:332 msgctxt "abbreviated month name" msgid "Sep" msgstr "Қыр" -#: glib/gdatetime.c:333 +#: glib/gdatetime.c:334 msgctxt "abbreviated month name" msgid "Oct" msgstr "Қаз" -#: glib/gdatetime.c:335 +#: glib/gdatetime.c:336 msgctxt "abbreviated month name" msgid "Nov" msgstr "Қар" -#: glib/gdatetime.c:337 +#: glib/gdatetime.c:338 msgctxt "abbreviated month name" msgid "Dec" msgstr "Жел" -#: glib/gdatetime.c:352 +#: glib/gdatetime.c:353 msgctxt "full weekday name" msgid "Monday" msgstr "Дүйсенбі" -#: glib/gdatetime.c:354 +#: glib/gdatetime.c:355 msgctxt "full weekday name" msgid "Tuesday" msgstr "Сейсенбі" -#: glib/gdatetime.c:356 +#: glib/gdatetime.c:357 msgctxt "full weekday name" msgid "Wednesday" msgstr "Сәрсенбі" -#: glib/gdatetime.c:358 +#: glib/gdatetime.c:359 msgctxt "full weekday name" msgid "Thursday" msgstr "Бейсенбі" -#: glib/gdatetime.c:360 +#: glib/gdatetime.c:361 msgctxt "full weekday name" msgid "Friday" msgstr "Жұма" -#: glib/gdatetime.c:362 +#: glib/gdatetime.c:363 msgctxt "full weekday name" msgid "Saturday" msgstr "Сенбі" -#: glib/gdatetime.c:364 +#: glib/gdatetime.c:365 msgctxt "full weekday name" msgid "Sunday" msgstr "Жексенбі" -#: glib/gdatetime.c:379 +#: glib/gdatetime.c:380 msgctxt "abbreviated weekday name" msgid "Mon" msgstr "Дс" -#: glib/gdatetime.c:381 +#: glib/gdatetime.c:382 msgctxt "abbreviated weekday name" msgid "Tue" msgstr "Сс" -#: glib/gdatetime.c:383 +#: glib/gdatetime.c:384 msgctxt "abbreviated weekday name" msgid "Wed" msgstr "Ср" -#: glib/gdatetime.c:385 +#: glib/gdatetime.c:386 msgctxt "abbreviated weekday name" msgid "Thu" msgstr "Бс" -#: glib/gdatetime.c:387 +#: glib/gdatetime.c:388 msgctxt "abbreviated weekday name" msgid "Fri" msgstr "Жм" -#: glib/gdatetime.c:389 +#: glib/gdatetime.c:390 msgctxt "abbreviated weekday name" msgid "Sat" msgstr "Сн" -#: glib/gdatetime.c:391 +#: glib/gdatetime.c:392 msgctxt "abbreviated weekday name" msgid "Sun" msgstr "Жк" @@ -4277,62 +4309,62 @@ #. * (western European, non-European) there is no difference between the #. * standalone and complete date form. #. -#: glib/gdatetime.c:455 +#: glib/gdatetime.c:456 msgctxt "full month name with day" msgid "January" msgstr "Қаңтар" -#: glib/gdatetime.c:457 +#: glib/gdatetime.c:458 msgctxt "full month name with day" msgid "February" msgstr "Ақпан" -#: glib/gdatetime.c:459 +#: glib/gdatetime.c:460 msgctxt "full month name with day" msgid "March" msgstr "Наурыз" -#: glib/gdatetime.c:461 +#: glib/gdatetime.c:462 msgctxt "full month name with day" msgid "April" msgstr "Сәуір" -#: glib/gdatetime.c:463 +#: glib/gdatetime.c:464 msgctxt "full month name with day" msgid "May" msgstr "Мамыр" -#: glib/gdatetime.c:465 +#: glib/gdatetime.c:466 msgctxt "full month name with day" msgid "June" msgstr "Маусым" -#: glib/gdatetime.c:467 +#: glib/gdatetime.c:468 msgctxt "full month name with day" msgid "July" msgstr "Шілде" -#: glib/gdatetime.c:469 +#: glib/gdatetime.c:470 msgctxt "full month name with day" msgid "August" msgstr "Тамыз" -#: glib/gdatetime.c:471 +#: glib/gdatetime.c:472 msgctxt "full month name with day" msgid "September" msgstr "Қыркүйек" -#: glib/gdatetime.c:473 +#: glib/gdatetime.c:474 msgctxt "full month name with day" msgid "October" msgstr "Қазан" -#: glib/gdatetime.c:475 +#: glib/gdatetime.c:476 msgctxt "full month name with day" msgid "November" msgstr "Қараша" -#: glib/gdatetime.c:477 +#: glib/gdatetime.c:478 msgctxt "full month name with day" msgid "December" msgstr "Желтоқсан" @@ -4354,79 +4386,79 @@ #. * month names almost ready to copy and paste here. In other systems #. * due to a bug the result is incorrect in some languages. #. -#: glib/gdatetime.c:542 +#: glib/gdatetime.c:543 msgctxt "abbreviated month name with day" msgid "Jan" msgstr "Қаң" -#: glib/gdatetime.c:544 +#: glib/gdatetime.c:545 msgctxt "abbreviated month name with day" msgid "Feb" msgstr "Ақп" -#: glib/gdatetime.c:546 +#: glib/gdatetime.c:547 msgctxt "abbreviated month name with day" msgid "Mar" msgstr "Нау" -#: glib/gdatetime.c:548 +#: glib/gdatetime.c:549 msgctxt "abbreviated month name with day" msgid "Apr" msgstr "Сәу" -#: glib/gdatetime.c:550 +#: glib/gdatetime.c:551 msgctxt "abbreviated month name with day" msgid "May" msgstr "Мам" -#: glib/gdatetime.c:552 +#: glib/gdatetime.c:553 msgctxt "abbreviated month name with day" msgid "Jun" msgstr "Мау" -#: glib/gdatetime.c:554 +#: glib/gdatetime.c:555 msgctxt "abbreviated month name with day" msgid "Jul" msgstr "Шіл" -#: glib/gdatetime.c:556 +#: glib/gdatetime.c:557 msgctxt "abbreviated month name with day" msgid "Aug" msgstr "Там" -#: glib/gdatetime.c:558 +#: glib/gdatetime.c:559 msgctxt "abbreviated month name with day" msgid "Sep" msgstr "Қыр" -#: glib/gdatetime.c:560 +#: glib/gdatetime.c:561 msgctxt "abbreviated month name with day" msgid "Oct" msgstr "Қаз" -#: glib/gdatetime.c:562 +#: glib/gdatetime.c:563 msgctxt "abbreviated month name with day" msgid "Nov" msgstr "Қар" -#: glib/gdatetime.c:564 +#: glib/gdatetime.c:565 msgctxt "abbreviated month name with day" msgid "Dec" msgstr "Жел" #. Translators: 'before midday' indicator -#: glib/gdatetime.c:581 +#: glib/gdatetime.c:582 msgctxt "GDateTime" msgid "AM" msgstr "AM" #. Translators: 'after midday' indicator -#: glib/gdatetime.c:584 +#: glib/gdatetime.c:585 msgctxt "GDateTime" msgid "PM" msgstr "PM" -#: glib/gdir.c:155 +#: glib/gdir.c:154 #, c-format msgid "Error opening directory “%s”: %s" msgstr "\"%s\" бумасын ашу қатесі: %s" @@ -4528,99 +4560,99 @@ msgid "Can’t do a raw read in g_io_channel_read_to_end" msgstr "" -#: glib/gkeyfile.c:788 +#: glib/gkeyfile.c:789 msgid "Valid key file could not be found in search dirs" msgstr "" -#: glib/gkeyfile.c:825 +#: glib/gkeyfile.c:826 msgid "Not a regular file" msgstr "Қалыпты файл емес" -#: glib/gkeyfile.c:1270 +#: glib/gkeyfile.c:1275 #, c-format msgid "" "Key file contains line “%s” which is not a key-value pair, group, or comment" msgstr "" -#: glib/gkeyfile.c:1327 +#: glib/gkeyfile.c:1332 #, c-format msgid "Invalid group name: %s" msgstr "Қате топ аты: %s" -#: glib/gkeyfile.c:1349 +#: glib/gkeyfile.c:1354 msgid "Key file does not start with a group" msgstr "" -#: glib/gkeyfile.c:1375 +#: glib/gkeyfile.c:1380 #, c-format msgid "Invalid key name: %s" msgstr "" -#: glib/gkeyfile.c:1402 +#: glib/gkeyfile.c:1407 #, c-format msgid "Key file contains unsupported encoding “%s”" msgstr "" -#: glib/gkeyfile.c:1645 glib/gkeyfile.c:1818 glib/gkeyfile.c:3271 -#: glib/gkeyfile.c:3334 glib/gkeyfile.c:3464 glib/gkeyfile.c:3594 -#: glib/gkeyfile.c:3738 glib/gkeyfile.c:3967 glib/gkeyfile.c:4034 +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3339 glib/gkeyfile.c:3469 glib/gkeyfile.c:3601 +#: glib/gkeyfile.c:3747 glib/gkeyfile.c:3976 glib/gkeyfile.c:4043 #, c-format msgid "Key file does not have group “%s”" msgstr "" -#: glib/gkeyfile.c:1773 +#: glib/gkeyfile.c:1778 #, c-format msgid "Key file does not have key “%s” in group “%s”" msgstr "" -#: glib/gkeyfile.c:1935 glib/gkeyfile.c:2051 +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 #, c-format msgid "Key file contains key “%s” with value “%s” which is not UTF-8" msgstr "" -#: glib/gkeyfile.c:1955 glib/gkeyfile.c:2071 glib/gkeyfile.c:2513 +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 #, c-format msgid "" "Key file contains key “%s” which has a value that cannot be interpreted." msgstr "" -#: glib/gkeyfile.c:2731 glib/gkeyfile.c:3100 +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 #, c-format msgid "" "Key file contains key “%s” in group “%s” which has a value that cannot be " "interpreted." msgstr "" -#: glib/gkeyfile.c:2809 glib/gkeyfile.c:2886 +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 #, c-format msgid "Key “%s” in group “%s” has value “%s” where %s was expected" msgstr "" -#: glib/gkeyfile.c:4274 +#: glib/gkeyfile.c:4283 msgid "Key file contains escape character at end of line" msgstr "" -#: glib/gkeyfile.c:4296 +#: glib/gkeyfile.c:4305 #, c-format msgid "Key file contains invalid escape sequence “%s”" msgstr "" -#: glib/gkeyfile.c:4440 +#: glib/gkeyfile.c:4449 #, c-format msgid "Value “%s” cannot be interpreted as a number." msgstr "" -#: glib/gkeyfile.c:4454 +#: glib/gkeyfile.c:4463 #, c-format msgid "Integer value “%s” out of range" msgstr "" -#: glib/gkeyfile.c:4487 +#: glib/gkeyfile.c:4496 #, c-format msgid "Value “%s” cannot be interpreted as a float number." msgstr "" -#: glib/gkeyfile.c:4526 +#: glib/gkeyfile.c:4535 #, c-format msgid "Value “%s” cannot be interpreted as a boolean." msgstr "" @@ -4640,91 +4672,91 @@ msgid "Failed to open file “%s”: open() failed: %s" msgstr "\"%s\" файлын ашу сәтсіз: open() аяқталды: %s" -#: glib/gmarkup.c:397 glib/gmarkup.c:439 +#: glib/gmarkup.c:398 glib/gmarkup.c:440 #, c-format msgid "Error on line %d char %d: " msgstr "" -#: glib/gmarkup.c:461 glib/gmarkup.c:544 +#: glib/gmarkup.c:462 glib/gmarkup.c:545 #, c-format msgid "Invalid UTF-8 encoded text in name — not valid “%s”" msgstr "" -#: glib/gmarkup.c:472 +#: glib/gmarkup.c:473 #, c-format msgid "“%s” is not a valid name" msgstr "\"%s\" дұрыс атау емес" -#: glib/gmarkup.c:488 +#: glib/gmarkup.c:489 #, c-format msgid "“%s” is not a valid name: “%c”" msgstr "\"%s\" дұрыс атау емес: \"%c\"" -#: glib/gmarkup.c:610 +#: glib/gmarkup.c:613 #, c-format msgid "Error on line %d: %s" msgstr "" -#: glib/gmarkup.c:687 +#: glib/gmarkup.c:690 #, c-format msgid "" "Failed to parse “%-.*s”, which should have been a digit inside a character " "reference (ê for example) — perhaps the digit is too large" msgstr "" -#: glib/gmarkup.c:699 +#: glib/gmarkup.c:702 msgid "" "Character reference did not end with a semicolon; most likely you used an " "ampersand character without intending to start an entity — escape ampersand " "as &" msgstr "" -#: glib/gmarkup.c:725 +#: glib/gmarkup.c:728 #, c-format msgid "Character reference “%-.*s” does not encode a permitted character" msgstr "" -#: glib/gmarkup.c:763 +#: glib/gmarkup.c:766 msgid "" "Empty entity “&;” seen; valid entities are: & " < > '" msgstr "" -#: glib/gmarkup.c:771 +#: glib/gmarkup.c:774 #, c-format msgid "Entity name “%-.*s” is not known" msgstr "" -#: glib/gmarkup.c:776 +#: glib/gmarkup.c:779 msgid "" "Entity did not end with a semicolon; most likely you used an ampersand " "character without intending to start an entity — escape ampersand as &" msgstr "" -#: glib/gmarkup.c:1182 +#: glib/gmarkup.c:1187 msgid "Document must begin with an element (e.g. )" msgstr "" -#: glib/gmarkup.c:1222 +#: glib/gmarkup.c:1227 #, c-format msgid "" "“%s” is not a valid character following a “<” character; it may not begin an " "element name" msgstr "" -#: glib/gmarkup.c:1264 +#: glib/gmarkup.c:1270 #, c-format msgid "" "Odd character “%s”, expected a “>” character to end the empty-element tag " "“%s”" msgstr "" -#: glib/gmarkup.c:1345 +#: glib/gmarkup.c:1352 #, c-format msgid "" "Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”" msgstr "" -#: glib/gmarkup.c:1386 +#: glib/gmarkup.c:1394 #, c-format msgid "" "Odd character “%s”, expected a “>” or “/” character to end the start tag of " @@ -4732,92 +4764,92 @@ "character in an attribute name" msgstr "" -#: glib/gmarkup.c:1430 +#: glib/gmarkup.c:1439 #, c-format msgid "" "Odd character “%s”, expected an open quote mark after the equals sign when " "giving value for attribute “%s” of element “%s”" msgstr "" -#: glib/gmarkup.c:1563 +#: glib/gmarkup.c:1573 #, c-format msgid "" "“%s” is not a valid character following the characters “”" msgstr "" -#: glib/gmarkup.c:1610 +#: glib/gmarkup.c:1623 #, c-format msgid "Element “%s” was closed, no element is currently open" msgstr "" -#: glib/gmarkup.c:1619 +#: glib/gmarkup.c:1632 #, c-format msgid "Element “%s” was closed, but the currently open element is “%s”" msgstr "" -#: glib/gmarkup.c:1772 +#: glib/gmarkup.c:1785 msgid "Document was empty or contained only whitespace" msgstr "" -#: glib/gmarkup.c:1786 +#: glib/gmarkup.c:1799 msgid "Document ended unexpectedly just after an open angle bracket “<”" msgstr "" -#: glib/gmarkup.c:1794 glib/gmarkup.c:1839 +#: glib/gmarkup.c:1807 glib/gmarkup.c:1852 #, c-format msgid "" "Document ended unexpectedly with elements still open — “%s” was the last " "element opened" msgstr "" -#: glib/gmarkup.c:1802 +#: glib/gmarkup.c:1815 #, c-format msgid "" "Document ended unexpectedly, expected to see a close angle bracket ending " "the tag <%s/>" msgstr "" -#: glib/gmarkup.c:1808 +#: glib/gmarkup.c:1821 msgid "Document ended unexpectedly inside an element name" msgstr "" -#: glib/gmarkup.c:1814 +#: glib/gmarkup.c:1827 msgid "Document ended unexpectedly inside an attribute name" msgstr "" -#: glib/gmarkup.c:1819 +#: glib/gmarkup.c:1832 msgid "Document ended unexpectedly inside an element-opening tag." msgstr "" -#: glib/gmarkup.c:1825 +#: glib/gmarkup.c:1838 msgid "" "Document ended unexpectedly after the equals sign following an attribute " "name; no attribute value" msgstr "" -#: glib/gmarkup.c:1832 +#: glib/gmarkup.c:1845 msgid "Document ended unexpectedly while inside an attribute value" msgstr "" -#: glib/gmarkup.c:1849 +#: glib/gmarkup.c:1862 #, c-format msgid "Document ended unexpectedly inside the close tag for element “%s”" msgstr "" -#: glib/gmarkup.c:1853 +#: glib/gmarkup.c:1866 msgid "" "Document ended unexpectedly inside the close tag for an unopened element" msgstr "" -#: glib/gmarkup.c:1859 +#: glib/gmarkup.c:1872 msgid "Document ended unexpectedly inside a comment or processing instruction" msgstr "" @@ -5232,15 +5264,15 @@ msgid "illegal symbolic reference" msgstr "" -#: glib/gregex.c:2582 +#: glib/gregex.c:2583 msgid "stray final “\\”" msgstr "" -#: glib/gregex.c:2586 +#: glib/gregex.c:2587 msgid "unknown escape sequence" msgstr "белгісіз escape тізбегі" -#: glib/gregex.c:2596 +#: glib/gregex.c:2597 #, c-format msgid "Error while parsing replacement text “%s” at char %lu: %s" msgstr "" @@ -5267,147 +5299,146 @@ msgid "Text was empty (or contained only whitespace)" msgstr "Мәтін бос болды (немесе тек бос аралықтан тұрды)" -#: glib/gspawn.c:302 +#: glib/gspawn.c:315 #, c-format msgid "Failed to read data from child process (%s)" msgstr "" -#: glib/gspawn.c:450 +#: glib/gspawn.c:463 #, c-format msgid "Unexpected error in select() reading data from a child process (%s)" msgstr "" -#: glib/gspawn.c:535 +#: glib/gspawn.c:548 #, c-format msgid "Unexpected error in waitpid() (%s)" msgstr "" -#: glib/gspawn.c:1043 glib/gspawn-win32.c:1318 +#: glib/gspawn.c:1056 glib/gspawn-win32.c:1329 #, c-format msgid "Child process exited with code %ld" msgstr "" -#: glib/gspawn.c:1051 +#: glib/gspawn.c:1064 #, c-format msgid "Child process killed by signal %ld" msgstr "" -#: glib/gspawn.c:1058 +#: glib/gspawn.c:1071 #, c-format msgid "Child process stopped by signal %ld" msgstr "" -#: glib/gspawn.c:1065 +#: glib/gspawn.c:1078 #, c-format msgid "Child process exited abnormally" msgstr "" -#: glib/gspawn.c:1360 glib/gspawn-win32.c:339 glib/gspawn-win32.c:347 +#: glib/gspawn.c:1405 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 #, c-format msgid "Failed to read from child pipe (%s)" msgstr "" -#: glib/gspawn.c:1596 +#: glib/gspawn.c:1653 #, c-format -#| msgid "Failed to open file “%s”: %s" msgid "Failed to spawn child process “%s” (%s)" msgstr "" -#: glib/gspawn.c:1635 +#: glib/gspawn.c:1692 #, c-format msgid "Failed to fork (%s)" msgstr "" -#: glib/gspawn.c:1784 glib/gspawn-win32.c:370 +#: glib/gspawn.c:1841 glib/gspawn-win32.c:381 #, c-format msgid "Failed to change to directory “%s” (%s)" msgstr "\"%s\" бумасына ауысу сәтсіз аяқталды (%s)" -#: glib/gspawn.c:1794 +#: glib/gspawn.c:1851 #, c-format msgid "Failed to execute child process “%s” (%s)" msgstr "" -#: glib/gspawn.c:1804 +#: glib/gspawn.c:1861 #, c-format msgid "Failed to redirect output or input of child process (%s)" msgstr "" -#: glib/gspawn.c:1813 +#: glib/gspawn.c:1870 #, c-format msgid "Failed to fork child process (%s)" msgstr "" -#: glib/gspawn.c:1821 +#: glib/gspawn.c:1878 #, c-format msgid "Unknown error executing child process “%s”" msgstr "" -#: glib/gspawn.c:1845 +#: glib/gspawn.c:1902 #, c-format msgid "Failed to read enough data from child pid pipe (%s)" msgstr "" -#: glib/gspawn-win32.c:283 +#: glib/gspawn-win32.c:294 msgid "Failed to read data from child process" msgstr "" -#: glib/gspawn-win32.c:300 +#: glib/gspawn-win32.c:311 #, c-format msgid "Failed to create pipe for communicating with child process (%s)" msgstr "" -#: glib/gspawn-win32.c:376 glib/gspawn-win32.c:381 glib/gspawn-win32.c:500 +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 #, c-format msgid "Failed to execute child process (%s)" msgstr "" -#: glib/gspawn-win32.c:450 +#: glib/gspawn-win32.c:461 #, c-format msgid "Invalid program name: %s" msgstr "Бағдарлама аты қате: %s" -#: glib/gspawn-win32.c:460 glib/gspawn-win32.c:714 +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 #, c-format msgid "Invalid string in argument vector at %d: %s" msgstr "" -#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:729 +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 #, c-format msgid "Invalid string in environment: %s" msgstr "" -#: glib/gspawn-win32.c:710 +#: glib/gspawn-win32.c:721 #, c-format msgid "Invalid working directory: %s" msgstr "Жұмыс бумасы қате: %s" -#: glib/gspawn-win32.c:772 +#: glib/gspawn-win32.c:783 #, c-format msgid "Failed to execute helper program (%s)" msgstr "Көмекші бағдарламаны орындау қатесі (%s)" -#: glib/gspawn-win32.c:1045 +#: glib/gspawn-win32.c:1056 msgid "" "Unexpected error in g_io_channel_win32_poll() reading data from a child " "process" msgstr "" -#: glib/gstrfuncs.c:3247 glib/gstrfuncs.c:3348 +#: glib/gstrfuncs.c:3286 glib/gstrfuncs.c:3388 msgid "Empty string is not a number" msgstr "" -#: glib/gstrfuncs.c:3271 +#: glib/gstrfuncs.c:3310 #, c-format msgid "“%s” is not a signed number" msgstr "\"%s\" таңбасы бар сан емес" -#: glib/gstrfuncs.c:3281 glib/gstrfuncs.c:3384 +#: glib/gstrfuncs.c:3320 glib/gstrfuncs.c:3424 #, c-format msgid "Number “%s” is out of bounds [%s, %s]" msgstr "" -#: glib/gstrfuncs.c:3374 +#: glib/gstrfuncs.c:3414 #, c-format msgid "“%s” is not an unsigned number" msgstr "\"%s\" таңбасы жоқ сан емес" @@ -5429,147 +5460,172 @@ msgid "Character out of range for UTF-16" msgstr "" -#: glib/gutils.c:2244 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2339 #, c-format -msgid "%.1f kB" -msgstr "%.1f КБ" +#| msgid "%.1f kB" +msgid "%.1f kB" +msgstr "%.1f КБ" -#: glib/gutils.c:2245 glib/gutils.c:2451 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2341 #, c-format -msgid "%.1f MB" -msgstr "%.1f МБ" +msgid "%.1f MB" +msgstr "%.1f МБ" -#: glib/gutils.c:2246 glib/gutils.c:2456 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2343 #, c-format -msgid "%.1f GB" -msgstr "%.1f ГБ" +msgid "%.1f GB" +msgstr "%.1f ГБ" -#: glib/gutils.c:2247 glib/gutils.c:2461 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2345 #, c-format -msgid "%.1f TB" -msgstr "%.1f ТБ" +msgid "%.1f TB" +msgstr "%.1f ТБ" -#: glib/gutils.c:2248 glib/gutils.c:2466 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2347 #, c-format -msgid "%.1f PB" -msgstr "%.1f ПБ" +msgid "%.1f PB" +msgstr "%.1f ПБ" -#: glib/gutils.c:2249 glib/gutils.c:2471 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2349 #, c-format -msgid "%.1f EB" -msgstr "%.1f ЭБ" +msgid "%.1f EB" +msgstr "%.1f ЭБ" -#: glib/gutils.c:2252 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2353 #, c-format -msgid "%.1f KiB" -msgstr "%.1f КиБ" +msgid "%.1f KiB" +msgstr "%.1f КиБ" -#: glib/gutils.c:2253 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2355 #, c-format -msgid "%.1f MiB" -msgstr "%.1f МиБ" +msgid "%.1f MiB" +msgstr "%.1f МиБ" -#: glib/gutils.c:2254 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2357 #, c-format -msgid "%.1f GiB" -msgstr "%.1f ГиБ" +msgid "%.1f GiB" +msgstr "%.1f ГиБ" -#: glib/gutils.c:2255 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2359 #, c-format -msgid "%.1f TiB" -msgstr "%.1f ТиБ" +msgid "%.1f TiB" +msgstr "%.1f ТиБ" -#: glib/gutils.c:2256 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2361 #, c-format -msgid "%.1f PiB" -msgstr "%.1f ПиБ" +msgid "%.1f PiB" +msgstr "%.1f ПиБ" -#: glib/gutils.c:2257 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2363 #, c-format -msgid "%.1f EiB" -msgstr "%.1f ЭиБ" +msgid "%.1f EiB" +msgstr "%.1f ЭиБ" -#: glib/gutils.c:2260 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2367 #, c-format -msgid "%.1f kb" -msgstr "%.1f кб" +msgid "%.1f kb" +msgstr "%.1f кб" -#: glib/gutils.c:2261 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2369 #, c-format -msgid "%.1f Mb" -msgstr "%.1f Мб" +msgid "%.1f Mb" +msgstr "%.1f Мб" -#: glib/gutils.c:2262 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2371 #, c-format -msgid "%.1f Gb" -msgstr "%.1f Гб" +msgid "%.1f Gb" +msgstr "%.1f Гб" -#: glib/gutils.c:2263 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2373 #, c-format -msgid "%.1f Tb" -msgstr "%.1f Тб" +msgid "%.1f Tb" +msgstr "%.1f Тб" -#: glib/gutils.c:2264 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2375 #, c-format -msgid "%.1f Pb" -msgstr "%.1f Пб" +msgid "%.1f Pb" +msgstr "%.1f Пб" -#: glib/gutils.c:2265 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2377 #, c-format -msgid "%.1f Eb" -msgstr "%.1f Эб" +msgid "%.1f Eb" +msgstr "%.1f Эб" -#: glib/gutils.c:2268 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2381 #, c-format -msgid "%.1f Kib" -msgstr "%.1f Киб" +msgid "%.1f Kib" +msgstr "%.1f Киб" -#: glib/gutils.c:2269 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2383 #, c-format -msgid "%.1f Mib" -msgstr "%.1f Миб" +msgid "%.1f Mib" +msgstr "%.1f Миб" -#: glib/gutils.c:2270 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2385 #, c-format -msgid "%.1f Gib" -msgstr "%.1f Гиб" +msgid "%.1f Gib" +msgstr "%.1f Гиб" -#: glib/gutils.c:2271 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2387 #, c-format -msgid "%.1f Tib" -msgstr "%.1f Тиб" +msgid "%.1f Tib" +msgstr "%.1f Тиб" -#: glib/gutils.c:2272 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2389 #, c-format -msgid "%.1f Pib" -msgstr "%.1f Пиб" +msgid "%.1f Pib" +msgstr "%.1f Пиб" -#: glib/gutils.c:2273 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2391 #, c-format -msgid "%.1f Eib" -msgstr "%.1f Эиб" +msgid "%.1f Eib" +msgstr "%.1f Эиб" -#: glib/gutils.c:2307 glib/gutils.c:2433 +#: glib/gutils.c:2425 glib/gutils.c:2551 #, c-format msgid "%u byte" msgid_plural "%u bytes" msgstr[0] "%u байт" -#: glib/gutils.c:2311 +#: glib/gutils.c:2429 #, c-format msgid "%u bit" msgid_plural "%u bits" msgstr[0] "%u бит" #. Translators: the %s in "%s bytes" will always be replaced by a number. -#: glib/gutils.c:2378 +#: glib/gutils.c:2496 #, c-format msgid "%s byte" msgid_plural "%s bytes" msgstr[0] "%s байт" #. Translators: the %s in "%s bits" will always be replaced by a number. -#: glib/gutils.c:2383 +#: glib/gutils.c:2501 #, c-format msgid "%s bit" msgid_plural "%s bits" @@ -5580,11 +5636,36 @@ #. * compatibility. Users will not see this string unless a program is using this deprecated function. #. * Please translate as literally as possible. #. -#: glib/gutils.c:2446 +#: glib/gutils.c:2564 #, c-format msgid "%.1f KB" msgstr "%.1f КБ" +#: glib/gutils.c:2569 +#, c-format +msgid "%.1f MB" +msgstr "%.1f МБ" + +#: glib/gutils.c:2574 +#, c-format +msgid "%.1f GB" +msgstr "%.1f ГБ" + +#: glib/gutils.c:2579 +#, c-format +msgid "%.1f TB" +msgstr "%.1f ТБ" + +#: glib/gutils.c:2584 +#, c-format +msgid "%.1f PB" +msgstr "%.1f ПБ" + +#: glib/gutils.c:2589 +#, c-format +msgid "%.1f EB" +msgstr "%.1f ЭБ" + #~ msgid "[ARGS...]" #~ msgstr "[АРГУМЕНТТЕР...]" diff -Nru glib2.0-2.59.2/po/pt_BR.po glib2.0-2.59.3/po/pt_BR.po --- glib2.0-2.59.2/po/pt_BR.po 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/pt_BR.po 2019-03-04 09:01:42.000000000 +0000 @@ -1,5 +1,5 @@ # Brazilian Portuguese translation of glib. -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2019 Free Software Foundation, Inc. # This file is distributed under the same license as the glib package. # Gustavo Noronha Silva , 2001-2005 # Leonardo Ferreira Fontenelle , 2006-2009. @@ -14,42 +14,47 @@ # Jonh Wendell , 2009, 2010, 2012. # Felipe Braga , 2015. # Artur de Aquino Morais , 2016. -# Rafael Fontenelle , 2013, 2016-2018. # Enrico Nicoletto , 2013, 2014, 2016. +# Rafael Fontenelle , 2013-2019. +# msgid "" msgstr "" "Project-Id-Version: glib\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" -"POT-Creation-Date: 2018-08-30 18:47+0000\n" -"PO-Revision-Date: 2018-09-01 12:21-0200\n" +"POT-Creation-Date: 2019-02-12 14:26+0000\n" +"PO-Revision-Date: 2019-02-13 11:18-0200\n" "Last-Translator: Rafael Fontenelle \n" -"Language-Team: Brazilian Portuguese \n" +"Language-Team: Portuguese - Brazil \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Virtaal 1.0.0-beta1\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" +"X-Generator: Gtranslator 3.31.90\n" "X-Project-Style: gnome\n" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "GApplication options" msgstr "Opções do GApplication" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "Show GApplication options" msgstr "Mostra as opções do GApplication" -#: gio/gapplication.c:541 +#: gio/gapplication.c:544 msgid "Enter GApplication service mode (use from D-Bus service files)" msgstr "" -"Digite o modo de serviço do GApplication (usar dos arquivos de serviços do " -"D-Bus)" +"Digite o modo de serviço do GApplication (usar dos arquivos de serviços do D-" +"Bus)" -#: gio/gapplication.c:553 +#: gio/gapplication.c:556 msgid "Override the application’s ID" msgstr "Substitui ID do aplicativo" +#: gio/gapplication.c:568 +msgid "Replace the running instance" +msgstr "Substitui a instância em execução" + #: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 #: gio/gresource-tool.c:495 gio/gsettings-tool.c:569 msgid "Print help" @@ -73,7 +78,8 @@ #: gio/gapplication-tool.c:53 msgid "List the installed D-Bus activatable applications (by .desktop files)" -msgstr "Lista os aplicativos instalados que ativam D-Bus (por arquivos .desktop)" +msgstr "" +"Lista os aplicativos instalados que ativam D-Bus (por arquivos .desktop)" #: gio/gapplication-tool.c:55 msgid "Launch an application" @@ -122,10 +128,11 @@ #: gio/gapplication-tool.c:71 msgid "Application identifier in D-Bus format (eg: org.example.viewer)" -msgstr "Identificador do aplicativo em formato D-Bus (ex: org.exemplo.visualizador)" +msgstr "" +"Identificador do aplicativo em formato D-Bus (ex: org.exemplo.visualizador)" -#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:737 -#: gio/glib-compile-resources.c:743 gio/glib-compile-resources.c:770 +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 #: gio/gresource-tool.c:502 gio/gresource-tool.c:568 msgid "FILE" msgstr "ARQUIVO" @@ -234,7 +241,8 @@ "action names must consist of only alphanumerics, “-” and “.”\n" msgstr "" "nome da ação inválido: “%s”\n" -"os nomes de ações devem consistir de apenas caracteres alfanuméricos, “-” e “.”\n" +"os nomes de ações devem consistir de apenas caracteres alfanuméricos, “-” e " +"“.”\n" #: gio/gapplication-tool.c:344 #, c-format @@ -265,8 +273,8 @@ #: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 #: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 -#: gio/ginputstream.c:1019 gio/goutputstream.c:203 gio/goutputstream.c:834 -#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:209 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 #, c-format msgid "Too large count value passed to %s" msgstr "Valor muito alto passado para %s" @@ -281,7 +289,7 @@ msgstr "Não é possível truncar GBufferedInputStream" #: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 -#: gio/goutputstream.c:1661 +#: gio/goutputstream.c:2198 msgid "Stream is already closed" msgstr "O fluxo já está fechado" @@ -289,7 +297,7 @@ msgid "Truncate not supported on base stream" msgstr "Não há suporte para truncar fluxo base" -#: gio/gcancellable.c:317 gio/gdbusconnection.c:1840 gio/gdbusprivate.c:1402 +#: gio/gcancellable.c:317 gio/gdbusconnection.c:1867 gio/gdbusprivate.c:1402 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 #, c-format msgid "Operation was cancelled" @@ -308,33 +316,33 @@ msgstr "Espaço insuficiente no destino" #: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 -#: gio/gdatainputstream.c:1261 glib/gconvert.c:454 glib/gconvert.c:883 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:455 glib/gconvert.c:885 #: glib/giochannel.c:1557 glib/giochannel.c:1599 glib/giochannel.c:2443 #: glib/gutf8.c:869 glib/gutf8.c:1322 msgid "Invalid byte sequence in conversion input" msgstr "Sequência de bytes inválida na entrada de conversão" -#: gio/gcharsetconverter.c:347 glib/gconvert.c:462 glib/gconvert.c:797 +#: gio/gcharsetconverter.c:347 glib/gconvert.c:463 glib/gconvert.c:799 #: glib/giochannel.c:1564 glib/giochannel.c:2455 #, c-format msgid "Error during conversion: %s" msgstr "Erro durante a conversão: %s" -#: gio/gcharsetconverter.c:445 gio/gsocket.c:1104 +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1093 msgid "Cancellable initialization not supported" msgstr "Sem suporte a inicialização cancelável" -#: gio/gcharsetconverter.c:456 glib/gconvert.c:327 glib/giochannel.c:1385 +#: gio/gcharsetconverter.c:456 glib/gconvert.c:328 glib/giochannel.c:1385 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported" msgstr "Não há suporte à conversão do conjunto de caracteres “%s” para “%s”" -#: gio/gcharsetconverter.c:460 glib/gconvert.c:331 +#: gio/gcharsetconverter.c:460 glib/gconvert.c:332 #, c-format msgid "Could not open converter from “%s” to “%s”" msgstr "Não foi possível abrir conversor de “%s” para “%s”" -#: gio/gcontenttype.c:358 +#: gio/gcontenttype.c:452 #, c-format msgid "%s type" msgstr "tipo %s" @@ -362,7 +370,9 @@ #: gio/gcredentials.c:568 msgid "Credentials spoofing is not possible on this OS" -msgstr "Não é possível fazer uso de falsificação de credenciais neste sistema operacional" +msgstr "" +"Não é possível fazer uso de falsificação de credenciais neste sistema " +"operacional" #: gio/gdatainputstream.c:304 msgid "Unexpected early end-of-stream" @@ -375,13 +385,17 @@ #: gio/gdbusaddress.c:185 #, c-format -msgid "Address “%s” is invalid (need exactly one of path, tmpdir or abstract keys)" -msgstr "O endereço “%s” é inválido (é necessário exatamente um dentre: caminho, diretório temporário ou chaves abstratas)" +msgid "" +"Address “%s” is invalid (need exactly one of path, tmpdir or abstract keys)" +msgstr "" +"O endereço “%s” é inválido (é necessário exatamente um dentre: caminho, " +"diretório temporário ou chaves abstratas)" #: gio/gdbusaddress.c:198 #, c-format msgid "Meaningless key/value pair combination in address entry “%s”" -msgstr "Combinação de pares chave/valor sem sentido na entrada de endereço “%s”" +msgstr "" +"Combinação de pares chave/valor sem sentido na entrada de endereço “%s”" #: gio/gdbusaddress.c:261 gio/gdbusaddress.c:342 #, c-format @@ -405,23 +419,36 @@ #: gio/gdbusaddress.c:488 #, c-format -msgid "Key/Value pair %d, “%s”, in address element “%s” does not contain an equal sign" -msgstr "O par chave/valor %d, “%s”, no elemento endereço “%s”, não contém um sinal de igual" +msgid "" +"Key/Value pair %d, “%s”, in address element “%s” does not contain an equal " +"sign" +msgstr "" +"O par chave/valor %d, “%s”, no elemento endereço “%s”, não contém um sinal " +"de igual" #: gio/gdbusaddress.c:502 #, c-format -msgid "Error unescaping key or value in Key/Value pair %d, “%s”, in address element “%s”" -msgstr "Erro ao distinguir a chave sem escape ou valor no par chave/valor %d, “%s”, no elemento endereço “%s”" +msgid "" +"Error unescaping key or value in Key/Value pair %d, “%s”, in address element " +"“%s”" +msgstr "" +"Erro ao distinguir a chave sem escape ou valor no par chave/valor %d, “%s”, " +"no elemento endereço “%s”" #: gio/gdbusaddress.c:580 #, c-format -msgid "Error in address “%s” — the unix transport requires exactly one of the keys “path” or “abstract” to be set" -msgstr "Erro no endereço “%s” — o transporte Unix requer exatamente uma das chaves “path” ou “abstract” sejam definidas" +msgid "" +"Error in address “%s” — the unix transport requires exactly one of the keys " +"“path” or “abstract” to be set" +msgstr "" +"Erro no endereço “%s” — o transporte Unix requer exatamente uma das chaves " +"“path” ou “abstract” sejam definidas" #: gio/gdbusaddress.c:616 #, c-format msgid "Error in address “%s” — the host attribute is missing or malformed" -msgstr "Erro no endereço “%s” — o atributo servidor está faltando ou malformado" +msgstr "" +"Erro no endereço “%s” — o atributo servidor está faltando ou malformado" #: gio/gdbusaddress.c:630 #, c-format @@ -431,7 +458,9 @@ #: gio/gdbusaddress.c:644 #, c-format msgid "Error in address “%s” — the noncefile attribute is missing or malformed" -msgstr "Erro no endereço “%s” — o atributo do arquivo de valor de uso único está faltando ou malformado" +msgstr "" +"Erro no endereço “%s” — o atributo do arquivo de valor de uso único está " +"faltando ou malformado" #: gio/gdbusaddress.c:665 msgid "Error auto-launching: " @@ -450,7 +479,9 @@ #: gio/gdbusaddress.c:746 #, c-format msgid "Error reading from nonce file “%s”, expected 16 bytes, got %d" -msgstr "Erro ao ler o arquivo de valor de uso único “%s”; era esperado 16 bytes, mas foi obtido %d" +msgstr "" +"Erro ao ler o arquivo de valor de uso único “%s”; era esperado 16 bytes, mas " +"foi obtido %d" #: gio/gdbusaddress.c:764 #, c-format @@ -468,7 +499,8 @@ #: gio/gdbusaddress.c:1093 msgid "Cannot spawn a message bus without a machine-id: " -msgstr "Não foi possível chamar um barramento de mensagens sem um ID de máquina: " +msgstr "" +"Não foi possível chamar um barramento de mensagens sem um ID de máquina: " #: gio/gdbusaddress.c:1100 #, c-format @@ -493,16 +525,26 @@ #: gio/gdbusaddress.c:1524 #, c-format msgid "Cannot determine session bus address (not implemented for this OS)" -msgstr "Não foi possível determinar o endereço de barramento da sessão (sem implementação para este SO)" +msgstr "" +"Não foi possível determinar o endereço de barramento da sessão (sem " +"implementação para este SO)" -#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7142 +#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7174 #, c-format -msgid "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable — unknown value “%s”" -msgstr "Não foi possível determinar o endereço de barramento da variável de ambiente DBUS_STARTER_BUS_TYPE — valor desconhecido “%s”" +msgid "" +"Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " +"— unknown value “%s”" +msgstr "" +"Não foi possível determinar o endereço de barramento da variável de ambiente " +"DBUS_STARTER_BUS_TYPE — valor desconhecido “%s”" -#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7151 -msgid "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment variable is not set" -msgstr "Não foi possível determinar o endereço do barramento porque a variável de ambiente DBUS_STARTER_BUS_TYPE não está definida" +#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7183 +msgid "" +"Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " +"variable is not set" +msgstr "" +"Não foi possível determinar o endereço do barramento porque a variável de " +"ambiente DBUS_STARTER_BUS_TYPE não está definida" #: gio/gdbusaddress.c:1681 #, c-format @@ -519,8 +561,11 @@ #: gio/gdbusauth.c:481 #, c-format -msgid "Exhausted all available authentication mechanisms (tried: %s) (available: %s)" -msgstr "Foram esgotados todos mecanismos de autenticação disponíveis (tentado: %s) (disponível: %s)" +msgid "" +"Exhausted all available authentication mechanisms (tried: %s) (available: %s)" +msgstr "" +"Foram esgotados todos mecanismos de autenticação disponíveis (tentado: %s) " +"(disponível: %s)" #: gio/gdbusauth.c:1144 msgid "Cancelled via GDBusAuthObserver::authorize-authenticated-peer" @@ -533,8 +578,11 @@ #: gio/gdbusauthmechanismsha1.c:274 #, c-format -msgid "Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o" -msgstr "As permissões no diretório “%s” estão malformadas. É esperado 0700, mas foi obtido 0%o" +msgid "" +"Permissions on directory “%s” are malformed. Expected mode 0700, got 0%o" +msgstr "" +"As permissões no diretório “%s” estão malformadas. É esperado 0700, mas foi " +"obtido 0%o" #: gio/gdbusauthmechanismsha1.c:299 #, c-format @@ -553,13 +601,19 @@ #: gio/gdbusauthmechanismsha1.c:383 gio/gdbusauthmechanismsha1.c:701 #, c-format -msgid "First token of line %d of the keyring at “%s” with content “%s” is malformed" -msgstr "O primeiro símbolo da linha %d do chaveiro em “%s” com o conteúdo “%s” está malformado" +msgid "" +"First token of line %d of the keyring at “%s” with content “%s” is malformed" +msgstr "" +"O primeiro símbolo da linha %d do chaveiro em “%s” com o conteúdo “%s” está " +"malformado" #: gio/gdbusauthmechanismsha1.c:397 gio/gdbusauthmechanismsha1.c:715 #, c-format -msgid "Second token of line %d of the keyring at “%s” with content “%s” is malformed" -msgstr "O segundo símbolo da linha %d do chaveiro em “%s” com o conteúdo “%s” está malformado" +msgid "" +"Second token of line %d of the keyring at “%s” with content “%s” is malformed" +msgstr "" +"O segundo símbolo da linha %d do chaveiro em “%s” com o conteúdo “%s” está " +"malformado" #: gio/gdbusauthmechanismsha1.c:421 #, c-format @@ -596,153 +650,182 @@ msgid "(Additionally, releasing the lock for “%s” also failed: %s) " msgstr "(Adicionalmente, liberar o bloqueio de “%s” também falhou: %s) " -#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2369 +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2396 msgid "The connection is closed" msgstr "A conexão está fechada" -#: gio/gdbusconnection.c:1870 +#: gio/gdbusconnection.c:1897 msgid "Timeout was reached" msgstr "O tempo limite foi alcançado" -#: gio/gdbusconnection.c:2491 -msgid "Unsupported flags encountered when constructing a client-side connection" -msgstr "Foram encontrados sinalizadores sem suporte ao construir uma conexão do lado do cliente" +#: gio/gdbusconnection.c:2518 +msgid "" +"Unsupported flags encountered when constructing a client-side connection" +msgstr "" +"Foram encontrados sinalizadores sem suporte ao construir uma conexão do lado " +"do cliente" -#: gio/gdbusconnection.c:4115 gio/gdbusconnection.c:4462 +#: gio/gdbusconnection.c:4147 gio/gdbusconnection.c:4494 #, c-format -msgid "No such interface “org.freedesktop.DBus.Properties” on object at path %s" -msgstr "Nenhuma interface “org.freedesktop.DBus.Properties” no objeto no caminho %s" +msgid "" +"No such interface “org.freedesktop.DBus.Properties” on object at path %s" +msgstr "" +"Nenhuma interface “org.freedesktop.DBus.Properties” no objeto no caminho %s" -#: gio/gdbusconnection.c:4257 +#: gio/gdbusconnection.c:4289 #, c-format msgid "No such property “%s”" msgstr "Nenhuma propriedade “%s”" -#: gio/gdbusconnection.c:4269 +#: gio/gdbusconnection.c:4301 #, c-format msgid "Property “%s” is not readable" msgstr "A propriedade “%s” não pode ser lida" -#: gio/gdbusconnection.c:4280 +#: gio/gdbusconnection.c:4312 #, c-format msgid "Property “%s” is not writable" msgstr "A propriedade “%s” não pode ser escrita" -#: gio/gdbusconnection.c:4300 +#: gio/gdbusconnection.c:4332 #, c-format msgid "Error setting property “%s”: Expected type “%s” but got “%s”" -msgstr "Erro ao definir a propriedade “%s”: o tipo esperado é “%s”, mas obteve “%s”" +msgstr "" +"Erro ao definir a propriedade “%s”: o tipo esperado é “%s”, mas obteve “%s”" -#: gio/gdbusconnection.c:4405 gio/gdbusconnection.c:4613 -#: gio/gdbusconnection.c:6582 +#: gio/gdbusconnection.c:4437 gio/gdbusconnection.c:4645 +#: gio/gdbusconnection.c:6614 #, c-format msgid "No such interface “%s”" msgstr "Nenhuma interface “%s”" -#: gio/gdbusconnection.c:4831 gio/gdbusconnection.c:7091 +#: gio/gdbusconnection.c:4863 gio/gdbusconnection.c:7123 #, c-format msgid "No such interface “%s” on object at path %s" msgstr "Nenhuma interface “%s” no objeto no caminho %s" -#: gio/gdbusconnection.c:4929 +#: gio/gdbusconnection.c:4961 #, c-format msgid "No such method “%s”" msgstr "Método inexistente “%s”" -#: gio/gdbusconnection.c:4960 +#: gio/gdbusconnection.c:4992 #, c-format msgid "Type of message, “%s”, does not match expected type “%s”" msgstr "O tipo da mensagem, “%s”, não equivale ao tipo esperado “%s”" -#: gio/gdbusconnection.c:5158 +#: gio/gdbusconnection.c:5190 #, c-format msgid "An object is already exported for the interface %s at %s" msgstr "Um objeto já foi exportado para a interface %s em %s" -#: gio/gdbusconnection.c:5384 +#: gio/gdbusconnection.c:5416 #, c-format msgid "Unable to retrieve property %s.%s" msgstr "Não foi possível obter a propriedade %s.%s" -#: gio/gdbusconnection.c:5440 +#: gio/gdbusconnection.c:5472 #, c-format msgid "Unable to set property %s.%s" msgstr "Não foi possível definir a propriedade %s.%s" -#: gio/gdbusconnection.c:5618 +#: gio/gdbusconnection.c:5650 #, c-format msgid "Method “%s” returned type “%s”, but expected “%s”" msgstr "O método “%s” retornou o tipo “%s”, mas é esperado “%s”" -#: gio/gdbusconnection.c:6693 +#: gio/gdbusconnection.c:6725 #, c-format msgid "Method “%s” on interface “%s” with signature “%s” does not exist" msgstr "O método “%s” na interface “%s” com a assinatura “%s” não existe" -#: gio/gdbusconnection.c:6814 +#: gio/gdbusconnection.c:6846 #, c-format msgid "A subtree is already exported for %s" msgstr "Uma subárvore já foi exportada para %s" -#: gio/gdbusmessage.c:1248 +#: gio/gdbusmessage.c:1251 msgid "type is INVALID" msgstr "o tipo é INVALID" -#: gio/gdbusmessage.c:1259 +#: gio/gdbusmessage.c:1262 msgid "METHOD_CALL message: PATH or MEMBER header field is missing" -msgstr "Mensagem de METHOD_CALL: O campo de cabeçalho PATH ou MEMBER está faltando" +msgstr "" +"Mensagem de METHOD_CALL: O campo de cabeçalho PATH ou MEMBER está faltando" -#: gio/gdbusmessage.c:1270 +#: gio/gdbusmessage.c:1273 msgid "METHOD_RETURN message: REPLY_SERIAL header field is missing" -msgstr "Mensagem de METHOD_RETURN: O campo de cabeçalho REPLY_SERIAL está faltando" +msgstr "" +"Mensagem de METHOD_RETURN: O campo de cabeçalho REPLY_SERIAL está faltando" -#: gio/gdbusmessage.c:1282 +#: gio/gdbusmessage.c:1285 msgid "ERROR message: REPLY_SERIAL or ERROR_NAME header field is missing" -msgstr "Mensagem de ERROR: O campo de cabeçalho REPLY_SERIAL ou ERROR_NAME está faltando" +msgstr "" +"Mensagem de ERROR: O campo de cabeçalho REPLY_SERIAL ou ERROR_NAME está " +"faltando" -#: gio/gdbusmessage.c:1295 +#: gio/gdbusmessage.c:1298 msgid "SIGNAL message: PATH, INTERFACE or MEMBER header field is missing" -msgstr "Mensagem de SIGNAL: O campo de cabeçalho PATH, INTERFACE ou MEMBER está faltando" +msgstr "" +"Mensagem de SIGNAL: O campo de cabeçalho PATH, INTERFACE ou MEMBER está " +"faltando" -#: gio/gdbusmessage.c:1303 -msgid "SIGNAL message: The PATH header field is using the reserved value /org/freedesktop/DBus/Local" -msgstr "Mensagem de SIGNAL: O campo de cabeçalho PATH está usando o valor reservado /org/freedesktop/DBus/Local" +#: gio/gdbusmessage.c:1306 +msgid "" +"SIGNAL message: The PATH header field is using the reserved value /org/" +"freedesktop/DBus/Local" +msgstr "" +"Mensagem de SIGNAL: O campo de cabeçalho PATH está usando o valor reservado /" +"org/freedesktop/DBus/Local" -#: gio/gdbusmessage.c:1311 -msgid "SIGNAL message: The INTERFACE header field is using the reserved value org.freedesktop.DBus.Local" -msgstr "Mensagem de SIGNAL: O campo de cabeçalho INTERFACE está usando o valor reservado org.freedesktop.DBus.Local" +#: gio/gdbusmessage.c:1314 +msgid "" +"SIGNAL message: The INTERFACE header field is using the reserved value org." +"freedesktop.DBus.Local" +msgstr "" +"Mensagem de SIGNAL: O campo de cabeçalho INTERFACE está usando o valor " +"reservado org.freedesktop.DBus.Local" -#: gio/gdbusmessage.c:1359 gio/gdbusmessage.c:1419 +#: gio/gdbusmessage.c:1362 gio/gdbusmessage.c:1422 #, c-format msgid "Wanted to read %lu byte but only got %lu" msgid_plural "Wanted to read %lu bytes but only got %lu" msgstr[0] "Ao tentar ler %lu byte obteve-se %lu" msgstr[1] "Ao tentar ler %lu bytes obteve-se %lu" -#: gio/gdbusmessage.c:1373 +#: gio/gdbusmessage.c:1376 #, c-format msgid "Expected NUL byte after the string “%s” but found byte %d" -msgstr "Era esperado um byte NUL (nulo) após o texto “%s”, mas foi localizado o byte %d" +msgstr "" +"Era esperado um byte NUL (nulo) após o texto “%s”, mas foi localizado o byte " +"%d" -#: gio/gdbusmessage.c:1392 +#: gio/gdbusmessage.c:1395 #, c-format -msgid "Expected valid UTF-8 string but found invalid bytes at byte offset %d (length of string is %d). The valid UTF-8 string up until that point was “%s”" -msgstr "Era esperado um texto UTF-8 válido, mas foi localizado bytes inválidos na posição %d (tamanho do texto é %d). O texto UTF-8 válido até este ponto era “%s”" +msgid "" +"Expected valid UTF-8 string but found invalid bytes at byte offset %d " +"(length of string is %d). The valid UTF-8 string up until that point was “%s”" +msgstr "" +"Era esperado um texto UTF-8 válido, mas foi localizado bytes inválidos na " +"posição %d (tamanho do texto é %d). O texto UTF-8 válido até este ponto era " +"“%s”" -#: gio/gdbusmessage.c:1595 +#: gio/gdbusmessage.c:1598 #, c-format msgid "Parsed value “%s” is not a valid D-Bus object path" msgstr "O valor “%s” analisado não é um objeto de caminho D-Bus válido" -#: gio/gdbusmessage.c:1617 +#: gio/gdbusmessage.c:1620 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature" msgstr "O valor “%s” analisado não é uma assinatura D-Bus válida" -#: gio/gdbusmessage.c:1664 +#: gio/gdbusmessage.c:1667 #, c-format -msgid "Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." -msgid_plural "Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." +msgid "" +"Encountered array of length %u byte. Maximum length is 2<<26 bytes (64 MiB)." +msgid_plural "" +"Encountered array of length %u bytes. Maximum length is 2<<26 bytes (64 MiB)." msgstr[0] "" "Foi encontrado um vetor com tamanho de %u byte. O tamanho máximo é de 2<<26 " "bytes (64 MiB)." @@ -750,112 +833,161 @@ "Foi encontrado um vetor com tamanho de %u bytes. O tamanho máximo é de 2<<26 " "bytes (64 MiB)." -#: gio/gdbusmessage.c:1684 +#: gio/gdbusmessage.c:1687 #, c-format -msgid "Encountered array of type “a%c”, expected to have a length a multiple of %u bytes, but found to be %u bytes in length" -msgstr "Foi encontrado um vetor de tipo “a%c”, esperava-se que tivesse um comprimento múltiplo de %u bytes, porém foi localizado %u bytes em comprimento" +msgid "" +"Encountered array of type “a%c”, expected to have a length a multiple of %u " +"bytes, but found to be %u bytes in length" +msgstr "" +"Foi encontrado um vetor de tipo “a%c”, esperava-se que tivesse um " +"comprimento múltiplo de %u bytes, porém foi localizado %u bytes em " +"comprimento" -#: gio/gdbusmessage.c:1851 +#: gio/gdbusmessage.c:1857 #, c-format msgid "Parsed value “%s” for variant is not a valid D-Bus signature" msgstr "O valor “%s” analisado para variante não é uma assinatura D-Bus válida" -#: gio/gdbusmessage.c:1875 +#: gio/gdbusmessage.c:1881 #, c-format -msgid "Error deserializing GVariant with type string “%s” from the D-Bus wire format" -msgstr "Erro ao desserializar GVariant com o texto de tipo “%s” do formato delimitado pelo D-Bus" +msgid "" +"Error deserializing GVariant with type string “%s” from the D-Bus wire format" +msgstr "" +"Erro ao desserializar GVariant com o texto de tipo “%s” do formato " +"delimitado pelo D-Bus" -#: gio/gdbusmessage.c:2057 +#: gio/gdbusmessage.c:2066 #, c-format -msgid "Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value 0x%02x" -msgstr "Valor identificador de endian inválido. Era esperado 0x6c (“l”) ou 0x42 (“B”), mas foi localizado o valor 0x%02x" +msgid "" +"Invalid endianness value. Expected 0x6c (“l”) or 0x42 (“B”) but found value " +"0x%02x" +msgstr "" +"Valor identificador de endian inválido. Era esperado 0x6c (“l”) ou 0x42 " +"(“B”), mas foi localizado o valor 0x%02x" -#: gio/gdbusmessage.c:2070 +#: gio/gdbusmessage.c:2079 #, c-format msgid "Invalid major protocol version. Expected 1 but found %d" -msgstr "Versão majoritária de protocolo inválida. Era esperado 1, mas foi localizado %d" +msgstr "" +"Versão majoritária de protocolo inválida. Era esperado 1, mas foi localizado " +"%d" -#: gio/gdbusmessage.c:2126 +#: gio/gdbusmessage.c:2132 gio/gdbusmessage.c:2724 +msgid "Signature header found but is not of type signature" +msgstr "Cabeçalho da assinatura localizado, mas não é do tipo assinatura" + +#: gio/gdbusmessage.c:2144 #, c-format msgid "Signature header with signature “%s” found but message body is empty" -msgstr "O cabeçalho de assinatura foi localizado com a assinatura “%s”, mas o corpo da mensagem está vazio" +msgstr "" +"O cabeçalho de assinatura foi localizado com a assinatura “%s”, mas o corpo " +"da mensagem está vazio" -#: gio/gdbusmessage.c:2140 +#: gio/gdbusmessage.c:2159 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature (for body)" -msgstr "O valor “%s” analisado não é uma assinatura D-Bus válida (para o corpo)" +msgstr "" +"O valor “%s” analisado não é uma assinatura D-Bus válida (para o corpo)" -#: gio/gdbusmessage.c:2170 +#: gio/gdbusmessage.c:2190 #, c-format msgid "No signature header in message but the message body is %u byte" msgid_plural "No signature header in message but the message body is %u bytes" -msgstr[0] "Nenhum cabeçalho de assinatura na mensagem, mas o corpo da mensagem tem %u byte" -msgstr[1] "Nenhum cabeçalho de assinatura na mensagem, mas o corpo da mensagem tem %u bytes" +msgstr[0] "" +"Nenhum cabeçalho de assinatura na mensagem, mas o corpo da mensagem tem %u " +"byte" +msgstr[1] "" +"Nenhum cabeçalho de assinatura na mensagem, mas o corpo da mensagem tem %u " +"bytes" -#: gio/gdbusmessage.c:2180 +#: gio/gdbusmessage.c:2200 msgid "Cannot deserialize message: " msgstr "Não foi possível desserializar a mensagem: " -#: gio/gdbusmessage.c:2521 +#: gio/gdbusmessage.c:2541 #, c-format -msgid "Error serializing GVariant with type string “%s” to the D-Bus wire format" -msgstr "Erro ao serializar GVariant com o texto de tipo “%s” para o formato delimitado pelo D-Bus" +msgid "" +"Error serializing GVariant with type string “%s” to the D-Bus wire format" +msgstr "" +"Erro ao serializar GVariant com o texto de tipo “%s” para o formato " +"delimitado pelo D-Bus" -#: gio/gdbusmessage.c:2658 +#: gio/gdbusmessage.c:2678 #, c-format -msgid "Number of file descriptors in message (%d) differs from header field (%d)" -msgstr "O número de descritores de arquivo na mensagem (%d) difere do campo de cabeçalho (%d)" +msgid "" +"Number of file descriptors in message (%d) differs from header field (%d)" +msgstr "" +"O número de descritores de arquivo na mensagem (%d) difere do campo de " +"cabeçalho (%d)" -#: gio/gdbusmessage.c:2666 +#: gio/gdbusmessage.c:2686 msgid "Cannot serialize message: " msgstr "Não foi possível serializar a mensagem: " -#: gio/gdbusmessage.c:2710 +#: gio/gdbusmessage.c:2739 #, c-format msgid "Message body has signature “%s” but there is no signature header" -msgstr "O corpo da mensagem tem a assinatura “%s”, mas não há um cabeçalho de assinatura" +msgstr "" +"O corpo da mensagem tem a assinatura “%s”, mas não há um cabeçalho de " +"assinatura" -#: gio/gdbusmessage.c:2720 +#: gio/gdbusmessage.c:2749 #, c-format -msgid "Message body has type signature “%s” but signature in the header field is “%s”" -msgstr "O corpo da mensagem tem o tipo de assinatura “%s”, mas a assinatura no campo de cabeçalho é “%s”" +msgid "" +"Message body has type signature “%s” but signature in the header field is " +"“%s”" +msgstr "" +"O corpo da mensagem tem o tipo de assinatura “%s”, mas a assinatura no campo " +"de cabeçalho é “%s”" -#: gio/gdbusmessage.c:2736 +#: gio/gdbusmessage.c:2765 #, c-format msgid "Message body is empty but signature in the header field is “(%s)”" -msgstr "O corpo da mensagem está vazio, mas a assinatura no campo de cabeçalho é “(%s)”" +msgstr "" +"O corpo da mensagem está vazio, mas a assinatura no campo de cabeçalho é " +"“(%s)”" -#: gio/gdbusmessage.c:3289 +#: gio/gdbusmessage.c:3318 #, c-format msgid "Error return with body of type “%s”" msgstr "Retorno de erro com o corpo de tipo “%s”" -#: gio/gdbusmessage.c:3297 +#: gio/gdbusmessage.c:3326 msgid "Error return with empty body" msgstr "Retorno de erro com o corpo vazio" -#: gio/gdbusprivate.c:2066 +#: gio/gdbusprivate.c:2075 #, c-format msgid "Unable to get Hardware profile: %s" msgstr "Não foi possível obter o perfil da máquina: %s" -#: gio/gdbusprivate.c:2111 +#: gio/gdbusprivate.c:2120 msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " -msgstr "Não foi possível carregar /var/lib/dbus/machine-id ou /etc/machine-id: " +msgstr "" +"Não foi possível carregar /var/lib/dbus/machine-id ou /etc/machine-id: " -#: gio/gdbusproxy.c:1612 +#: gio/gdbusproxy.c:1617 #, c-format msgid "Error calling StartServiceByName for %s: " msgstr "Erro ao chamar StartServiceByName para %s: " -#: gio/gdbusproxy.c:1635 +#: gio/gdbusproxy.c:1640 #, c-format msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" msgstr "Resposta %d inesperada do método StartServiceByName(\"%s\")" -#: gio/gdbusproxy.c:2726 gio/gdbusproxy.c:2860 -msgid "Cannot invoke method; proxy is for a well-known name without an owner and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" -msgstr "Não foi possível chamar método; o proxy é para um nome conhecido sem um dono e o proxy foi construído com o sinalizador G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" +#: gio/gdbusproxy.c:2740 gio/gdbusproxy.c:2875 +#, c-format +#| msgid "" +#| "Cannot invoke method; proxy is for a well-known name without an owner and " +#| "proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgid "" +"Cannot invoke method; proxy is for the well-known name %s without an owner, " +"and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" +msgstr "" +"Não foi possível chamar método; o proxy é para um nome conhecido %s sem um " +"dono e o proxy foi construído com o sinalizador " +"G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START" #: gio/gdbusserver.c:708 msgid "Abstract name space not supported" @@ -863,7 +995,9 @@ #: gio/gdbusserver.c:795 msgid "Cannot specify nonce file when creating a server" -msgstr "Não foi possível especificar o arquivo de valor de uso único ao criar um servidor" +msgstr "" +"Não foi possível especificar o arquivo de valor de uso único ao criar um " +"servidor" #: gio/gdbusserver.c:876 #, c-format @@ -952,13 +1086,19 @@ #: gio/gdbus-tool.c:497 #, c-format -msgid "Warning: According to introspection data, interface “%s” does not exist\n" -msgstr "Aviso: De acordo com os dados de introspecção a interface “%s” não existe\n" +msgid "" +"Warning: According to introspection data, interface “%s” does not exist\n" +msgstr "" +"Aviso: De acordo com os dados de introspecção a interface “%s” não existe\n" #: gio/gdbus-tool.c:506 #, c-format -msgid "Warning: According to introspection data, method “%s” does not exist on interface “%s”\n" -msgstr "Aviso: De acordo com os dados de introspecção o método “%s” não existe na interface “%s”\n" +msgid "" +"Warning: According to introspection data, method “%s” does not exist on " +"interface “%s”\n" +msgstr "" +"Aviso: De acordo com os dados de introspecção o método “%s” não existe na " +"interface “%s”\n" #: gio/gdbus-tool.c:568 msgid "Optional destination for signal (unique name)" @@ -1108,15 +1248,21 @@ #: gio/gdbus-tool.c:1954 msgid "Error: can’t monitor a non-message-bus connection\n" -msgstr "Erro: não é possível monitorar uma conexão que não seja de barramento de mensagem\n" +msgstr "" +"Erro: não é possível monitorar uma conexão que não seja de barramento de " +"mensagem\n" #: gio/gdbus-tool.c:2078 msgid "Service to activate before waiting for the other one (well-known name)" msgstr "Serviço a ser ativado antes de esperar por uma outra (nome conhecido)" #: gio/gdbus-tool.c:2081 -msgid "Timeout to wait for before exiting with an error (seconds); 0 for no timeout (default)" -msgstr "Tempo limite de espera antes de sair com um erro (segundos); 0 para nenhum tempo limite (padrão)" +msgid "" +"Timeout to wait for before exiting with an error (seconds); 0 for no timeout " +"(default)" +msgstr "" +"Tempo limite de espera antes de sair com um erro (segundos); 0 para nenhum " +"tempo limite (padrão)" #: gio/gdbus-tool.c:2129 msgid "[OPTION…] BUS-NAME" @@ -1143,38 +1289,39 @@ msgid "Error: %s is not a valid well-known bus name.\n" msgstr "Erro: %s não é um nome válido de barramento conhecido.\n" -#: gio/gdesktopappinfo.c:2023 gio/gdesktopappinfo.c:4633 +#: gio/gdesktopappinfo.c:2041 gio/gdesktopappinfo.c:4822 msgid "Unnamed" msgstr "Sem nome" -#: gio/gdesktopappinfo.c:2433 +#: gio/gdesktopappinfo.c:2451 msgid "Desktop file didn’t specify Exec field" msgstr "O arquivo da área de trabalho não especifica o campo Exec" -#: gio/gdesktopappinfo.c:2692 +#: gio/gdesktopappinfo.c:2710 msgid "Unable to find terminal required for application" msgstr "Não é possível localizar o terminal requerido para o aplicativo" -#: gio/gdesktopappinfo.c:3202 +#: gio/gdesktopappinfo.c:3362 #, c-format msgid "Can’t create user application configuration folder %s: %s" -msgstr "Não é possível criar pasta de configuração do aplicativo do usuário %s: %s" +msgstr "" +"Não é possível criar pasta de configuração do aplicativo do usuário %s: %s" -#: gio/gdesktopappinfo.c:3206 +#: gio/gdesktopappinfo.c:3366 #, c-format msgid "Can’t create user MIME configuration folder %s: %s" msgstr "Não é possível criar pasta de configuração MIME do usuário %s: %s" -#: gio/gdesktopappinfo.c:3446 gio/gdesktopappinfo.c:3470 +#: gio/gdesktopappinfo.c:3606 gio/gdesktopappinfo.c:3630 msgid "Application information lacks an identifier" msgstr "A informação do aplicativo carece de um identificador" -#: gio/gdesktopappinfo.c:3704 +#: gio/gdesktopappinfo.c:3864 #, c-format msgid "Can’t create user desktop file %s" msgstr "Não é possível criar arquivo %s da área de trabalho do usuário" -#: gio/gdesktopappinfo.c:3838 +#: gio/gdesktopappinfo.c:3998 #, c-format msgid "Custom definition for %s" msgstr "Definição personalizada para %s" @@ -1240,7 +1387,7 @@ #: gio/gfile.c:2008 gio/gfile.c:2063 gio/gfile.c:3738 gio/gfile.c:3793 #: gio/gfile.c:4029 gio/gfile.c:4071 gio/gfile.c:4539 gio/gfile.c:4950 #: gio/gfile.c:5035 gio/gfile.c:5125 gio/gfile.c:5222 gio/gfile.c:5309 -#: gio/gfile.c:5410 gio/gfile.c:7988 gio/gfile.c:8078 gio/gfile.c:8162 +#: gio/gfile.c:5410 gio/gfile.c:8113 gio/gfile.c:8203 gio/gfile.c:8287 #: gio/win32/gwinhttpfile.c:437 msgid "Operation not supported" msgstr "Operação sem suporte" @@ -1253,7 +1400,7 @@ msgid "Containing mount does not exist" msgstr "Ponto de montagem contido não existe" -#: gio/gfile.c:2622 gio/glocalfile.c:2399 +#: gio/gfile.c:2622 gio/glocalfile.c:2446 msgid "Can’t copy over directory" msgstr "Não é possível copiar sobre diretório" @@ -1311,7 +1458,7 @@ msgid "volume doesn’t implement mount" msgstr "volume não implementa montagem" -#: gio/gfile.c:6882 +#: gio/gfile.c:6884 gio/gfile.c:6930 msgid "No application is registered as handling this file" msgstr "Nenhum aplicativo está registrado como manipulador deste arquivo" @@ -1356,8 +1503,8 @@ msgid "Truncate not supported on stream" msgstr "Não há suporte para truncar fluxo" -#: gio/ghttpproxy.c:91 gio/gresolver.c:410 gio/gresolver.c:476 -#: glib/gconvert.c:1786 +#: gio/ghttpproxy.c:91 gio/gresolver.c:377 gio/gresolver.c:529 +#: glib/gconvert.c:1785 msgid "Invalid hostname" msgstr "Nome de servidor inválido" @@ -1386,37 +1533,37 @@ msgid "HTTP proxy server closed connection unexpectedly." msgstr "O servidor proxy HTTP fechou a conexão de forma inesperada." -#: gio/gicon.c:290 +#: gio/gicon.c:298 #, c-format msgid "Wrong number of tokens (%d)" msgstr "Número errado de tokens (%d)" -#: gio/gicon.c:310 +#: gio/gicon.c:318 #, c-format msgid "No type for class name %s" msgstr "Sem tipo para a classe chamada %s" -#: gio/gicon.c:320 +#: gio/gicon.c:328 #, c-format msgid "Type %s does not implement the GIcon interface" msgstr "O tipo %s não implementa a interface GIcon" -#: gio/gicon.c:331 +#: gio/gicon.c:339 #, c-format msgid "Type %s is not classed" msgstr "O tipo %s não tem classe" -#: gio/gicon.c:345 +#: gio/gicon.c:353 #, c-format msgid "Malformed version number: %s" msgstr "Número de versão malformado: %s" -#: gio/gicon.c:359 +#: gio/gicon.c:367 #, c-format msgid "Type %s does not implement from_tokens() on the GIcon interface" msgstr "O tipo %s não implementa from_tokens() na interface GIcon" -#: gio/gicon.c:461 +#: gio/gicon.c:469 msgid "Can’t handle the supplied version of the icon encoding" msgstr "Não é possível lidar com a versão fornecida da codificação do ícone" @@ -1457,7 +1604,7 @@ #. Translators: This is an error you get if there is #. * already an operation running against this stream when #. * you try to start one -#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:1671 +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 msgid "Stream has outstanding operation" msgstr "O fluxo tem operação pendente" @@ -1562,7 +1709,7 @@ #: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:282 gio/gio-tool-list.c:165 #: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 #: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 -#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:113 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:70 #: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 #: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 msgid "LOCATION" @@ -1583,7 +1730,7 @@ "usar alguma coisa como smb://servidor/recurso/arquivo.txt como local." #: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:313 gio/gio-tool-mkdir.c:76 -#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:139 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:96 #: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 msgid "No locations given" msgstr "Nenhum local fornecido" @@ -1865,7 +2012,8 @@ #: gio/gio-tool-monitor.c:45 msgid "Report moves and renames as simple deleted/created events" -msgstr "Relata movimentos e renomeação como eventos de exclusão/criação simples" +msgstr "" +"Relata movimentos e renomeação como eventos de exclusão/criação simples" #: gio/gio-tool-monitor.c:47 msgid "Watch for mount events" @@ -1988,7 +2136,7 @@ msgid "Target %s is not a directory" msgstr "Alvo %s não é um diretório" -#: gio/gio-tool-open.c:118 +#: gio/gio-tool-open.c:75 msgid "" "Open files with the default application that\n" "is registered to handle files of this type." @@ -2163,7 +2311,9 @@ #: gio/glib-compile-resources.c:427 #, c-format msgid "%s preprocessing requested, but %s is not set, and %s is not in PATH" -msgstr "Pré-processamento de %s requisitado, mas %s não está definida e %s não está no PATH" +msgstr "" +"Pré-processamento de %s requisitado, mas %s não está definida e %s não está " +"no PATH" #: gio/glib-compile-resources.c:460 #, c-format @@ -2180,60 +2330,73 @@ msgid "text may not appear inside <%s>" msgstr "texto não pode aparecer dentro de <%s>" -#: gio/glib-compile-resources.c:736 gio/glib-compile-schemas.c:2139 +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2139 msgid "Show program version and exit" msgstr "Mostra a versão do programa e sai" -#: gio/glib-compile-resources.c:737 +#: gio/glib-compile-resources.c:738 msgid "Name of the output file" msgstr "Nome do arquivo de saída" -#: gio/glib-compile-resources.c:738 -msgid "The directories to load files referenced in FILE from (default: current directory)" -msgstr "Os diretórios do quais serão carregados arquivos referenciados em ARQUIVO (padrão: diretório atual)" +#: gio/glib-compile-resources.c:739 +msgid "" +"The directories to load files referenced in FILE from (default: current " +"directory)" +msgstr "" +"Os diretórios do quais serão carregados arquivos referenciados em ARQUIVO " +"(padrão: diretório atual)" -#: gio/glib-compile-resources.c:738 gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2140 #: gio/glib-compile-schemas.c:2169 msgid "DIRECTORY" msgstr "DIRETÓRIO" -#: gio/glib-compile-resources.c:739 -msgid "Generate output in the format selected for by the target filename extension" +#: gio/glib-compile-resources.c:740 +msgid "" +"Generate output in the format selected for by the target filename extension" msgstr "Gera a saída no formato definido pela extensão do arquivo alvo" -#: gio/glib-compile-resources.c:740 +#: gio/glib-compile-resources.c:741 msgid "Generate source header" msgstr "Gera um cabeçalho" -#: gio/glib-compile-resources.c:741 +#: gio/glib-compile-resources.c:742 msgid "Generate source code used to link in the resource file into your code" msgstr "Gera código-fonte que vincula o recurso ao seu programa" -#: gio/glib-compile-resources.c:742 +#: gio/glib-compile-resources.c:743 msgid "Generate dependency list" msgstr "Gera uma lista de dependência" -#: gio/glib-compile-resources.c:743 +#: gio/glib-compile-resources.c:744 msgid "Name of the dependency file to generate" msgstr "Nome do arquivo de dependências para gerar" -#: gio/glib-compile-resources.c:744 +#: gio/glib-compile-resources.c:745 msgid "Include phony targets in the generated dependency file" msgstr "Inclui alvos falsos no arquivo de dependência gerado" -#: gio/glib-compile-resources.c:745 +#: gio/glib-compile-resources.c:746 msgid "Don’t automatically create and register resource" msgstr "Não cria e registra o recurso automaticamente" -#: gio/glib-compile-resources.c:746 +#: gio/glib-compile-resources.c:747 msgid "Don’t export functions; declare them G_GNUC_INTERNAL" msgstr "Não exporta funções; declara-as G_GNUC_INTERNAL" -#: gio/glib-compile-resources.c:747 +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Não embute dados de recurso no arquivo C; presume estar vinculado " +"externamente" + +#: gio/glib-compile-resources.c:749 msgid "C identifier name used for the generated source code" msgstr "Nome do identificador C usado no código-fonte gerado" -#: gio/glib-compile-resources.c:773 +#: gio/glib-compile-resources.c:775 msgid "" "Compile a resource specification into a resource file.\n" "Resource specification files have the extension .gresource.xml,\n" @@ -2243,7 +2406,7 @@ "Arquivos de especificação de recurso têm a extensão .gresource.xml,\n" "e um arquivo de recurso tem a extensão .gresource." -#: gio/glib-compile-resources.c:795 +#: gio/glib-compile-resources.c:797 msgid "You should give exactly one file name\n" msgstr "Você deve fornecer exatamente um arquivo\n" @@ -2330,8 +2493,11 @@ msgstr "Falha ao analisar o valor de tipo “%s”: " #: gio/glib-compile-schemas.c:494 -msgid " cannot be specified for keys tagged as having an enumerated type" -msgstr " não pode ser especificado para chaves marcadas como tendo um tipo enumerado" +msgid "" +" cannot be specified for keys tagged as having an enumerated type" +msgstr "" +" não pode ser especificado para chaves marcadas como tendo um tipo " +"enumerado" #: gio/glib-compile-schemas.c:503 msgid " already specified for this key" @@ -2357,18 +2523,25 @@ msgstr " já especificado para essa chave" #: gio/glib-compile-schemas.c:564 -msgid " can only be specified for keys with enumerated or flags types or after " -msgstr " só pode ser especificado para chaves com tipos enumerados ou sinalizadores ou após " +msgid "" +" can only be specified for keys with enumerated or flags types or " +"after " +msgstr "" +" só pode ser especificado para chaves com tipos enumerados ou " +"sinalizadores ou após " #: gio/glib-compile-schemas.c:583 #, c-format -msgid " given when “%s” is already a member of the enumerated type" +msgid "" +" given when “%s” is already a member of the enumerated " +"type" msgstr " dado quando “%s” já é um membro do tipo enumerado" #: gio/glib-compile-schemas.c:589 #, c-format msgid " given when was already given" -msgstr " dado quando já tinha sido dado" +msgstr "" +" dado quando já tinha sido dado" #: gio/glib-compile-schemas.c:597 #, c-format @@ -2401,8 +2574,12 @@ #: gio/glib-compile-schemas.c:820 #, c-format -msgid "Invalid name “%s”: invalid character “%c”; only lowercase letters, numbers and hyphen (“-”) are permitted" -msgstr "Nome inválido “%s”: caractere inválido “%c”; apenas é permitido letras minúsculas, números e traços (”-”)" +msgid "" +"Invalid name “%s”: invalid character “%c”; only lowercase letters, numbers " +"and hyphen (“-”) are permitted" +msgstr "" +"Nome inválido “%s”: caractere inválido “%c”; apenas é permitido letras " +"minúsculas, números e traços (”-”)" #: gio/glib-compile-schemas.c:829 #, c-format @@ -2435,13 +2612,21 @@ #: gio/glib-compile-schemas.c:973 #, c-format -msgid " shadows in ; use to modify value" -msgstr " oculta em ; use para modificar o valor" +msgid "" +" shadows in ; use " +"to modify value" +msgstr "" +" oculta em ; use " +"para modificar o valor" #: gio/glib-compile-schemas.c:984 #, c-format -msgid "Exactly one of “type”, “enum” or “flags” must be specified as an attribute to " -msgstr "Apenas um entre “type”, “enum” ou “flags” deve ser especificado como atributo para " +msgid "" +"Exactly one of “type”, “enum” or “flags” must be specified as an attribute " +"to " +msgstr "" +"Apenas um entre “type”, “enum” ou “flags” deve ser especificado como " +"atributo para " #: gio/glib-compile-schemas.c:1003 #, c-format @@ -2494,13 +2679,19 @@ #: gio/glib-compile-schemas.c:1198 #, c-format -msgid " is a list, extending which is not a list" -msgstr " é uma lista, estendendo que não é uma lista" +msgid "" +" is a list, extending which is not a list" +msgstr "" +" é uma lista, estendendo que não é uma lista" #: gio/glib-compile-schemas.c:1208 #, c-format -msgid " extends but “%s” does not extend “%s”" -msgstr " estende , mas “%s” não estende “%s”" +msgid "" +" extends but “%s” " +"does not extend “%s”" +msgstr "" +" estende , mas " +"“%s” não estende “%s”" #: gio/glib-compile-schemas.c:1225 #, c-format @@ -2514,8 +2705,12 @@ #: gio/glib-compile-schemas.c:1241 #, c-format -msgid "Warning: Schema “%s” has path “%s”. Paths starting with “/apps/”, “/desktop/” or “/system/” are deprecated." -msgstr "Aviso: Esquema “%s” possui caminho “%s”. Caminhos iniciando com “/apps/”, “/desktop/” ou “/system/” são obsoletos." +msgid "" +"Warning: Schema “%s” has path “%s”. Paths starting with “/apps/”, “/" +"desktop/” or “/system/” are deprecated." +msgstr "" +"Aviso: Esquema “%s” possui caminho “%s”. Caminhos iniciando com “/apps/”, “/" +"desktop/” ou “/system/” são obsoletos." #: gio/glib-compile-schemas.c:1271 #, c-format @@ -2566,7 +2761,9 @@ #: gio/glib-compile-schemas.c:1959 #, c-format msgid "No such key “%s” in schema “%s” as specified in override file “%s”" -msgstr "Nenhuma chave “%s” no esquema “%s” como especificado no arquivo de sobrescrita “%s”" +msgstr "" +"Nenhuma chave “%s” no esquema “%s” como especificado no arquivo de " +"sobrescrita “%s”" #: gio/glib-compile-schemas.c:1965 gio/glib-compile-schemas.c:1990 #: gio/glib-compile-schemas.c:2050 gio/glib-compile-schemas.c:2079 @@ -2582,13 +2779,20 @@ #: gio/glib-compile-schemas.c:1984 #, c-format -msgid "cannot provide per-desktop overrides for localised key “%s” in schema “%s” (override file “%s”)" -msgstr "não foi possível fornecer substituição por-desktop para chave localizada “%s” no esquema “%s” (arquivo de substituição “%s”)" +msgid "" +"cannot provide per-desktop overrides for localised key “%s” in schema " +"“%s” (override file “%s”)" +msgstr "" +"não foi possível fornecer substituição por-desktop para chave localizada " +"“%s” no esquema “%s” (arquivo de substituição “%s”)" #: gio/glib-compile-schemas.c:2011 #, c-format -msgid "error parsing key “%s” in schema “%s” as specified in override file “%s”: %s." -msgstr "erro ao analisar chave “%s” no esquema “%s” como especificado no arquivo de sobrescrita “%s”: %s." +msgid "" +"error parsing key “%s” in schema “%s” as specified in override file “%s”: %s." +msgstr "" +"erro ao analisar chave “%s” no esquema “%s” como especificado no arquivo de " +"sobrescrita “%s”: %s." #: gio/glib-compile-schemas.c:2021 #, c-format @@ -2597,13 +2801,21 @@ #: gio/glib-compile-schemas.c:2040 #, c-format -msgid "override for key “%s” in schema “%s” in override file “%s” is outside the range given in the schema" -msgstr "sobrescrita para chave “%s” no esquema “%s” no arquivo de sobrescrita “%s” está fora dos limites dado pelo esquema" +msgid "" +"override for key “%s” in schema “%s” in override file “%s” is outside the " +"range given in the schema" +msgstr "" +"sobrescrita para chave “%s” no esquema “%s” no arquivo de sobrescrita “%s” " +"está fora dos limites dado pelo esquema" #: gio/glib-compile-schemas.c:2069 #, c-format -msgid "override for key “%s” in schema “%s” in override file “%s” is not in the list of valid choices" -msgstr "sobrescrita para a chave “%s” no esquema “%s” no arquivo de sobrescrita “%s” não está na lista de escolhas válidas" +msgid "" +"override for key “%s” in schema “%s” in override file “%s” is not in the " +"list of valid choices" +msgstr "" +"sobrescrita para a chave “%s” no esquema “%s” no arquivo de sobrescrita “%s” " +"não está na lista de escolhas válidas" #: gio/glib-compile-schemas.c:2140 msgid "where to store the gschemas.compiled file" @@ -2651,12 +2863,12 @@ msgid "removed existing output file.\n" msgstr "arquivo de saída existente removido.\n" -#: gio/glocalfile.c:544 gio/win32/gwinhttpfile.c:420 +#: gio/glocalfile.c:546 gio/win32/gwinhttpfile.c:420 #, c-format msgid "Invalid filename %s" msgstr "Nome de arquivo inválido: %s" -#: gio/glocalfile.c:1011 +#: gio/glocalfile.c:1013 #, c-format msgid "Error getting filesystem info for %s: %s" msgstr "Erro ao obter informações do sistema de arquivos para %s: %s" @@ -2665,128 +2877,130 @@ #. * the enclosing (user visible) mount of a file, but none #. * exists. #. -#: gio/glocalfile.c:1150 +#: gio/glocalfile.c:1152 #, c-format msgid "Containing mount for file %s not found" msgstr "Ponto de montagem contido para arquivo %s não existe" -#: gio/glocalfile.c:1173 +#: gio/glocalfile.c:1175 msgid "Can’t rename root directory" msgstr "Não é possível renomear o diretório root" -#: gio/glocalfile.c:1191 gio/glocalfile.c:1214 +#: gio/glocalfile.c:1193 gio/glocalfile.c:1216 #, c-format msgid "Error renaming file %s: %s" msgstr "Erro ao renomear arquivo %s: %s" -#: gio/glocalfile.c:1198 +#: gio/glocalfile.c:1200 msgid "Can’t rename file, filename already exists" msgstr "Não é possível renomear o arquivo, o nome do arquivo já existe" -#: gio/glocalfile.c:1211 gio/glocalfile.c:2275 gio/glocalfile.c:2303 -#: gio/glocalfile.c:2460 gio/glocalfileoutputstream.c:551 +#: gio/glocalfile.c:1213 gio/glocalfile.c:2322 gio/glocalfile.c:2350 +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:646 msgid "Invalid filename" msgstr "Nome de arquivo inválido" -#: gio/glocalfile.c:1379 gio/glocalfile.c:1394 +#: gio/glocalfile.c:1381 gio/glocalfile.c:1396 #, c-format msgid "Error opening file %s: %s" msgstr "Erro ao abrir arquivo %s: %s" -#: gio/glocalfile.c:1519 +#: gio/glocalfile.c:1521 #, c-format msgid "Error removing file %s: %s" msgstr "Erro ao remover arquivo %s: %s" -#: gio/glocalfile.c:1916 +#: gio/glocalfile.c:1963 #, c-format msgid "Error trashing file %s: %s" msgstr "Erro ao mover para a lixeira o arquivo %s: %s" -#: gio/glocalfile.c:1957 +#: gio/glocalfile.c:2004 #, c-format msgid "Unable to create trash dir %s: %s" msgstr "Não é possível criar o diretório da lixeira %s: %s" -#: gio/glocalfile.c:1978 +#: gio/glocalfile.c:2025 #, c-format msgid "Unable to find toplevel directory to trash %s" msgstr "Não é possível localizar diretório de nível superior para a lixeira %s" -#: gio/glocalfile.c:1987 +#: gio/glocalfile.c:2034 #, c-format msgid "Trashing on system internal mounts is not supported" msgstr "Não há suporte a mover para lixeira em montagens internas do sistema" -#: gio/glocalfile.c:2071 gio/glocalfile.c:2091 +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 #, c-format msgid "Unable to find or create trash directory for %s" msgstr "Não é possível localizar ou criar o diretório da lixeira para %s" -#: gio/glocalfile.c:2126 +#: gio/glocalfile.c:2173 #, c-format msgid "Unable to create trashing info file for %s: %s" msgstr "Não é possível criar o arquivo de informações da lixeira para %s: %s" -#: gio/glocalfile.c:2186 +#: gio/glocalfile.c:2233 #, c-format msgid "Unable to trash file %s across filesystem boundaries" -msgstr "Não é possível mover para a lixeira o arquivo %s entre os limites de sistema de arquivos" +msgstr "" +"Não é possível mover para a lixeira o arquivo %s entre os limites de sistema " +"de arquivos" -#: gio/glocalfile.c:2190 gio/glocalfile.c:2246 +#: gio/glocalfile.c:2237 gio/glocalfile.c:2293 #, c-format msgid "Unable to trash file %s: %s" msgstr "Não é possível mover para a lixeira o arquivo %s: %s" -#: gio/glocalfile.c:2252 +#: gio/glocalfile.c:2299 #, c-format msgid "Unable to trash file %s" msgstr "Não é possível mover para a lixeira o arquivo %s" -#: gio/glocalfile.c:2278 +#: gio/glocalfile.c:2325 #, c-format msgid "Error creating directory %s: %s" msgstr "Erro ao criar o diretório %s: %s" -#: gio/glocalfile.c:2307 +#: gio/glocalfile.c:2354 #, c-format msgid "Filesystem does not support symbolic links" msgstr "O sistema de arquivos não tem suporte a links simbólicos" -#: gio/glocalfile.c:2310 +#: gio/glocalfile.c:2357 #, c-format msgid "Error making symbolic link %s: %s" msgstr "Erro ao criar link simbólico %s: %s" -#: gio/glocalfile.c:2316 glib/gfileutils.c:2138 +#: gio/glocalfile.c:2363 glib/gfileutils.c:2138 msgid "Symbolic links not supported" msgstr "Não há suporte a links simbólicos" -#: gio/glocalfile.c:2371 gio/glocalfile.c:2406 gio/glocalfile.c:2463 +#: gio/glocalfile.c:2418 gio/glocalfile.c:2453 gio/glocalfile.c:2510 #, c-format msgid "Error moving file %s: %s" msgstr "Erro ao mover arquivo %s: %s" -#: gio/glocalfile.c:2394 +#: gio/glocalfile.c:2441 msgid "Can’t move directory over directory" msgstr "Não é possível mover diretório sobre diretório" -#: gio/glocalfile.c:2420 gio/glocalfileoutputstream.c:935 -#: gio/glocalfileoutputstream.c:949 gio/glocalfileoutputstream.c:964 -#: gio/glocalfileoutputstream.c:981 gio/glocalfileoutputstream.c:995 +#: gio/glocalfile.c:2467 gio/glocalfileoutputstream.c:1030 +#: gio/glocalfileoutputstream.c:1044 gio/glocalfileoutputstream.c:1059 +#: gio/glocalfileoutputstream.c:1076 gio/glocalfileoutputstream.c:1090 msgid "Backup file creation failed" msgstr "Falha ao criar arquivo de backup" -#: gio/glocalfile.c:2439 +#: gio/glocalfile.c:2486 #, c-format msgid "Error removing target file: %s" msgstr "Erro ao remover arquivo alvo: %s" -#: gio/glocalfile.c:2453 +#: gio/glocalfile.c:2500 msgid "Move between mounts not supported" msgstr "Não há suporte a mover entre montagens" -#: gio/glocalfile.c:2644 +#: gio/glocalfile.c:2691 #, c-format msgid "Could not determine the disk usage of %s: %s" msgstr "Não foi possível determinar a utilização de disco de %s: %s" @@ -2812,146 +3026,146 @@ msgid " (invalid encoding)" msgstr " (codificação inválida)" -#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:813 +#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:908 #, c-format msgid "Error when getting information for file “%s”: %s" msgstr "Erro ao obter informação para o arquivo “%s”: %s" -#: gio/glocalfileinfo.c:2053 +#: gio/glocalfileinfo.c:2059 #, c-format msgid "Error when getting information for file descriptor: %s" msgstr "Erro ao obter informação para o descritor de arquivo: %s" -#: gio/glocalfileinfo.c:2098 +#: gio/glocalfileinfo.c:2104 msgid "Invalid attribute type (uint32 expected)" msgstr "Tipo de atributo inválido (esperado uint32)" -#: gio/glocalfileinfo.c:2116 +#: gio/glocalfileinfo.c:2122 msgid "Invalid attribute type (uint64 expected)" msgstr "Tipo de atributo inválido (esperado uint64)" -#: gio/glocalfileinfo.c:2135 gio/glocalfileinfo.c:2154 +#: gio/glocalfileinfo.c:2141 gio/glocalfileinfo.c:2160 msgid "Invalid attribute type (byte string expected)" msgstr "Tipo de atributo inválido (expressão de byte esperada)" -#: gio/glocalfileinfo.c:2201 +#: gio/glocalfileinfo.c:2207 msgid "Cannot set permissions on symlinks" msgstr "Não foi possível definir permissões aos links simbólicos" -#: gio/glocalfileinfo.c:2217 +#: gio/glocalfileinfo.c:2223 #, c-format msgid "Error setting permissions: %s" msgstr "Erro ao definir permissões: %s" -#: gio/glocalfileinfo.c:2268 +#: gio/glocalfileinfo.c:2274 #, c-format msgid "Error setting owner: %s" msgstr "Erro ao definir proprietário: %s" -#: gio/glocalfileinfo.c:2291 +#: gio/glocalfileinfo.c:2297 msgid "symlink must be non-NULL" msgstr "o link simbólico deve ser não-NULO" -#: gio/glocalfileinfo.c:2301 gio/glocalfileinfo.c:2320 -#: gio/glocalfileinfo.c:2331 +#: gio/glocalfileinfo.c:2307 gio/glocalfileinfo.c:2326 +#: gio/glocalfileinfo.c:2337 #, c-format msgid "Error setting symlink: %s" msgstr "Erro ao definir link simbólico: %s" -#: gio/glocalfileinfo.c:2310 +#: gio/glocalfileinfo.c:2316 msgid "Error setting symlink: file is not a symlink" msgstr "Erro ao definir link simbólico: o arquivo não é um link simbólico" -#: gio/glocalfileinfo.c:2436 +#: gio/glocalfileinfo.c:2442 #, c-format msgid "Error setting modification or access time: %s" msgstr "Erro ao definir data/hora de modificação ou acesso: %s" -#: gio/glocalfileinfo.c:2459 +#: gio/glocalfileinfo.c:2465 msgid "SELinux context must be non-NULL" msgstr "O contexto SELinux deve ser não-NULO" -#: gio/glocalfileinfo.c:2474 +#: gio/glocalfileinfo.c:2480 #, c-format msgid "Error setting SELinux context: %s" msgstr "Erro ao definir o contexto SELinux: %s" -#: gio/glocalfileinfo.c:2481 +#: gio/glocalfileinfo.c:2487 msgid "SELinux is not enabled on this system" msgstr "SELinux não está habilitado neste sistema" -#: gio/glocalfileinfo.c:2573 +#: gio/glocalfileinfo.c:2579 #, c-format msgid "Setting attribute %s not supported" msgstr "Não há suporte à definição do atributo %s" -#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:696 +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:791 #, c-format msgid "Error reading from file: %s" msgstr "Erro ao ler do arquivo: %s" #: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 #: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 -#: gio/glocalfileoutputstream.c:458 gio/glocalfileoutputstream.c:1013 +#: gio/glocalfileoutputstream.c:553 gio/glocalfileoutputstream.c:1108 #, c-format msgid "Error seeking in file: %s" msgstr "Erro ao buscar no arquivo: %s" -#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:248 -#: gio/glocalfileoutputstream.c:342 +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:343 +#: gio/glocalfileoutputstream.c:437 #, c-format msgid "Error closing file: %s" msgstr "Erro ao fechar arquivo: %s" -#: gio/glocalfilemonitor.c:854 +#: gio/glocalfilemonitor.c:856 msgid "Unable to find default local file monitor type" msgstr "Não é possível localizar o tipo de arquivo monitor local padrão" -#: gio/glocalfileoutputstream.c:196 gio/glocalfileoutputstream.c:228 -#: gio/glocalfileoutputstream.c:717 +#: gio/glocalfileoutputstream.c:208 gio/glocalfileoutputstream.c:286 +#: gio/glocalfileoutputstream.c:323 gio/glocalfileoutputstream.c:812 #, c-format msgid "Error writing to file: %s" msgstr "Erro ao gravar o arquivo: %s" -#: gio/glocalfileoutputstream.c:275 +#: gio/glocalfileoutputstream.c:370 #, c-format msgid "Error removing old backup link: %s" msgstr "Erro ao remover link antigo de backup: %s" -#: gio/glocalfileoutputstream.c:289 gio/glocalfileoutputstream.c:302 +#: gio/glocalfileoutputstream.c:384 gio/glocalfileoutputstream.c:397 #, c-format msgid "Error creating backup copy: %s" msgstr "Erro ao criar cópia de backup: %s" -#: gio/glocalfileoutputstream.c:320 +#: gio/glocalfileoutputstream.c:415 #, c-format msgid "Error renaming temporary file: %s" msgstr "Erro ao renomear arquivo temporário: %s" -#: gio/glocalfileoutputstream.c:504 gio/glocalfileoutputstream.c:1064 +#: gio/glocalfileoutputstream.c:599 gio/glocalfileoutputstream.c:1159 #, c-format msgid "Error truncating file: %s" msgstr "Erro ao truncar arquivo: %s" -#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:795 -#: gio/glocalfileoutputstream.c:1045 gio/gsubprocess.c:380 +#: gio/glocalfileoutputstream.c:652 gio/glocalfileoutputstream.c:890 +#: gio/glocalfileoutputstream.c:1140 gio/gsubprocess.c:380 #, c-format msgid "Error opening file “%s”: %s" msgstr "Erro ao abrir arquivo “%s”: %s" -#: gio/glocalfileoutputstream.c:826 +#: gio/glocalfileoutputstream.c:921 msgid "Target file is a directory" msgstr "Arquivo alvo é um diretório" -#: gio/glocalfileoutputstream.c:831 +#: gio/glocalfileoutputstream.c:926 msgid "Target file is not a regular file" msgstr "Arquivo alvo não é um arquivo comum" -#: gio/glocalfileoutputstream.c:843 +#: gio/glocalfileoutputstream.c:938 msgid "The file was externally modified" msgstr "O arquivo foi modificado externamente" -#: gio/glocalfileoutputstream.c:1029 +#: gio/glocalfileoutputstream.c:1124 #, c-format msgid "Error removing old file: %s" msgstr "Erro ao remover arquivo antigo: %s" @@ -2977,8 +3191,12 @@ msgstr "Falha ao redimensionar fluxo de saída da memória" #: gio/gmemoryoutputstream.c:673 -msgid "Amount of memory required to process the write is larger than available address space" -msgstr "Quantidade de memória necessária para processar a escrita é maior que a disponível" +msgid "" +"Amount of memory required to process the write is larger than available " +"address space" +msgstr "" +"Quantidade de memória necessária para processar a escrita é maior que a " +"disponível" #: gio/gmemoryoutputstream.c:782 msgid "Requested seek before the beginning of the stream" @@ -3007,7 +3225,8 @@ #. * don't implement any of unmount or unmount_with_operation. #: gio/gmount.c:553 msgid "mount doesn’t implement “unmount” or “unmount_with_operation”" -msgstr "objeto de montagem não implementa “unmount” ou “unmount_with_operation”" +msgstr "" +"objeto de montagem não implementa “unmount” ou “unmount_with_operation”" #. Translators: This is an error #. * message for mount objects that @@ -3035,9 +3254,10 @@ #. * don't implement content type guessing. #: gio/gmount.c:895 msgid "mount doesn’t implement synchronous content type guessing" -msgstr "objeto de montagem não implementa estimativa de tipo de conteúdo síncrono" +msgstr "" +"objeto de montagem não implementa estimativa de tipo de conteúdo síncrono" -#: gio/gnetworkaddress.c:378 +#: gio/gnetworkaddress.c:388 #, c-format msgid "Hostname “%s” contains “[” but not “]”" msgstr "Nome da máquina “%s” contém “[” mas não “]”" @@ -3050,51 +3270,68 @@ msgid "Host unreachable" msgstr "Máquina inalcançável" -#: gio/gnetworkmonitornetlink.c:97 gio/gnetworkmonitornetlink.c:109 -#: gio/gnetworkmonitornetlink.c:128 +#: gio/gnetworkmonitornetlink.c:99 gio/gnetworkmonitornetlink.c:111 +#: gio/gnetworkmonitornetlink.c:130 #, c-format msgid "Could not create network monitor: %s" msgstr "Não foi possível criar o monitor de rede: %s" -#: gio/gnetworkmonitornetlink.c:118 +#: gio/gnetworkmonitornetlink.c:120 msgid "Could not create network monitor: " msgstr "Não foi possível criar o monitor de rede: " -#: gio/gnetworkmonitornetlink.c:176 +#: gio/gnetworkmonitornetlink.c:183 msgid "Could not get network status: " msgstr "Não foi possível obter o estado da rede: " -#: gio/gnetworkmonitornm.c:322 +#: gio/gnetworkmonitornm.c:313 +#, c-format +#| msgid "NetworkManager version too old" +msgid "NetworkManager not running" +msgstr "O NetworkManager não está em execução" + +#: gio/gnetworkmonitornm.c:324 #, c-format msgid "NetworkManager version too old" msgstr "A versão do NetworkManager é muito antiga" -#: gio/goutputstream.c:212 gio/goutputstream.c:560 +#: gio/goutputstream.c:232 gio/goutputstream.c:775 msgid "Output stream doesn’t implement write" msgstr "Fluxo de saída não implementa escrita" -#: gio/goutputstream.c:521 gio/goutputstream.c:1224 +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "A soma dos vetores passada para %s é grande demais" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 msgid "Source stream is already closed" msgstr "A fonte do fluxo já está fechada" -#: gio/gresolver.c:342 gio/gthreadedresolver.c:116 gio/gthreadedresolver.c:126 +#: gio/gresolver.c:344 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:160 #, c-format msgid "Error resolving “%s”: %s" msgstr "Erro ao resolver “%s”: %s" -#: gio/gresolver.c:729 gio/gresolver.c:781 +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:389 gio/gresolver.c:547 +#, c-format +msgid "%s not implemented" +msgstr "%s não implementado" + +#: gio/gresolver.c:915 gio/gresolver.c:967 msgid "Invalid domain" msgstr "Domínio inválido" -#: gio/gresource.c:644 gio/gresource.c:903 gio/gresource.c:942 -#: gio/gresource.c:1066 gio/gresource.c:1138 gio/gresource.c:1211 -#: gio/gresource.c:1281 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 #: gio/gresourcefile.c:736 #, c-format msgid "The resource at “%s” does not exist" msgstr "O recurso em “%s” não existe" -#: gio/gresource.c:809 +#: gio/gresource.c:830 #, c-format msgid "The resource at “%s” failed to decompress" msgstr "Falha ao descompactar o recurso em “%s”" @@ -3392,7 +3629,8 @@ " get Obtém o valor de uma chave\n" " set Define o valor de uma chave\n" " reset Redefine o valor de uma chave\n" -" reset-recursively Restaura todas as chaves em um determinado esquema\n" +" reset-recursively Restaura todas as chaves em um determinado " +"esquema\n" " writable Verifica se uma chave é gravável\n" " monitor Monitora alterações\n" "\n" @@ -3456,142 +3694,145 @@ msgid "No such key “%s”\n" msgstr "Nenhuma chave “%s”\n" -#: gio/gsocket.c:384 +#: gio/gsocket.c:373 msgid "Invalid socket, not initialized" msgstr "Soquete inválido, não inicializado" -#: gio/gsocket.c:391 +#: gio/gsocket.c:380 #, c-format msgid "Invalid socket, initialization failed due to: %s" msgstr "Soquete inválido, inicialização falhou devido a: %s" -#: gio/gsocket.c:399 +#: gio/gsocket.c:388 msgid "Socket is already closed" msgstr "O soquete já está fechado" -#: gio/gsocket.c:414 gio/gsocket.c:3034 gio/gsocket.c:4244 gio/gsocket.c:4302 +#: gio/gsocket.c:403 gio/gsocket.c:3027 gio/gsocket.c:4244 gio/gsocket.c:4302 msgid "Socket I/O timed out" msgstr "Tempo de E/S do soquete foi esgotado" -#: gio/gsocket.c:549 +#: gio/gsocket.c:538 #, c-format msgid "creating GSocket from fd: %s" msgstr "criando GSocket a partir do fd: %s" -#: gio/gsocket.c:578 gio/gsocket.c:632 gio/gsocket.c:639 +#: gio/gsocket.c:567 gio/gsocket.c:621 gio/gsocket.c:628 #, c-format msgid "Unable to create socket: %s" msgstr "Não é possível criar soquete: %s" -#: gio/gsocket.c:632 +#: gio/gsocket.c:621 msgid "Unknown family was specified" msgstr "Foi especificada uma família desconhecida" -#: gio/gsocket.c:639 +#: gio/gsocket.c:628 msgid "Unknown protocol was specified" msgstr "Foi especificado um protocolo desconhecido" -#: gio/gsocket.c:1130 +#: gio/gsocket.c:1119 #, c-format msgid "Cannot use datagram operations on a non-datagram socket." -msgstr "Não foi possível usar operações de datagrama em um soquete não-datagrama." +msgstr "" +"Não foi possível usar operações de datagrama em um soquete não-datagrama." -#: gio/gsocket.c:1147 +#: gio/gsocket.c:1136 #, c-format msgid "Cannot use datagram operations on a socket with a timeout set." -msgstr "Não foi possível usar operações de datagrama em um soquete com um tempo limite definido." +msgstr "" +"Não foi possível usar operações de datagrama em um soquete com um tempo " +"limite definido." -#: gio/gsocket.c:1954 +#: gio/gsocket.c:1943 #, c-format msgid "could not get local address: %s" msgstr "não foi possível obter endereço local: %s" -#: gio/gsocket.c:2000 +#: gio/gsocket.c:1989 #, c-format msgid "could not get remote address: %s" msgstr "não foi possível obter endereço remoto: %s" -#: gio/gsocket.c:2066 +#: gio/gsocket.c:2055 #, c-format msgid "could not listen: %s" msgstr "não foi possível escutar: %s" -#: gio/gsocket.c:2168 +#: gio/gsocket.c:2157 #, c-format msgid "Error binding to address: %s" msgstr "Erro ao vincular ao endereço: %s" -#: gio/gsocket.c:2226 gio/gsocket.c:2263 gio/gsocket.c:2373 gio/gsocket.c:2398 -#: gio/gsocket.c:2471 gio/gsocket.c:2529 gio/gsocket.c:2547 +#: gio/gsocket.c:2215 gio/gsocket.c:2252 gio/gsocket.c:2362 gio/gsocket.c:2387 +#: gio/gsocket.c:2460 gio/gsocket.c:2518 gio/gsocket.c:2536 #, c-format msgid "Error joining multicast group: %s" msgstr "Erro ao entrar no grupo multicast: %s" -#: gio/gsocket.c:2227 gio/gsocket.c:2264 gio/gsocket.c:2374 gio/gsocket.c:2399 -#: gio/gsocket.c:2472 gio/gsocket.c:2530 gio/gsocket.c:2548 +#: gio/gsocket.c:2216 gio/gsocket.c:2253 gio/gsocket.c:2363 gio/gsocket.c:2388 +#: gio/gsocket.c:2461 gio/gsocket.c:2519 gio/gsocket.c:2537 #, c-format msgid "Error leaving multicast group: %s" msgstr "Erro ao sair do grupo multicast: %s" -#: gio/gsocket.c:2228 +#: gio/gsocket.c:2217 msgid "No support for source-specific multicast" msgstr "Não há suporte para multicast específico da origem" -#: gio/gsocket.c:2375 +#: gio/gsocket.c:2364 msgid "Unsupported socket family" msgstr "Família de soquete sem suporte" -#: gio/gsocket.c:2400 +#: gio/gsocket.c:2389 msgid "source-specific not an IPv4 address" msgstr "a origem específica não é um endereço IPv4" -#: gio/gsocket.c:2418 gio/gsocket.c:2447 gio/gsocket.c:2497 +#: gio/gsocket.c:2407 gio/gsocket.c:2436 gio/gsocket.c:2486 #, c-format msgid "Interface not found: %s" msgstr "Interface não localizada: %s" -#: gio/gsocket.c:2434 +#: gio/gsocket.c:2423 #, c-format msgid "Interface name too long" msgstr "Nome de interface grande demais" -#: gio/gsocket.c:2473 +#: gio/gsocket.c:2462 msgid "No support for IPv4 source-specific multicast" msgstr "Não há suporte para multicast específico da origem IPv4" -#: gio/gsocket.c:2531 +#: gio/gsocket.c:2520 msgid "No support for IPv6 source-specific multicast" msgstr "Não há suporte para multicast específico da origem IPv6" -#: gio/gsocket.c:2740 +#: gio/gsocket.c:2729 #, c-format msgid "Error accepting connection: %s" msgstr "Erro ao aceitar a conexão: %s" -#: gio/gsocket.c:2864 +#: gio/gsocket.c:2855 msgid "Connection in progress" msgstr "Conexão em progresso" -#: gio/gsocket.c:2913 +#: gio/gsocket.c:2906 msgid "Unable to get pending error: " msgstr "Não é possível obter erro pendente: " -#: gio/gsocket.c:3097 +#: gio/gsocket.c:3092 #, c-format msgid "Error receiving data: %s" msgstr "Erro ao receber dados: %s" -#: gio/gsocket.c:3292 +#: gio/gsocket.c:3289 #, c-format msgid "Error sending data: %s" msgstr "Erro ao enviar dados: %s" -#: gio/gsocket.c:3479 +#: gio/gsocket.c:3476 #, c-format msgid "Unable to shutdown socket: %s" msgstr "Não é possível encerrar soquete: %s" -#: gio/gsocket.c:3560 +#: gio/gsocket.c:3557 #, c-format msgid "Error closing socket: %s" msgstr "Erro ao fechar soquete: %s" @@ -3601,52 +3842,53 @@ msgid "Waiting for socket condition: %s" msgstr "Aguardando pela condição do soquete: %s" -#: gio/gsocket.c:4711 gio/gsocket.c:4791 gio/gsocket.c:4969 +#: gio/gsocket.c:4614 gio/gsocket.c:4616 gio/gsocket.c:4762 gio/gsocket.c:4847 +#: gio/gsocket.c:5027 gio/gsocket.c:5067 gio/gsocket.c:5069 #, c-format msgid "Error sending message: %s" msgstr "Erro ao enviar mensagem: %s" -#: gio/gsocket.c:4735 +#: gio/gsocket.c:4789 msgid "GSocketControlMessage not supported on Windows" msgstr "Não há suporte a GSocketControlMessage no Windows" -#: gio/gsocket.c:5188 gio/gsocket.c:5261 gio/gsocket.c:5487 +#: gio/gsocket.c:5260 gio/gsocket.c:5333 gio/gsocket.c:5560 #, c-format msgid "Error receiving message: %s" msgstr "Erro ao receber mensagem: %s" -#: gio/gsocket.c:5759 +#: gio/gsocket.c:5832 #, c-format msgid "Unable to read socket credentials: %s" msgstr "Não é possível ler as credenciais do soquete: %s" -#: gio/gsocket.c:5768 +#: gio/gsocket.c:5841 msgid "g_socket_get_credentials not implemented for this OS" msgstr "g_socket_get_credentials não está implementado para este SO" -#: gio/gsocketclient.c:176 +#: gio/gsocketclient.c:181 #, c-format msgid "Could not connect to proxy server %s: " msgstr "Não foi possível conectar-se ao servidor proxy %s: " -#: gio/gsocketclient.c:190 +#: gio/gsocketclient.c:195 #, c-format msgid "Could not connect to %s: " msgstr "Não foi possível conectar-se a %s: " -#: gio/gsocketclient.c:192 +#: gio/gsocketclient.c:197 msgid "Could not connect: " msgstr "Não foi possível conectar: " -#: gio/gsocketclient.c:1027 gio/gsocketclient.c:1599 +#: gio/gsocketclient.c:1032 gio/gsocketclient.c:1731 msgid "Unknown error on connect" msgstr "Erro desconhecido ao conectar" -#: gio/gsocketclient.c:1081 gio/gsocketclient.c:1535 +#: gio/gsocketclient.c:1086 gio/gsocketclient.c:1640 msgid "Proxying over a non-TCP connection is not supported." msgstr "Não há suporte ao uso de proxy sobre uma conexão não TCP." -#: gio/gsocketclient.c:1110 gio/gsocketclient.c:1561 +#: gio/gsocketclient.c:1115 gio/gsocketclient.c:1666 #, c-format msgid "Proxy protocol “%s” is not supported." msgstr "Não há suporte ao protocolo de proxy “%s”." @@ -3690,16 +3932,20 @@ msgstr "O proxy SOCKSv5 requer autenticação." #: gio/gsocks5proxy.c:177 -msgid "The SOCKSv5 proxy requires an authentication method that is not supported by GLib." +msgid "" +"The SOCKSv5 proxy requires an authentication method that is not supported by " +"GLib." msgstr "O SOCKSv5 requer um método de autenticação sem suporte pelo GLib." #: gio/gsocks5proxy.c:206 msgid "Username or password is too long for SOCKSv5 protocol." -msgstr "O nome de usuário ou a senha são muito longos para o protocolo SOCKSv5." +msgstr "" +"O nome de usuário ou a senha são muito longos para o protocolo SOCKSv5." #: gio/gsocks5proxy.c:236 msgid "SOCKSv5 authentication failed due to wrong username or password." -msgstr "A autenticação SOCKSv5 falhou devido a um nome de usuário ou senha errados." +msgstr "" +"A autenticação SOCKSv5 falhou devido a um nome de usuário ou senha errados." #: gio/gsocks5proxy.c:286 #, c-format @@ -3747,61 +3993,69 @@ msgid "Can’t handle version %d of GThemedIcon encoding" msgstr "Não é possível lidar com a versão %d da codificação GThemedIcon" -#: gio/gthreadedresolver.c:118 +#: gio/gthreadedresolver.c:152 msgid "No valid addresses were found" msgstr "Nenhum endereço válido foi localizado" -#: gio/gthreadedresolver.c:213 +#: gio/gthreadedresolver.c:317 #, c-format msgid "Error reverse-resolving “%s”: %s" msgstr "Erro ao resolver reversamente “%s”: %s" -#: gio/gthreadedresolver.c:549 gio/gthreadedresolver.c:628 -#: gio/gthreadedresolver.c:726 gio/gthreadedresolver.c:776 +#: gio/gthreadedresolver.c:653 gio/gthreadedresolver.c:732 +#: gio/gthreadedresolver.c:830 gio/gthreadedresolver.c:880 #, c-format msgid "No DNS record of the requested type for “%s”" msgstr "Nenhum registro DNS do tipo de requisição para “%s”" -#: gio/gthreadedresolver.c:554 gio/gthreadedresolver.c:731 +#: gio/gthreadedresolver.c:658 gio/gthreadedresolver.c:835 #, c-format msgid "Temporarily unable to resolve “%s”" msgstr "Temporariamente sem condições de resolver “%s”" -#: gio/gthreadedresolver.c:559 gio/gthreadedresolver.c:736 -#: gio/gthreadedresolver.c:844 +#: gio/gthreadedresolver.c:663 gio/gthreadedresolver.c:840 +#: gio/gthreadedresolver.c:948 #, c-format msgid "Error resolving “%s”" msgstr "Erro ao resolver “%s”" -#: gio/gtlscertificate.c:250 -msgid "Cannot decrypt PEM-encoded private key" -msgstr "Não foi possível decodificar uma chave privada codificada com PEM" - -#: gio/gtlscertificate.c:255 +#: gio/gtlscertificate.c:243 msgid "No PEM-encoded private key found" msgstr "Chave privada codificada com PEM não localizada" -#: gio/gtlscertificate.c:265 +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Não foi possível decodificar uma chave privada codificada com PEM" + +#: gio/gtlscertificate.c:264 msgid "Could not parse PEM-encoded private key" msgstr "Não foi possível analisar chave privada codificada com PEM" -#: gio/gtlscertificate.c:290 +#: gio/gtlscertificate.c:291 msgid "No PEM-encoded certificate found" msgstr "Certificado codificado com PEM não localizado" -#: gio/gtlscertificate.c:299 +#: gio/gtlscertificate.c:300 msgid "Could not parse PEM-encoded certificate" msgstr "Não foi possível analisar certificado codificado com PEM" #: gio/gtlspassword.c:111 -msgid "This is the last chance to enter the password correctly before your access is locked out." -msgstr "Esta é a última chance para digitar a senha corretamente antes de seu acesso ser bloqueado." +msgid "" +"This is the last chance to enter the password correctly before your access " +"is locked out." +msgstr "" +"Esta é a última chance para digitar a senha corretamente antes de seu acesso " +"ser bloqueado." #. Translators: This is not the 'This is the last chance' string. It is #. * displayed when more than one attempt is allowed. #: gio/gtlspassword.c:115 -msgid "Several passwords entered have been incorrect, and your access will be locked out after further failures." -msgstr "Várias das senhas digitadas estavam incorretas, e o seu acesso será bloqueado se houverem mais falhas." +msgid "" +"Several passwords entered have been incorrect, and your access will be " +"locked out after further failures." +msgstr "" +"Várias das senhas digitadas estavam incorretas, e o seu acesso será " +"bloqueado se houverem mais falhas." #: gio/gtlspassword.c:117 msgid "The password entered is incorrect." @@ -3844,8 +4098,11 @@ msgstr "Erro ao habilitar SO_PASSCRED: %s" #: gio/gunixconnection.c:549 -msgid "Expecting to read a single byte for receiving credentials but read zero bytes" -msgstr "Era esperado ler apenas um byte para receber credenciais, mas foi lido zero byte" +msgid "" +"Expecting to read a single byte for receiving credentials but read zero bytes" +msgstr "" +"Era esperado ler apenas um byte para receber credenciais, mas foi lido zero " +"byte" #: gio/gunixconnection.c:589 #, c-format @@ -3862,24 +4119,28 @@ msgid "Error reading from file descriptor: %s" msgstr "Erro ao ler do descritor de arquivo: %s" -#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:411 +#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:534 #: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 #, c-format msgid "Error closing file descriptor: %s" msgstr "Erro ao fechar o descritor de arquivo: %s" -#: gio/gunixmounts.c:2589 gio/gunixmounts.c:2642 +#: gio/gunixmounts.c:2650 gio/gunixmounts.c:2703 msgid "Filesystem root" msgstr "Sistema de arquivos root" -#: gio/gunixoutputstream.c:358 gio/gunixoutputstream.c:378 +#: gio/gunixoutputstream.c:371 gio/gunixoutputstream.c:391 +#: gio/gunixoutputstream.c:478 gio/gunixoutputstream.c:498 +#: gio/gunixoutputstream.c:675 #, c-format msgid "Error writing to file descriptor: %s" msgstr "Erro ao gravar o descritor de arquivo: %s" #: gio/gunixsocketaddress.c:243 msgid "Abstract UNIX domain socket addresses not supported on this system" -msgstr "Não há suporte a endereços de soquetes de domínio UNIX abstratos neste sistema" +msgstr "" +"Não há suporte a endereços de soquetes de domínio UNIX abstratos neste " +"sistema" #: gio/gvolume.c:438 msgid "volume doesn’t implement eject" @@ -3973,7 +4234,8 @@ #: glib/gbookmarkfile.c:1813 msgid "No valid bookmark file found in data dirs" -msgstr "Nenhum arquivo de marcadores válido foi localizado nos diretórios de dados" +msgstr "" +"Nenhum arquivo de marcadores válido foi localizado nos diretórios de dados" #: glib/gbookmarkfile.c:2014 #, c-format @@ -3988,7 +4250,7 @@ #: glib/gbookmarkfile.c:2968 glib/gbookmarkfile.c:3158 #: glib/gbookmarkfile.c:3234 glib/gbookmarkfile.c:3402 #: glib/gbookmarkfile.c:3491 glib/gbookmarkfile.c:3580 -#: glib/gbookmarkfile.c:3696 +#: glib/gbookmarkfile.c:3699 #, c-format msgid "No bookmark found for URI “%s”" msgstr "Nenhum marcador localizado para o URI “%s”" @@ -4018,78 +4280,79 @@ msgid "Failed to expand exec line “%s” with URI “%s”" msgstr "Falha em expandir linha de execução “%s” com URI “%s”" -#: glib/gconvert.c:473 +#: glib/gconvert.c:474 msgid "Unrepresentable character in conversion input" msgstr "Caractere não representável na conversão da entrada" -#: glib/gconvert.c:500 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 +#: glib/gconvert.c:501 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 #: glib/gutf8.c:1318 msgid "Partial character sequence at end of input" msgstr "Sequência de caracteres parcial no final da entrada" -#: glib/gconvert.c:769 +#: glib/gconvert.c:770 #, c-format msgid "Cannot convert fallback “%s” to codeset “%s”" -msgstr "Não é possível converter a sequência “%s” para conjunto caracteres “%s”" +msgstr "" +"Não é possível converter a sequência “%s” para conjunto caracteres “%s”" -#: glib/gconvert.c:940 +#: glib/gconvert.c:942 msgid "Embedded NUL byte in conversion input" msgstr "Byte NULO embutido na entrada de conversão" -#: glib/gconvert.c:961 +#: glib/gconvert.c:963 msgid "Embedded NUL byte in conversion output" msgstr "Byte NULO embutido na saída de conversão" -#: glib/gconvert.c:1649 +#: glib/gconvert.c:1648 #, c-format msgid "The URI “%s” is not an absolute URI using the “file” scheme" msgstr "O URI “%s” não é um URI absoluto que utilize o esquema “file”" -#: glib/gconvert.c:1659 +#: glib/gconvert.c:1658 #, c-format msgid "The local file URI “%s” may not include a “#”" msgstr "O URI de arquivo local “%s” não pode incluir um “#”" -#: glib/gconvert.c:1676 +#: glib/gconvert.c:1675 #, c-format msgid "The URI “%s” is invalid" msgstr "O URI “%s” é inválido" -#: glib/gconvert.c:1688 +#: glib/gconvert.c:1687 #, c-format msgid "The hostname of the URI “%s” is invalid" msgstr "O nome de servidor do URI “%s” é inválido" -#: glib/gconvert.c:1704 +#: glib/gconvert.c:1703 #, c-format msgid "The URI “%s” contains invalidly escaped characters" msgstr "O URI “%s” contém caracteres com escape inválido" -#: glib/gconvert.c:1776 +#: glib/gconvert.c:1775 #, c-format msgid "The pathname “%s” is not an absolute path" msgstr "O nome de caminho “%s” não é um caminho absoluto" #. Translators: this is the preferred format for expressing the date and the time -#: glib/gdatetime.c:213 +#: glib/gdatetime.c:214 msgctxt "GDateTime" msgid "%a %b %e %H:%M:%S %Y" msgstr "%a %d de %b %H:%M:%S %Y" #. Translators: this is the preferred format for expressing the date -#: glib/gdatetime.c:216 +#: glib/gdatetime.c:217 msgctxt "GDateTime" msgid "%m/%d/%y" msgstr "%d/%m/%y" #. Translators: this is the preferred format for expressing the time -#: glib/gdatetime.c:219 +#: glib/gdatetime.c:220 msgctxt "GDateTime" msgid "%H:%M:%S" msgstr "%H:%M:%S" #. Translators: this is the preferred format for expressing 12 hour time -#: glib/gdatetime.c:222 +#: glib/gdatetime.c:223 msgctxt "GDateTime" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" @@ -4110,62 +4373,62 @@ #. * non-European) there is no difference between the standalone and #. * complete date form. #. -#: glib/gdatetime.c:261 +#: glib/gdatetime.c:262 msgctxt "full month name" msgid "January" msgstr "janeiro" -#: glib/gdatetime.c:263 +#: glib/gdatetime.c:264 msgctxt "full month name" msgid "February" msgstr "fevereiro" -#: glib/gdatetime.c:265 +#: glib/gdatetime.c:266 msgctxt "full month name" msgid "March" msgstr "março" -#: glib/gdatetime.c:267 +#: glib/gdatetime.c:268 msgctxt "full month name" msgid "April" msgstr "abril" -#: glib/gdatetime.c:269 +#: glib/gdatetime.c:270 msgctxt "full month name" msgid "May" msgstr "maio" -#: glib/gdatetime.c:271 +#: glib/gdatetime.c:272 msgctxt "full month name" msgid "June" msgstr "junho" -#: glib/gdatetime.c:273 +#: glib/gdatetime.c:274 msgctxt "full month name" msgid "July" msgstr "julho" -#: glib/gdatetime.c:275 +#: glib/gdatetime.c:276 msgctxt "full month name" msgid "August" msgstr "agosto" -#: glib/gdatetime.c:277 +#: glib/gdatetime.c:278 msgctxt "full month name" msgid "September" msgstr "setembro" -#: glib/gdatetime.c:279 +#: glib/gdatetime.c:280 msgctxt "full month name" msgid "October" msgstr "outubro" -#: glib/gdatetime.c:281 +#: glib/gdatetime.c:282 msgctxt "full month name" msgid "November" msgstr "novembro" -#: glib/gdatetime.c:283 +#: glib/gdatetime.c:284 msgctxt "full month name" msgid "December" msgstr "dezembro" @@ -4187,132 +4450,132 @@ #. * other platform. Here are abbreviated month names in a form #. * appropriate when they are used standalone. #. -#: glib/gdatetime.c:315 +#: glib/gdatetime.c:316 msgctxt "abbreviated month name" msgid "Jan" msgstr "jan" -#: glib/gdatetime.c:317 +#: glib/gdatetime.c:318 msgctxt "abbreviated month name" msgid "Feb" msgstr "fev" -#: glib/gdatetime.c:319 +#: glib/gdatetime.c:320 msgctxt "abbreviated month name" msgid "Mar" msgstr "mar" -#: glib/gdatetime.c:321 +#: glib/gdatetime.c:322 msgctxt "abbreviated month name" msgid "Apr" msgstr "abr" -#: glib/gdatetime.c:323 +#: glib/gdatetime.c:324 msgctxt "abbreviated month name" msgid "May" msgstr "maio" -#: glib/gdatetime.c:325 +#: glib/gdatetime.c:326 msgctxt "abbreviated month name" msgid "Jun" msgstr "jun" -#: glib/gdatetime.c:327 +#: glib/gdatetime.c:328 msgctxt "abbreviated month name" msgid "Jul" msgstr "jul" -#: glib/gdatetime.c:329 +#: glib/gdatetime.c:330 msgctxt "abbreviated month name" msgid "Aug" msgstr "ago" -#: glib/gdatetime.c:331 +#: glib/gdatetime.c:332 msgctxt "abbreviated month name" msgid "Sep" msgstr "set" -#: glib/gdatetime.c:333 +#: glib/gdatetime.c:334 msgctxt "abbreviated month name" msgid "Oct" msgstr "out" -#: glib/gdatetime.c:335 +#: glib/gdatetime.c:336 msgctxt "abbreviated month name" msgid "Nov" msgstr "nov" -#: glib/gdatetime.c:337 +#: glib/gdatetime.c:338 msgctxt "abbreviated month name" msgid "Dec" msgstr "dez" -#: glib/gdatetime.c:352 +#: glib/gdatetime.c:353 msgctxt "full weekday name" msgid "Monday" msgstr "segunda-feira" -#: glib/gdatetime.c:354 +#: glib/gdatetime.c:355 msgctxt "full weekday name" msgid "Tuesday" msgstr "terça-feira" -#: glib/gdatetime.c:356 +#: glib/gdatetime.c:357 msgctxt "full weekday name" msgid "Wednesday" msgstr "quarta-feira" -#: glib/gdatetime.c:358 +#: glib/gdatetime.c:359 msgctxt "full weekday name" msgid "Thursday" msgstr "quinta-feira" -#: glib/gdatetime.c:360 +#: glib/gdatetime.c:361 msgctxt "full weekday name" msgid "Friday" msgstr "sexta-feira" -#: glib/gdatetime.c:362 +#: glib/gdatetime.c:363 msgctxt "full weekday name" msgid "Saturday" msgstr "sábado" -#: glib/gdatetime.c:364 +#: glib/gdatetime.c:365 msgctxt "full weekday name" msgid "Sunday" msgstr "domingo" -#: glib/gdatetime.c:379 +#: glib/gdatetime.c:380 msgctxt "abbreviated weekday name" msgid "Mon" msgstr "seg" -#: glib/gdatetime.c:381 +#: glib/gdatetime.c:382 msgctxt "abbreviated weekday name" msgid "Tue" msgstr "ter" -#: glib/gdatetime.c:383 +#: glib/gdatetime.c:384 msgctxt "abbreviated weekday name" msgid "Wed" msgstr "qua" -#: glib/gdatetime.c:385 +#: glib/gdatetime.c:386 msgctxt "abbreviated weekday name" msgid "Thu" msgstr "qui" -#: glib/gdatetime.c:387 +#: glib/gdatetime.c:388 msgctxt "abbreviated weekday name" msgid "Fri" msgstr "sex" -#: glib/gdatetime.c:389 +#: glib/gdatetime.c:390 msgctxt "abbreviated weekday name" msgid "Sat" msgstr "sáb" -#: glib/gdatetime.c:391 +#: glib/gdatetime.c:392 msgctxt "abbreviated weekday name" msgid "Sun" msgstr "dom" @@ -4334,62 +4597,62 @@ #. * (western European, non-European) there is no difference between the #. * standalone and complete date form. #. -#: glib/gdatetime.c:455 +#: glib/gdatetime.c:456 msgctxt "full month name with day" msgid "January" msgstr "janeiro" -#: glib/gdatetime.c:457 +#: glib/gdatetime.c:458 msgctxt "full month name with day" msgid "February" msgstr "fevereiro" -#: glib/gdatetime.c:459 +#: glib/gdatetime.c:460 msgctxt "full month name with day" msgid "March" msgstr "março" -#: glib/gdatetime.c:461 +#: glib/gdatetime.c:462 msgctxt "full month name with day" msgid "April" msgstr "abril" -#: glib/gdatetime.c:463 +#: glib/gdatetime.c:464 msgctxt "full month name with day" msgid "May" msgstr "maio" -#: glib/gdatetime.c:465 +#: glib/gdatetime.c:466 msgctxt "full month name with day" msgid "June" msgstr "junho" -#: glib/gdatetime.c:467 +#: glib/gdatetime.c:468 msgctxt "full month name with day" msgid "July" msgstr "julho" -#: glib/gdatetime.c:469 +#: glib/gdatetime.c:470 msgctxt "full month name with day" msgid "August" msgstr "agosto" -#: glib/gdatetime.c:471 +#: glib/gdatetime.c:472 msgctxt "full month name with day" msgid "September" msgstr "setembro" -#: glib/gdatetime.c:473 +#: glib/gdatetime.c:474 msgctxt "full month name with day" msgid "October" msgstr "outubro" -#: glib/gdatetime.c:475 +#: glib/gdatetime.c:476 msgctxt "full month name with day" msgid "November" msgstr "novembro" -#: glib/gdatetime.c:477 +#: glib/gdatetime.c:478 msgctxt "full month name with day" msgid "December" msgstr "dezembro" @@ -4411,79 +4674,79 @@ #. * month names almost ready to copy and paste here. In other systems #. * due to a bug the result is incorrect in some languages. #. -#: glib/gdatetime.c:542 +#: glib/gdatetime.c:543 msgctxt "abbreviated month name with day" msgid "Jan" msgstr "jan" -#: glib/gdatetime.c:544 +#: glib/gdatetime.c:545 msgctxt "abbreviated month name with day" msgid "Feb" msgstr "fev" -#: glib/gdatetime.c:546 +#: glib/gdatetime.c:547 msgctxt "abbreviated month name with day" msgid "Mar" msgstr "mar" -#: glib/gdatetime.c:548 +#: glib/gdatetime.c:549 msgctxt "abbreviated month name with day" msgid "Apr" msgstr "abr" -#: glib/gdatetime.c:550 +#: glib/gdatetime.c:551 msgctxt "abbreviated month name with day" msgid "May" msgstr "maio" -#: glib/gdatetime.c:552 +#: glib/gdatetime.c:553 msgctxt "abbreviated month name with day" msgid "Jun" msgstr "jun" -#: glib/gdatetime.c:554 +#: glib/gdatetime.c:555 msgctxt "abbreviated month name with day" msgid "Jul" msgstr "jul" -#: glib/gdatetime.c:556 +#: glib/gdatetime.c:557 msgctxt "abbreviated month name with day" msgid "Aug" msgstr "ago" -#: glib/gdatetime.c:558 +#: glib/gdatetime.c:559 msgctxt "abbreviated month name with day" msgid "Sep" msgstr "set" -#: glib/gdatetime.c:560 +#: glib/gdatetime.c:561 msgctxt "abbreviated month name with day" msgid "Oct" msgstr "out" -#: glib/gdatetime.c:562 +#: glib/gdatetime.c:563 msgctxt "abbreviated month name with day" msgid "Nov" msgstr "nov" -#: glib/gdatetime.c:564 +#: glib/gdatetime.c:565 msgctxt "abbreviated month name with day" msgid "Dec" msgstr "dez" #. Translators: 'before midday' indicator -#: glib/gdatetime.c:581 +#: glib/gdatetime.c:582 msgctxt "GDateTime" msgid "AM" msgstr "AM" #. Translators: 'after midday' indicator -#: glib/gdatetime.c:584 +#: glib/gdatetime.c:585 msgctxt "GDateTime" msgid "PM" msgstr "PM" -#: glib/gdir.c:155 +#: glib/gdir.c:154 #, c-format msgid "Error opening directory “%s”: %s" msgstr "Erro ao abrir o diretório “%s”: %s" @@ -4572,7 +4835,8 @@ #: glib/giochannel.c:1734 msgid "Can’t do a raw read in g_io_channel_read_line_string" -msgstr "Não é possível fazer uma leitura em bruto em g_io_channel_read_line_string" +msgstr "" +"Não é possível fazer uma leitura em bruto em g_io_channel_read_line_string" #: glib/giochannel.c:1781 glib/giochannel.c:2039 glib/giochannel.c:2126 msgid "Leftover unconverted data in read buffer" @@ -4586,95 +4850,105 @@ msgid "Can’t do a raw read in g_io_channel_read_to_end" msgstr "Não é possível fazer uma leitura em bruto de g_io_channel_read_to_end" -#: glib/gkeyfile.c:788 +#: glib/gkeyfile.c:789 msgid "Valid key file could not be found in search dirs" -msgstr "Não foi possível localizar arquivo de chave válido nos diretórios pesquisados" +msgstr "" +"Não foi possível localizar arquivo de chave válido nos diretórios pesquisados" -#: glib/gkeyfile.c:825 +#: glib/gkeyfile.c:826 msgid "Not a regular file" msgstr "Não é um arquivo comum" -#: glib/gkeyfile.c:1270 +#: glib/gkeyfile.c:1275 #, c-format -msgid "Key file contains line “%s” which is not a key-value pair, group, or comment" -msgstr "Arquivo de chave contém a linha “%s” que não é um par chave-valor, grupo ou comentário" +msgid "" +"Key file contains line “%s” which is not a key-value pair, group, or comment" +msgstr "" +"Arquivo de chave contém a linha “%s” que não é um par chave-valor, grupo ou " +"comentário" -#: glib/gkeyfile.c:1327 +#: glib/gkeyfile.c:1332 #, c-format msgid "Invalid group name: %s" msgstr "Nome de grupo inválido: %s" -#: glib/gkeyfile.c:1349 +#: glib/gkeyfile.c:1354 msgid "Key file does not start with a group" msgstr "Arquivo de chave não começa com um grupo" -#: glib/gkeyfile.c:1375 +#: glib/gkeyfile.c:1380 #, c-format msgid "Invalid key name: %s" msgstr "Nome de chave inválido: %s" -#: glib/gkeyfile.c:1402 +#: glib/gkeyfile.c:1407 #, c-format msgid "Key file contains unsupported encoding “%s”" msgstr "Arquivo de chave contém codificação “%s” sem suporte" -#: glib/gkeyfile.c:1645 glib/gkeyfile.c:1818 glib/gkeyfile.c:3271 -#: glib/gkeyfile.c:3334 glib/gkeyfile.c:3464 glib/gkeyfile.c:3594 -#: glib/gkeyfile.c:3738 glib/gkeyfile.c:3967 glib/gkeyfile.c:4034 +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3339 glib/gkeyfile.c:3469 glib/gkeyfile.c:3601 +#: glib/gkeyfile.c:3747 glib/gkeyfile.c:3976 glib/gkeyfile.c:4043 #, c-format msgid "Key file does not have group “%s”" msgstr "Arquivo de chave não tem grupo “%s”" -#: glib/gkeyfile.c:1773 +#: glib/gkeyfile.c:1778 #, c-format msgid "Key file does not have key “%s” in group “%s”" msgstr "Arquivo de chave não tem chave “%s” no grupo “%s”" -#: glib/gkeyfile.c:1935 glib/gkeyfile.c:2051 +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 #, c-format msgid "Key file contains key “%s” with value “%s” which is not UTF-8" msgstr "Arquivo de chave contém chave “%s” com valor “%s” que não é UTF-8" -#: glib/gkeyfile.c:1955 glib/gkeyfile.c:2071 glib/gkeyfile.c:2513 +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 #, c-format -msgid "Key file contains key “%s” which has a value that cannot be interpreted." -msgstr "Arquivo de chave contém chave “%s” cujo valor não pode ser interpretado." +msgid "" +"Key file contains key “%s” which has a value that cannot be interpreted." +msgstr "" +"Arquivo de chave contém chave “%s” cujo valor não pode ser interpretado." -#: glib/gkeyfile.c:2731 glib/gkeyfile.c:3100 +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 #, c-format -msgid "Key file contains key “%s” in group “%s” which has a value that cannot be interpreted." -msgstr "Arquivo de chave contém chave “%s” no grupo “%s” que tem um valor que não pode ser interpretado." +msgid "" +"Key file contains key “%s” in group “%s” which has a value that cannot be " +"interpreted." +msgstr "" +"Arquivo de chave contém chave “%s” no grupo “%s” que tem um valor que não " +"pode ser interpretado." -#: glib/gkeyfile.c:2809 glib/gkeyfile.c:2886 +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 #, c-format msgid "Key “%s” in group “%s” has value “%s” where %s was expected" msgstr "Chave “%s” no grupo “%s” tem o valor “%s” onde %s era esperado" -#: glib/gkeyfile.c:4274 +#: glib/gkeyfile.c:4283 msgid "Key file contains escape character at end of line" msgstr "Arquivo de chave contém caractere de escape no fim da linha" -#: glib/gkeyfile.c:4296 +#: glib/gkeyfile.c:4305 #, c-format msgid "Key file contains invalid escape sequence “%s”" msgstr "Arquivo de chave contém sequência de escape “%s” inválida" -#: glib/gkeyfile.c:4440 +#: glib/gkeyfile.c:4449 #, c-format msgid "Value “%s” cannot be interpreted as a number." msgstr "O valor “%s” não pode ser interpretado como um número." -#: glib/gkeyfile.c:4454 +#: glib/gkeyfile.c:4463 #, c-format msgid "Integer value “%s” out of range" msgstr "Valor inteiro “%s” fora dos limites" -#: glib/gkeyfile.c:4487 +#: glib/gkeyfile.c:4496 #, c-format msgid "Value “%s” cannot be interpreted as a float number." msgstr "O valor “%s” não pode ser interpretado como ponto flutuante." -#: glib/gkeyfile.c:4526 +#: glib/gkeyfile.c:4535 #, c-format msgid "Value “%s” cannot be interpreted as a boolean." msgstr "O valor “%s” não pode ser interpretado como um booleano." @@ -4694,157 +4968,223 @@ msgid "Failed to open file “%s”: open() failed: %s" msgstr "Falha ao abrir arquivo “%s”: open() falhou: %s" -#: glib/gmarkup.c:397 glib/gmarkup.c:439 +#: glib/gmarkup.c:398 glib/gmarkup.c:440 #, c-format msgid "Error on line %d char %d: " msgstr "Erro na linha %d caractere %d: " -#: glib/gmarkup.c:461 glib/gmarkup.c:544 +#: glib/gmarkup.c:462 glib/gmarkup.c:545 #, c-format msgid "Invalid UTF-8 encoded text in name — not valid “%s”" msgstr "Texto do nome codificado em UTF-8 inválido — “%s” não válido" -#: glib/gmarkup.c:472 +#: glib/gmarkup.c:473 #, c-format msgid "“%s” is not a valid name" msgstr "“%s” não é um nome válido" -#: glib/gmarkup.c:488 +#: glib/gmarkup.c:489 #, c-format msgid "“%s” is not a valid name: “%c”" msgstr "“%s” não é um nome válido: “%c”" -#: glib/gmarkup.c:610 +#: glib/gmarkup.c:613 #, c-format msgid "Error on line %d: %s" msgstr "Erro na linha %d: %s" -#: glib/gmarkup.c:687 +#: glib/gmarkup.c:690 #, c-format -msgid "Failed to parse “%-.*s”, which should have been a digit inside a character reference (ê for example) — perhaps the digit is too large" -msgstr "Falha ao analisar “%-.*s”, que deveria ter sido um dígito dentro de uma referência de caractere (ê por exemplo) — talvez o dígito seja grande demais" +msgid "" +"Failed to parse “%-.*s”, which should have been a digit inside a character " +"reference (ê for example) — perhaps the digit is too large" +msgstr "" +"Falha ao analisar “%-.*s”, que deveria ter sido um dígito dentro de uma " +"referência de caractere (ê por exemplo) — talvez o dígito seja grande " +"demais" -#: glib/gmarkup.c:699 -msgid "Character reference did not end with a semicolon; most likely you used an ampersand character without intending to start an entity — escape ampersand as &" -msgstr "Referência de caractere não terminou com um ponto e vírgula; provavelmente utilizou um caractere “e comercial” sem desejar iniciar uma entidade — escape-o com &" +#: glib/gmarkup.c:702 +msgid "" +"Character reference did not end with a semicolon; most likely you used an " +"ampersand character without intending to start an entity — escape ampersand " +"as &" +msgstr "" +"Referência de caractere não terminou com um ponto e vírgula; provavelmente " +"utilizou um caractere “e comercial” sem desejar iniciar uma entidade — " +"escape-o com &" -#: glib/gmarkup.c:725 +#: glib/gmarkup.c:728 #, c-format msgid "Character reference “%-.*s” does not encode a permitted character" msgstr "Referência de caractere “%-.*s” não codifica um caractere permitido" -#: glib/gmarkup.c:763 -msgid "Empty entity “&;” seen; valid entities are: & " < > '" -msgstr "Entidade “&;” vazia; as entidades válidas são: & " < > '" +#: glib/gmarkup.c:766 +msgid "" +"Empty entity “&;” seen; valid entities are: & " < > '" +msgstr "" +"Entidade “&;” vazia; as entidades válidas são: & " < > '" -#: glib/gmarkup.c:771 +#: glib/gmarkup.c:774 #, c-format msgid "Entity name “%-.*s” is not known" msgstr "Nome de entidade “%-.*s” não é conhecido" -#: glib/gmarkup.c:776 -msgid "Entity did not end with a semicolon; most likely you used an ampersand character without intending to start an entity — escape ampersand as &" -msgstr "Entidade não termina com um ponto e vírgula; provavelmente você utilizou um “e comercial” sem desejar iniciar uma entidade — escape-o com &" +#: glib/gmarkup.c:779 +msgid "" +"Entity did not end with a semicolon; most likely you used an ampersand " +"character without intending to start an entity — escape ampersand as &" +msgstr "" +"Entidade não termina com um ponto e vírgula; provavelmente você utilizou um " +"“e comercial” sem desejar iniciar uma entidade — escape-o com &" -#: glib/gmarkup.c:1182 +#: glib/gmarkup.c:1187 msgid "Document must begin with an element (e.g. )" msgstr "Documento tem de começar com um elemento (ex. )" -#: glib/gmarkup.c:1222 +#: glib/gmarkup.c:1227 #, c-format -msgid "“%s” is not a valid character following a “<” character; it may not begin an element name" -msgstr "“%s” não é um caractere válido após um caractere “<”; não poderá começar um nome de elemento" +msgid "" +"“%s” is not a valid character following a “<” character; it may not begin an " +"element name" +msgstr "" +"“%s” não é um caractere válido após um caractere “<”; não poderá começar um " +"nome de elemento" -#: glib/gmarkup.c:1264 +#: glib/gmarkup.c:1270 #, c-format -msgid "Odd character “%s”, expected a “>” character to end the empty-element tag “%s”" -msgstr "Caractere estranho “%s”, esperado um caractere “>” para finalizar a marca “%s” de elemento vazio" +msgid "" +"Odd character “%s”, expected a “>” character to end the empty-element tag " +"“%s”" +msgstr "" +"Caractere estranho “%s”, esperado um caractere “>” para finalizar a marca " +"“%s” de elemento vazio" -#: glib/gmarkup.c:1345 +#: glib/gmarkup.c:1352 #, c-format -msgid "Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”" -msgstr "Caractere estranho “%s”, esperava-se um “=” após o nome do atributo “%s” do elemento “%s”" +msgid "" +"Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”" +msgstr "" +"Caractere estranho “%s”, esperava-se um “=” após o nome do atributo “%s” do " +"elemento “%s”" -#: glib/gmarkup.c:1386 +#: glib/gmarkup.c:1394 #, c-format -msgid "Odd character “%s”, expected a “>” or “/” character to end the start tag of element “%s”, or optionally an attribute; perhaps you used an invalid character in an attribute name" -msgstr "Caractere estranho “%s”, esperava-se um caractere “>” ou “/” para terminar a marca inicial do elemento “%s”, ou opcionalmente um atributo; talvez tenha utilizado um caractere inválido no nome de atributo" +msgid "" +"Odd character “%s”, expected a “>” or “/” character to end the start tag of " +"element “%s”, or optionally an attribute; perhaps you used an invalid " +"character in an attribute name" +msgstr "" +"Caractere estranho “%s”, esperava-se um caractere “>” ou “/” para terminar a " +"marca inicial do elemento “%s”, ou opcionalmente um atributo; talvez tenha " +"utilizado um caractere inválido no nome de atributo" -#: glib/gmarkup.c:1430 +#: glib/gmarkup.c:1439 #, c-format -msgid "Odd character “%s”, expected an open quote mark after the equals sign when giving value for attribute “%s” of element “%s”" -msgstr "Caractere estranho “%s”, esperava-se uma abertura de aspas após o sinal de igual ao atribuir o valor ao atributo “%s” do elemento “%s”" +msgid "" +"Odd character “%s”, expected an open quote mark after the equals sign when " +"giving value for attribute “%s” of element “%s”" +msgstr "" +"Caractere estranho “%s”, esperava-se uma abertura de aspas após o sinal de " +"igual ao atribuir o valor ao atributo “%s” do elemento “%s”" -#: glib/gmarkup.c:1563 +#: glib/gmarkup.c:1573 #, c-format -msgid "“%s” is not a valid character following the characters “”" -msgstr "“%s” não é um caractere válido após o nome do elemento de fecho “%s”; o caractere permitido é “>”" +msgid "" +"“%s” is not a valid character following the close element name “%s”; the " +"allowed character is “>”" +msgstr "" +"“%s” não é um caractere válido após o nome do elemento de fecho “%s”; o " +"caractere permitido é “>”" -#: glib/gmarkup.c:1610 +#: glib/gmarkup.c:1623 #, c-format msgid "Element “%s” was closed, no element is currently open" msgstr "Elemento “%s” foi fechado, nenhum elemento está atualmente aberto" -#: glib/gmarkup.c:1619 +#: glib/gmarkup.c:1632 #, c-format msgid "Element “%s” was closed, but the currently open element is “%s”" msgstr "Elemento “%s” foi fechado, mas o elemento atualmente aberto é “%s”" -#: glib/gmarkup.c:1772 +#: glib/gmarkup.c:1785 msgid "Document was empty or contained only whitespace" msgstr "Documento estava vazio ou apenas continha espaços" -#: glib/gmarkup.c:1786 +#: glib/gmarkup.c:1799 msgid "Document ended unexpectedly just after an open angle bracket “<”" msgstr "Documento terminou inesperadamente logo após um menor que “<”" -#: glib/gmarkup.c:1794 glib/gmarkup.c:1839 +#: glib/gmarkup.c:1807 glib/gmarkup.c:1852 #, c-format -msgid "Document ended unexpectedly with elements still open — “%s” was the last element opened" -msgstr "Documento terminou inesperadamente com elementos ainda abertos — “%s” foi o último elemento aberto" +msgid "" +"Document ended unexpectedly with elements still open — “%s” was the last " +"element opened" +msgstr "" +"Documento terminou inesperadamente com elementos ainda abertos — “%s” foi o " +"último elemento aberto" -#: glib/gmarkup.c:1802 +#: glib/gmarkup.c:1815 #, c-format -msgid "Document ended unexpectedly, expected to see a close angle bracket ending the tag <%s/>" -msgstr "Documento terminou inesperadamente, esperava-se ver um sinal de maior (“>”) para terminar a marca <%s/>" +msgid "" +"Document ended unexpectedly, expected to see a close angle bracket ending " +"the tag <%s/>" +msgstr "" +"Documento terminou inesperadamente, esperava-se ver um sinal de maior (“>”) " +"para terminar a marca <%s/>" -#: glib/gmarkup.c:1808 +#: glib/gmarkup.c:1821 msgid "Document ended unexpectedly inside an element name" msgstr "Documento terminou inesperadamente dentro de um nome de elemento" -#: glib/gmarkup.c:1814 +#: glib/gmarkup.c:1827 msgid "Document ended unexpectedly inside an attribute name" msgstr "Documento terminou inesperadamente dentro de um nome de atributo" -#: glib/gmarkup.c:1819 +#: glib/gmarkup.c:1832 msgid "Document ended unexpectedly inside an element-opening tag." -msgstr "Documento terminou inesperadamente dentro de uma marca de abertura de elemento." +msgstr "" +"Documento terminou inesperadamente dentro de uma marca de abertura de " +"elemento." -#: glib/gmarkup.c:1825 -msgid "Document ended unexpectedly after the equals sign following an attribute name; no attribute value" -msgstr "Documento terminou inesperadamente após o sinal de igual que se seguiu a um nome de atributo; nenhum valor de atributo" +#: glib/gmarkup.c:1838 +msgid "" +"Document ended unexpectedly after the equals sign following an attribute " +"name; no attribute value" +msgstr "" +"Documento terminou inesperadamente após o sinal de igual que se seguiu a um " +"nome de atributo; nenhum valor de atributo" -#: glib/gmarkup.c:1832 +#: glib/gmarkup.c:1845 msgid "Document ended unexpectedly while inside an attribute value" msgstr "Documento terminou inesperadamente dentro de um valor de atributo" -#: glib/gmarkup.c:1849 +#: glib/gmarkup.c:1862 #, c-format msgid "Document ended unexpectedly inside the close tag for element “%s”" -msgstr "Documento terminou inesperadamente dentro da marca de fechamento do elemento “%s”" +msgstr "" +"Documento terminou inesperadamente dentro da marca de fechamento do elemento " +"“%s”" -#: glib/gmarkup.c:1853 -msgid "Document ended unexpectedly inside the close tag for an unopened element" -msgstr "Documento terminou inesperadamente dentro da marca de um elemento não aberto" +#: glib/gmarkup.c:1866 +msgid "" +"Document ended unexpectedly inside the close tag for an unopened element" +msgstr "" +"Documento terminou inesperadamente dentro da marca de um elemento não aberto" -#: glib/gmarkup.c:1859 +#: glib/gmarkup.c:1872 msgid "Document ended unexpectedly inside a comment or processing instruction" -msgstr "Documento terminou inesperadamente dentro de um comentário ou instrução de processamento" +msgstr "" +"Documento terminou inesperadamente dentro de um comentário ou instrução de " +"processamento" #: glib/goption.c:861 msgid "[OPTION…]" @@ -4883,7 +5223,8 @@ #: glib/goption.c:1148 #, c-format msgid "Cannot parse double value “%s” for %s" -msgstr "Não é possível converter o ponto flutuante com dupla precisão “%s” para %s" +msgstr "" +"Não é possível converter o ponto flutuante com dupla precisão “%s” para %s" #: glib/goption.c:1156 #, c-format @@ -4931,7 +5272,9 @@ #: glib/gregex.c:288 msgid "back references as conditions are not supported for partial matching" -msgstr "não há suporte à referência retroativa como condição para correspondência parcial" +msgstr "" +"não há suporte à referência retroativa como condição para correspondência " +"parcial" #: glib/gregex.c:297 msgid "recursion limit reached" @@ -5138,8 +5481,12 @@ # obs.: "angle-brackets" não existe no Brasil, mas existe brackets, que é '<' e '>' #: glib/gregex.c:476 -msgid "\\g is not followed by a braced, angle-bracketed, or quoted name or number, or by a plain number" -msgstr "\\g não é seguido por um número ou nome entre aspas, chaves ou sinais de menor que ou maior que um número diferente de zero opcionalmente entre chaves" +msgid "" +"\\g is not followed by a braced, angle-bracketed, or quoted name or number, " +"or by a plain number" +msgstr "" +"\\g não é seguido por um número ou nome entre aspas, chaves ou sinais de " +"menor que ou maior que um número diferente de zero opcionalmente entre chaves" #: glib/gregex.c:480 msgid "a numbered reference must not be zero" @@ -5167,7 +5514,8 @@ #: glib/gregex.c:498 msgid "] is an invalid data character in JavaScript compatibility mode" -msgstr "] é um caractere de dados inválido no modo de compatibilidade do JavaScript" +msgstr "" +"] é um caractere de dados inválido no modo de compatibilidade do JavaScript" #: glib/gregex.c:501 msgid "different names for subpatterns of the same number are not allowed" @@ -5184,7 +5532,9 @@ # obs.: "angle-brackets" não existe no Brasil, mas existe brackets, que é '<' e '>' #: glib/gregex.c:510 msgid "\\k is not followed by a braced, angle-bracketed, or quoted name" -msgstr "\\k não é seguido por um nome entre aspas, chaves ou sinais de menor que ou maior que" +msgstr "" +"\\k não é seguido por um nome entre aspas, chaves ou sinais de menor que ou " +"maior que" #: glib/gregex.c:513 msgid "\\N is not supported in a class" @@ -5257,15 +5607,15 @@ msgid "illegal symbolic reference" msgstr "referência simbólica ilegal" -#: glib/gregex.c:2582 +#: glib/gregex.c:2583 msgid "stray final “\\”" msgstr "“\\” final errado" -#: glib/gregex.c:2586 +#: glib/gregex.c:2587 msgid "unknown escape sequence" msgstr "sequência de escape desconhecida" -#: glib/gregex.c:2596 +#: glib/gregex.c:2597 #, c-format msgid "Error while parsing replacement text “%s” at char %lu: %s" msgstr "Erro ao analisar texto de substituição “%s” no caractere %lu: %s" @@ -5286,150 +5636,156 @@ #: glib/gshell.c:587 #, c-format msgid "Text ended before matching quote was found for %c. (The text was “%s”)" -msgstr "Texto terminou antes da aspa equivalente ter sido localizada para %c. (texto era “%s”)" +msgstr "" +"Texto terminou antes da aspa equivalente ter sido localizada para %c. (texto " +"era “%s”)" #: glib/gshell.c:599 msgid "Text was empty (or contained only whitespace)" msgstr "Texto estava vazio (ou apenas continha espaços)" -#: glib/gspawn.c:308 +#: glib/gspawn.c:315 #, c-format msgid "Failed to read data from child process (%s)" msgstr "Falha ao ler dados de processo filho (%s)" -#: glib/gspawn.c:456 +#: glib/gspawn.c:463 #, c-format msgid "Unexpected error in select() reading data from a child process (%s)" msgstr "Erro inesperado no select() ao ler dados de processo filho (%s)" -#: glib/gspawn.c:541 +#: glib/gspawn.c:548 #, c-format msgid "Unexpected error in waitpid() (%s)" msgstr "Erro inesperado em waitpid() (%s)" -#: glib/gspawn.c:1049 glib/gspawn-win32.c:1318 +#: glib/gspawn.c:1056 glib/gspawn-win32.c:1329 #, c-format msgid "Child process exited with code %ld" msgstr "Processo filho concluiu com código %ld" -#: glib/gspawn.c:1057 +#: glib/gspawn.c:1064 #, c-format msgid "Child process killed by signal %ld" msgstr "Processo filho foi terminado pelo sinal %ld" -#: glib/gspawn.c:1064 +#: glib/gspawn.c:1071 #, c-format msgid "Child process stopped by signal %ld" msgstr "Processo filho foi parado pelo sinal %ld" -#: glib/gspawn.c:1071 +#: glib/gspawn.c:1078 #, c-format msgid "Child process exited abnormally" msgstr "Processo filho concluiu anormalmente" -#: glib/gspawn.c:1366 glib/gspawn-win32.c:339 glib/gspawn-win32.c:347 +#: glib/gspawn.c:1405 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 #, c-format msgid "Failed to read from child pipe (%s)" msgstr "Falha ao ler de canal filho (%s)" -#: glib/gspawn.c:1614 +#: glib/gspawn.c:1653 #, c-format msgid "Failed to spawn child process “%s” (%s)" msgstr "Falha ao criar processo filho “%s” (%s)" -#: glib/gspawn.c:1653 +#: glib/gspawn.c:1692 #, c-format msgid "Failed to fork (%s)" msgstr "Falha no fork (%s)" -#: glib/gspawn.c:1802 glib/gspawn-win32.c:370 +#: glib/gspawn.c:1841 glib/gspawn-win32.c:381 #, c-format msgid "Failed to change to directory “%s” (%s)" msgstr "Falha ao ir para diretório “%s” (%s)" -#: glib/gspawn.c:1812 +#: glib/gspawn.c:1851 #, c-format msgid "Failed to execute child process “%s” (%s)" msgstr "Falha ao executar processo filho “%s” (%s)" -#: glib/gspawn.c:1822 +#: glib/gspawn.c:1861 #, c-format msgid "Failed to redirect output or input of child process (%s)" msgstr "Falha ao redirecionar saída ou entrada do processo filho (%s)" -#: glib/gspawn.c:1831 +#: glib/gspawn.c:1870 #, c-format msgid "Failed to fork child process (%s)" msgstr "Falha no fork de processo filho (%s)" -#: glib/gspawn.c:1839 +#: glib/gspawn.c:1878 #, c-format msgid "Unknown error executing child process “%s”" msgstr "Erro desconhecido ao executar processo filho “%s”" -#: glib/gspawn.c:1863 +#: glib/gspawn.c:1902 #, c-format msgid "Failed to read enough data from child pid pipe (%s)" msgstr "Falha ao ler dados suficientes de canal pid do filho (%s)" -#: glib/gspawn-win32.c:283 +#: glib/gspawn-win32.c:294 msgid "Failed to read data from child process" msgstr "Falha ao ler dados de processo filho" -#: glib/gspawn-win32.c:300 +#: glib/gspawn-win32.c:311 #, c-format msgid "Failed to create pipe for communicating with child process (%s)" msgstr "Falha ao criar canal para comunicar com processo filho (%s)" -#: glib/gspawn-win32.c:376 glib/gspawn-win32.c:381 glib/gspawn-win32.c:500 +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 #, c-format msgid "Failed to execute child process (%s)" msgstr "Falha ao executar processo filho (%s)" -#: glib/gspawn-win32.c:450 +#: glib/gspawn-win32.c:461 #, c-format msgid "Invalid program name: %s" msgstr "Nome de programa inválido: %s" -#: glib/gspawn-win32.c:460 glib/gspawn-win32.c:714 +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 #, c-format msgid "Invalid string in argument vector at %d: %s" msgstr "String inválida no vetor de argumentos em %d: %s" -#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:729 +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 #, c-format msgid "Invalid string in environment: %s" msgstr "String inválida no ambiente: %s" -#: glib/gspawn-win32.c:710 +#: glib/gspawn-win32.c:721 #, c-format msgid "Invalid working directory: %s" msgstr "Diretório de trabalho inválido: %s" -#: glib/gspawn-win32.c:772 +#: glib/gspawn-win32.c:783 #, c-format msgid "Failed to execute helper program (%s)" msgstr "Falha ao executar programa auxiliar (%s)" -#: glib/gspawn-win32.c:1045 -msgid "Unexpected error in g_io_channel_win32_poll() reading data from a child process" -msgstr "Erro inesperado no g_io_channel_win32_poll() ao ler dados de um processo filho" +#: glib/gspawn-win32.c:1056 +msgid "" +"Unexpected error in g_io_channel_win32_poll() reading data from a child " +"process" +msgstr "" +"Erro inesperado no g_io_channel_win32_poll() ao ler dados de um processo " +"filho" -#: glib/gstrfuncs.c:3247 glib/gstrfuncs.c:3348 +#: glib/gstrfuncs.c:3286 glib/gstrfuncs.c:3388 msgid "Empty string is not a number" msgstr "Texto vazio não é um número" -#: glib/gstrfuncs.c:3271 +#: glib/gstrfuncs.c:3310 #, c-format msgid "“%s” is not a signed number" msgstr "“%s” não é um número assinado" -#: glib/gstrfuncs.c:3281 glib/gstrfuncs.c:3384 +#: glib/gstrfuncs.c:3320 glib/gstrfuncs.c:3424 #, c-format msgid "Number “%s” is out of bounds [%s, %s]" msgstr "O número “%s” está fora dos limites [%s, %s]" -#: glib/gstrfuncs.c:3374 +#: glib/gstrfuncs.c:3414 #, c-format msgid "“%s” is not an unsigned number" msgstr "“%s” não é um número não assinado" @@ -5451,134 +5807,182 @@ msgid "Character out of range for UTF-16" msgstr "Caractere fora do limite para UTF-16" -#: glib/gutils.c:2244 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2339 #, c-format -msgid "%.1f kB" -msgstr "%.1f kB" +#| msgid "%.1f kB" +msgid "%.1f kB" +msgstr "%.1f kB" -#: glib/gutils.c:2245 glib/gutils.c:2451 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2341 #, c-format -msgid "%.1f MB" -msgstr "%.1f MB" +#| msgid "%.1f MB" +msgid "%.1f MB" +msgstr "%.1f MB" -#: glib/gutils.c:2246 glib/gutils.c:2456 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2343 #, c-format -msgid "%.1f GB" -msgstr "%.1f GB" +#| msgid "%.1f GB" +msgid "%.1f GB" +msgstr "%.1f GB" -#: glib/gutils.c:2247 glib/gutils.c:2461 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2345 #, c-format -msgid "%.1f TB" -msgstr "%.1f TB" +#| msgid "%.1f TB" +msgid "%.1f TB" +msgstr "%.1f TB" -#: glib/gutils.c:2248 glib/gutils.c:2466 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2347 #, c-format -msgid "%.1f PB" -msgstr "%.1f PB" +#| msgid "%.1f PB" +msgid "%.1f PB" +msgstr "%.1f PB" -#: glib/gutils.c:2249 glib/gutils.c:2471 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2349 #, c-format -msgid "%.1f EB" -msgstr "%.1f EB" +#| msgid "%.1f EB" +msgid "%.1f EB" +msgstr "%.1f EB" -#: glib/gutils.c:2252 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2353 #, c-format -msgid "%.1f KiB" -msgstr "%.1f KiB" +#| msgid "%.1f KiB" +msgid "%.1f KiB" +msgstr "%.1f KiB" -#: glib/gutils.c:2253 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2355 #, c-format -msgid "%.1f MiB" -msgstr "%.1f MiB" +#| msgid "%.1f MiB" +msgid "%.1f MiB" +msgstr "%.1f MiB" -#: glib/gutils.c:2254 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2357 #, c-format -msgid "%.1f GiB" -msgstr "%.1f GiB" +#| msgid "%.1f GiB" +msgid "%.1f GiB" +msgstr "%.1f GiB" -#: glib/gutils.c:2255 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2359 #, c-format -msgid "%.1f TiB" -msgstr "%.1f TiB" +#| msgid "%.1f TiB" +msgid "%.1f TiB" +msgstr "%.1f TiB" -#: glib/gutils.c:2256 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2361 #, c-format -msgid "%.1f PiB" -msgstr "%.1f PiB" +#| msgid "%.1f PiB" +msgid "%.1f PiB" +msgstr "%.1f PiB" -#: glib/gutils.c:2257 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2363 #, c-format -msgid "%.1f EiB" -msgstr "%.1f EiB" +#| msgid "%.1f EiB" +msgid "%.1f EiB" +msgstr "%.1f EiB" -#: glib/gutils.c:2260 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2367 #, c-format -msgid "%.1f kb" -msgstr "%.1f kb" +#| msgid "%.1f kb" +msgid "%.1f kb" +msgstr "%.1f kb" -#: glib/gutils.c:2261 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2369 #, c-format -msgid "%.1f Mb" -msgstr "%.1f Mb" +#| msgid "%.1f Mb" +msgid "%.1f Mb" +msgstr "%.1f Mb" -#: glib/gutils.c:2262 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2371 #, c-format -msgid "%.1f Gb" -msgstr "%.1f Gb" +#| msgid "%.1f Gb" +msgid "%.1f Gb" +msgstr "%.1f Gb" -#: glib/gutils.c:2263 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2373 #, c-format -msgid "%.1f Tb" -msgstr "%.1f Tb" +#| msgid "%.1f Tb" +msgid "%.1f Tb" +msgstr "%.1f Tb" -#: glib/gutils.c:2264 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2375 #, c-format -msgid "%.1f Pb" -msgstr "%.1f Pb" +#| msgid "%.1f Pb" +msgid "%.1f Pb" +msgstr "%.1f Pb" -#: glib/gutils.c:2265 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2377 #, c-format -msgid "%.1f Eb" -msgstr "%.1f Eb" +#| msgid "%.1f Eb" +msgid "%.1f Eb" +msgstr "%.1f Eb" -#: glib/gutils.c:2268 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2381 #, c-format -msgid "%.1f Kib" -msgstr "%.1f Kib" +#| msgid "%.1f Kib" +msgid "%.1f Kib" +msgstr "%.1f Kib" -#: glib/gutils.c:2269 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2383 #, c-format -msgid "%.1f Mib" -msgstr "%.1f Mib" +#| msgid "%.1f Mib" +msgid "%.1f Mib" +msgstr "%.1f Mib" -#: glib/gutils.c:2270 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2385 #, c-format -msgid "%.1f Gib" -msgstr "%.1f Gib" +#| msgid "%.1f Gib" +msgid "%.1f Gib" +msgstr "%.1f Gib" -#: glib/gutils.c:2271 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2387 #, c-format -msgid "%.1f Tib" -msgstr "%.1f Tib" +#| msgid "%.1f Tib" +msgid "%.1f Tib" +msgstr "%.1f Tib" -#: glib/gutils.c:2272 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2389 #, c-format -msgid "%.1f Pib" -msgstr "%.1f Pib" +#| msgid "%.1f Pib" +msgid "%.1f Pib" +msgstr "%.1f Pib" -#: glib/gutils.c:2273 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2391 #, c-format -msgid "%.1f Eib" -msgstr "%.1f Eib" +#| msgid "%.1f Eib" +msgid "%.1f Eib" +msgstr "%.1f Eib" -#: glib/gutils.c:2307 glib/gutils.c:2433 +#: glib/gutils.c:2425 glib/gutils.c:2551 #, c-format msgid "%u byte" msgid_plural "%u bytes" msgstr[0] "%u byte" msgstr[1] "%u bytes" -#: glib/gutils.c:2311 +#: glib/gutils.c:2429 #, c-format msgid "%u bit" msgid_plural "%u bits" @@ -5586,7 +5990,7 @@ msgstr[1] "%u bits" #. Translators: the %s in "%s bytes" will always be replaced by a number. -#: glib/gutils.c:2378 +#: glib/gutils.c:2496 #, c-format msgid "%s byte" msgid_plural "%s bytes" @@ -5594,7 +5998,7 @@ msgstr[1] "%s bytes" #. Translators: the %s in "%s bits" will always be replaced by a number. -#: glib/gutils.c:2383 +#: glib/gutils.c:2501 #, c-format msgid "%s bit" msgid_plural "%s bits" @@ -5606,16 +6010,45 @@ #. * compatibility. Users will not see this string unless a program is using this deprecated function. #. * Please translate as literally as possible. #. -#: glib/gutils.c:2446 +#: glib/gutils.c:2564 #, c-format msgid "%.1f KB" msgstr "%.1f KB" +#: glib/gutils.c:2569 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2574 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2579 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2584 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2589 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + #~ msgid "No such method '%s'" #~ msgstr "Método “%s” inexistente" -#~ msgid "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable - unknown value '%s'" -#~ msgstr "Não foi possível determinar o endereço de barramento da variável de ambiente DBUS_STARTER_BUS_TYPE - valor desconhecido “%s”" +#~ msgid "" +#~ "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment " +#~ "variable - unknown value '%s'" +#~ msgstr "" +#~ "Não foi possível determinar o endereço de barramento da variável de " +#~ "ambiente DBUS_STARTER_BUS_TYPE - valor desconhecido “%s”" #~ msgid "[ARGS...]" #~ msgstr "[ARGUMENTOS…]" @@ -5623,8 +6056,12 @@ #~ msgid "Failed to create temp file: %s" #~ msgstr "Falha ao criar um arquivo temporário: %s" -#~ msgid "Message has %d file descriptors but the header field indicates %d file descriptors" -#~ msgstr "A mensagem possui %d descritores de arquivos, mas o campo de cabeçalho indica %d descritores de arquivos" +#~ msgid "" +#~ "Message has %d file descriptors but the header field indicates %d file " +#~ "descriptors" +#~ msgstr "" +#~ "A mensagem possui %d descritores de arquivos, mas o campo de cabeçalho " +#~ "indica %d descritores de arquivos" #~ msgid "Error: object path not specified.\n" #~ msgstr "Erro: caminho do objeto não especificado.\n" @@ -5730,14 +6167,20 @@ #~ msgid "Incomplete data received for '%s'" #~ msgstr "Dados incompletos recebidos para \"%s\"" -#~ msgid "Unexpected option length while checking if SO_PASSCRED is enabled for socket. Expected %d bytes, got %d" -#~ msgstr "Tamanho inesperado de opção ao verificar se SO_PASSCRED está habilitado pelo soquete. Esperado %d bytes, mas obteve %d" +#~ msgid "" +#~ "Unexpected option length while checking if SO_PASSCRED is enabled for " +#~ "socket. Expected %d bytes, got %d" +#~ msgstr "" +#~ "Tamanho inesperado de opção ao verificar se SO_PASSCRED está habilitado " +#~ "pelo soquete. Esperado %d bytes, mas obteve %d" #~ msgid "Abnormal program termination spawning command line '%s': %s" -#~ msgstr "Término anormal de programa ao chamar a linha de comandos \"%s\": %s" +#~ msgstr "" +#~ "Término anormal de programa ao chamar a linha de comandos \"%s\": %s" #~ msgid "Command line '%s' exited with non-zero exit status %d: %s" -#~ msgstr "A linha de comandos \"%s\" saiu com status de saída não-zero, %d: %s" +#~ msgstr "" +#~ "A linha de comandos \"%s\" saiu com status de saída não-zero, %d: %s" #~ msgid "No service record for '%s'" #~ msgstr "Nenhum serviço de registro para \"%s\"" @@ -5746,7 +6189,9 @@ #~ msgstr "limite de espaço de trabalho para substrings vazias alcançado" #~ msgid "case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here" -#~ msgstr "escapes de alteração de maiusculização (\\l, \\L, \\u, \\U) não são permitidos aqui" +#~ msgstr "" +#~ "escapes de alteração de maiusculização (\\l, \\L, \\u, \\U) não são " +#~ "permitidos aqui" #~ msgid "repeating a DEFINE group is not allowed" #~ msgstr "repetição de um grupo DEFINE não é permitida" @@ -5767,7 +6212,8 @@ #~ msgstr "A implementação SOCKSv4 limita o nome de usuário a %i caracteres" #~ msgid "SOCKSv4a implementation limits hostname to %i characters" -#~ msgstr "A implementação SOCKSv4a limita o nome de servidor para %i caracteres" +#~ msgstr "" +#~ "A implementação SOCKSv4a limita o nome de servidor para %i caracteres" #~ msgid "Error reading from unix: %s" #~ msgstr "Erro ao ler do unix: %s" @@ -5775,8 +6221,11 @@ #~ msgid "Error writing to unix: %s" #~ msgstr "Erro ao escrever para unix: %s" -#~ msgid "Key file contains key '%s' which has value that cannot be interpreted." -#~ msgstr "Arquivo de chave contém chave \"%s\" que tem valor que não pode ser interpretado." +#~ msgid "" +#~ "Key file contains key '%s' which has value that cannot be interpreted." +#~ msgstr "" +#~ "Arquivo de chave contém chave \"%s\" que tem valor que não pode ser " +#~ "interpretado." #~ msgid "Error stating file '%s': %s" #~ msgstr "Erro ao iniciar arquivo \"%s\": %s" @@ -5790,10 +6239,16 @@ #~ msgstr "pm" #~ msgid "Type of return value is incorrect, got '%s', expected '%s'" -#~ msgstr "O tipo do valor de retorno está incorreto, obtido \"%s\", era esperado \"%s\"" +#~ msgstr "" +#~ "O tipo do valor de retorno está incorreto, obtido \"%s\", era esperado " +#~ "\"%s\"" -#~ msgid "Trying to set property %s of type %s but according to the expected interface the type is %s" -#~ msgstr "Tentando definir a propriedade %s do tipo %s, mas de acordo com a interface esperada o tipo é %s" +#~ msgid "" +#~ "Trying to set property %s of type %s but according to the expected " +#~ "interface the type is %s" +#~ msgstr "" +#~ "Tentando definir a propriedade %s do tipo %s, mas de acordo com a " +#~ "interface esperada o tipo é %s" #~ msgid "No such schema '%s' specified in override file '%s'" #~ msgstr "Nenhum esquema \"%s\" especificado no arquivo de sobrescrita \"%s\"" @@ -5831,7 +6286,8 @@ #~ "Argumentos:\n" #~ " ESQUEMA A identificação do esquema\n" #~ " CHAVE O nome da chave\n" -#~ " VALOR O valor para definir na chave, como um GVariant serializado\n" +#~ " VALOR O valor para definir na chave, como um GVariant " +#~ "serializado\n" #~ msgid "" #~ "Monitor KEY for changes and print the changed values.\n" diff -Nru glib2.0-2.59.2/po/sl.po glib2.0-2.59.3/po/sl.po --- glib2.0-2.59.2/po/sl.po 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/sl.po 2019-03-04 09:01:42.000000000 +0000 @@ -3,14 +3,14 @@ # This file is distributed under the same license as the glib package. # # Andraž Tori 2000. -# Matej Urbančič , 2007–2018. +# Matej Urbančič , 2007–2019. # msgid "" msgstr "" "Project-Id-Version: glib master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" -"POT-Creation-Date: 2018-12-04 18:15+0000\n" -"PO-Revision-Date: 2018-12-04 20:45+0100\n" +"POT-Creation-Date: 2019-02-14 15:07+0000\n" +"PO-Revision-Date: 2019-02-14 18:38+0100\n" "Last-Translator: Matej Urbančič \n" "Language-Team: Slovenian GNOME Translation Team \n" "Language: sl_SI\n" @@ -119,8 +119,8 @@ msgstr "" "Določila programa v zapisu vodila D-Bus (na primer: org.example.viewer)" -#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:737 -#: gio/glib-compile-resources.c:743 gio/glib-compile-resources.c:770 +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 #: gio/gresource-tool.c:502 gio/gresource-tool.c:568 msgid "FILE" msgstr "DATOTEKA" @@ -259,8 +259,8 @@ #: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 #: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 -#: gio/ginputstream.c:1019 gio/goutputstream.c:203 gio/goutputstream.c:834 -#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:209 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 #, c-format msgid "Too large count value passed to %s" msgstr "Prevelika vrednost štetja poslana na %s" @@ -275,7 +275,7 @@ msgstr "Ni mogoče razčleniti GBufferedInputStream" #: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 -#: gio/goutputstream.c:1661 +#: gio/goutputstream.c:2198 msgid "Stream is already closed" msgstr "Pretok je že zaprt" @@ -283,7 +283,7 @@ msgid "Truncate not supported on base stream" msgstr "Razčlenitev na osnovnem pretoku ni dovoljena" -#: gio/gcancellable.c:317 gio/gdbusconnection.c:1840 gio/gdbusprivate.c:1402 +#: gio/gcancellable.c:317 gio/gdbusconnection.c:1867 gio/gdbusprivate.c:1402 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 #, c-format msgid "Operation was cancelled" @@ -302,33 +302,33 @@ msgstr "Ni dovolj prostora za cilju" #: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 -#: gio/gdatainputstream.c:1261 glib/gconvert.c:454 glib/gconvert.c:884 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:455 glib/gconvert.c:885 #: glib/giochannel.c:1557 glib/giochannel.c:1599 glib/giochannel.c:2443 #: glib/gutf8.c:869 glib/gutf8.c:1322 msgid "Invalid byte sequence in conversion input" msgstr "Neveljavno zaporedje bajtov na vhodu pretvorbe" -#: gio/gcharsetconverter.c:347 glib/gconvert.c:462 glib/gconvert.c:798 +#: gio/gcharsetconverter.c:347 glib/gconvert.c:463 glib/gconvert.c:799 #: glib/giochannel.c:1564 glib/giochannel.c:2455 #, c-format msgid "Error during conversion: %s" msgstr "Napaka med pretvorbo: %s" -#: gio/gcharsetconverter.c:445 gio/gsocket.c:1104 +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1093 msgid "Cancellable initialization not supported" msgstr "Dejanje prekinitve zagona ni podprto" -#: gio/gcharsetconverter.c:456 glib/gconvert.c:327 glib/giochannel.c:1385 +#: gio/gcharsetconverter.c:456 glib/gconvert.c:328 glib/giochannel.c:1385 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported" msgstr "Pretvorba iz nabora znakov »%s« v »%s« ni podprta" -#: gio/gcharsetconverter.c:460 glib/gconvert.c:331 +#: gio/gcharsetconverter.c:460 glib/gconvert.c:332 #, c-format msgid "Could not open converter from “%s” to “%s”" msgstr "Ni mogoče odpreti pretvornika iz »%s« v »%s«" -#: gio/gcontenttype.c:358 +#: gio/gcontenttype.c:452 #, c-format msgid "%s type" msgstr "%s vrsta" @@ -510,7 +510,7 @@ msgid "Cannot determine session bus address (not implemented for this OS)" msgstr "Ni mogoče določiti naslova vodila seje (ni podprto v tem OS)" -#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7147 +#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7174 #, c-format msgid "" "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " @@ -519,7 +519,7 @@ "Ni mogoče določiti naslova vodila iz okoljske spremenljivke " "DBUS_STARTER_BUS_TYPE – neznana vrednost »%s«" -#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7156 +#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7183 msgid "" "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " "variable is not set" @@ -631,97 +631,97 @@ msgid "(Additionally, releasing the lock for “%s” also failed: %s) " msgstr "(V nadaljevanju je spodletelo tudi sproščanje zaklepa »%s«: %s)" -#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2369 +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2396 msgid "The connection is closed" msgstr "Povezava je zaprta" -#: gio/gdbusconnection.c:1870 +#: gio/gdbusconnection.c:1897 msgid "Timeout was reached" msgstr "Čas zakasnitve je potekel" -#: gio/gdbusconnection.c:2491 +#: gio/gdbusconnection.c:2518 msgid "" "Unsupported flags encountered when constructing a client-side connection" msgstr "" "Med izgrajevanjem povezave s strani odjemalca so bile odkrite nepodprte " "zastavice" -#: gio/gdbusconnection.c:4120 gio/gdbusconnection.c:4467 +#: gio/gdbusconnection.c:4147 gio/gdbusconnection.c:4494 #, c-format msgid "" "No such interface “org.freedesktop.DBus.Properties” on object at path %s" msgstr "" "Vmesnik »org.freedesktop.DBus.Properties« na predmetu na poti %s ne obstaja" -#: gio/gdbusconnection.c:4262 +#: gio/gdbusconnection.c:4289 #, c-format msgid "No such property “%s”" msgstr "Lastnost »%s« ne obstaja" -#: gio/gdbusconnection.c:4274 +#: gio/gdbusconnection.c:4301 #, c-format msgid "Property “%s” is not readable" msgstr "Lastnost »%s« ni berljiva" -#: gio/gdbusconnection.c:4285 +#: gio/gdbusconnection.c:4312 #, c-format msgid "Property “%s” is not writable" msgstr "Lastnost »%s« ni zapisljiva" -#: gio/gdbusconnection.c:4305 +#: gio/gdbusconnection.c:4332 #, c-format msgid "Error setting property “%s”: Expected type “%s” but got “%s”" msgstr "" "Napaka med nastavljanjem lastnosti »%s«: pričakovana je vrsta »%s«, javljena " "pa »%s«." -#: gio/gdbusconnection.c:4410 gio/gdbusconnection.c:4618 -#: gio/gdbusconnection.c:6587 +#: gio/gdbusconnection.c:4437 gio/gdbusconnection.c:4645 +#: gio/gdbusconnection.c:6614 #, c-format msgid "No such interface “%s”" msgstr "Vmesnik »%s« ne obstaja" -#: gio/gdbusconnection.c:4836 gio/gdbusconnection.c:7096 +#: gio/gdbusconnection.c:4863 gio/gdbusconnection.c:7123 #, c-format msgid "No such interface “%s” on object at path %s" msgstr "Vmesnik »%s« na predmetu na poti %s ne obstaja" -#: gio/gdbusconnection.c:4934 +#: gio/gdbusconnection.c:4961 #, c-format msgid "No such method “%s”" msgstr "Način »%s« ne obstaja" -#: gio/gdbusconnection.c:4965 +#: gio/gdbusconnection.c:4992 #, c-format msgid "Type of message, “%s”, does not match expected type “%s”" msgstr "Vrsta sporočila »%s« se ne sklada s pričakovano vrsto »%s«" -#: gio/gdbusconnection.c:5163 +#: gio/gdbusconnection.c:5190 #, c-format msgid "An object is already exported for the interface %s at %s" msgstr "Za vmesnik %s pri %s je predmet že izvožen" -#: gio/gdbusconnection.c:5389 +#: gio/gdbusconnection.c:5416 #, c-format msgid "Unable to retrieve property %s.%s" msgstr "Ni mogoče pridobiti lastnosti %s.%s" -#: gio/gdbusconnection.c:5445 +#: gio/gdbusconnection.c:5472 #, c-format msgid "Unable to set property %s.%s" msgstr "Ni mogoče določiti lastnosti %s.%s" -#: gio/gdbusconnection.c:5623 +#: gio/gdbusconnection.c:5650 #, c-format msgid "Method “%s” returned type “%s”, but expected “%s”" msgstr "Način »%s« je vrnil vrsto »%s«, pričakovana pa je vrsta »%s«" -#: gio/gdbusconnection.c:6698 +#: gio/gdbusconnection.c:6725 #, c-format msgid "Method “%s” on interface “%s” with signature “%s” does not exist" msgstr "Način »%s« na vmesniku »%s« s podpisom »%s« ne obstaja" -#: gio/gdbusconnection.c:6819 +#: gio/gdbusconnection.c:6846 #, c-format msgid "A subtree is already exported for %s" msgstr "Podrejeno drevo je že izvoženo za %s" @@ -904,12 +904,12 @@ msgid "Cannot serialize message: " msgstr "Sporočila ni bilo mogoče združiti v zaporedje:" -#: gio/gdbusmessage.c:2740 +#: gio/gdbusmessage.c:2739 #, c-format msgid "Message body has signature “%s” but there is no signature header" msgstr "Telo sporočila ima podpis »%s«, vendar v glavi ni podpisa" -#: gio/gdbusmessage.c:2750 +#: gio/gdbusmessage.c:2749 #, c-format msgid "" "Message body has type signature “%s” but signature in the header field is " @@ -917,40 +917,40 @@ msgstr "" "Telo sporočila ima podpis vrste »%s«, vendar je podpis v polju glave »%s«" -#: gio/gdbusmessage.c:2766 +#: gio/gdbusmessage.c:2765 #, c-format msgid "Message body is empty but signature in the header field is “(%s)”" msgstr "Telo sporočila je prazno, vendar je v polju glave podpis »(%s)«" -#: gio/gdbusmessage.c:3319 +#: gio/gdbusmessage.c:3318 #, c-format msgid "Error return with body of type “%s”" msgstr "Napaka vrnjena s telesom vrste »%s«" -#: gio/gdbusmessage.c:3327 +#: gio/gdbusmessage.c:3326 msgid "Error return with empty body" msgstr "Napaka vrnjena s praznim telesom" -#: gio/gdbusprivate.c:2066 +#: gio/gdbusprivate.c:2075 #, c-format msgid "Unable to get Hardware profile: %s" msgstr "Ni mogoče pridobiti strojnega profila: %s" -#: gio/gdbusprivate.c:2111 +#: gio/gdbusprivate.c:2120 msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " msgstr "Ni mogoče naložiti /var/lib/dbus/machine-id oziroma /etc/machine-id: " -#: gio/gdbusproxy.c:1611 +#: gio/gdbusproxy.c:1617 #, c-format msgid "Error calling StartServiceByName for %s: " msgstr "Napaka med klicanjem predmeta StartServiceByName za %s: " -#: gio/gdbusproxy.c:1634 +#: gio/gdbusproxy.c:1640 #, c-format msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" msgstr "Nepričakovan odgovor %d iz načina StartServiceByName(»%s«)" -#: gio/gdbusproxy.c:2733 gio/gdbusproxy.c:2868 +#: gio/gdbusproxy.c:2740 gio/gdbusproxy.c:2875 #, c-format msgid "" "Cannot invoke method; proxy is for the well-known name %s without an owner, " @@ -1256,38 +1256,38 @@ msgid "Error: %s is not a valid well-known bus name.\n" msgstr "Napaka: %s ni veljavno enoznačno ime vodila.\n" -#: gio/gdesktopappinfo.c:2023 gio/gdesktopappinfo.c:4660 +#: gio/gdesktopappinfo.c:2041 gio/gdesktopappinfo.c:4822 msgid "Unnamed" msgstr "Neimenovano" -#: gio/gdesktopappinfo.c:2433 +#: gio/gdesktopappinfo.c:2451 msgid "Desktop file didn’t specify Exec field" msgstr "Namizna datoteka ne vsebuje določenega polja Exec" -#: gio/gdesktopappinfo.c:2692 +#: gio/gdesktopappinfo.c:2710 msgid "Unable to find terminal required for application" msgstr "Ni mogoče najti terminala, ki ga zahteva program" -#: gio/gdesktopappinfo.c:3202 +#: gio/gdesktopappinfo.c:3362 #, c-format msgid "Can’t create user application configuration folder %s: %s" msgstr "Ni mogoče ustvariti nastavitvene mape uporabnikovega programa %s: %s" -#: gio/gdesktopappinfo.c:3206 +#: gio/gdesktopappinfo.c:3366 #, c-format msgid "Can’t create user MIME configuration folder %s: %s" msgstr "Ni mogoče ustvariti uporabnikove nastavitvene mape MIME %s: %s" -#: gio/gdesktopappinfo.c:3446 gio/gdesktopappinfo.c:3470 +#: gio/gdesktopappinfo.c:3606 gio/gdesktopappinfo.c:3630 msgid "Application information lacks an identifier" msgstr "Podatki programa so brez določila" -#: gio/gdesktopappinfo.c:3704 +#: gio/gdesktopappinfo.c:3864 #, c-format msgid "Can’t create user desktop file %s" msgstr "Ni mogoče ustvariti uporabnikove datoteke namizja %s" -#: gio/gdesktopappinfo.c:3838 +#: gio/gdesktopappinfo.c:3998 #, c-format msgid "Custom definition for %s" msgstr "Določilo po meri za %s" @@ -1353,7 +1353,7 @@ #: gio/gfile.c:2008 gio/gfile.c:2063 gio/gfile.c:3738 gio/gfile.c:3793 #: gio/gfile.c:4029 gio/gfile.c:4071 gio/gfile.c:4539 gio/gfile.c:4950 #: gio/gfile.c:5035 gio/gfile.c:5125 gio/gfile.c:5222 gio/gfile.c:5309 -#: gio/gfile.c:5410 gio/gfile.c:7988 gio/gfile.c:8078 gio/gfile.c:8162 +#: gio/gfile.c:5410 gio/gfile.c:8113 gio/gfile.c:8203 gio/gfile.c:8287 #: gio/win32/gwinhttpfile.c:437 msgid "Operation not supported" msgstr "Opravilo ni podprto" @@ -1366,7 +1366,7 @@ msgid "Containing mount does not exist" msgstr "Obstoječa enota ne obstaja" -#: gio/gfile.c:2622 gio/glocalfile.c:2441 +#: gio/gfile.c:2622 gio/glocalfile.c:2446 msgid "Can’t copy over directory" msgstr "Ni mogoče kopirati prek mape" @@ -1425,7 +1425,7 @@ msgid "volume doesn’t implement mount" msgstr "enota ne podpira priklopa" -#: gio/gfile.c:6882 +#: gio/gfile.c:6884 gio/gfile.c:6930 msgid "No application is registered as handling this file" msgstr "Na voljo ni programa z a upravljanje s to datoteko" @@ -1470,8 +1470,8 @@ msgid "Truncate not supported on stream" msgstr "Razčlenitev ni podprta na pretoku" -#: gio/ghttpproxy.c:91 gio/gresolver.c:410 gio/gresolver.c:476 -#: glib/gconvert.c:1787 +#: gio/ghttpproxy.c:91 gio/gresolver.c:377 gio/gresolver.c:529 +#: glib/gconvert.c:1785 msgid "Invalid hostname" msgstr "Neveljavno ime gostitelja" @@ -1571,7 +1571,7 @@ #. Translators: This is an error you get if there is #. * already an operation running against this stream when #. * you try to start one -#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:1671 +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 msgid "Stream has outstanding operation" msgstr "Pretok izvaja izredno dejanje" @@ -1676,7 +1676,7 @@ #: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:282 gio/gio-tool-list.c:165 #: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 #: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 -#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:113 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:70 #: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 #: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 msgid "LOCATION" @@ -1697,7 +1697,7 @@ "mogoče uporabiti smb://strežnik/vir/datoteka.txt." #: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:313 gio/gio-tool-mkdir.c:76 -#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:139 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:96 #: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 msgid "No locations given" msgstr "Ni podanih mest" @@ -2103,7 +2103,7 @@ msgid "Target %s is not a directory" msgstr "Cilj %s ni mapa" -#: gio/gio-tool-open.c:118 +#: gio/gio-tool-open.c:75 msgid "" "Open files with the default application that\n" "is registered to handle files of this type." @@ -2297,64 +2297,70 @@ msgid "text may not appear inside <%s>" msgstr "besedilo se ne sme pojaviti znotraj <%s>" -#: gio/glib-compile-resources.c:736 gio/glib-compile-schemas.c:2139 +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2139 msgid "Show program version and exit" msgstr "Izpiši podrobnosti različice in končaj" -#: gio/glib-compile-resources.c:737 +#: gio/glib-compile-resources.c:738 msgid "Name of the output file" msgstr "Ime izhodne datoteke" -#: gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:739 msgid "" "The directories to load files referenced in FILE from (default: current " "directory)" msgstr "" "Mape, iz katerih naj bodo prebrane datoteke (privzeto je to trenutna mapa)" -#: gio/glib-compile-resources.c:738 gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2140 #: gio/glib-compile-schemas.c:2169 msgid "DIRECTORY" msgstr "MAPA" -#: gio/glib-compile-resources.c:739 +#: gio/glib-compile-resources.c:740 msgid "" "Generate output in the format selected for by the target filename extension" msgstr "Ustvari odvod v obliki, izbrani s pripono imena ciljne datoteke" -#: gio/glib-compile-resources.c:740 +#: gio/glib-compile-resources.c:741 msgid "Generate source header" msgstr "Ustvari glavo vira" -#: gio/glib-compile-resources.c:741 +#: gio/glib-compile-resources.c:742 msgid "Generate source code used to link in the resource file into your code" msgstr "Ustvari izvorno kodo za povezavo datoteke virov z vašo kodo" -#: gio/glib-compile-resources.c:742 +#: gio/glib-compile-resources.c:743 msgid "Generate dependency list" msgstr "Ustvari seznam odvisnosti." -#: gio/glib-compile-resources.c:743 +#: gio/glib-compile-resources.c:744 msgid "Name of the dependency file to generate" msgstr "Ime ustvarjene datoteke odvisnosti za ustvarjanje" -#: gio/glib-compile-resources.c:744 +#: gio/glib-compile-resources.c:745 msgid "Include phony targets in the generated dependency file" msgstr "Vključi lažne cilje v ustvarjeni datoteki odvisnosti" -#: gio/glib-compile-resources.c:745 +#: gio/glib-compile-resources.c:746 msgid "Don’t automatically create and register resource" msgstr "Vira ne ustvari in ne vpiši samodejno" -#: gio/glib-compile-resources.c:746 +#: gio/glib-compile-resources.c:747 msgid "Don’t export functions; declare them G_GNUC_INTERNAL" msgstr "Ne izvozi funkcij; te je treba deklarirati v G_GNUC_INTERNAL" -#: gio/glib-compile-resources.c:747 +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "Ne vgrajuj podatkov vira v datoteko C; predvidi zunanjo povezavo" + +#: gio/glib-compile-resources.c:749 msgid "C identifier name used for the generated source code" msgstr "Določilo imena jezika C za ustvarjanje izvorne kode" -#: gio/glib-compile-resources.c:773 +#: gio/glib-compile-resources.c:775 msgid "" "Compile a resource specification into a resource file.\n" "Resource specification files have the extension .gresource.xml,\n" @@ -2364,7 +2370,7 @@ "Datoteke določil vira imajo pripone .gresource.xml,\n" "datoteke vira pa pripono .gresource." -#: gio/glib-compile-resources.c:795 +#: gio/glib-compile-resources.c:797 msgid "You should give exactly one file name\n" msgstr "Podati je treba natanko eno ime datoteke\n" @@ -2819,12 +2825,12 @@ msgid "removed existing output file.\n" msgstr "odstranjena obstoječa odvodna datoteka.\n" -#: gio/glocalfile.c:544 gio/win32/gwinhttpfile.c:420 +#: gio/glocalfile.c:546 gio/win32/gwinhttpfile.c:420 #, c-format msgid "Invalid filename %s" msgstr "Neveljavno ime datoteke %s" -#: gio/glocalfile.c:1011 +#: gio/glocalfile.c:1013 #, c-format msgid "Error getting filesystem info for %s: %s" msgstr "Napaka med pridobivanjem podrobnosti datotečnega sistema za %s: %s" @@ -2833,130 +2839,130 @@ #. * the enclosing (user visible) mount of a file, but none #. * exists. #. -#: gio/glocalfile.c:1150 +#: gio/glocalfile.c:1152 #, c-format msgid "Containing mount for file %s not found" msgstr "Priklopne točke datoteke %s ni mogoče najti" -#: gio/glocalfile.c:1173 +#: gio/glocalfile.c:1175 msgid "Can’t rename root directory" msgstr "Ni mogoče preimenovati korenske mape" -#: gio/glocalfile.c:1191 gio/glocalfile.c:1214 +#: gio/glocalfile.c:1193 gio/glocalfile.c:1216 #, c-format msgid "Error renaming file %s: %s" msgstr "Napaka med preimenovanjem datoteke %s: %s" -#: gio/glocalfile.c:1198 +#: gio/glocalfile.c:1200 msgid "Can’t rename file, filename already exists" msgstr "Ni mogoče preimenovati datoteke, izbrano ime že obstaja" -#: gio/glocalfile.c:1211 gio/glocalfile.c:2317 gio/glocalfile.c:2345 -#: gio/glocalfile.c:2502 gio/glocalfileoutputstream.c:551 +#: gio/glocalfile.c:1213 gio/glocalfile.c:2322 gio/glocalfile.c:2350 +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:646 msgid "Invalid filename" msgstr "Neveljavno ime datoteke" -#: gio/glocalfile.c:1379 gio/glocalfile.c:1394 +#: gio/glocalfile.c:1381 gio/glocalfile.c:1396 #, c-format msgid "Error opening file %s: %s" msgstr "Napaka med odpiranjem datoteke %s: %s" -#: gio/glocalfile.c:1519 +#: gio/glocalfile.c:1521 #, c-format msgid "Error removing file %s: %s" msgstr "Napaka med odstranjevanjem datoteke %s: %s" -#: gio/glocalfile.c:1958 +#: gio/glocalfile.c:1963 #, c-format msgid "Error trashing file %s: %s" msgstr "Napaka med premikanjem datoteke %s v smeti: %s" -#: gio/glocalfile.c:1999 +#: gio/glocalfile.c:2004 #, c-format msgid "Unable to create trash dir %s: %s" msgstr "Ni mogoče ustvariti mape smeti %s: %s" -#: gio/glocalfile.c:2020 +#: gio/glocalfile.c:2025 #, c-format msgid "Unable to find toplevel directory to trash %s" msgstr "Ni mogoče najti vrhnje ravni smeti %s" -#: gio/glocalfile.c:2029 +#: gio/glocalfile.c:2034 #, c-format msgid "Trashing on system internal mounts is not supported" msgstr "" "Kopiranje (sklic povezave/kloniranje) med različnimi priklopi ni podprto" -#: gio/glocalfile.c:2113 gio/glocalfile.c:2133 +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 #, c-format msgid "Unable to find or create trash directory for %s" msgstr "Ni mogoče najti oziroma ustvariti mape smeti za %s" -#: gio/glocalfile.c:2168 +#: gio/glocalfile.c:2173 #, c-format msgid "Unable to create trashing info file for %s: %s" msgstr "Ni mogoče ustvariti datoteke podrobnosti smeti za %s: %s" -#: gio/glocalfile.c:2228 +#: gio/glocalfile.c:2233 #, c-format msgid "Unable to trash file %s across filesystem boundaries" msgstr "" "Datoteke %s ni mogoče premakniti v smeti prek različnih datotečnih sistemov" -#: gio/glocalfile.c:2232 gio/glocalfile.c:2288 +#: gio/glocalfile.c:2237 gio/glocalfile.c:2293 #, c-format msgid "Unable to trash file %s: %s" msgstr "Datoteke %s ni mogoče premakniti v smeti: %s" -#: gio/glocalfile.c:2294 +#: gio/glocalfile.c:2299 #, c-format msgid "Unable to trash file %s" msgstr "Datoteke %s ni mogoče premakniti v smeti" -#: gio/glocalfile.c:2320 +#: gio/glocalfile.c:2325 #, c-format msgid "Error creating directory %s: %s" msgstr "Napaka med ustvarjanjem mape %s: %s" -#: gio/glocalfile.c:2349 +#: gio/glocalfile.c:2354 #, c-format msgid "Filesystem does not support symbolic links" msgstr "Datotečni sistem ne podpira simbolnih povezav" -#: gio/glocalfile.c:2352 +#: gio/glocalfile.c:2357 #, c-format msgid "Error making symbolic link %s: %s" msgstr "Napaka med ustvarjanjem simbolne povezave %s: %s" -#: gio/glocalfile.c:2358 glib/gfileutils.c:2138 +#: gio/glocalfile.c:2363 glib/gfileutils.c:2138 msgid "Symbolic links not supported" msgstr "Simbolne povezave niso podprte" -#: gio/glocalfile.c:2413 gio/glocalfile.c:2448 gio/glocalfile.c:2505 +#: gio/glocalfile.c:2418 gio/glocalfile.c:2453 gio/glocalfile.c:2510 #, c-format msgid "Error moving file %s: %s" msgstr "Napaka med premikanjem datoteke %s: %s" -#: gio/glocalfile.c:2436 +#: gio/glocalfile.c:2441 msgid "Can’t move directory over directory" msgstr "Ni mogoče premakniti mape čez mapo" -#: gio/glocalfile.c:2462 gio/glocalfileoutputstream.c:935 -#: gio/glocalfileoutputstream.c:949 gio/glocalfileoutputstream.c:964 -#: gio/glocalfileoutputstream.c:981 gio/glocalfileoutputstream.c:995 +#: gio/glocalfile.c:2467 gio/glocalfileoutputstream.c:1030 +#: gio/glocalfileoutputstream.c:1044 gio/glocalfileoutputstream.c:1059 +#: gio/glocalfileoutputstream.c:1076 gio/glocalfileoutputstream.c:1090 msgid "Backup file creation failed" msgstr "Ustvarjanje varnostne kopije je spodletelo." -#: gio/glocalfile.c:2481 +#: gio/glocalfile.c:2486 #, c-format msgid "Error removing target file: %s" msgstr "Napaka med odstranjevanjem ciljne datoteke: %s" -#: gio/glocalfile.c:2495 +#: gio/glocalfile.c:2500 msgid "Move between mounts not supported" msgstr "Premikanje med priklopi ni podprto" -#: gio/glocalfile.c:2686 +#: gio/glocalfile.c:2691 #, c-format msgid "Could not determine the disk usage of %s: %s" msgstr "Ni mogoče določiti porabe diska %s: %s." @@ -2982,7 +2988,7 @@ msgid " (invalid encoding)" msgstr " (neveljavni nabor znakov)" -#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:813 +#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:908 #, c-format msgid "Error when getting information for file “%s”: %s" msgstr "Napaka med pridobivanjem podatkov za datoteko »%s«: %s" @@ -3056,20 +3062,20 @@ msgid "Setting attribute %s not supported" msgstr "Določanje atributa %s ni podprto" -#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:696 +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:791 #, c-format msgid "Error reading from file: %s" msgstr "Napaka med branjem iz datoteke: %s" #: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 #: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 -#: gio/glocalfileoutputstream.c:458 gio/glocalfileoutputstream.c:1013 +#: gio/glocalfileoutputstream.c:553 gio/glocalfileoutputstream.c:1108 #, c-format msgid "Error seeking in file: %s" msgstr "Napaka med iskanjem v datoteki: %s" -#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:248 -#: gio/glocalfileoutputstream.c:342 +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:343 +#: gio/glocalfileoutputstream.c:437 #, c-format msgid "Error closing file: %s" msgstr "Napaka med zapiranjem datoteke: %s" @@ -3078,51 +3084,51 @@ msgid "Unable to find default local file monitor type" msgstr "Ni mogoče najti privzete krajevne datoteke nadzora" -#: gio/glocalfileoutputstream.c:196 gio/glocalfileoutputstream.c:228 -#: gio/glocalfileoutputstream.c:717 +#: gio/glocalfileoutputstream.c:208 gio/glocalfileoutputstream.c:286 +#: gio/glocalfileoutputstream.c:323 gio/glocalfileoutputstream.c:812 #, c-format msgid "Error writing to file: %s" msgstr "Napaka med pisanjem v datoteko: %s" -#: gio/glocalfileoutputstream.c:275 +#: gio/glocalfileoutputstream.c:370 #, c-format msgid "Error removing old backup link: %s" msgstr "Napaka med odstranjevanjem stare varnostne povezave: %s" -#: gio/glocalfileoutputstream.c:289 gio/glocalfileoutputstream.c:302 +#: gio/glocalfileoutputstream.c:384 gio/glocalfileoutputstream.c:397 #, c-format msgid "Error creating backup copy: %s" msgstr "Napaka med ustvarjanjem varnostne kopije: %s" -#: gio/glocalfileoutputstream.c:320 +#: gio/glocalfileoutputstream.c:415 #, c-format msgid "Error renaming temporary file: %s" msgstr "Napaka med preimenovanjem začasne datoteke: %s" -#: gio/glocalfileoutputstream.c:504 gio/glocalfileoutputstream.c:1064 +#: gio/glocalfileoutputstream.c:599 gio/glocalfileoutputstream.c:1159 #, c-format msgid "Error truncating file: %s" msgstr "Napaka med obrezovanjem datoteke: %s" -#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:795 -#: gio/glocalfileoutputstream.c:1045 gio/gsubprocess.c:380 +#: gio/glocalfileoutputstream.c:652 gio/glocalfileoutputstream.c:890 +#: gio/glocalfileoutputstream.c:1140 gio/gsubprocess.c:380 #, c-format msgid "Error opening file “%s”: %s" msgstr "Napaka med odpiranjem datoteke »%s«: %s" -#: gio/glocalfileoutputstream.c:826 +#: gio/glocalfileoutputstream.c:921 msgid "Target file is a directory" msgstr "Ciljna datoteka je mapa" -#: gio/glocalfileoutputstream.c:831 +#: gio/glocalfileoutputstream.c:926 msgid "Target file is not a regular file" msgstr "Ciljna datoteka ni običajna datoteka" -#: gio/glocalfileoutputstream.c:843 +#: gio/glocalfileoutputstream.c:938 msgid "The file was externally modified" msgstr "Datoteka je bila zunanje spremenjena" -#: gio/glocalfileoutputstream.c:1029 +#: gio/glocalfileoutputstream.c:1124 #, c-format msgid "Error removing old file: %s" msgstr "Napaka med odstranjevanjem datoteke: %s" @@ -3212,7 +3218,7 @@ msgid "mount doesn’t implement synchronous content type guessing" msgstr "priklop ne podpira usklajevanja ugibanja vsebine vrste" -#: gio/gnetworkaddress.c:378 +#: gio/gnetworkaddress.c:388 #, c-format msgid "Hostname “%s” contains “[” but not “]”" msgstr "Ime gostitelja »%s« vsebuje » [ «, ne pa tudi » ] «" @@ -3249,32 +3255,43 @@ msgid "NetworkManager version too old" msgstr "Različica programa NetworkManager je prestara" -#: gio/goutputstream.c:212 gio/goutputstream.c:560 +#: gio/goutputstream.c:232 gio/goutputstream.c:775 msgid "Output stream doesn’t implement write" msgstr "Odvodni pretok ne podpira pisanja" -#: gio/goutputstream.c:521 gio/goutputstream.c:1224 +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "Vsota vektorjev, poslanih na %s, je prevelika." + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 msgid "Source stream is already closed" msgstr "Izvorni pretok je že zaprt" -#: gio/gresolver.c:342 gio/gthreadedresolver.c:116 gio/gthreadedresolver.c:126 +#: gio/gresolver.c:344 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:160 #, c-format msgid "Error resolving “%s”: %s" msgstr "Napaka med razreševanjem »%s«: %s" -#: gio/gresolver.c:729 gio/gresolver.c:781 +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:389 gio/gresolver.c:547 +#, c-format +msgid "%s not implemented" +msgstr "Za funkcijo %s ni zagotovljene podpore." + +#: gio/gresolver.c:915 gio/gresolver.c:967 msgid "Invalid domain" msgstr "Neveljavna domena" -#: gio/gresource.c:644 gio/gresource.c:903 gio/gresource.c:942 -#: gio/gresource.c:1066 gio/gresource.c:1138 gio/gresource.c:1211 -#: gio/gresource.c:1281 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 #: gio/gresourcefile.c:736 #, c-format msgid "The resource at “%s” does not exist" msgstr "Vir »%s« ne obstaja." -#: gio/gresource.c:809 +#: gio/gresource.c:830 #, c-format msgid "The resource at “%s” failed to decompress" msgstr "Vira »%s« ni mogoče razširiti" @@ -3636,144 +3653,144 @@ msgid "No such key “%s”\n" msgstr "Ključ »%s« ne obstaja.\n" -#: gio/gsocket.c:384 +#: gio/gsocket.c:373 msgid "Invalid socket, not initialized" msgstr "Neveljaven vtič, ni zagnano" -#: gio/gsocket.c:391 +#: gio/gsocket.c:380 #, c-format msgid "Invalid socket, initialization failed due to: %s" msgstr "Neveljaven vtič, zaganjanje je spodletelo: %s" -#: gio/gsocket.c:399 +#: gio/gsocket.c:388 msgid "Socket is already closed" msgstr "Vtič je že zaprt" -#: gio/gsocket.c:414 gio/gsocket.c:3034 gio/gsocket.c:4244 gio/gsocket.c:4302 +#: gio/gsocket.c:403 gio/gsocket.c:3027 gio/gsocket.c:4244 gio/gsocket.c:4302 msgid "Socket I/O timed out" msgstr "Vtič V/I naprave je časovno potekel" -#: gio/gsocket.c:549 +#: gio/gsocket.c:538 #, c-format msgid "creating GSocket from fd: %s" msgstr "ustvarjanje GSocet preko fd: %s" -#: gio/gsocket.c:578 gio/gsocket.c:632 gio/gsocket.c:639 +#: gio/gsocket.c:567 gio/gsocket.c:621 gio/gsocket.c:628 #, c-format msgid "Unable to create socket: %s" msgstr "Ni mogoče ustvariti vtiča: %s" -#: gio/gsocket.c:632 +#: gio/gsocket.c:621 msgid "Unknown family was specified" msgstr "Določena je neznana družina" -#: gio/gsocket.c:639 +#: gio/gsocket.c:628 msgid "Unknown protocol was specified" msgstr "Določen je neznan protokol" -#: gio/gsocket.c:1130 +#: gio/gsocket.c:1119 #, c-format msgid "Cannot use datagram operations on a non-datagram socket." msgstr "Ni mogoče uporabiti opravil datagrama na vtiču, ki jih ne podpira." -#: gio/gsocket.c:1147 +#: gio/gsocket.c:1136 #, c-format msgid "Cannot use datagram operations on a socket with a timeout set." msgstr "" "Ni mogoče uporabiti opravil datagrama na vtiču z nastavljenim časovnim " "pretekom" -#: gio/gsocket.c:1954 +#: gio/gsocket.c:1943 #, c-format msgid "could not get local address: %s" msgstr "ni mogoče pridobiti krajevnega naslova: %s" -#: gio/gsocket.c:2000 +#: gio/gsocket.c:1989 #, c-format msgid "could not get remote address: %s" msgstr "ni mogoče pridobiti oddaljenega naslova: %s" -#: gio/gsocket.c:2066 +#: gio/gsocket.c:2055 #, c-format msgid "could not listen: %s" msgstr "ni mogoče slediti: %s" -#: gio/gsocket.c:2168 +#: gio/gsocket.c:2157 #, c-format msgid "Error binding to address: %s" msgstr "Napaka vezanjem na naslov: %s" -#: gio/gsocket.c:2226 gio/gsocket.c:2263 gio/gsocket.c:2373 gio/gsocket.c:2398 -#: gio/gsocket.c:2471 gio/gsocket.c:2529 gio/gsocket.c:2547 +#: gio/gsocket.c:2215 gio/gsocket.c:2252 gio/gsocket.c:2362 gio/gsocket.c:2387 +#: gio/gsocket.c:2460 gio/gsocket.c:2518 gio/gsocket.c:2536 #, c-format msgid "Error joining multicast group: %s" msgstr "Napaka povezovanja v skupino za večsmerno oddajanje: %s" -#: gio/gsocket.c:2227 gio/gsocket.c:2264 gio/gsocket.c:2374 gio/gsocket.c:2399 -#: gio/gsocket.c:2472 gio/gsocket.c:2530 gio/gsocket.c:2548 +#: gio/gsocket.c:2216 gio/gsocket.c:2253 gio/gsocket.c:2363 gio/gsocket.c:2388 +#: gio/gsocket.c:2461 gio/gsocket.c:2519 gio/gsocket.c:2537 #, c-format msgid "Error leaving multicast group: %s" msgstr "Napaka zapuščanja skupine za večsmerno oddajanje: %s" -#: gio/gsocket.c:2228 +#: gio/gsocket.c:2217 msgid "No support for source-specific multicast" msgstr "Ni podpore za večsmerno oddajanje lastno viru" -#: gio/gsocket.c:2375 +#: gio/gsocket.c:2364 msgid "Unsupported socket family" msgstr "Nepodprta skupina vtiča" -#: gio/gsocket.c:2400 +#: gio/gsocket.c:2389 msgid "source-specific not an IPv4 address" msgstr "določeno po viru in ne po naslovu IPv4" -#: gio/gsocket.c:2418 gio/gsocket.c:2447 gio/gsocket.c:2497 +#: gio/gsocket.c:2407 gio/gsocket.c:2436 gio/gsocket.c:2486 #, c-format msgid "Interface not found: %s" msgstr "Vmesnika ni mogoče najti: %s" -#: gio/gsocket.c:2434 +#: gio/gsocket.c:2423 #, c-format msgid "Interface name too long" msgstr "Ime vmesnika je predolgo" -#: gio/gsocket.c:2473 +#: gio/gsocket.c:2462 msgid "No support for IPv4 source-specific multicast" msgstr "Ni podpore za večsmerno oddajanje v protokolu IPv4" -#: gio/gsocket.c:2531 +#: gio/gsocket.c:2520 msgid "No support for IPv6 source-specific multicast" msgstr "Ni podpore za večsmerno oddajanje v protokolu IPv6" -#: gio/gsocket.c:2740 +#: gio/gsocket.c:2729 #, c-format msgid "Error accepting connection: %s" msgstr "Napaka med sprejemanjem povezave: %s" -#: gio/gsocket.c:2864 +#: gio/gsocket.c:2855 msgid "Connection in progress" msgstr "Povezava v teku" -#: gio/gsocket.c:2913 +#: gio/gsocket.c:2906 msgid "Unable to get pending error: " msgstr "Ni mogoče pridobiti uvrščene napake:" -#: gio/gsocket.c:3097 +#: gio/gsocket.c:3092 #, c-format msgid "Error receiving data: %s" msgstr "Napaka med prejemanjem podatkov: %s" -#: gio/gsocket.c:3292 +#: gio/gsocket.c:3289 #, c-format msgid "Error sending data: %s" msgstr "Napaka med pošiljanjem podatkov: %s" -#: gio/gsocket.c:3479 +#: gio/gsocket.c:3476 #, c-format msgid "Unable to shutdown socket: %s" msgstr "Ni mogoče izklopiti vtiča: %s" -#: gio/gsocket.c:3560 +#: gio/gsocket.c:3557 #, c-format msgid "Error closing socket: %s" msgstr "Napaka med zapiranjem vtiča: %s" @@ -3783,52 +3800,53 @@ msgid "Waiting for socket condition: %s" msgstr "Čakanje na stanje vtiča: %s" -#: gio/gsocket.c:4711 gio/gsocket.c:4791 gio/gsocket.c:4969 +#: gio/gsocket.c:4614 gio/gsocket.c:4616 gio/gsocket.c:4762 gio/gsocket.c:4847 +#: gio/gsocket.c:5027 gio/gsocket.c:5067 gio/gsocket.c:5069 #, c-format msgid "Error sending message: %s" msgstr "Napaka med pošiljanjem sporočila: %s" -#: gio/gsocket.c:4735 +#: gio/gsocket.c:4789 msgid "GSocketControlMessage not supported on Windows" msgstr "Predmet GSocketControlMessage na sistemih Windows ni podprt" -#: gio/gsocket.c:5188 gio/gsocket.c:5261 gio/gsocket.c:5487 +#: gio/gsocket.c:5260 gio/gsocket.c:5333 gio/gsocket.c:5560 #, c-format msgid "Error receiving message: %s" msgstr "Napaka med prejemanjem sporočila: %s" -#: gio/gsocket.c:5759 +#: gio/gsocket.c:5832 #, c-format msgid "Unable to read socket credentials: %s" msgstr "Ni mogoče prebrati poveril vtiča: %s." -#: gio/gsocket.c:5768 +#: gio/gsocket.c:5841 msgid "g_socket_get_credentials not implemented for this OS" msgstr "Operacijski sistem ne podpira možnosti g_socket_get_credentials" -#: gio/gsocketclient.c:176 +#: gio/gsocketclient.c:181 #, c-format msgid "Could not connect to proxy server %s: " msgstr "Ni se mogoče povezati s posredniškim strežnikom %s:" -#: gio/gsocketclient.c:190 +#: gio/gsocketclient.c:195 #, c-format msgid "Could not connect to %s: " msgstr "Ni se mogoče povezati s strežnikom %s:" -#: gio/gsocketclient.c:192 +#: gio/gsocketclient.c:197 msgid "Could not connect: " msgstr "Ni se mogoče povezati:" -#: gio/gsocketclient.c:1027 gio/gsocketclient.c:1599 +#: gio/gsocketclient.c:1032 gio/gsocketclient.c:1731 msgid "Unknown error on connect" msgstr "Neznana napaka med povezovanjem" -#: gio/gsocketclient.c:1081 gio/gsocketclient.c:1535 +#: gio/gsocketclient.c:1086 gio/gsocketclient.c:1640 msgid "Proxying over a non-TCP connection is not supported." msgstr "Posredovanje preko ne-TCP povezave ni podprto." -#: gio/gsocketclient.c:1110 gio/gsocketclient.c:1561 +#: gio/gsocketclient.c:1115 gio/gsocketclient.c:1666 #, c-format msgid "Proxy protocol “%s” is not supported." msgstr "Protokol posredniškega strežnika »%s« ni podprt." @@ -3933,49 +3951,49 @@ msgid "Can’t handle version %d of GThemedIcon encoding" msgstr "Ni mogoče upravljati z različico %d kodiranja GThemedIcon" -#: gio/gthreadedresolver.c:118 +#: gio/gthreadedresolver.c:152 msgid "No valid addresses were found" msgstr "Ni mogoče najti veljavnega naslova" -#: gio/gthreadedresolver.c:213 +#: gio/gthreadedresolver.c:317 #, c-format msgid "Error reverse-resolving “%s”: %s" msgstr "Napaka med obratnim razreševanjem »%s«: %s" -#: gio/gthreadedresolver.c:549 gio/gthreadedresolver.c:628 -#: gio/gthreadedresolver.c:726 gio/gthreadedresolver.c:776 +#: gio/gthreadedresolver.c:653 gio/gthreadedresolver.c:732 +#: gio/gthreadedresolver.c:830 gio/gthreadedresolver.c:880 #, c-format msgid "No DNS record of the requested type for “%s”" msgstr "Ni zapisa DNS za zahtevano vrsto »%s«" -#: gio/gthreadedresolver.c:554 gio/gthreadedresolver.c:731 +#: gio/gthreadedresolver.c:658 gio/gthreadedresolver.c:835 #, c-format msgid "Temporarily unable to resolve “%s”" msgstr "Trenutno ni mogoče razrešiti »%s«" -#: gio/gthreadedresolver.c:559 gio/gthreadedresolver.c:736 -#: gio/gthreadedresolver.c:844 +#: gio/gthreadedresolver.c:663 gio/gthreadedresolver.c:840 +#: gio/gthreadedresolver.c:948 #, c-format msgid "Error resolving “%s”" msgstr "Napaka med razreševanjem »%s«" -#: gio/gtlscertificate.c:250 -msgid "Cannot decrypt PEM-encoded private key" -msgstr "Ni mogoče odšifrirati s protokolom PEM šifriranega osebnega ključa" - -#: gio/gtlscertificate.c:255 +#: gio/gtlscertificate.c:243 msgid "No PEM-encoded private key found" msgstr "Potrdila kodiranega s protokolom PEM ni mogoče najti." -#: gio/gtlscertificate.c:265 +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "Ni mogoče odšifrirati s protokolom PEM šifriranega osebnega ključa" + +#: gio/gtlscertificate.c:264 msgid "Could not parse PEM-encoded private key" msgstr "Ni mogoče razčleniti s protokolom PEM kodiranega zasebnega ključa." -#: gio/gtlscertificate.c:290 +#: gio/gtlscertificate.c:291 msgid "No PEM-encoded certificate found" msgstr "Potrdila kodiranega s protokolom PEM ni mogoče najti." -#: gio/gtlscertificate.c:299 +#: gio/gtlscertificate.c:300 msgid "Could not parse PEM-encoded certificate" msgstr "Ni mogoče razčleniti s protokolom PEM kodiranega potrdila." @@ -4062,17 +4080,19 @@ msgid "Error reading from file descriptor: %s" msgstr "Napaka med branjem iz opisovalnika datoteke: %s" -#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:411 +#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:534 #: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 #, c-format msgid "Error closing file descriptor: %s" msgstr "Napaka med zapiranjem opisovalnika datoteke: %s" -#: gio/gunixmounts.c:2651 gio/gunixmounts.c:2704 +#: gio/gunixmounts.c:2650 gio/gunixmounts.c:2703 msgid "Filesystem root" msgstr "Koren datotečnega sistema" -#: gio/gunixoutputstream.c:358 gio/gunixoutputstream.c:378 +#: gio/gunixoutputstream.c:371 gio/gunixoutputstream.c:391 +#: gio/gunixoutputstream.c:478 gio/gunixoutputstream.c:498 +#: gio/gunixoutputstream.c:675 #, c-format msgid "Error writing to file descriptor: %s" msgstr "Napaka med pisanjem v opisovalnik datoteke: %s" @@ -4218,78 +4238,78 @@ msgid "Failed to expand exec line “%s” with URI “%s”" msgstr "Razširjanje ukazne vrstice »%s« z naslovom URI »%s« je spodletelo." -#: glib/gconvert.c:473 +#: glib/gconvert.c:474 msgid "Unrepresentable character in conversion input" msgstr "Nepredstavljiv znak na dovodu pretvorbe" -#: glib/gconvert.c:500 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 +#: glib/gconvert.c:501 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 #: glib/gutf8.c:1318 msgid "Partial character sequence at end of input" msgstr "Nedokončano zaporedje znakov na koncu vhoda" -#: glib/gconvert.c:769 +#: glib/gconvert.c:770 #, c-format msgid "Cannot convert fallback “%s” to codeset “%s”" msgstr "Ni mogoče pretvoriti »%s« v nabor znakov »%s«" -#: glib/gconvert.c:941 +#: glib/gconvert.c:942 msgid "Embedded NUL byte in conversion input" msgstr "Vstavljeno je prazno zaporedje bajtov na dovod pretvorbe" -#: glib/gconvert.c:962 +#: glib/gconvert.c:963 msgid "Embedded NUL byte in conversion output" msgstr "Vstavljeno je prazno zaporedje bajtov na odvod pretvorbe" -#: glib/gconvert.c:1650 +#: glib/gconvert.c:1648 #, c-format msgid "The URI “%s” is not an absolute URI using the “file” scheme" msgstr "Naslov URI »%s« pri uporabi »datotečne« sheme ni absoluten" -#: glib/gconvert.c:1660 +#: glib/gconvert.c:1658 #, c-format msgid "The local file URI “%s” may not include a “#”" msgstr "V naslovu URI krajevne datoteke »%s« ni mogoče uporabiti '#'" -#: glib/gconvert.c:1677 +#: glib/gconvert.c:1675 #, c-format msgid "The URI “%s” is invalid" msgstr "Naslov URI »%s« je neveljaven" -#: glib/gconvert.c:1689 +#: glib/gconvert.c:1687 #, c-format msgid "The hostname of the URI “%s” is invalid" msgstr "Ime gostitelja naslova URI »%s« ni veljavno" -#: glib/gconvert.c:1705 +#: glib/gconvert.c:1703 #, c-format msgid "The URI “%s” contains invalidly escaped characters" msgstr "Naslov URI »%s« vsebuje neveljavne ubežne znake" -#: glib/gconvert.c:1777 +#: glib/gconvert.c:1775 #, c-format msgid "The pathname “%s” is not an absolute path" msgstr "Pot »%s« ni absolutna pot" #. Translators: this is the preferred format for expressing the date and the time -#: glib/gdatetime.c:213 +#: glib/gdatetime.c:214 msgctxt "GDateTime" msgid "%a %b %e %H:%M:%S %Y" msgstr "%a, %e. %b %Y %H:%M:%S" #. Translators: this is the preferred format for expressing the date -#: glib/gdatetime.c:216 +#: glib/gdatetime.c:217 msgctxt "GDateTime" msgid "%m/%d/%y" msgstr "%d.%m.%y" #. Translators: this is the preferred format for expressing the time -#: glib/gdatetime.c:219 +#: glib/gdatetime.c:220 msgctxt "GDateTime" msgid "%H:%M:%S" msgstr "%H:%M:%S" #. Translators: this is the preferred format for expressing 12 hour time -#: glib/gdatetime.c:222 +#: glib/gdatetime.c:223 msgctxt "GDateTime" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" @@ -4310,62 +4330,62 @@ #. * non-European) there is no difference between the standalone and #. * complete date form. #. -#: glib/gdatetime.c:261 +#: glib/gdatetime.c:262 msgctxt "full month name" msgid "January" msgstr "januar" -#: glib/gdatetime.c:263 +#: glib/gdatetime.c:264 msgctxt "full month name" msgid "February" msgstr "februar" -#: glib/gdatetime.c:265 +#: glib/gdatetime.c:266 msgctxt "full month name" msgid "March" msgstr "marec" -#: glib/gdatetime.c:267 +#: glib/gdatetime.c:268 msgctxt "full month name" msgid "April" msgstr "april" -#: glib/gdatetime.c:269 +#: glib/gdatetime.c:270 msgctxt "full month name" msgid "May" msgstr "maj" -#: glib/gdatetime.c:271 +#: glib/gdatetime.c:272 msgctxt "full month name" msgid "June" msgstr "junij" -#: glib/gdatetime.c:273 +#: glib/gdatetime.c:274 msgctxt "full month name" msgid "July" msgstr "julij" -#: glib/gdatetime.c:275 +#: glib/gdatetime.c:276 msgctxt "full month name" msgid "August" msgstr "avgust" -#: glib/gdatetime.c:277 +#: glib/gdatetime.c:278 msgctxt "full month name" msgid "September" msgstr "september" -#: glib/gdatetime.c:279 +#: glib/gdatetime.c:280 msgctxt "full month name" msgid "October" msgstr "oktober" -#: glib/gdatetime.c:281 +#: glib/gdatetime.c:282 msgctxt "full month name" msgid "November" msgstr "november" -#: glib/gdatetime.c:283 +#: glib/gdatetime.c:284 msgctxt "full month name" msgid "December" msgstr "december" @@ -4387,132 +4407,132 @@ #. * other platform. Here are abbreviated month names in a form #. * appropriate when they are used standalone. #. -#: glib/gdatetime.c:315 +#: glib/gdatetime.c:316 msgctxt "abbreviated month name" msgid "Jan" msgstr "jan" -#: glib/gdatetime.c:317 +#: glib/gdatetime.c:318 msgctxt "abbreviated month name" msgid "Feb" msgstr "feb" -#: glib/gdatetime.c:319 +#: glib/gdatetime.c:320 msgctxt "abbreviated month name" msgid "Mar" msgstr "mar" -#: glib/gdatetime.c:321 +#: glib/gdatetime.c:322 msgctxt "abbreviated month name" msgid "Apr" msgstr "apr" -#: glib/gdatetime.c:323 +#: glib/gdatetime.c:324 msgctxt "abbreviated month name" msgid "May" msgstr "maj" -#: glib/gdatetime.c:325 +#: glib/gdatetime.c:326 msgctxt "abbreviated month name" msgid "Jun" msgstr "jun" -#: glib/gdatetime.c:327 +#: glib/gdatetime.c:328 msgctxt "abbreviated month name" msgid "Jul" msgstr "jul" -#: glib/gdatetime.c:329 +#: glib/gdatetime.c:330 msgctxt "abbreviated month name" msgid "Aug" msgstr "avg" -#: glib/gdatetime.c:331 +#: glib/gdatetime.c:332 msgctxt "abbreviated month name" msgid "Sep" msgstr "sep" -#: glib/gdatetime.c:333 +#: glib/gdatetime.c:334 msgctxt "abbreviated month name" msgid "Oct" msgstr "okt" -#: glib/gdatetime.c:335 +#: glib/gdatetime.c:336 msgctxt "abbreviated month name" msgid "Nov" msgstr "nov" -#: glib/gdatetime.c:337 +#: glib/gdatetime.c:338 msgctxt "abbreviated month name" msgid "Dec" msgstr "dec" -#: glib/gdatetime.c:352 +#: glib/gdatetime.c:353 msgctxt "full weekday name" msgid "Monday" msgstr "ponedeljek" -#: glib/gdatetime.c:354 +#: glib/gdatetime.c:355 msgctxt "full weekday name" msgid "Tuesday" msgstr "torek" -#: glib/gdatetime.c:356 +#: glib/gdatetime.c:357 msgctxt "full weekday name" msgid "Wednesday" msgstr "sreda" -#: glib/gdatetime.c:358 +#: glib/gdatetime.c:359 msgctxt "full weekday name" msgid "Thursday" msgstr "četrtek" -#: glib/gdatetime.c:360 +#: glib/gdatetime.c:361 msgctxt "full weekday name" msgid "Friday" msgstr "petek" -#: glib/gdatetime.c:362 +#: glib/gdatetime.c:363 msgctxt "full weekday name" msgid "Saturday" msgstr "sobota" -#: glib/gdatetime.c:364 +#: glib/gdatetime.c:365 msgctxt "full weekday name" msgid "Sunday" msgstr "nedeljo" -#: glib/gdatetime.c:379 +#: glib/gdatetime.c:380 msgctxt "abbreviated weekday name" msgid "Mon" msgstr "pon" -#: glib/gdatetime.c:381 +#: glib/gdatetime.c:382 msgctxt "abbreviated weekday name" msgid "Tue" msgstr "tor" -#: glib/gdatetime.c:383 +#: glib/gdatetime.c:384 msgctxt "abbreviated weekday name" msgid "Wed" msgstr "sre" -#: glib/gdatetime.c:385 +#: glib/gdatetime.c:386 msgctxt "abbreviated weekday name" msgid "Thu" msgstr "čet" -#: glib/gdatetime.c:387 +#: glib/gdatetime.c:388 msgctxt "abbreviated weekday name" msgid "Fri" msgstr "pet" -#: glib/gdatetime.c:389 +#: glib/gdatetime.c:390 msgctxt "abbreviated weekday name" msgid "Sat" msgstr "sob" -#: glib/gdatetime.c:391 +#: glib/gdatetime.c:392 msgctxt "abbreviated weekday name" msgid "Sun" msgstr "ned" @@ -4534,62 +4554,62 @@ #. * (western European, non-European) there is no difference between the #. * standalone and complete date form. #. -#: glib/gdatetime.c:455 +#: glib/gdatetime.c:456 msgctxt "full month name with day" msgid "January" msgstr "januar" -#: glib/gdatetime.c:457 +#: glib/gdatetime.c:458 msgctxt "full month name with day" msgid "February" msgstr "februar" -#: glib/gdatetime.c:459 +#: glib/gdatetime.c:460 msgctxt "full month name with day" msgid "March" msgstr "marec" -#: glib/gdatetime.c:461 +#: glib/gdatetime.c:462 msgctxt "full month name with day" msgid "April" msgstr "april" -#: glib/gdatetime.c:463 +#: glib/gdatetime.c:464 msgctxt "full month name with day" msgid "May" msgstr "maj" -#: glib/gdatetime.c:465 +#: glib/gdatetime.c:466 msgctxt "full month name with day" msgid "June" msgstr "junij" -#: glib/gdatetime.c:467 +#: glib/gdatetime.c:468 msgctxt "full month name with day" msgid "July" msgstr "julij" -#: glib/gdatetime.c:469 +#: glib/gdatetime.c:470 msgctxt "full month name with day" msgid "August" msgstr "avgust" -#: glib/gdatetime.c:471 +#: glib/gdatetime.c:472 msgctxt "full month name with day" msgid "September" msgstr "september" -#: glib/gdatetime.c:473 +#: glib/gdatetime.c:474 msgctxt "full month name with day" msgid "October" msgstr "oktober" -#: glib/gdatetime.c:475 +#: glib/gdatetime.c:476 msgctxt "full month name with day" msgid "November" msgstr "november" -#: glib/gdatetime.c:477 +#: glib/gdatetime.c:478 msgctxt "full month name with day" msgid "December" msgstr "december" @@ -4611,79 +4631,79 @@ #. * month names almost ready to copy and paste here. In other systems #. * due to a bug the result is incorrect in some languages. #. -#: glib/gdatetime.c:542 +#: glib/gdatetime.c:543 msgctxt "abbreviated month name with day" msgid "Jan" msgstr "jan" -#: glib/gdatetime.c:544 +#: glib/gdatetime.c:545 msgctxt "abbreviated month name with day" msgid "Feb" msgstr "feb" -#: glib/gdatetime.c:546 +#: glib/gdatetime.c:547 msgctxt "abbreviated month name with day" msgid "Mar" msgstr "mar" -#: glib/gdatetime.c:548 +#: glib/gdatetime.c:549 msgctxt "abbreviated month name with day" msgid "Apr" msgstr "apr" -#: glib/gdatetime.c:550 +#: glib/gdatetime.c:551 msgctxt "abbreviated month name with day" msgid "May" msgstr "maj" -#: glib/gdatetime.c:552 +#: glib/gdatetime.c:553 msgctxt "abbreviated month name with day" msgid "Jun" msgstr "jun" -#: glib/gdatetime.c:554 +#: glib/gdatetime.c:555 msgctxt "abbreviated month name with day" msgid "Jul" msgstr "jul" -#: glib/gdatetime.c:556 +#: glib/gdatetime.c:557 msgctxt "abbreviated month name with day" msgid "Aug" msgstr "avg" -#: glib/gdatetime.c:558 +#: glib/gdatetime.c:559 msgctxt "abbreviated month name with day" msgid "Sep" msgstr "sep" -#: glib/gdatetime.c:560 +#: glib/gdatetime.c:561 msgctxt "abbreviated month name with day" msgid "Oct" msgstr "okt" -#: glib/gdatetime.c:562 +#: glib/gdatetime.c:563 msgctxt "abbreviated month name with day" msgid "Nov" msgstr "nov" -#: glib/gdatetime.c:564 +#: glib/gdatetime.c:565 msgctxt "abbreviated month name with day" msgid "Dec" msgstr "dec" #. Translators: 'before midday' indicator -#: glib/gdatetime.c:581 +#: glib/gdatetime.c:582 msgctxt "GDateTime" msgid "AM" msgstr "dop" #. Translators: 'after midday' indicator -#: glib/gdatetime.c:584 +#: glib/gdatetime.c:585 msgctxt "GDateTime" msgid "PM" msgstr "pop" -#: glib/gdir.c:155 +#: glib/gdir.c:154 #, c-format msgid "Error opening directory “%s”: %s" msgstr "Napaka med odpiranjem imenika »%s«: %s" @@ -4917,32 +4937,32 @@ msgstr "" "Odpiranje datoteke »%s« je spodletelo: ukaz open() ni uspešno izveden: %s" -#: glib/gmarkup.c:397 glib/gmarkup.c:439 +#: glib/gmarkup.c:398 glib/gmarkup.c:440 #, c-format msgid "Error on line %d char %d: " msgstr "Napaka v vrstici %d, znak %d:" -#: glib/gmarkup.c:461 glib/gmarkup.c:544 +#: glib/gmarkup.c:462 glib/gmarkup.c:545 #, c-format msgid "Invalid UTF-8 encoded text in name — not valid “%s”" msgstr "Neveljavno UTF-8 kodirano besedilo imena – neveljaven »%s«" -#: glib/gmarkup.c:472 +#: glib/gmarkup.c:473 #, c-format msgid "“%s” is not a valid name" msgstr "»%s« ni veljavno ime" -#: glib/gmarkup.c:488 +#: glib/gmarkup.c:489 #, c-format msgid "“%s” is not a valid name: “%c”" msgstr "»%s« ni veljavno ime: »%c«" -#: glib/gmarkup.c:612 +#: glib/gmarkup.c:613 #, c-format msgid "Error on line %d: %s" msgstr "Napaka v vrstici %d: %s" -#: glib/gmarkup.c:689 +#: glib/gmarkup.c:690 #, c-format msgid "" "Failed to parse “%-.*s”, which should have been a digit inside a character " @@ -4951,7 +4971,7 @@ "Razčlenjevanje vrste »%-.*s«, ki bi morala določati številko znotraj sklica " "znaka (na primer ê) je spodletelo – morda je številka prevelika" -#: glib/gmarkup.c:701 +#: glib/gmarkup.c:702 msgid "" "Character reference did not end with a semicolon; most likely you used an " "ampersand character without intending to start an entity — escape ampersand " @@ -4960,24 +4980,24 @@ "Sklic znaka ni končan s podpičjem; najverjetneje je uporabljen znak » & « " "brez povezave s predmetom – znak » & « mora biti zapisan kot »&«." -#: glib/gmarkup.c:727 +#: glib/gmarkup.c:728 #, c-format msgid "Character reference “%-.*s” does not encode a permitted character" msgstr "Sklic znaka »%-.*s« ne kodira dovoljenega znaka" -#: glib/gmarkup.c:765 +#: glib/gmarkup.c:766 msgid "" "Empty entity “&;” seen; valid entities are: & " < > '" msgstr "" "Zaznan je prazen predmet » &; «; veljavne možnosti so: & " < " "> '" -#: glib/gmarkup.c:773 +#: glib/gmarkup.c:774 #, c-format msgid "Entity name “%-.*s” is not known" msgstr "Ime predmeta »%-.*s« ni prepoznano" -#: glib/gmarkup.c:778 +#: glib/gmarkup.c:779 msgid "" "Entity did not end with a semicolon; most likely you used an ampersand " "character without intending to start an entity — escape ampersand as &" @@ -4985,11 +5005,11 @@ "Predmet ni zaključen s podpičjem; najverjetneje je uporabljen znak » & « " "brez povezave s predmetom – znak » & « mora biti zapisan kot »&«." -#: glib/gmarkup.c:1186 +#: glib/gmarkup.c:1187 msgid "Document must begin with an element (e.g. )" msgstr "Dokument se mora začeti z predmetom (na primer )" -#: glib/gmarkup.c:1226 +#: glib/gmarkup.c:1227 #, c-format msgid "" "“%s” is not a valid character following a “<” character; it may not begin an " @@ -4998,7 +5018,7 @@ "»%s« ni veljaven znak, ki lahko sledi znaku » < «;. Morda se ne začne z " "imenom predmeta." -#: glib/gmarkup.c:1269 +#: glib/gmarkup.c:1270 #, c-format msgid "" "Odd character “%s”, expected a “>” character to end the empty-element tag " @@ -5007,7 +5027,7 @@ "Nenavaden znak »%s«; pričakovan znak je » > «, da zaključi oznako predmeta " "»%s«" -#: glib/gmarkup.c:1351 +#: glib/gmarkup.c:1352 #, c-format msgid "" "Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”" @@ -5015,7 +5035,7 @@ "Nenavaden znak »%s«; za imenom atributa »%s« (predmeta »%s«) je pričakovan " "znak » = «." -#: glib/gmarkup.c:1393 +#: glib/gmarkup.c:1394 #, c-format msgid "" "Odd character “%s”, expected a “>” or “/” character to end the start tag of " @@ -5026,7 +5046,7 @@ "predmeta »%s« ali pogojno atribut. Morda je uporabljen neveljaven znak v " "imenu atributa." -#: glib/gmarkup.c:1438 +#: glib/gmarkup.c:1439 #, c-format msgid "" "Odd character “%s”, expected an open quote mark after the equals sign when " @@ -5035,7 +5055,7 @@ "Nenavaden znak »%s«; za enačajem je pričakovan narekovaj, znotraj katerega " "je podana vrednost atributa »%s« predmeta »%s«." -#: glib/gmarkup.c:1572 +#: glib/gmarkup.c:1573 #, c-format msgid "" "“%s” is not a valid character following the characters “ «." -#: glib/gmarkup.c:1622 +#: glib/gmarkup.c:1623 #, c-format msgid "Element “%s” was closed, no element is currently open" msgstr "Predmet »%s« je zaprt, trenutno ni odprtega drugega predmeta" -#: glib/gmarkup.c:1631 +#: glib/gmarkup.c:1632 #, c-format msgid "Element “%s” was closed, but the currently open element is “%s”" msgstr "Predmet »%s« je zaprt, še vedno pa je odprt predmet »%s«" -#: glib/gmarkup.c:1784 +#: glib/gmarkup.c:1785 msgid "Document was empty or contained only whitespace" msgstr "Dokument je prazen ali pa vsebuje le presledne znake" -#: glib/gmarkup.c:1798 +#: glib/gmarkup.c:1799 msgid "Document ended unexpectedly just after an open angle bracket “<”" msgstr "Dokument je nepričakovano zaključen takoj za odprtjem oznake z » < «" -#: glib/gmarkup.c:1806 glib/gmarkup.c:1851 +#: glib/gmarkup.c:1807 glib/gmarkup.c:1852 #, c-format msgid "" "Document ended unexpectedly with elements still open — “%s” was the last " @@ -5080,7 +5100,7 @@ "Dokument je nepričakovano zaključen s še odprtimi predmeti – »%s« je zadnji " "odprt predmet" -#: glib/gmarkup.c:1814 +#: glib/gmarkup.c:1815 #, c-format msgid "" "Document ended unexpectedly, expected to see a close angle bracket ending " @@ -5089,19 +5109,19 @@ "Dokument nepričakovano zaključen, pričakovan je zaključni zaklepaj oznake <" "%s/>" -#: glib/gmarkup.c:1820 +#: glib/gmarkup.c:1821 msgid "Document ended unexpectedly inside an element name" msgstr "Dokument nepričakovano zaključen sredi imena predmeta" -#: glib/gmarkup.c:1826 +#: glib/gmarkup.c:1827 msgid "Document ended unexpectedly inside an attribute name" msgstr "Dokument nepričakovano zaključen sredi imena atributa" -#: glib/gmarkup.c:1831 +#: glib/gmarkup.c:1832 msgid "Document ended unexpectedly inside an element-opening tag." msgstr "Dokument nepričakovano zaključen sredi oznake za odprtje predmeta." -#: glib/gmarkup.c:1837 +#: glib/gmarkup.c:1838 msgid "" "Document ended unexpectedly after the equals sign following an attribute " "name; no attribute value" @@ -5109,23 +5129,23 @@ "Dokument nepričakovano zaključen za enačajem, ki sledil imenu atributa; ni " "določena vrednosti atributa" -#: glib/gmarkup.c:1844 +#: glib/gmarkup.c:1845 msgid "Document ended unexpectedly while inside an attribute value" msgstr "Dokument nepričakovano zaključen sredi vrednosti atributa" -#: glib/gmarkup.c:1861 +#: glib/gmarkup.c:1862 #, c-format msgid "Document ended unexpectedly inside the close tag for element “%s”" msgstr "Dokument je nepričakovano zaključen sredi oznake zaprtja predmeta »%s«" -#: glib/gmarkup.c:1865 +#: glib/gmarkup.c:1866 msgid "" "Document ended unexpectedly inside the close tag for an unopened element" msgstr "" "Dokument je nepričakovano zaključen sredi oznake zaprtja predmeta za neodprt " "predmet" -#: glib/gmarkup.c:1871 +#: glib/gmarkup.c:1872 msgid "Document ended unexpectedly inside a comment or processing instruction" msgstr "Dokument nepričakovano zaključen sredi opombe ali ukaza" @@ -5595,7 +5615,7 @@ msgid "Unexpected error in waitpid() (%s)" msgstr "Nepričakovana napaka v waitpid() (%s)" -#: glib/gspawn.c:1056 glib/gspawn-win32.c:1318 +#: glib/gspawn.c:1056 glib/gspawn-win32.c:1329 #, c-format msgid "Child process exited with code %ld" msgstr "Podrejeni proces se je zaključil s kodo %ld" @@ -5615,7 +5635,7 @@ msgid "Child process exited abnormally" msgstr "Podrejeni proces se je zaključil nenaravno" -#: glib/gspawn.c:1405 glib/gspawn-win32.c:339 glib/gspawn-win32.c:347 +#: glib/gspawn.c:1405 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 #, c-format msgid "Failed to read from child pipe (%s)" msgstr "Ni mogoče prebrati iz cevi podrejenega procesa (%s)" @@ -5630,7 +5650,7 @@ msgid "Failed to fork (%s)" msgstr "Ni mogoča razvejitev (%s)" -#: glib/gspawn.c:1841 glib/gspawn-win32.c:370 +#: glib/gspawn.c:1841 glib/gspawn-win32.c:381 #, c-format msgid "Failed to change to directory “%s” (%s)" msgstr "Ni mogoče spremeniti v mapo »%s« (%s)" @@ -5660,46 +5680,46 @@ msgid "Failed to read enough data from child pid pipe (%s)" msgstr "Ni mogoče prebrati dovolj podatkov iz cevi podrejenega procesa (%s)" -#: glib/gspawn-win32.c:283 +#: glib/gspawn-win32.c:294 msgid "Failed to read data from child process" msgstr "Ni mogoče prebrati podatkov iz opravila podrejenega predmeta" -#: glib/gspawn-win32.c:300 +#: glib/gspawn-win32.c:311 #, c-format msgid "Failed to create pipe for communicating with child process (%s)" msgstr "Ni mogoče ustvariti cevi za stik z opravilom podrejenega predmeta (%s)" -#: glib/gspawn-win32.c:376 glib/gspawn-win32.c:381 glib/gspawn-win32.c:500 +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 #, c-format msgid "Failed to execute child process (%s)" msgstr "Ni mogoče izvesti podrejenega opravila (%s)" -#: glib/gspawn-win32.c:450 +#: glib/gspawn-win32.c:461 #, c-format msgid "Invalid program name: %s" msgstr "Neveljavno ime programa: %s" -#: glib/gspawn-win32.c:460 glib/gspawn-win32.c:714 +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 #, c-format msgid "Invalid string in argument vector at %d: %s" msgstr "Neveljaven niz v vektorju argumenta pri %d: %s" -#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:729 +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 #, c-format msgid "Invalid string in environment: %s" msgstr "Neveljaven niz okolja: %s" -#: glib/gspawn-win32.c:710 +#: glib/gspawn-win32.c:721 #, c-format msgid "Invalid working directory: %s" msgstr "Neveljavna delovna mapa: %s" -#: glib/gspawn-win32.c:772 +#: glib/gspawn-win32.c:783 #, c-format msgid "Failed to execute helper program (%s)" msgstr "Napaka med izvajanjem pomožnega programa (%s)" -#: glib/gspawn-win32.c:1045 +#: glib/gspawn-win32.c:1056 msgid "" "Unexpected error in g_io_channel_win32_poll() reading data from a child " "process" @@ -5707,21 +5727,21 @@ "Nepričakovana napaka v g_io_channel_win32_poll() med branjem podatkov " "procesa podrejenega predmeta" -#: glib/gstrfuncs.c:3247 glib/gstrfuncs.c:3348 +#: glib/gstrfuncs.c:3286 glib/gstrfuncs.c:3388 msgid "Empty string is not a number" msgstr "Prazen niz ni številska vrednost" -#: glib/gstrfuncs.c:3271 +#: glib/gstrfuncs.c:3310 #, c-format msgid "“%s” is not a signed number" msgstr "»%s« ni podpisano število" -#: glib/gstrfuncs.c:3281 glib/gstrfuncs.c:3384 +#: glib/gstrfuncs.c:3320 glib/gstrfuncs.c:3424 #, c-format msgid "Number “%s” is out of bounds [%s, %s]" msgstr "Število »%s« je izven območja [%s, %s]" -#: glib/gstrfuncs.c:3374 +#: glib/gstrfuncs.c:3414 #, c-format msgid "“%s” is not an unsigned number" msgstr "»%s« ni nepodpisano število" @@ -5743,127 +5763,175 @@ msgid "Character out of range for UTF-16" msgstr "Znak izven območja za UTF-16" -#: glib/gutils.c:2244 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2339 #, c-format -msgid "%.1f kB" -msgstr "%.1f kB" +#| msgid "%.1f kB" +msgid "%.1f kB" +msgstr "%.1f kB" -#: glib/gutils.c:2245 glib/gutils.c:2451 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2341 #, c-format -msgid "%.1f MB" -msgstr "%.1f MB" +#| msgid "%.1f MB" +msgid "%.1f MB" +msgstr "%.1f MB" -#: glib/gutils.c:2246 glib/gutils.c:2456 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2343 #, c-format -msgid "%.1f GB" -msgstr "%.1f GB" +#| msgid "%.1f GB" +msgid "%.1f GB" +msgstr "%.1f GB" -#: glib/gutils.c:2247 glib/gutils.c:2461 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2345 #, c-format -msgid "%.1f TB" -msgstr "%.1f TB" +#| msgid "%.1f TB" +msgid "%.1f TB" +msgstr "%.1f TB" -#: glib/gutils.c:2248 glib/gutils.c:2466 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2347 #, c-format -msgid "%.1f PB" -msgstr "%.1f PB" +#| msgid "%.1f PB" +msgid "%.1f PB" +msgstr "%.1f PB" -#: glib/gutils.c:2249 glib/gutils.c:2471 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2349 #, c-format -msgid "%.1f EB" -msgstr "%.1f EB" +#| msgid "%.1f EB" +msgid "%.1f EB" +msgstr "%.1f EB" -#: glib/gutils.c:2252 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2353 #, c-format -msgid "%.1f KiB" -msgstr "%.1f KiB" +#| msgid "%.1f KiB" +msgid "%.1f KiB" +msgstr "%.1f KiB" -#: glib/gutils.c:2253 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2355 #, c-format -msgid "%.1f MiB" -msgstr "%.1f MiB" +#| msgid "%.1f MiB" +msgid "%.1f MiB" +msgstr "%.1f MiB" -#: glib/gutils.c:2254 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2357 #, c-format -msgid "%.1f GiB" -msgstr "%.1f GiB" +#| msgid "%.1f GiB" +msgid "%.1f GiB" +msgstr "%.1f GiB" -#: glib/gutils.c:2255 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2359 #, c-format -msgid "%.1f TiB" -msgstr "%.1f TiB" +#| msgid "%.1f TiB" +msgid "%.1f TiB" +msgstr "%.1f TiB" -#: glib/gutils.c:2256 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2361 #, c-format -msgid "%.1f PiB" -msgstr "%.1f PiB" +#| msgid "%.1f PiB" +msgid "%.1f PiB" +msgstr "%.1f PiB" -#: glib/gutils.c:2257 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2363 #, c-format -msgid "%.1f EiB" -msgstr "%.1f EiB" +#| msgid "%.1f EiB" +msgid "%.1f EiB" +msgstr "%.1f EiB" -#: glib/gutils.c:2260 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2367 #, c-format -msgid "%.1f kb" -msgstr "%.1f kb" +#| msgid "%.1f kb" +msgid "%.1f kb" +msgstr "%.1f kb" -#: glib/gutils.c:2261 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2369 #, c-format -msgid "%.1f Mb" -msgstr "%.1f Mb" +#| msgid "%.1f Mb" +msgid "%.1f Mb" +msgstr "%.1f Mb" -#: glib/gutils.c:2262 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2371 #, c-format -msgid "%.1f Gb" -msgstr "%.1f Gb" +#| msgid "%.1f Gb" +msgid "%.1f Gb" +msgstr "%.1f Gb" -#: glib/gutils.c:2263 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2373 #, c-format -msgid "%.1f Tb" -msgstr "%.1f Tb" +#| msgid "%.1f Tb" +msgid "%.1f Tb" +msgstr "%.1f Tb" -#: glib/gutils.c:2264 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2375 #, c-format -msgid "%.1f Pb" -msgstr "%.1f Pb" +#| msgid "%.1f Pb" +msgid "%.1f Pb" +msgstr "%.1f Pb" -#: glib/gutils.c:2265 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2377 #, c-format -msgid "%.1f Eb" -msgstr "%.1f Eb" +#| msgid "%.1f Eb" +msgid "%.1f Eb" +msgstr "%.1f Eb" -#: glib/gutils.c:2268 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2381 #, c-format -msgid "%.1f Kib" -msgstr "%.1f Kib" +#| msgid "%.1f Kib" +msgid "%.1f Kib" +msgstr "%.1f Kib" -#: glib/gutils.c:2269 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2383 #, c-format -msgid "%.1f Mib" -msgstr "%.1f Mib" +#| msgid "%.1f Mib" +msgid "%.1f Mib" +msgstr "%.1f Mib" -#: glib/gutils.c:2270 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2385 #, c-format -msgid "%.1f Gib" -msgstr "%.1f Gib" +#| msgid "%.1f Gib" +msgid "%.1f Gib" +msgstr "%.1f Gib" -#: glib/gutils.c:2271 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2387 #, c-format -msgid "%.1f Tib" -msgstr "%.1f Tib" +#| msgid "%.1f Tib" +msgid "%.1f Tib" +msgstr "%.1f Tib" -#: glib/gutils.c:2272 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2389 #, c-format -msgid "%.1f Pib" -msgstr "%.1f Pib" +#| msgid "%.1f Pib" +msgid "%.1f Pib" +msgstr "%.1f Pib" -#: glib/gutils.c:2273 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2391 #, c-format -msgid "%.1f Eib" -msgstr "%.1f Eib" +#| msgid "%.1f Eib" +msgid "%.1f Eib" +msgstr "%.1f Eib" -#: glib/gutils.c:2307 glib/gutils.c:2433 +#: glib/gutils.c:2425 glib/gutils.c:2551 #, c-format msgid "%u byte" msgid_plural "%u bytes" @@ -5872,7 +5940,7 @@ msgstr[2] "%u bajta" msgstr[3] "%u bajti" -#: glib/gutils.c:2311 +#: glib/gutils.c:2429 #, c-format msgid "%u bit" msgid_plural "%u bits" @@ -5882,7 +5950,7 @@ msgstr[3] "%u biti" #. Translators: the %s in "%s bytes" will always be replaced by a number. -#: glib/gutils.c:2378 +#: glib/gutils.c:2496 #, c-format msgid "%s byte" msgid_plural "%s bytes" @@ -5892,7 +5960,7 @@ msgstr[3] "%s bajti" #. Translators: the %s in "%s bits" will always be replaced by a number. -#: glib/gutils.c:2383 +#: glib/gutils.c:2501 #, c-format msgid "%s bit" msgid_plural "%s bits" @@ -5906,11 +5974,36 @@ #. * compatibility. Users will not see this string unless a program is using this deprecated function. #. * Please translate as literally as possible. #. -#: glib/gutils.c:2446 +#: glib/gutils.c:2564 #, c-format msgid "%.1f KB" msgstr "%.1f KB" +#: glib/gutils.c:2569 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2574 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2579 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2584 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2589 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + #~ msgid "No such interface '%s'" #~ msgstr "Vmesnik »%s«ne obstaja" diff -Nru glib2.0-2.59.2/po/tr.po glib2.0-2.59.3/po/tr.po --- glib2.0-2.59.2/po/tr.po 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/po/tr.po 2019-03-04 09:01:42.000000000 +0000 @@ -9,14 +9,15 @@ # Necdet Yücel , 2015. # Kaan Özdinçer , 2015. # Muhammet Kara , 2011, 2014, 2015, 2016. -# Emin Tufan Çetin , 2017, 2018. +# Serdar Sağlam , 2019. +# Emin Tufan Çetin , 2017-2019. # msgid "" msgstr "" "Project-Id-Version: glib\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/glib/issues\n" -"POT-Creation-Date: 2018-11-06 16:23+0000\n" -"PO-Revision-Date: 2018-11-06 22:51+0300\n" +"POT-Creation-Date: 2019-02-12 14:21+0000\n" +"PO-Revision-Date: 2019-02-12 17:25+0300\n" "Last-Translator: Emin Tufan Çetin \n" "Language-Team: Türkçe \n" "Language: tr\n" @@ -24,25 +25,29 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Gtranslator 2.91.7\n" +"X-Generator: Gtranslator 3.30.1\n" "X-POOTLE-MTIME: 1433280446.000000\n" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "GApplication options" msgstr "GApplication seçenekleri" -#: gio/gapplication.c:496 +#: gio/gapplication.c:499 msgid "Show GApplication options" msgstr "GApplication seçeneklerini göster" -#: gio/gapplication.c:541 +#: gio/gapplication.c:544 msgid "Enter GApplication service mode (use from D-Bus service files)" msgstr "GApplication servis kipi girin (D-Bus servis dosyalarından kullan)" -#: gio/gapplication.c:553 +#: gio/gapplication.c:556 msgid "Override the application’s ID" msgstr "Uygulama kimliğini (ID) geçersiz kıl" +#: gio/gapplication.c:568 +msgid "Replace the running instance" +msgstr "Çalışan örneği değiştirin" + #: gio/gapplication-tool.c:45 gio/gapplication-tool.c:46 gio/gio-tool.c:227 #: gio/gresource-tool.c:495 gio/gsettings-tool.c:569 msgid "Print help" @@ -118,8 +123,8 @@ msgid "Application identifier in D-Bus format (eg: org.example.viewer)" msgstr "D-Bus biçiminde uygulama tanımlayıcı (örneğin: org.example.viewer)" -#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:737 -#: gio/glib-compile-resources.c:743 gio/glib-compile-resources.c:770 +#: gio/gapplication-tool.c:72 gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:744 gio/glib-compile-resources.c:772 #: gio/gresource-tool.c:502 gio/gresource-tool.c:568 msgid "FILE" msgstr "DOSYA" @@ -257,8 +262,8 @@ #: gio/gbufferedinputstream.c:420 gio/gbufferedinputstream.c:498 #: gio/ginputstream.c:179 gio/ginputstream.c:379 gio/ginputstream.c:617 -#: gio/ginputstream.c:1019 gio/goutputstream.c:203 gio/goutputstream.c:834 -#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:209 +#: gio/ginputstream.c:1019 gio/goutputstream.c:223 gio/goutputstream.c:1049 +#: gio/gpollableinputstream.c:205 gio/gpollableoutputstream.c:277 #, c-format msgid "Too large count value passed to %s" msgstr "%s için çok büyük sayaç değeri geçildi" @@ -273,7 +278,7 @@ msgstr "GBufferedInputStreamsonu kesilemiyor" #: gio/gbufferedinputstream.c:982 gio/ginputstream.c:1208 gio/giostream.c:300 -#: gio/goutputstream.c:1661 +#: gio/goutputstream.c:2198 msgid "Stream is already closed" msgstr "Akış zaten kapalı" @@ -281,7 +286,7 @@ msgid "Truncate not supported on base stream" msgstr "Taban akış üzerinde sonunun kesilmesi desteklenmiyor" -#: gio/gcancellable.c:317 gio/gdbusconnection.c:1840 gio/gdbusprivate.c:1402 +#: gio/gcancellable.c:317 gio/gdbusconnection.c:1867 gio/gdbusprivate.c:1402 #: gio/gsimpleasyncresult.c:871 gio/gsimpleasyncresult.c:897 #, c-format msgid "Operation was cancelled" @@ -300,33 +305,33 @@ msgstr "Hedefte yeterli alan yok" #: gio/gcharsetconverter.c:342 gio/gdatainputstream.c:848 -#: gio/gdatainputstream.c:1261 glib/gconvert.c:454 glib/gconvert.c:884 +#: gio/gdatainputstream.c:1261 glib/gconvert.c:455 glib/gconvert.c:885 #: glib/giochannel.c:1557 glib/giochannel.c:1599 glib/giochannel.c:2443 #: glib/gutf8.c:869 glib/gutf8.c:1322 msgid "Invalid byte sequence in conversion input" msgstr "Dönüşüm girdisinde geçersiz bayt dizisi" -#: gio/gcharsetconverter.c:347 glib/gconvert.c:462 glib/gconvert.c:798 +#: gio/gcharsetconverter.c:347 glib/gconvert.c:463 glib/gconvert.c:799 #: glib/giochannel.c:1564 glib/giochannel.c:2455 #, c-format msgid "Error during conversion: %s" msgstr "Dönüşüm sırasında hata oluştu: %s" -#: gio/gcharsetconverter.c:445 gio/gsocket.c:1104 +#: gio/gcharsetconverter.c:445 gio/gsocket.c:1093 msgid "Cancellable initialization not supported" msgstr "İptal edilebilir başlatma desteklenmiyor" -#: gio/gcharsetconverter.c:456 glib/gconvert.c:327 glib/giochannel.c:1385 +#: gio/gcharsetconverter.c:456 glib/gconvert.c:328 glib/giochannel.c:1385 #, c-format msgid "Conversion from character set “%s” to “%s” is not supported" msgstr "“%s” karakter kümesinden “%s” karakter kümesine dönüşüm desteklenmiyor" -#: gio/gcharsetconverter.c:460 glib/gconvert.c:331 +#: gio/gcharsetconverter.c:460 glib/gconvert.c:332 #, c-format msgid "Could not open converter from “%s” to “%s”" msgstr "“%s”den “%s”e dönüştürücü açılamıyor" -#: gio/gcontenttype.c:358 +#: gio/gcontenttype.c:452 #, c-format msgid "%s type" msgstr "%s türü" @@ -505,7 +510,7 @@ msgstr "" "Oturum veri yolu adresi saptanamıyor (bu işletim sistemi için uygulanmadı)" -#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7142 +#: gio/gdbusaddress.c:1662 gio/gdbusconnection.c:7174 #, c-format msgid "" "Cannot determine bus address from DBUS_STARTER_BUS_TYPE environment variable " @@ -514,7 +519,7 @@ "DBUS_STARTER_BUS_TYPE ortam değişkeninden veri yolu adresi saptanamıyor — " "bilinmeyen değer “%s”" -#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7151 +#: gio/gdbusaddress.c:1671 gio/gdbusconnection.c:7183 msgid "" "Cannot determine bus address because the DBUS_STARTER_BUS_TYPE environment " "variable is not set" @@ -626,94 +631,94 @@ msgid "(Additionally, releasing the lock for “%s” also failed: %s) " msgstr "(Ayrıca, “%s” için kilidi açma başarısız oldu: %s) " -#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2369 +#: gio/gdbusconnection.c:603 gio/gdbusconnection.c:2396 msgid "The connection is closed" msgstr "Bağlantı kapalı" -#: gio/gdbusconnection.c:1870 +#: gio/gdbusconnection.c:1897 msgid "Timeout was reached" msgstr "Zaman aşımı gerçekleşti" -#: gio/gdbusconnection.c:2491 +#: gio/gdbusconnection.c:2518 msgid "" "Unsupported flags encountered when constructing a client-side connection" msgstr "" "İstemci taraflı bağlantı kurulurken desteklenmeyen etiketlerle karşılaşıldı" -#: gio/gdbusconnection.c:4115 gio/gdbusconnection.c:4462 +#: gio/gdbusconnection.c:4147 gio/gdbusconnection.c:4494 #, c-format msgid "" "No such interface “org.freedesktop.DBus.Properties” on object at path %s" msgstr "" "%s yolundaki nesnede “org.freedesktop.DBus.Properties” gibi bir arayüz yok" -#: gio/gdbusconnection.c:4257 +#: gio/gdbusconnection.c:4289 #, c-format msgid "No such property “%s”" msgstr "“%s” gibi bir özellik yok" -#: gio/gdbusconnection.c:4269 +#: gio/gdbusconnection.c:4301 #, c-format msgid "Property “%s” is not readable" msgstr "“%s” özelliği okunabilir değil" -#: gio/gdbusconnection.c:4280 +#: gio/gdbusconnection.c:4312 #, c-format msgid "Property “%s” is not writable" msgstr "“%s” özelliği yazılabilir değil" -#: gio/gdbusconnection.c:4300 +#: gio/gdbusconnection.c:4332 #, c-format msgid "Error setting property “%s”: Expected type “%s” but got “%s”" msgstr "“%s” özelliği ayarlanırken hata: “%s” türü beklendi, “%s” elde edildi" -#: gio/gdbusconnection.c:4405 gio/gdbusconnection.c:4613 -#: gio/gdbusconnection.c:6582 +#: gio/gdbusconnection.c:4437 gio/gdbusconnection.c:4645 +#: gio/gdbusconnection.c:6614 #, c-format msgid "No such interface “%s”" msgstr "“%s” gibi bir arabirim yok" -#: gio/gdbusconnection.c:4831 gio/gdbusconnection.c:7091 +#: gio/gdbusconnection.c:4863 gio/gdbusconnection.c:7123 #, c-format msgid "No such interface “%s” on object at path %s" msgstr "%2$s yolundaki nesnede “%1$s” gibi bir arayüz yok" -#: gio/gdbusconnection.c:4929 +#: gio/gdbusconnection.c:4961 #, c-format msgid "No such method “%s”" msgstr "“%s” gibi bir anahtar yok" -#: gio/gdbusconnection.c:4960 +#: gio/gdbusconnection.c:4992 #, c-format msgid "Type of message, “%s”, does not match expected type “%s”" msgstr "“%s” iletisinin türü, beklenen “%s” türü ile örtüşmüyor" -#: gio/gdbusconnection.c:5158 +#: gio/gdbusconnection.c:5190 #, c-format msgid "An object is already exported for the interface %s at %s" msgstr "%2$s konumundaki %1$s arayüzü için bir nesne zaten dışa aktarıldı" -#: gio/gdbusconnection.c:5384 +#: gio/gdbusconnection.c:5416 #, c-format msgid "Unable to retrieve property %s.%s" msgstr "%s.%s özelliği alınamadı" -#: gio/gdbusconnection.c:5440 +#: gio/gdbusconnection.c:5472 #, c-format msgid "Unable to set property %s.%s" msgstr "%s.%s özelliği ayarlanamadı" -#: gio/gdbusconnection.c:5618 +#: gio/gdbusconnection.c:5650 #, c-format msgid "Method “%s” returned type “%s”, but expected “%s”" msgstr "“%s” yöntemi “%s” türü döndürdü, ancak “%s” bekleniyordu" -#: gio/gdbusconnection.c:6693 +#: gio/gdbusconnection.c:6725 #, c-format msgid "Method “%s” on interface “%s” with signature “%s” does not exist" msgstr "“%3$s” imzalı “%2$s” arayüzü üzerinde “%1$s” yöntemi yok" -#: gio/gdbusconnection.c:6814 +#: gio/gdbusconnection.c:6846 #, c-format msgid "A subtree is already exported for %s" msgstr "%s için bir alt ağaç zaten dışa aktarılmış" @@ -829,7 +834,7 @@ msgid "Invalid major protocol version. Expected 1 but found %d" msgstr "Geçersiz önemli iletişim kuralı sürümü. 1 beklendi, %d bulundu" -#: gio/gdbusmessage.c:2132 gio/gdbusmessage.c:2722 +#: gio/gdbusmessage.c:2132 gio/gdbusmessage.c:2724 msgid "Signature header found but is not of type signature" msgstr "İmza başlığı bulundu, ancak tür imzası değil" @@ -838,43 +843,43 @@ msgid "Signature header with signature “%s” found but message body is empty" msgstr "“%s” imzalı bir imza başlığı bulundu ama ileti gövdesi boş" -#: gio/gdbusmessage.c:2158 +#: gio/gdbusmessage.c:2159 #, c-format msgid "Parsed value “%s” is not a valid D-Bus signature (for body)" msgstr "Ayrıştırılan değer “%s” geçerli bir D-Bus imzası değil (gövde için)" -#: gio/gdbusmessage.c:2188 +#: gio/gdbusmessage.c:2190 #, c-format msgid "No signature header in message but the message body is %u byte" msgid_plural "No signature header in message but the message body is %u bytes" msgstr[0] "İletide imza başlığı yok fakat ileti gövdesi %u bayt" -#: gio/gdbusmessage.c:2198 +#: gio/gdbusmessage.c:2200 msgid "Cannot deserialize message: " msgstr "İleti geri dönüştürülemiyor: " -#: gio/gdbusmessage.c:2539 +#: gio/gdbusmessage.c:2541 #, c-format msgid "" "Error serializing GVariant with type string “%s” to the D-Bus wire format" msgstr "GVariant, D-Bus tel biçimine “%s” dizge türüyle dönüştürülürken hata" -#: gio/gdbusmessage.c:2676 +#: gio/gdbusmessage.c:2678 #, c-format msgid "" "Number of file descriptors in message (%d) differs from header field (%d)" msgstr "İletideki dosya açıklayıcı sayısı (%d) başlık alanından (%d) farklı" -#: gio/gdbusmessage.c:2684 +#: gio/gdbusmessage.c:2686 msgid "Cannot serialize message: " msgstr "İleti dönüştürülemiyor: " -#: gio/gdbusmessage.c:2738 +#: gio/gdbusmessage.c:2739 #, c-format msgid "Message body has signature “%s” but there is no signature header" msgstr "İleti gövdesi “%s” imzasına sahip fakat imza başlığı yok" -#: gio/gdbusmessage.c:2748 +#: gio/gdbusmessage.c:2749 #, c-format msgid "" "Message body has type signature “%s” but signature in the header field is " @@ -882,45 +887,42 @@ msgstr "" "İleti gövdesi “%s” tür imzasına sahip fakat başlık alanındaki imza “%s”" -#: gio/gdbusmessage.c:2764 +#: gio/gdbusmessage.c:2765 #, c-format msgid "Message body is empty but signature in the header field is “(%s)”" msgstr "İleti gövdesi boş, fakat başlık alanındaki imza “(%s)”" -#: gio/gdbusmessage.c:3317 +#: gio/gdbusmessage.c:3318 #, c-format msgid "Error return with body of type “%s”" msgstr "“%s” türünden bir gövdeyle dönüş hatası" -#: gio/gdbusmessage.c:3325 +#: gio/gdbusmessage.c:3326 msgid "Error return with empty body" msgstr "Boş gövdeyle dönüş hatası" -#: gio/gdbusprivate.c:2066 +#: gio/gdbusprivate.c:2075 #, c-format msgid "Unable to get Hardware profile: %s" msgstr "Donanım profili alınamıyor: %s" -#: gio/gdbusprivate.c:2111 +#: gio/gdbusprivate.c:2120 msgid "Unable to load /var/lib/dbus/machine-id or /etc/machine-id: " msgstr "" "/var/lib/dbus/makine-kimliği veya /etc/makine-kimliği konumuna yüklenemiyor: " -#: gio/gdbusproxy.c:1612 +#: gio/gdbusproxy.c:1617 #, c-format msgid "Error calling StartServiceByName for %s: " msgstr "%s için StartServiceByName çağrısında hata: " -#: gio/gdbusproxy.c:1635 +#: gio/gdbusproxy.c:1640 #, c-format msgid "Unexpected reply %d from StartServiceByName(\"%s\") method" msgstr "StartServiceByName %d yönteminden beklenmeyen yanıt (\"%s\")" -#: gio/gdbusproxy.c:2734 gio/gdbusproxy.c:2869 +#: gio/gdbusproxy.c:2740 gio/gdbusproxy.c:2875 #, c-format -#| msgid "" -#| "Cannot invoke method; proxy is for a well-known name without an owner and " -#| "proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" msgid "" "Cannot invoke method; proxy is for the well-known name %s without an owner, " "and proxy was constructed with the G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START flag" @@ -1221,38 +1223,38 @@ msgid "Error: %s is not a valid well-known bus name.\n" msgstr "Hata: %s geçerli bilinen bir veri yolu adı değil\n" -#: gio/gdesktopappinfo.c:2023 gio/gdesktopappinfo.c:4660 +#: gio/gdesktopappinfo.c:2041 gio/gdesktopappinfo.c:4822 msgid "Unnamed" msgstr "Adlandırılmamış" -#: gio/gdesktopappinfo.c:2433 +#: gio/gdesktopappinfo.c:2451 msgid "Desktop file didn’t specify Exec field" msgstr "Desktop dosyası Exec alanı belirtmemiş" -#: gio/gdesktopappinfo.c:2692 +#: gio/gdesktopappinfo.c:2710 msgid "Unable to find terminal required for application" msgstr "Uygulama için gerekli uçbirim bulunamadı" -#: gio/gdesktopappinfo.c:3202 +#: gio/gdesktopappinfo.c:3362 #, c-format msgid "Can’t create user application configuration folder %s: %s" msgstr "Kullanıcı uygulaması yapılandırma klasörü %s oluşturulamıyor: %s" -#: gio/gdesktopappinfo.c:3206 +#: gio/gdesktopappinfo.c:3366 #, c-format msgid "Can’t create user MIME configuration folder %s: %s" msgstr "Kullanıcı MIME yapılandırma klasörü %s oluşturulamıyor: %s" -#: gio/gdesktopappinfo.c:3446 gio/gdesktopappinfo.c:3470 +#: gio/gdesktopappinfo.c:3606 gio/gdesktopappinfo.c:3630 msgid "Application information lacks an identifier" msgstr "Uygulama bilgisi bir tanımlayıcıya sahip değildir" -#: gio/gdesktopappinfo.c:3704 +#: gio/gdesktopappinfo.c:3864 #, c-format msgid "Can’t create user desktop file %s" msgstr "Kullanıcı masaüstü dosyası %s oluşturulamıyor" -#: gio/gdesktopappinfo.c:3838 +#: gio/gdesktopappinfo.c:3998 #, c-format msgid "Custom definition for %s" msgstr "%s için özel tanım" @@ -1318,7 +1320,7 @@ #: gio/gfile.c:2008 gio/gfile.c:2063 gio/gfile.c:3738 gio/gfile.c:3793 #: gio/gfile.c:4029 gio/gfile.c:4071 gio/gfile.c:4539 gio/gfile.c:4950 #: gio/gfile.c:5035 gio/gfile.c:5125 gio/gfile.c:5222 gio/gfile.c:5309 -#: gio/gfile.c:5410 gio/gfile.c:7988 gio/gfile.c:8078 gio/gfile.c:8162 +#: gio/gfile.c:5410 gio/gfile.c:8113 gio/gfile.c:8203 gio/gfile.c:8287 #: gio/win32/gwinhttpfile.c:437 msgid "Operation not supported" msgstr "İşlem desteklenmiyor" @@ -1331,7 +1333,7 @@ msgid "Containing mount does not exist" msgstr "Bağlama yok" -#: gio/gfile.c:2622 gio/glocalfile.c:2441 +#: gio/gfile.c:2622 gio/glocalfile.c:2446 msgid "Can’t copy over directory" msgstr "Dizin üzerine kopyalanamıyor" @@ -1391,7 +1393,7 @@ msgid "volume doesn’t implement mount" msgstr "bölüm, bağlamayı yerine getirmiyor" -#: gio/gfile.c:6882 +#: gio/gfile.c:6884 gio/gfile.c:6930 msgid "No application is registered as handling this file" msgstr "Bu dosyayı işlemek için hiçbir uygulama kayıtlı değil" @@ -1436,8 +1438,8 @@ msgid "Truncate not supported on stream" msgstr "Akış üzerinde sonunun kesilmesi desteklenmiyor" -#: gio/ghttpproxy.c:91 gio/gresolver.c:410 gio/gresolver.c:476 -#: glib/gconvert.c:1787 +#: gio/ghttpproxy.c:91 gio/gresolver.c:377 gio/gresolver.c:529 +#: glib/gconvert.c:1785 msgid "Invalid hostname" msgstr "Geçersiz makine adı" @@ -1464,7 +1466,7 @@ #: gio/ghttpproxy.c:269 msgid "HTTP proxy server closed connection unexpectedly." -msgstr "HTTP vekil sunucusu bağlantıyı beklenmedik şekilde kesti." +msgstr "HTTP vekil sunucusu bağlantıyı beklenmedik biçimde kesti." #: gio/gicon.c:298 #, c-format @@ -1537,7 +1539,7 @@ #. Translators: This is an error you get if there is #. * already an operation running against this stream when #. * you try to start one -#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:1671 +#: gio/ginputstream.c:1218 gio/giostream.c:310 gio/goutputstream.c:2208 msgid "Stream has outstanding operation" msgstr "Akışın sıradışı işlemi var" @@ -1642,7 +1644,7 @@ #: gio/gio-tool-cat.c:133 gio/gio-tool-info.c:282 gio/gio-tool-list.c:165 #: gio/gio-tool-mkdir.c:48 gio/gio-tool-monitor.c:37 gio/gio-tool-monitor.c:39 #: gio/gio-tool-monitor.c:41 gio/gio-tool-monitor.c:43 -#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:113 +#: gio/gio-tool-monitor.c:203 gio/gio-tool-mount.c:1212 gio/gio-tool-open.c:70 #: gio/gio-tool-remove.c:48 gio/gio-tool-rename.c:45 gio/gio-tool-set.c:89 #: gio/gio-tool-trash.c:81 gio/gio-tool-tree.c:239 msgid "LOCATION" @@ -1663,7 +1665,7 @@ "gibi bir şeyi konum olarak kullanabilirsiniz." #: gio/gio-tool-cat.c:162 gio/gio-tool-info.c:313 gio/gio-tool-mkdir.c:76 -#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:139 +#: gio/gio-tool-monitor.c:228 gio/gio-tool-mount.c:1263 gio/gio-tool-open.c:96 #: gio/gio-tool-remove.c:72 gio/gio-tool-trash.c:136 msgid "No locations given" msgstr "Konum verilmedi" @@ -2070,7 +2072,7 @@ msgid "Target %s is not a directory" msgstr "%s hedefi bir dizin değil" -#: gio/gio-tool-open.c:118 +#: gio/gio-tool-open.c:75 msgid "" "Open files with the default application that\n" "is registered to handle files of this type." @@ -2262,66 +2264,74 @@ msgid "text may not appear inside <%s>" msgstr "<%s> içinde metin bulunamaz" -#: gio/glib-compile-resources.c:736 gio/glib-compile-schemas.c:2139 +#: gio/glib-compile-resources.c:737 gio/glib-compile-schemas.c:2139 msgid "Show program version and exit" msgstr "Programın sürümünü göster ve çık" -#: gio/glib-compile-resources.c:737 +#: gio/glib-compile-resources.c:738 msgid "Name of the output file" msgstr "Çıktı dosyasının adı" -#: gio/glib-compile-resources.c:738 +#: gio/glib-compile-resources.c:739 msgid "" "The directories to load files referenced in FILE from (default: current " "directory)" msgstr "" "FILEʼda belirtilen dosyaların yükleneceği dizinler (öntanımlı: geçerli dizin)" -#: gio/glib-compile-resources.c:738 gio/glib-compile-schemas.c:2140 +#: gio/glib-compile-resources.c:739 gio/glib-compile-schemas.c:2140 #: gio/glib-compile-schemas.c:2169 msgid "DIRECTORY" msgstr "DİZİN" -#: gio/glib-compile-resources.c:739 +#: gio/glib-compile-resources.c:740 msgid "" "Generate output in the format selected for by the target filename extension" msgstr "Hedef dosya adı uzantısı tarafından seçilen biçimde çıktı oluştur" -#: gio/glib-compile-resources.c:740 +#: gio/glib-compile-resources.c:741 msgid "Generate source header" msgstr "Kaynak başlığı oluştur" -#: gio/glib-compile-resources.c:741 +#: gio/glib-compile-resources.c:742 msgid "Generate source code used to link in the resource file into your code" msgstr "" "Kodunuz içinde kaynak dosyasına bağlanmak için kullanılacak kaynak kodu " "oluşturun" -#: gio/glib-compile-resources.c:742 +#: gio/glib-compile-resources.c:743 msgid "Generate dependency list" msgstr "Bağımlılık listesi oluştur" -#: gio/glib-compile-resources.c:743 +#: gio/glib-compile-resources.c:744 msgid "Name of the dependency file to generate" msgstr "Oluşturulacak bağımlılık dosyasının adı" -#: gio/glib-compile-resources.c:744 +#: gio/glib-compile-resources.c:745 msgid "Include phony targets in the generated dependency file" msgstr "Oluşturulan bağımlılık dosyasında sahte hedefleri içer" -#: gio/glib-compile-resources.c:745 +#: gio/glib-compile-resources.c:746 msgid "Don’t automatically create and register resource" msgstr "Kaynağı kendiliğinden oluşturma ve kaydetme" -#: gio/glib-compile-resources.c:746 +#: gio/glib-compile-resources.c:747 msgid "Don’t export functions; declare them G_GNUC_INTERNAL" msgstr "İşlevleri dışarı aktarma; onları G_GNUC_INTERNAL beyan et" -#: gio/glib-compile-resources.c:747 +#: gio/glib-compile-resources.c:748 +msgid "" +"Don’t embed resource data in the C file; assume it's linked externally " +"instead" +msgstr "" +"Kaynak verileri C dosyasına gömme; bunun yerine harici olarak bağlandığını " +"varsay" + +#: gio/glib-compile-resources.c:749 msgid "C identifier name used for the generated source code" msgstr "C oluşturulan kaynak kod için kullanılan tanımlayıcı ad" -#: gio/glib-compile-resources.c:773 +#: gio/glib-compile-resources.c:775 msgid "" "Compile a resource specification into a resource file.\n" "Resource specification files have the extension .gresource.xml,\n" @@ -2331,7 +2341,7 @@ "Kaynak özellikleri dosyaları .gresource.xml uzantısına sahiptir\n" "ve kaynak dosyaları uzantısı .gresource." -#: gio/glib-compile-resources.c:795 +#: gio/glib-compile-resources.c:797 msgid "You should give exactly one file name\n" msgstr "Tam olarak bir adet dosya adı vermelisiniz\n" @@ -2790,12 +2800,12 @@ msgid "removed existing output file.\n" msgstr "var olan çıktı dosyası silindi.\n" -#: gio/glocalfile.c:544 gio/win32/gwinhttpfile.c:420 +#: gio/glocalfile.c:546 gio/win32/gwinhttpfile.c:420 #, c-format msgid "Invalid filename %s" msgstr "Geçersiz dosya adı %s" -#: gio/glocalfile.c:1011 +#: gio/glocalfile.c:1013 #, c-format msgid "Error getting filesystem info for %s: %s" msgstr "%s için dosya sistemi bilgisi alınırken hata: %s" @@ -2804,128 +2814,128 @@ #. * the enclosing (user visible) mount of a file, but none #. * exists. #. -#: gio/glocalfile.c:1150 +#: gio/glocalfile.c:1152 #, c-format msgid "Containing mount for file %s not found" msgstr "%s dosyası için bağlama bulunamadı" -#: gio/glocalfile.c:1173 +#: gio/glocalfile.c:1175 msgid "Can’t rename root directory" msgstr "Kök dizini yeniden adlandırılamaz" -#: gio/glocalfile.c:1191 gio/glocalfile.c:1214 +#: gio/glocalfile.c:1193 gio/glocalfile.c:1216 #, c-format msgid "Error renaming file %s: %s" msgstr "%s dosyası yeniden adlandırılırken hata: %s" -#: gio/glocalfile.c:1198 +#: gio/glocalfile.c:1200 msgid "Can’t rename file, filename already exists" msgstr "Dosya yeniden adlandırılamıyor, dosya adı zaten var" -#: gio/glocalfile.c:1211 gio/glocalfile.c:2317 gio/glocalfile.c:2345 -#: gio/glocalfile.c:2502 gio/glocalfileoutputstream.c:551 +#: gio/glocalfile.c:1213 gio/glocalfile.c:2322 gio/glocalfile.c:2350 +#: gio/glocalfile.c:2507 gio/glocalfileoutputstream.c:646 msgid "Invalid filename" msgstr "Geçersiz dosya adı" -#: gio/glocalfile.c:1379 gio/glocalfile.c:1394 +#: gio/glocalfile.c:1381 gio/glocalfile.c:1396 #, c-format msgid "Error opening file %s: %s" msgstr "%s dosyası açılırken hata: %s" -#: gio/glocalfile.c:1519 +#: gio/glocalfile.c:1521 #, c-format msgid "Error removing file %s: %s" msgstr "%s dosyası silinirken hata: %s" -#: gio/glocalfile.c:1958 +#: gio/glocalfile.c:1963 #, c-format msgid "Error trashing file %s: %s" msgstr "%s dosyası çöpe atılırken hata: %s" -#: gio/glocalfile.c:1999 +#: gio/glocalfile.c:2004 #, c-format msgid "Unable to create trash dir %s: %s" msgstr "Çöp dizini %s oluşturulamıyor: %s" -#: gio/glocalfile.c:2020 +#: gio/glocalfile.c:2025 #, c-format msgid "Unable to find toplevel directory to trash %s" msgstr "%s çöpe atmak için en üst seviye dizin bulunamıyor" -#: gio/glocalfile.c:2029 +#: gio/glocalfile.c:2034 #, c-format msgid "Trashing on system internal mounts is not supported" msgstr "Sistem iç bağlarına çöpleme desteklenmiyor" -#: gio/glocalfile.c:2113 gio/glocalfile.c:2133 +#: gio/glocalfile.c:2118 gio/glocalfile.c:2138 #, c-format msgid "Unable to find or create trash directory for %s" msgstr "%s için çöp dizini bulunamıyor ya da oluşturulamıyor" -#: gio/glocalfile.c:2168 +#: gio/glocalfile.c:2173 #, c-format msgid "Unable to create trashing info file for %s: %s" msgstr "%s için çöp bilgi dosyası oluşturulamıyor: %s" -#: gio/glocalfile.c:2228 +#: gio/glocalfile.c:2233 #, c-format msgid "Unable to trash file %s across filesystem boundaries" msgstr "%s dosyası, dosya sistemi sınırları dışına, çöpe atılamıyor" -#: gio/glocalfile.c:2232 gio/glocalfile.c:2288 +#: gio/glocalfile.c:2237 gio/glocalfile.c:2293 #, c-format msgid "Unable to trash file %s: %s" msgstr "%s dosyası çöpe atılamıyor: %s" -#: gio/glocalfile.c:2294 +#: gio/glocalfile.c:2299 #, c-format msgid "Unable to trash file %s" msgstr "%s dosyası çöpe atılamıyor" -#: gio/glocalfile.c:2320 +#: gio/glocalfile.c:2325 #, c-format msgid "Error creating directory %s: %s" msgstr "%s dizini oluşturulurken hata: %s" -#: gio/glocalfile.c:2349 +#: gio/glocalfile.c:2354 #, c-format msgid "Filesystem does not support symbolic links" msgstr "Dosya sistemi simgesel bağları desteklemiyor" -#: gio/glocalfile.c:2352 +#: gio/glocalfile.c:2357 #, c-format msgid "Error making symbolic link %s: %s" msgstr "%s simgesel bağlantısı yapılırken hata: %s" -#: gio/glocalfile.c:2358 glib/gfileutils.c:2138 +#: gio/glocalfile.c:2363 glib/gfileutils.c:2138 msgid "Symbolic links not supported" msgstr "Simgesel bağlar desteklenmiyor" -#: gio/glocalfile.c:2413 gio/glocalfile.c:2448 gio/glocalfile.c:2505 +#: gio/glocalfile.c:2418 gio/glocalfile.c:2453 gio/glocalfile.c:2510 #, c-format msgid "Error moving file %s: %s" msgstr "%s dosyası taşınırken hata: %s" -#: gio/glocalfile.c:2436 +#: gio/glocalfile.c:2441 msgid "Can’t move directory over directory" msgstr "Dizin dizin üzerine taşınamıyor" -#: gio/glocalfile.c:2462 gio/glocalfileoutputstream.c:935 -#: gio/glocalfileoutputstream.c:949 gio/glocalfileoutputstream.c:964 -#: gio/glocalfileoutputstream.c:981 gio/glocalfileoutputstream.c:995 +#: gio/glocalfile.c:2467 gio/glocalfileoutputstream.c:1030 +#: gio/glocalfileoutputstream.c:1044 gio/glocalfileoutputstream.c:1059 +#: gio/glocalfileoutputstream.c:1076 gio/glocalfileoutputstream.c:1090 msgid "Backup file creation failed" msgstr "Yedek dosyası oluşturma başarısız oldu" -#: gio/glocalfile.c:2481 +#: gio/glocalfile.c:2486 #, c-format msgid "Error removing target file: %s" msgstr "Hedef dosya silerken hata: %s" -#: gio/glocalfile.c:2495 +#: gio/glocalfile.c:2500 msgid "Move between mounts not supported" msgstr "Bağlı sistemler arasında taşıma desteklenmiyor" -#: gio/glocalfile.c:2686 +#: gio/glocalfile.c:2691 #, c-format msgid "Could not determine the disk usage of %s: %s" msgstr "%s’in disk kullanımı saptanamadı: %s" @@ -2951,7 +2961,7 @@ msgid " (invalid encoding)" msgstr " (geçersiz kodlama)" -#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:813 +#: gio/glocalfileinfo.c:1789 gio/glocalfileoutputstream.c:908 #, c-format msgid "Error when getting information for file “%s”: %s" msgstr "“%s” dosyası için bilgi alınırken hata: %s" @@ -3024,20 +3034,20 @@ msgid "Setting attribute %s not supported" msgstr "Öznitelik %s ataması desteklenmiyor" -#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:696 +#: gio/glocalfileinputstream.c:168 gio/glocalfileoutputstream.c:791 #, c-format msgid "Error reading from file: %s" msgstr "Dosyadan okunurken hata: %s" #: gio/glocalfileinputstream.c:199 gio/glocalfileinputstream.c:211 #: gio/glocalfileinputstream.c:225 gio/glocalfileinputstream.c:333 -#: gio/glocalfileoutputstream.c:458 gio/glocalfileoutputstream.c:1013 +#: gio/glocalfileoutputstream.c:553 gio/glocalfileoutputstream.c:1108 #, c-format msgid "Error seeking in file: %s" msgstr "Dosya içinde atlama yapılırken hata: %s" -#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:248 -#: gio/glocalfileoutputstream.c:342 +#: gio/glocalfileinputstream.c:255 gio/glocalfileoutputstream.c:343 +#: gio/glocalfileoutputstream.c:437 #, c-format msgid "Error closing file: %s" msgstr "Dosya kapatılırken hata: %s" @@ -3046,51 +3056,51 @@ msgid "Unable to find default local file monitor type" msgstr "Öntanımlı yerel dosya izleme türü bulunamadı" -#: gio/glocalfileoutputstream.c:196 gio/glocalfileoutputstream.c:228 -#: gio/glocalfileoutputstream.c:717 +#: gio/glocalfileoutputstream.c:208 gio/glocalfileoutputstream.c:286 +#: gio/glocalfileoutputstream.c:323 gio/glocalfileoutputstream.c:812 #, c-format msgid "Error writing to file: %s" msgstr "Dosyaya yazılırken hata: %s" -#: gio/glocalfileoutputstream.c:275 +#: gio/glocalfileoutputstream.c:370 #, c-format msgid "Error removing old backup link: %s" msgstr "Eski yedek bağı silinirken hata: %s" -#: gio/glocalfileoutputstream.c:289 gio/glocalfileoutputstream.c:302 +#: gio/glocalfileoutputstream.c:384 gio/glocalfileoutputstream.c:397 #, c-format msgid "Error creating backup copy: %s" msgstr "Yedek kopyası oluşturulurken hata: %s" -#: gio/glocalfileoutputstream.c:320 +#: gio/glocalfileoutputstream.c:415 #, c-format msgid "Error renaming temporary file: %s" msgstr "Geçici dosya yeniden adlandırılırken hata: %s" -#: gio/glocalfileoutputstream.c:504 gio/glocalfileoutputstream.c:1064 +#: gio/glocalfileoutputstream.c:599 gio/glocalfileoutputstream.c:1159 #, c-format msgid "Error truncating file: %s" msgstr "Dosyanın sonu kesilirken hata: %s" -#: gio/glocalfileoutputstream.c:557 gio/glocalfileoutputstream.c:795 -#: gio/glocalfileoutputstream.c:1045 gio/gsubprocess.c:380 +#: gio/glocalfileoutputstream.c:652 gio/glocalfileoutputstream.c:890 +#: gio/glocalfileoutputstream.c:1140 gio/gsubprocess.c:380 #, c-format msgid "Error opening file “%s”: %s" msgstr "“%s” dosyası açılırken hata: %s" -#: gio/glocalfileoutputstream.c:826 +#: gio/glocalfileoutputstream.c:921 msgid "Target file is a directory" msgstr "Hedef dosya bir dizin" -#: gio/glocalfileoutputstream.c:831 +#: gio/glocalfileoutputstream.c:926 msgid "Target file is not a regular file" msgstr "Hedef dosya normal dosya değil" -#: gio/glocalfileoutputstream.c:843 +#: gio/glocalfileoutputstream.c:938 msgid "The file was externally modified" msgstr "Dosya dışarıdan değiştirilmiş" -#: gio/glocalfileoutputstream.c:1029 +#: gio/glocalfileoutputstream.c:1124 #, c-format msgid "Error removing old file: %s" msgstr "Eski dosya silinirken hata: %s" @@ -3182,7 +3192,7 @@ msgid "mount doesn’t implement synchronous content type guessing" msgstr "bağlama, eş zamanlı içerik türü tahminini yerine getirmiyor" -#: gio/gnetworkaddress.c:378 +#: gio/gnetworkaddress.c:388 #, c-format msgid "Hostname “%s” contains “[” but not “]”" msgstr "“%s” ana makine adı “[” içeriyor ama “]” içermiyor" @@ -3211,7 +3221,6 @@ #: gio/gnetworkmonitornm.c:313 #, c-format -#| msgid "NetworkManager version too old" msgid "NetworkManager not running" msgstr "NetworkManager çalışmıyor" @@ -3220,32 +3229,43 @@ msgid "NetworkManager version too old" msgstr "NetworkManager sürümü çok eski" -#: gio/goutputstream.c:212 gio/goutputstream.c:560 +#: gio/goutputstream.c:232 gio/goutputstream.c:775 msgid "Output stream doesn’t implement write" msgstr "Çıktı akışı yazmayı yerine getirmiyor" -#: gio/goutputstream.c:521 gio/goutputstream.c:1224 +#: gio/goutputstream.c:472 gio/goutputstream.c:1533 +#, c-format +msgid "Sum of vectors passed to %s too large" +msgstr "%s için geçilen vektörlerin toplamı çok büyük" + +#: gio/goutputstream.c:736 gio/goutputstream.c:1761 msgid "Source stream is already closed" msgstr "Kaynak akışı zaten kapalı" -#: gio/gresolver.c:342 gio/gthreadedresolver.c:116 gio/gthreadedresolver.c:126 +#: gio/gresolver.c:344 gio/gthreadedresolver.c:150 gio/gthreadedresolver.c:160 #, c-format msgid "Error resolving “%s”: %s" msgstr "“%s” çözülürken hata: %s" -#: gio/gresolver.c:729 gio/gresolver.c:781 +#. Translators: The placeholder is for a function name. +#: gio/gresolver.c:389 gio/gresolver.c:547 +#, c-format +msgid "%s not implemented" +msgstr "%s uygulanmadı" + +#: gio/gresolver.c:915 gio/gresolver.c:967 msgid "Invalid domain" msgstr "Geçersiz alan adı" -#: gio/gresource.c:644 gio/gresource.c:903 gio/gresource.c:942 -#: gio/gresource.c:1066 gio/gresource.c:1138 gio/gresource.c:1211 -#: gio/gresource.c:1281 gio/gresourcefile.c:476 gio/gresourcefile.c:599 +#: gio/gresource.c:665 gio/gresource.c:924 gio/gresource.c:963 +#: gio/gresource.c:1087 gio/gresource.c:1159 gio/gresource.c:1232 +#: gio/gresource.c:1313 gio/gresourcefile.c:476 gio/gresourcefile.c:599 #: gio/gresourcefile.c:736 #, c-format msgid "The resource at “%s” does not exist" msgstr "“%s” konumundaki kaynak yok" -#: gio/gresource.c:809 +#: gio/gresource.c:830 #, c-format msgid "The resource at “%s” failed to decompress" msgstr "“%s” konumundaki kaynak açılamadı" @@ -3446,7 +3466,7 @@ "List keys and values, recursively\n" "If no SCHEMA is given, list all keys\n" msgstr "" -"Yinelemeli bir şekilde anahtar ve değerleri listele\n" +"Özyinelemeli biçimde anahtar ve değerleri listele\n" "Eğer hiçbir ŞEMA verilmediyse, tüm anahtarları listele\n" #: gio/gsettings-tool.c:607 @@ -3609,143 +3629,143 @@ msgid "No such key “%s”\n" msgstr "“%s” gibi bir anahtar yok\n" -#: gio/gsocket.c:384 +#: gio/gsocket.c:373 msgid "Invalid socket, not initialized" msgstr "Geçersiz soket, başlatılmamış" -#: gio/gsocket.c:391 +#: gio/gsocket.c:380 #, c-format msgid "Invalid socket, initialization failed due to: %s" msgstr "Geçersiz soket, başlatma başarısız oldu: %s" -#: gio/gsocket.c:399 +#: gio/gsocket.c:388 msgid "Socket is already closed" msgstr "Soket zaten kapalı" -#: gio/gsocket.c:414 gio/gsocket.c:3034 gio/gsocket.c:4244 gio/gsocket.c:4302 +#: gio/gsocket.c:403 gio/gsocket.c:3027 gio/gsocket.c:4244 gio/gsocket.c:4302 msgid "Socket I/O timed out" msgstr "Soket Girdi/Çıktı zaman aşımı" -#: gio/gsocket.c:549 +#: gio/gsocket.c:538 #, c-format msgid "creating GSocket from fd: %s" msgstr "fd’den GSocket oluşturuluyor: %s" -#: gio/gsocket.c:578 gio/gsocket.c:632 gio/gsocket.c:639 +#: gio/gsocket.c:567 gio/gsocket.c:621 gio/gsocket.c:628 #, c-format msgid "Unable to create socket: %s" msgstr "Soket oluşturulamadı: %s" -#: gio/gsocket.c:632 +#: gio/gsocket.c:621 msgid "Unknown family was specified" msgstr "Bilinmeyen grup belirtildi" -#: gio/gsocket.c:639 +#: gio/gsocket.c:628 msgid "Unknown protocol was specified" msgstr "Bilinmeyen iletişim kuralı belirtildi" -#: gio/gsocket.c:1130 +#: gio/gsocket.c:1119 #, c-format msgid "Cannot use datagram operations on a non-datagram socket." msgstr "Datagram olmayan bir yuva üzerinde datagram işlemleri kullanılamaz." -#: gio/gsocket.c:1147 +#: gio/gsocket.c:1136 #, c-format msgid "Cannot use datagram operations on a socket with a timeout set." msgstr "" "Zamanaşımı ayarlanmış bir yuva üzerinde datagram işlemleri kullanılamaz." -#: gio/gsocket.c:1954 +#: gio/gsocket.c:1943 #, c-format msgid "could not get local address: %s" msgstr "yerel adres alınamadı: %s" -#: gio/gsocket.c:2000 +#: gio/gsocket.c:1989 #, c-format msgid "could not get remote address: %s" msgstr "uzaktaki adres alınamadı: %s" -#: gio/gsocket.c:2066 +#: gio/gsocket.c:2055 #, c-format msgid "could not listen: %s" msgstr "dinlenemedi: %s" -#: gio/gsocket.c:2168 +#: gio/gsocket.c:2157 #, c-format msgid "Error binding to address: %s" msgstr "Adrese bağlarken hata: %s" -#: gio/gsocket.c:2226 gio/gsocket.c:2263 gio/gsocket.c:2373 gio/gsocket.c:2398 -#: gio/gsocket.c:2471 gio/gsocket.c:2529 gio/gsocket.c:2547 +#: gio/gsocket.c:2215 gio/gsocket.c:2252 gio/gsocket.c:2362 gio/gsocket.c:2387 +#: gio/gsocket.c:2460 gio/gsocket.c:2518 gio/gsocket.c:2536 #, c-format msgid "Error joining multicast group: %s" msgstr "Çok yöne yayın grubuna katılırken hata: %s" -#: gio/gsocket.c:2227 gio/gsocket.c:2264 gio/gsocket.c:2374 gio/gsocket.c:2399 -#: gio/gsocket.c:2472 gio/gsocket.c:2530 gio/gsocket.c:2548 +#: gio/gsocket.c:2216 gio/gsocket.c:2253 gio/gsocket.c:2363 gio/gsocket.c:2388 +#: gio/gsocket.c:2461 gio/gsocket.c:2519 gio/gsocket.c:2537 #, c-format msgid "Error leaving multicast group: %s" msgstr "Çok yöne yayın grubundan ayrılırken hata: %s" -#: gio/gsocket.c:2228 +#: gio/gsocket.c:2217 msgid "No support for source-specific multicast" msgstr "Kaynağa-özgü çok yöne yayın desteklenmiyor" -#: gio/gsocket.c:2375 +#: gio/gsocket.c:2364 msgid "Unsupported socket family" msgstr "Desteklenmeyen soket ailesi" -#: gio/gsocket.c:2400 +#: gio/gsocket.c:2389 msgid "source-specific not an IPv4 address" msgstr "kaynağa-özgü bir IPv4 adresi değil" -#: gio/gsocket.c:2418 gio/gsocket.c:2447 gio/gsocket.c:2497 +#: gio/gsocket.c:2407 gio/gsocket.c:2436 gio/gsocket.c:2486 #, c-format msgid "Interface not found: %s" msgstr "Arayüz bulunamadı: %s" -#: gio/gsocket.c:2434 +#: gio/gsocket.c:2423 #, c-format msgid "Interface name too long" msgstr "Arayüz adı çok uzun" -#: gio/gsocket.c:2473 +#: gio/gsocket.c:2462 msgid "No support for IPv4 source-specific multicast" msgstr "IPv4 kaynağa-özgü çok yöne yayın desteklenmiyor" -#: gio/gsocket.c:2531 +#: gio/gsocket.c:2520 msgid "No support for IPv6 source-specific multicast" msgstr "IPv6 kaynağa-özgü çok yöne yayın desteklenmiyor" -#: gio/gsocket.c:2740 +#: gio/gsocket.c:2729 #, c-format msgid "Error accepting connection: %s" msgstr "Bağlantı kabul edilirken hata: %s" -#: gio/gsocket.c:2864 +#: gio/gsocket.c:2855 msgid "Connection in progress" msgstr "Bağlantı devam ediyor" -#: gio/gsocket.c:2913 +#: gio/gsocket.c:2906 msgid "Unable to get pending error: " msgstr "Bekleyen hata alınamadı: " -#: gio/gsocket.c:3097 +#: gio/gsocket.c:3092 #, c-format msgid "Error receiving data: %s" msgstr "Veri alırken hata: %s" -#: gio/gsocket.c:3292 +#: gio/gsocket.c:3289 #, c-format msgid "Error sending data: %s" msgstr "Veri gönderirken hata: %s" -#: gio/gsocket.c:3479 +#: gio/gsocket.c:3476 #, c-format msgid "Unable to shutdown socket: %s" msgstr "Soket kapatılamadı: %s" -#: gio/gsocket.c:3560 +#: gio/gsocket.c:3557 #, c-format msgid "Error closing socket: %s" msgstr "Soket kapatılırken hata: %s" @@ -3755,52 +3775,53 @@ msgid "Waiting for socket condition: %s" msgstr "Soket durumu bekleniyor: %s" -#: gio/gsocket.c:4711 gio/gsocket.c:4791 gio/gsocket.c:4969 +#: gio/gsocket.c:4614 gio/gsocket.c:4616 gio/gsocket.c:4762 gio/gsocket.c:4847 +#: gio/gsocket.c:5027 gio/gsocket.c:5067 gio/gsocket.c:5069 #, c-format msgid "Error sending message: %s" msgstr "İleti gönderme hatası: %s" -#: gio/gsocket.c:4735 +#: gio/gsocket.c:4789 msgid "GSocketControlMessage not supported on Windows" msgstr "GSocketControlMessage Windows işletim sisteminde desteklenmiyor" -#: gio/gsocket.c:5188 gio/gsocket.c:5261 gio/gsocket.c:5487 +#: gio/gsocket.c:5260 gio/gsocket.c:5333 gio/gsocket.c:5560 #, c-format msgid "Error receiving message: %s" msgstr "İleti alma hatası: %s" -#: gio/gsocket.c:5759 +#: gio/gsocket.c:5832 #, c-format msgid "Unable to read socket credentials: %s" msgstr "Soket kimliği okunamadı : %s" -#: gio/gsocket.c:5768 +#: gio/gsocket.c:5841 msgid "g_socket_get_credentials not implemented for this OS" msgstr "bu işletim sistemi için g_socket_get_credentials uygulanmadı" -#: gio/gsocketclient.c:176 +#: gio/gsocketclient.c:181 #, c-format msgid "Could not connect to proxy server %s: " msgstr "%s vekil sunucusuna bağlanılamadı: " -#: gio/gsocketclient.c:190 +#: gio/gsocketclient.c:195 #, c-format msgid "Could not connect to %s: " msgstr "%s bağlantısı gerçekleştirilemedi: " -#: gio/gsocketclient.c:192 +#: gio/gsocketclient.c:197 msgid "Could not connect: " msgstr "Bağlanılamadı: " -#: gio/gsocketclient.c:1027 gio/gsocketclient.c:1599 +#: gio/gsocketclient.c:1032 gio/gsocketclient.c:1731 msgid "Unknown error on connect" msgstr "Bağlanırken bilinmeyen bir hata" -#: gio/gsocketclient.c:1081 gio/gsocketclient.c:1535 +#: gio/gsocketclient.c:1086 gio/gsocketclient.c:1640 msgid "Proxying over a non-TCP connection is not supported." msgstr "TCP olmayan bağlantılar üzerinden vekil sunucusu desteklenmiyor." -#: gio/gsocketclient.c:1110 gio/gsocketclient.c:1561 +#: gio/gsocketclient.c:1115 gio/gsocketclient.c:1666 #, c-format msgid "Proxy protocol “%s” is not supported." msgstr "“%s” vekil iletişim kuralı desteklenmiyor." @@ -3907,49 +3928,49 @@ msgid "Can’t handle version %d of GThemedIcon encoding" msgstr "GThemedIcon kodlaması %d sürümü işlenemiyor" -#: gio/gthreadedresolver.c:118 +#: gio/gthreadedresolver.c:152 msgid "No valid addresses were found" msgstr "Geçersiz adresler bulundu" -#: gio/gthreadedresolver.c:213 +#: gio/gthreadedresolver.c:317 #, c-format msgid "Error reverse-resolving “%s”: %s" msgstr "“%s” tersine çözülürken hata: %s" -#: gio/gthreadedresolver.c:549 gio/gthreadedresolver.c:628 -#: gio/gthreadedresolver.c:726 gio/gthreadedresolver.c:776 +#: gio/gthreadedresolver.c:653 gio/gthreadedresolver.c:732 +#: gio/gthreadedresolver.c:830 gio/gthreadedresolver.c:880 #, c-format msgid "No DNS record of the requested type for “%s”" -msgstr "“%s” için talep edilen türün DNS kaydı yok" +msgstr "“%s” için istenen türün DNS kaydı yok" -#: gio/gthreadedresolver.c:554 gio/gthreadedresolver.c:731 +#: gio/gthreadedresolver.c:658 gio/gthreadedresolver.c:835 #, c-format msgid "Temporarily unable to resolve “%s”" msgstr "Geçici olarak “%s” çözülemiyor" -#: gio/gthreadedresolver.c:559 gio/gthreadedresolver.c:736 -#: gio/gthreadedresolver.c:844 +#: gio/gthreadedresolver.c:663 gio/gthreadedresolver.c:840 +#: gio/gthreadedresolver.c:948 #, c-format msgid "Error resolving “%s”" msgstr "“%s” çözerken hata" -#: gio/gtlscertificate.c:250 -msgid "Cannot decrypt PEM-encoded private key" -msgstr "PEM-kodlamalı özel anahtar şifresi çözülemiyor" - -#: gio/gtlscertificate.c:255 +#: gio/gtlscertificate.c:243 msgid "No PEM-encoded private key found" msgstr "Hiçbir PEM-kodlamalı özel anahtar bulunamadı" -#: gio/gtlscertificate.c:265 +#: gio/gtlscertificate.c:253 +msgid "Cannot decrypt PEM-encoded private key" +msgstr "PEM-kodlamalı özel anahtar şifresi çözülemiyor" + +#: gio/gtlscertificate.c:264 msgid "Could not parse PEM-encoded private key" msgstr "PEM-kodlamalı özel anahtar ayrıştırılamadı" -#: gio/gtlscertificate.c:290 +#: gio/gtlscertificate.c:291 msgid "No PEM-encoded certificate found" msgstr "PEM-kodlamalı sertifika bulunamadı" -#: gio/gtlscertificate.c:299 +#: gio/gtlscertificate.c:300 msgid "Could not parse PEM-encoded certificate" msgstr "PEM-kodlamalı sertifika ayrıştırılamadı" @@ -4029,17 +4050,19 @@ msgid "Error reading from file descriptor: %s" msgstr "Dosya tanımlayıcıdan okuma hatası: %s" -#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:411 +#: gio/gunixinputstream.c:426 gio/gunixoutputstream.c:534 #: gio/gwin32inputstream.c:217 gio/gwin32outputstream.c:204 #, c-format msgid "Error closing file descriptor: %s" msgstr "Dosya tanımlayıcı kapatılırken hata: %s" -#: gio/gunixmounts.c:2651 gio/gunixmounts.c:2704 +#: gio/gunixmounts.c:2650 gio/gunixmounts.c:2703 msgid "Filesystem root" msgstr "Dosya sistemi kök dizini" -#: gio/gunixoutputstream.c:358 gio/gunixoutputstream.c:378 +#: gio/gunixoutputstream.c:371 gio/gunixoutputstream.c:391 +#: gio/gunixoutputstream.c:478 gio/gunixoutputstream.c:498 +#: gio/gunixoutputstream.c:675 #, c-format msgid "Error writing to file descriptor: %s" msgstr "Dosya tanımlayıcıya yazmada hata: %s" @@ -4185,79 +4208,79 @@ msgid "Failed to expand exec line “%s” with URI “%s”" msgstr "Exec satırı “%s”, “%s” URI’si ile genişletilirken başarısız olundu" -#: glib/gconvert.c:473 +#: glib/gconvert.c:474 msgid "Unrepresentable character in conversion input" msgstr "Dönüşüm girdisi içinde temsil edilemez karakter" -#: glib/gconvert.c:500 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 +#: glib/gconvert.c:501 glib/gutf8.c:865 glib/gutf8.c:1077 glib/gutf8.c:1214 #: glib/gutf8.c:1318 msgid "Partial character sequence at end of input" msgstr "Girdinin sonunda parçalı karakter dizisi" -#: glib/gconvert.c:769 +#: glib/gconvert.c:770 #, c-format msgid "Cannot convert fallback “%s” to codeset “%s”" msgstr "" "Geridönüş karakter kümesi “%s”, “%s” karakter kümesine dönüştürülemiyor" -#: glib/gconvert.c:941 +#: glib/gconvert.c:942 msgid "Embedded NUL byte in conversion input" msgstr "Dönüşüm girdisinde gömülü NUL baytı" -#: glib/gconvert.c:962 +#: glib/gconvert.c:963 msgid "Embedded NUL byte in conversion output" msgstr "Dönüşüm çıktısında gömülü NUL baytı" -#: glib/gconvert.c:1650 +#: glib/gconvert.c:1648 #, c-format msgid "The URI “%s” is not an absolute URI using the “file” scheme" msgstr "“%s” URI’si, “file” şemasını kullanan kesin bir URI değil" -#: glib/gconvert.c:1660 +#: glib/gconvert.c:1658 #, c-format msgid "The local file URI “%s” may not include a “#”" msgstr "Yerel dosya URI’si “%s”, “#” içeremez" -#: glib/gconvert.c:1677 +#: glib/gconvert.c:1675 #, c-format msgid "The URI “%s” is invalid" msgstr "“%s” URI’si geçersiz" -#: glib/gconvert.c:1689 +#: glib/gconvert.c:1687 #, c-format msgid "The hostname of the URI “%s” is invalid" msgstr "“%s” URI’sinin ana makine adı geçersiz" -#: glib/gconvert.c:1705 +#: glib/gconvert.c:1703 #, c-format msgid "The URI “%s” contains invalidly escaped characters" msgstr "“%s” URI’si geçersiz olarak çıkış yapılmış karakterler içeriyor" -#: glib/gconvert.c:1777 +#: glib/gconvert.c:1775 #, c-format msgid "The pathname “%s” is not an absolute path" msgstr "Yol adı “%s”, kesin bir yol değil" #. Translators: this is the preferred format for expressing the date and the time -#: glib/gdatetime.c:213 +#: glib/gdatetime.c:214 msgctxt "GDateTime" msgid "%a %b %e %H:%M:%S %Y" msgstr "%a %d %b %Y %T %Z" #. Translators: this is the preferred format for expressing the date -#: glib/gdatetime.c:216 +#: glib/gdatetime.c:217 msgctxt "GDateTime" msgid "%m/%d/%y" msgstr "%d/%m/%y" #. Translators: this is the preferred format for expressing the time -#: glib/gdatetime.c:219 +#: glib/gdatetime.c:220 msgctxt "GDateTime" msgid "%H:%M:%S" msgstr "%H:%M:%S" #. Translators: this is the preferred format for expressing 12 hour time -#: glib/gdatetime.c:222 +#: glib/gdatetime.c:223 msgctxt "GDateTime" msgid "%I:%M:%S %p" msgstr "%I:%M:%S %p" @@ -4278,62 +4301,62 @@ #. * non-European) there is no difference between the standalone and #. * complete date form. #. -#: glib/gdatetime.c:261 +#: glib/gdatetime.c:262 msgctxt "full month name" msgid "January" msgstr "Ocak" -#: glib/gdatetime.c:263 +#: glib/gdatetime.c:264 msgctxt "full month name" msgid "February" msgstr "Şubat" -#: glib/gdatetime.c:265 +#: glib/gdatetime.c:266 msgctxt "full month name" msgid "March" msgstr "Mart" -#: glib/gdatetime.c:267 +#: glib/gdatetime.c:268 msgctxt "full month name" msgid "April" msgstr "Nisan" -#: glib/gdatetime.c:269 +#: glib/gdatetime.c:270 msgctxt "full month name" msgid "May" msgstr "Mayıs" -#: glib/gdatetime.c:271 +#: glib/gdatetime.c:272 msgctxt "full month name" msgid "June" msgstr "Haziran" -#: glib/gdatetime.c:273 +#: glib/gdatetime.c:274 msgctxt "full month name" msgid "July" msgstr "Temmuz" -#: glib/gdatetime.c:275 +#: glib/gdatetime.c:276 msgctxt "full month name" msgid "August" msgstr "Ağustos" -#: glib/gdatetime.c:277 +#: glib/gdatetime.c:278 msgctxt "full month name" msgid "September" msgstr "Eylül" -#: glib/gdatetime.c:279 +#: glib/gdatetime.c:280 msgctxt "full month name" msgid "October" msgstr "Ekim" -#: glib/gdatetime.c:281 +#: glib/gdatetime.c:282 msgctxt "full month name" msgid "November" msgstr "Kasım" -#: glib/gdatetime.c:283 +#: glib/gdatetime.c:284 msgctxt "full month name" msgid "December" msgstr "Aralık" @@ -4355,132 +4378,132 @@ #. * other platform. Here are abbreviated month names in a form #. * appropriate when they are used standalone. #. -#: glib/gdatetime.c:315 +#: glib/gdatetime.c:316 msgctxt "abbreviated month name" msgid "Jan" msgstr "Oca" -#: glib/gdatetime.c:317 +#: glib/gdatetime.c:318 msgctxt "abbreviated month name" msgid "Feb" msgstr "Şub" -#: glib/gdatetime.c:319 +#: glib/gdatetime.c:320 msgctxt "abbreviated month name" msgid "Mar" msgstr "Mar" -#: glib/gdatetime.c:321 +#: glib/gdatetime.c:322 msgctxt "abbreviated month name" msgid "Apr" msgstr "Nis" -#: glib/gdatetime.c:323 +#: glib/gdatetime.c:324 msgctxt "abbreviated month name" msgid "May" msgstr "May" -#: glib/gdatetime.c:325 +#: glib/gdatetime.c:326 msgctxt "abbreviated month name" msgid "Jun" msgstr "Haz" -#: glib/gdatetime.c:327 +#: glib/gdatetime.c:328 msgctxt "abbreviated month name" msgid "Jul" msgstr "Tem" -#: glib/gdatetime.c:329 +#: glib/gdatetime.c:330 msgctxt "abbreviated month name" msgid "Aug" msgstr "Ağu" -#: glib/gdatetime.c:331 +#: glib/gdatetime.c:332 msgctxt "abbreviated month name" msgid "Sep" msgstr "Eyl" -#: glib/gdatetime.c:333 +#: glib/gdatetime.c:334 msgctxt "abbreviated month name" msgid "Oct" msgstr "Eki" -#: glib/gdatetime.c:335 +#: glib/gdatetime.c:336 msgctxt "abbreviated month name" msgid "Nov" msgstr "Kas" -#: glib/gdatetime.c:337 +#: glib/gdatetime.c:338 msgctxt "abbreviated month name" msgid "Dec" msgstr "Ara" -#: glib/gdatetime.c:352 +#: glib/gdatetime.c:353 msgctxt "full weekday name" msgid "Monday" msgstr "Pazartesi" -#: glib/gdatetime.c:354 +#: glib/gdatetime.c:355 msgctxt "full weekday name" msgid "Tuesday" msgstr "Salı" -#: glib/gdatetime.c:356 +#: glib/gdatetime.c:357 msgctxt "full weekday name" msgid "Wednesday" msgstr "Çarşamba" -#: glib/gdatetime.c:358 +#: glib/gdatetime.c:359 msgctxt "full weekday name" msgid "Thursday" msgstr "Perşembe" -#: glib/gdatetime.c:360 +#: glib/gdatetime.c:361 msgctxt "full weekday name" msgid "Friday" msgstr "Cuma" -#: glib/gdatetime.c:362 +#: glib/gdatetime.c:363 msgctxt "full weekday name" msgid "Saturday" msgstr "Cumartesi" -#: glib/gdatetime.c:364 +#: glib/gdatetime.c:365 msgctxt "full weekday name" msgid "Sunday" msgstr "Pazar" -#: glib/gdatetime.c:379 +#: glib/gdatetime.c:380 msgctxt "abbreviated weekday name" msgid "Mon" msgstr "Pzt" -#: glib/gdatetime.c:381 +#: glib/gdatetime.c:382 msgctxt "abbreviated weekday name" msgid "Tue" msgstr "Sal" -#: glib/gdatetime.c:383 +#: glib/gdatetime.c:384 msgctxt "abbreviated weekday name" msgid "Wed" msgstr "Çar" -#: glib/gdatetime.c:385 +#: glib/gdatetime.c:386 msgctxt "abbreviated weekday name" msgid "Thu" msgstr "Per" -#: glib/gdatetime.c:387 +#: glib/gdatetime.c:388 msgctxt "abbreviated weekday name" msgid "Fri" msgstr "Cum" -#: glib/gdatetime.c:389 +#: glib/gdatetime.c:390 msgctxt "abbreviated weekday name" msgid "Sat" msgstr "Cmt" -#: glib/gdatetime.c:391 +#: glib/gdatetime.c:392 msgctxt "abbreviated weekday name" msgid "Sun" msgstr "Paz" @@ -4502,62 +4525,62 @@ #. * (western European, non-European) there is no difference between the #. * standalone and complete date form. #. -#: glib/gdatetime.c:455 +#: glib/gdatetime.c:456 msgctxt "full month name with day" msgid "January" msgstr "Ocak" -#: glib/gdatetime.c:457 +#: glib/gdatetime.c:458 msgctxt "full month name with day" msgid "February" msgstr "Şubat" -#: glib/gdatetime.c:459 +#: glib/gdatetime.c:460 msgctxt "full month name with day" msgid "March" msgstr "Mart" -#: glib/gdatetime.c:461 +#: glib/gdatetime.c:462 msgctxt "full month name with day" msgid "April" msgstr "Nisan" -#: glib/gdatetime.c:463 +#: glib/gdatetime.c:464 msgctxt "full month name with day" msgid "May" msgstr "Mayıs" -#: glib/gdatetime.c:465 +#: glib/gdatetime.c:466 msgctxt "full month name with day" msgid "June" msgstr "Haziran" -#: glib/gdatetime.c:467 +#: glib/gdatetime.c:468 msgctxt "full month name with day" msgid "July" msgstr "Temmuz" -#: glib/gdatetime.c:469 +#: glib/gdatetime.c:470 msgctxt "full month name with day" msgid "August" msgstr "Ağustos" -#: glib/gdatetime.c:471 +#: glib/gdatetime.c:472 msgctxt "full month name with day" msgid "September" msgstr "Eylül" -#: glib/gdatetime.c:473 +#: glib/gdatetime.c:474 msgctxt "full month name with day" msgid "October" msgstr "Ekim" -#: glib/gdatetime.c:475 +#: glib/gdatetime.c:476 msgctxt "full month name with day" msgid "November" msgstr "Kasım" -#: glib/gdatetime.c:477 +#: glib/gdatetime.c:478 msgctxt "full month name with day" msgid "December" msgstr "Aralık" @@ -4579,79 +4602,79 @@ #. * month names almost ready to copy and paste here. In other systems #. * due to a bug the result is incorrect in some languages. #. -#: glib/gdatetime.c:542 +#: glib/gdatetime.c:543 msgctxt "abbreviated month name with day" msgid "Jan" msgstr "Oca" -#: glib/gdatetime.c:544 +#: glib/gdatetime.c:545 msgctxt "abbreviated month name with day" msgid "Feb" msgstr "Şub" -#: glib/gdatetime.c:546 +#: glib/gdatetime.c:547 msgctxt "abbreviated month name with day" msgid "Mar" msgstr "Mar" -#: glib/gdatetime.c:548 +#: glib/gdatetime.c:549 msgctxt "abbreviated month name with day" msgid "Apr" msgstr "Nis" -#: glib/gdatetime.c:550 +#: glib/gdatetime.c:551 msgctxt "abbreviated month name with day" msgid "May" msgstr "May" -#: glib/gdatetime.c:552 +#: glib/gdatetime.c:553 msgctxt "abbreviated month name with day" msgid "Jun" msgstr "Haz" -#: glib/gdatetime.c:554 +#: glib/gdatetime.c:555 msgctxt "abbreviated month name with day" msgid "Jul" msgstr "Tem" -#: glib/gdatetime.c:556 +#: glib/gdatetime.c:557 msgctxt "abbreviated month name with day" msgid "Aug" msgstr "Ağu" -#: glib/gdatetime.c:558 +#: glib/gdatetime.c:559 msgctxt "abbreviated month name with day" msgid "Sep" msgstr "Eyl" -#: glib/gdatetime.c:560 +#: glib/gdatetime.c:561 msgctxt "abbreviated month name with day" msgid "Oct" msgstr "Eki" -#: glib/gdatetime.c:562 +#: glib/gdatetime.c:563 msgctxt "abbreviated month name with day" msgid "Nov" msgstr "Kas" -#: glib/gdatetime.c:564 +#: glib/gdatetime.c:565 msgctxt "abbreviated month name with day" msgid "Dec" msgstr "Ara" #. Translators: 'before midday' indicator -#: glib/gdatetime.c:581 +#: glib/gdatetime.c:582 msgctxt "GDateTime" msgid "AM" msgstr "ÖÖ" #. Translators: 'after midday' indicator -#: glib/gdatetime.c:584 +#: glib/gdatetime.c:585 msgctxt "GDateTime" msgid "PM" msgstr "ÖS" -#: glib/gdir.c:155 +#: glib/gdir.c:154 #, c-format msgid "Error opening directory “%s”: %s" msgstr "“%s” dizini açılamadı: %s" @@ -4756,15 +4779,15 @@ msgid "Can’t do a raw read in g_io_channel_read_to_end" msgstr "g_io_channel_read_to_end içinde okuma başarısız" -#: glib/gkeyfile.c:788 +#: glib/gkeyfile.c:789 msgid "Valid key file could not be found in search dirs" msgstr "Arama dizinlerinde geçerli anahtar dosyası bulunamadı" -#: glib/gkeyfile.c:825 +#: glib/gkeyfile.c:826 msgid "Not a regular file" msgstr "Normal dosya değil" -#: glib/gkeyfile.c:1274 +#: glib/gkeyfile.c:1275 #, c-format msgid "" "Key file contains line “%s” which is not a key-value pair, group, or comment" @@ -4772,50 +4795,50 @@ "Anahtar dosyası; anahtar-değer çifti, grup veya yorum olmayan “%s” satırını " "içeriyor" -#: glib/gkeyfile.c:1331 +#: glib/gkeyfile.c:1332 #, c-format msgid "Invalid group name: %s" msgstr "Geçersiz grup adı: %s" -#: glib/gkeyfile.c:1353 +#: glib/gkeyfile.c:1354 msgid "Key file does not start with a group" msgstr "Anahtar dosyası bir grupla başlamıyor" -#: glib/gkeyfile.c:1379 +#: glib/gkeyfile.c:1380 #, c-format msgid "Invalid key name: %s" msgstr "Geçersiz anahtar adı: %s" -#: glib/gkeyfile.c:1406 +#: glib/gkeyfile.c:1407 #, c-format msgid "Key file contains unsupported encoding “%s”" msgstr "Anahtar dosya desteklenmeyen “%s” kodlamasını içeriyor" -#: glib/gkeyfile.c:1649 glib/gkeyfile.c:1822 glib/gkeyfile.c:3275 -#: glib/gkeyfile.c:3338 glib/gkeyfile.c:3468 glib/gkeyfile.c:3598 -#: glib/gkeyfile.c:3742 glib/gkeyfile.c:3971 glib/gkeyfile.c:4038 +#: glib/gkeyfile.c:1650 glib/gkeyfile.c:1823 glib/gkeyfile.c:3276 +#: glib/gkeyfile.c:3339 glib/gkeyfile.c:3469 glib/gkeyfile.c:3601 +#: glib/gkeyfile.c:3747 glib/gkeyfile.c:3976 glib/gkeyfile.c:4043 #, c-format msgid "Key file does not have group “%s”" msgstr "Anahtar dosyasında “%s” grubu yok" -#: glib/gkeyfile.c:1777 +#: glib/gkeyfile.c:1778 #, c-format msgid "Key file does not have key “%s” in group “%s”" msgstr "Anahtar dosyası, “%2$s” grubunda “%1$s” anahtarı içermiyor" -#: glib/gkeyfile.c:1939 glib/gkeyfile.c:2055 +#: glib/gkeyfile.c:1940 glib/gkeyfile.c:2056 #, c-format msgid "Key file contains key “%s” with value “%s” which is not UTF-8" msgstr "Anahtar dosyası, UTF-8 olmayan “%s” anahtarını “%s” değeriyle içeriyor" -#: glib/gkeyfile.c:1959 glib/gkeyfile.c:2075 glib/gkeyfile.c:2517 +#: glib/gkeyfile.c:1960 glib/gkeyfile.c:2076 glib/gkeyfile.c:2518 #, c-format msgid "" "Key file contains key “%s” which has a value that cannot be interpreted." msgstr "" "Anahtar dosyası yorumlanamayan bir değere sahip olan “%s” anahtarını içerir." -#: glib/gkeyfile.c:2735 glib/gkeyfile.c:3104 +#: glib/gkeyfile.c:2736 glib/gkeyfile.c:3105 #, c-format msgid "" "Key file contains key “%s” in group “%s” which has a value that cannot be " @@ -4823,38 +4846,38 @@ msgstr "" "“%2$s” grubundaki anahtar dosyası, yorumlanamayan “%1$s” anahtarını içeriyor." -#: glib/gkeyfile.c:2813 glib/gkeyfile.c:2890 +#: glib/gkeyfile.c:2814 glib/gkeyfile.c:2891 #, c-format msgid "Key “%s” in group “%s” has value “%s” where %s was expected" msgstr "" "“%2$s” grubundaki “%1$s” anahtarı “%4$s” değerine sahip olması beklenirken " "“%3$s” değerine sahip" -#: glib/gkeyfile.c:4278 +#: glib/gkeyfile.c:4283 msgid "Key file contains escape character at end of line" msgstr "Anahtar dosyası satır sonunda çıkış karakteri içeriyor" -#: glib/gkeyfile.c:4300 +#: glib/gkeyfile.c:4305 #, c-format msgid "Key file contains invalid escape sequence “%s”" msgstr "“%s” anahtar dosyası geçersiz çıkış dizisi içeriyor" -#: glib/gkeyfile.c:4444 +#: glib/gkeyfile.c:4449 #, c-format msgid "Value “%s” cannot be interpreted as a number." msgstr "“%s” değeri bir sayı olarak yorumlanamıyor." -#: glib/gkeyfile.c:4458 +#: glib/gkeyfile.c:4463 #, c-format msgid "Integer value “%s” out of range" msgstr "“%s”, tamsayı değeri aralık dışında" -#: glib/gkeyfile.c:4491 +#: glib/gkeyfile.c:4496 #, c-format msgid "Value “%s” cannot be interpreted as a float number." msgstr "“%s” değeri bir gerçel sayı olarak yorumlanamıyor." -#: glib/gkeyfile.c:4530 +#: glib/gkeyfile.c:4535 #, c-format msgid "Value “%s” cannot be interpreted as a boolean." msgstr "“%s” değeri mantıksal değer olarak yorumlanamıyor." @@ -4875,32 +4898,32 @@ msgid "Failed to open file “%s”: open() failed: %s" msgstr "“%s” dosyası açılamadı: open() başarısızlığı: %s" -#: glib/gmarkup.c:397 glib/gmarkup.c:439 +#: glib/gmarkup.c:398 glib/gmarkup.c:440 #, c-format msgid "Error on line %d char %d: " msgstr "Satır %d karakter %d hatalı: " -#: glib/gmarkup.c:461 glib/gmarkup.c:544 +#: glib/gmarkup.c:462 glib/gmarkup.c:545 #, c-format msgid "Invalid UTF-8 encoded text in name — not valid “%s”" msgstr "Adda geçersiz UTF-8 kodlu metin — geçerli olmayan “%s”" -#: glib/gmarkup.c:472 +#: glib/gmarkup.c:473 #, c-format msgid "“%s” is not a valid name" msgstr "“%s” geçerli bir ad değil" -#: glib/gmarkup.c:488 +#: glib/gmarkup.c:489 #, c-format msgid "“%s” is not a valid name: “%c”" msgstr "“%s” geçerli bir ad değil: “%c”" -#: glib/gmarkup.c:612 +#: glib/gmarkup.c:613 #, c-format msgid "Error on line %d: %s" msgstr "Satır %d hata içeriyor: %s" -#: glib/gmarkup.c:689 +#: glib/gmarkup.c:690 #, c-format msgid "" "Failed to parse “%-.*s”, which should have been a digit inside a character " @@ -4909,7 +4932,7 @@ "Karakter referansı içinde bir rakam olması gereken “%-.*s” ayrıştırılamadı, " "(örneğin; ê) — rakam çok büyük olabilir" -#: glib/gmarkup.c:701 +#: glib/gmarkup.c:702 msgid "" "Character reference did not end with a semicolon; most likely you used an " "ampersand character without intending to start an entity — escape ampersand " @@ -4919,23 +4942,23 @@ "özvarlık başlatmak istemeksizin “ve” işareti kullandınız — “ve” işaretini " "& olarak kullanabilirsiniz" -#: glib/gmarkup.c:727 +#: glib/gmarkup.c:728 #, c-format msgid "Character reference “%-.*s” does not encode a permitted character" msgstr "Karakter referansı “%-.*s” izin verilen karakteri kodlamıyor" -#: glib/gmarkup.c:765 +#: glib/gmarkup.c:766 msgid "" "Empty entity “&;” seen; valid entities are: & " < > '" msgstr "" "Boş özvarlık “&;” görüldü; geçerli ögeler: & " < > '" -#: glib/gmarkup.c:773 +#: glib/gmarkup.c:774 #, c-format msgid "Entity name “%-.*s” is not known" msgstr "Varlık adı “%-.*s” bilinmiyor" -#: glib/gmarkup.c:778 +#: glib/gmarkup.c:779 msgid "" "Entity did not end with a semicolon; most likely you used an ampersand " "character without intending to start an entity — escape ampersand as &" @@ -4944,11 +4967,11 @@ "başlatmak istemeksizin “ve” işareti kullandınız — “ve” işaretini & " "olarak kullanabilirsiniz" -#: glib/gmarkup.c:1186 +#: glib/gmarkup.c:1187 msgid "Document must begin with an element (e.g. )" msgstr "Belge bir öge ile başlamalıdır (örneğin )" -#: glib/gmarkup.c:1226 +#: glib/gmarkup.c:1227 #, c-format msgid "" "“%s” is not a valid character following a “<” character; it may not begin an " @@ -4957,7 +4980,7 @@ "“<” karakterinden sonra gelen “%s” geçerli bir karakter değil; bir öge adı " "başlatmamalı" -#: glib/gmarkup.c:1269 +#: glib/gmarkup.c:1270 #, c-format msgid "" "Odd character “%s”, expected a “>” character to end the empty-element tag " @@ -4965,7 +4988,7 @@ msgstr "" "Tuhaf karakter “%s”, “%s” boş öge etiketinin sonunda “>” karakteri bekledi" -#: glib/gmarkup.c:1351 +#: glib/gmarkup.c:1352 #, c-format msgid "" "Odd character “%s”, expected a “=” after attribute name “%s” of element “%s”" @@ -4973,7 +4996,7 @@ "Tuhaf karakter “%1$s”, “%3$s” ögesinin “%2$s” özniteliğinin sonunda “=” " "karakteri bekledi" -#: glib/gmarkup.c:1393 +#: glib/gmarkup.c:1394 #, c-format msgid "" "Odd character “%s”, expected a “>” or “/” character to end the start tag of " @@ -4984,7 +5007,7 @@ "“>”, “/” karakteri veya bir öznitelik bekledi; öznitelik adında geçersiz bir " "karakter kullanmış olabilirsiniz" -#: glib/gmarkup.c:1438 +#: glib/gmarkup.c:1439 #, c-format msgid "" "Odd character “%s”, expected an open quote mark after the equals sign when " @@ -4993,7 +5016,7 @@ "Tuhaf karakter “%1$s”, “%3$s” ögesindeki “%2$s” özniteliği için değer " "verildiğinde eşittir işaretinden sonra tırnak işareti beklendi" -#: glib/gmarkup.c:1572 +#: glib/gmarkup.c:1573 #, c-format msgid "" "“%s” is not a valid character following the characters “”" -#: glib/gmarkup.c:1622 +#: glib/gmarkup.c:1623 #, c-format msgid "Element “%s” was closed, no element is currently open" msgstr "“%s” ögesi kapatılmış, hiçbir öge şu anda açık değil" -#: glib/gmarkup.c:1631 +#: glib/gmarkup.c:1632 #, c-format msgid "Element “%s” was closed, but the currently open element is “%s”" msgstr "“%s” ögesi kapatılmış, ancak “%s” şu an açık olan ögedir" -#: glib/gmarkup.c:1784 +#: glib/gmarkup.c:1785 msgid "Document was empty or contained only whitespace" msgstr "Belge boş veya yalnızca boşluk karakteri içeriyor" -#: glib/gmarkup.c:1798 +#: glib/gmarkup.c:1799 msgid "Document ended unexpectedly just after an open angle bracket “<”" msgstr "" -"Belge, açık açı parantezi “<” işaretinden hemen sonra beklenmedik bir " -"şekilde bitti" +"Belge, açık açı parantezi “<” işaretinden hemen sonra beklenmedik biçimde " +"sonlandı" -#: glib/gmarkup.c:1806 glib/gmarkup.c:1851 +#: glib/gmarkup.c:1807 glib/gmarkup.c:1852 #, c-format msgid "" "Document ended unexpectedly with elements still open — “%s” was the last " "element opened" msgstr "" -"Belge, ögeleri hala açıkken beklenmedik bir şekilde bitti - son açılan öge: " +"Belge, ögeleri hala açıkken beklenmedik biçimde sonlandı - son açılan öge: " "“%s”" -#: glib/gmarkup.c:1814 +#: glib/gmarkup.c:1815 #, c-format msgid "" "Document ended unexpectedly, expected to see a close angle bracket ending " "the tag <%s/>" msgstr "" -"Belge beklenmedik bir şekilde bitti, etiketi bitiren kapalı açı parantezi " -"ile biten <%s/> beklendi" +"Belge beklenmedik biçimde sonlandı, etiketi bitiren kapalı açı parantezi ile " +"biten <%s/> beklendi" -#: glib/gmarkup.c:1820 +#: glib/gmarkup.c:1821 msgid "Document ended unexpectedly inside an element name" -msgstr "Belge bir öge adının içinde beklenmedik bir şekilde bitti" +msgstr "Belge bir öge adının içinde beklenmedik biçimde sonlandı" -#: glib/gmarkup.c:1826 +#: glib/gmarkup.c:1827 msgid "Document ended unexpectedly inside an attribute name" -msgstr "Belge bir öznitelik adı içinde beklenmedik bir şekilde bitti" +msgstr "Belge bir öznitelik adı içinde beklenmedik biçimde sonlandı" -#: glib/gmarkup.c:1831 +#: glib/gmarkup.c:1832 msgid "Document ended unexpectedly inside an element-opening tag." -msgstr "Belge bir öge-açma etiketi içinde beklenmedik bir şekilde bitti." +msgstr "Belge bir öge-açma etiketi içinde beklenmedik biçimde sonlandı." -#: glib/gmarkup.c:1837 +#: glib/gmarkup.c:1838 msgid "" "Document ended unexpectedly after the equals sign following an attribute " "name; no attribute value" msgstr "" -"Belge öznitelik adını takip eden eşittir işaretinden sonra beklenmedik bir " -"şekilde bitti; öznitelik değeri yok" +"Belge öznitelik adını takip eden eşittir işaretinden sonra beklenmedik " +"biçimde sonlandı; öznitelik değeri yok" -#: glib/gmarkup.c:1844 +#: glib/gmarkup.c:1845 msgid "Document ended unexpectedly while inside an attribute value" -msgstr "Belge bir öznitelik değeri içinde iken beklenmedik bir şekilde bitti" +msgstr "Belge bir öznitelik değeri içinde iken beklenmedik biçimde sonlandı" -#: glib/gmarkup.c:1861 +#: glib/gmarkup.c:1862 #, c-format msgid "Document ended unexpectedly inside the close tag for element “%s”" msgstr "" -"Belge, “%s” ögesinin kapatma etiketi içinde beklenmedik bir şekilde bitti" +"Belge, “%s” ögesinin kapatma etiketi içinde beklenmedik biçimde sonlandı" -#: glib/gmarkup.c:1865 +#: glib/gmarkup.c:1866 msgid "" "Document ended unexpectedly inside the close tag for an unopened element" msgstr "" -"Belge, açık olmayan bir öge için kapatma etiketi içinde beklenmedik bir " -"şekilde bitti" +"Belge, açık olmayan bir öge için kapatma etiketi içinde beklenmedik biçimde " +"sonlandı" -#: glib/gmarkup.c:1871 +#: glib/gmarkup.c:1872 msgid "Document ended unexpectedly inside a comment or processing instruction" msgstr "" -"Belge bir yorum veya işlem talimatı içindeyken beklenmedik bir şekilde bitti" +"Belge bir yorum veya işlem talimatı içindeyken beklenmedik biçimde sonlandı" #: glib/goption.c:861 msgid "[OPTION…]" @@ -5542,126 +5565,126 @@ msgid "Text was empty (or contained only whitespace)" msgstr "Metin boştu (veya yalnızca boşluk içeriyordu)" -#: glib/gspawn.c:311 +#: glib/gspawn.c:315 #, c-format msgid "Failed to read data from child process (%s)" msgstr "Alt süreçten bilgi okuma başarısızlığı (%s)" -#: glib/gspawn.c:459 +#: glib/gspawn.c:463 #, c-format msgid "Unexpected error in select() reading data from a child process (%s)" msgstr "Alt süreçten bilgi okurken select()’te beklenmeyen hata oluştu (%s)" -#: glib/gspawn.c:544 +#: glib/gspawn.c:548 #, c-format msgid "Unexpected error in waitpid() (%s)" msgstr "waitpid()’de beklenmeyen hata (%s)" -#: glib/gspawn.c:1052 glib/gspawn-win32.c:1318 +#: glib/gspawn.c:1056 glib/gspawn-win32.c:1329 #, c-format msgid "Child process exited with code %ld" msgstr "Alt işlem %ld kodu ile sonlandı" -#: glib/gspawn.c:1060 +#: glib/gspawn.c:1064 #, c-format msgid "Child process killed by signal %ld" msgstr "Alt işlem, %ld sinyali ile sonlandı" -#: glib/gspawn.c:1067 +#: glib/gspawn.c:1071 #, c-format msgid "Child process stopped by signal %ld" msgstr "Alt işlem %ld sinyali ile durduruldu" -#: glib/gspawn.c:1074 +#: glib/gspawn.c:1078 #, c-format msgid "Child process exited abnormally" msgstr "Alt işlem anormal bir biçimde sonlandı" -#: glib/gspawn.c:1369 glib/gspawn-win32.c:339 glib/gspawn-win32.c:347 +#: glib/gspawn.c:1405 glib/gspawn-win32.c:350 glib/gspawn-win32.c:358 #, c-format msgid "Failed to read from child pipe (%s)" msgstr "Alt süreç borusundan okuma başarısızlığı (%s)" -#: glib/gspawn.c:1617 +#: glib/gspawn.c:1653 #, c-format msgid "Failed to spawn child process “%s” (%s)" msgstr "“%s” alt süreci üretme başarısız (%s)" -#: glib/gspawn.c:1656 +#: glib/gspawn.c:1692 #, c-format msgid "Failed to fork (%s)" msgstr "Çatallama başarısızlığı (%s)" -#: glib/gspawn.c:1805 glib/gspawn-win32.c:370 +#: glib/gspawn.c:1841 glib/gspawn-win32.c:381 #, c-format msgid "Failed to change to directory “%s” (%s)" msgstr "“%s” dizinine değiştirme başarısızlığı (%s)" -#: glib/gspawn.c:1815 +#: glib/gspawn.c:1851 #, c-format msgid "Failed to execute child process “%s” (%s)" msgstr "“%s” alt süreci çalıştırılırken hata oluştu (%s)" -#: glib/gspawn.c:1825 +#: glib/gspawn.c:1861 #, c-format msgid "Failed to redirect output or input of child process (%s)" msgstr "Alt sürecin girdisi veya çıktısı yönlendirilemedi (%s)" -#: glib/gspawn.c:1834 +#: glib/gspawn.c:1870 #, c-format msgid "Failed to fork child process (%s)" msgstr "Alt süreç çatallanamadı (%s)" -#: glib/gspawn.c:1842 +#: glib/gspawn.c:1878 #, c-format msgid "Unknown error executing child process “%s”" msgstr "Alt süreç “%s” çalıştırılırken bilinmeyen hata oluştu" -#: glib/gspawn.c:1866 +#: glib/gspawn.c:1902 #, c-format msgid "Failed to read enough data from child pid pipe (%s)" msgstr "Alt süreç borusundan yeterli bilgi okunamadı (%s)" -#: glib/gspawn-win32.c:283 +#: glib/gspawn-win32.c:294 msgid "Failed to read data from child process" msgstr "Alt süreçten bilgi okuma başarısızlığı" -#: glib/gspawn-win32.c:300 +#: glib/gspawn-win32.c:311 #, c-format msgid "Failed to create pipe for communicating with child process (%s)" msgstr "Alt süreçle haberleşme için boru yaratılamadı (%s)" -#: glib/gspawn-win32.c:376 glib/gspawn-win32.c:381 glib/gspawn-win32.c:500 +#: glib/gspawn-win32.c:387 glib/gspawn-win32.c:392 glib/gspawn-win32.c:511 #, c-format msgid "Failed to execute child process (%s)" msgstr "Alt süreç yürütme başarısızlığı (%s)" -#: glib/gspawn-win32.c:450 +#: glib/gspawn-win32.c:461 #, c-format msgid "Invalid program name: %s" msgstr "Geçersiz program adı: %s" -#: glib/gspawn-win32.c:460 glib/gspawn-win32.c:714 +#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:725 #, c-format msgid "Invalid string in argument vector at %d: %s" msgstr "%d konumunda argüman vektörü içinde geçersiz dizgi: %s" -#: glib/gspawn-win32.c:471 glib/gspawn-win32.c:729 +#: glib/gspawn-win32.c:482 glib/gspawn-win32.c:740 #, c-format msgid "Invalid string in environment: %s" msgstr "Çevre içinde geçersiz dizgi: %s" -#: glib/gspawn-win32.c:710 +#: glib/gspawn-win32.c:721 #, c-format msgid "Invalid working directory: %s" msgstr "Geçersiz çalışma dizini: %s" -#: glib/gspawn-win32.c:772 +#: glib/gspawn-win32.c:783 #, c-format msgid "Failed to execute helper program (%s)" msgstr "Yardımcı program (%s) çalıştırılamadı" -#: glib/gspawn-win32.c:1045 +#: glib/gspawn-win32.c:1056 msgid "" "Unexpected error in g_io_channel_win32_poll() reading data from a child " "process" @@ -5669,21 +5692,21 @@ "Alt süreçten bilgi okurken g_io_channel_win32_poll() işleminde beklenmeyen " "hata" -#: glib/gstrfuncs.c:3247 glib/gstrfuncs.c:3348 +#: glib/gstrfuncs.c:3286 glib/gstrfuncs.c:3388 msgid "Empty string is not a number" msgstr "Boş dizge bir sayı değildir" -#: glib/gstrfuncs.c:3271 +#: glib/gstrfuncs.c:3310 #, c-format msgid "“%s” is not a signed number" msgstr "“%s” işaretli bir sayı değil" -#: glib/gstrfuncs.c:3281 glib/gstrfuncs.c:3384 +#: glib/gstrfuncs.c:3320 glib/gstrfuncs.c:3424 #, c-format msgid "Number “%s” is out of bounds [%s, %s]" msgstr "“%s” sayısı sınırların dışındadır [%s, %s]" -#: glib/gstrfuncs.c:3374 +#: glib/gstrfuncs.c:3414 #, c-format msgid "“%s” is not an unsigned number" msgstr "“%s” işaretsiz bir sayı değil" @@ -5705,147 +5728,171 @@ msgid "Character out of range for UTF-16" msgstr "Karakter UTF-16 sınırlarının dışında" -#: glib/gutils.c:2244 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2339 #, c-format -msgid "%.1f kB" -msgstr "%.1f kB" +msgid "%.1f kB" +msgstr "%.1f kB" -#: glib/gutils.c:2245 glib/gutils.c:2451 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2341 #, c-format -msgid "%.1f MB" -msgstr "%.1f MB" +msgid "%.1f MB" +msgstr "%.1f MB" -#: glib/gutils.c:2246 glib/gutils.c:2456 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2343 #, c-format -msgid "%.1f GB" -msgstr "%.1f GB" +msgid "%.1f GB" +msgstr "%.1f GB" -#: glib/gutils.c:2247 glib/gutils.c:2461 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2345 #, c-format -msgid "%.1f TB" -msgstr "%.1f TB" +msgid "%.1f TB" +msgstr "%.1f TB" -#: glib/gutils.c:2248 glib/gutils.c:2466 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2347 #, c-format -msgid "%.1f PB" -msgstr "%.1f PB" +msgid "%.1f PB" +msgstr "%.1f PB" -#: glib/gutils.c:2249 glib/gutils.c:2471 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2349 #, c-format -msgid "%.1f EB" -msgstr "%.1f EB" +msgid "%.1f EB" +msgstr "%.1f EB" -#: glib/gutils.c:2252 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2353 #, c-format -msgid "%.1f KiB" -msgstr "%.1f KiB" +msgid "%.1f KiB" +msgstr "%.1f KiB" -#: glib/gutils.c:2253 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2355 #, c-format -msgid "%.1f MiB" -msgstr "%.1f MiB" +msgid "%.1f MiB" +msgstr "%.1f MiB" -#: glib/gutils.c:2254 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2357 #, c-format -msgid "%.1f GiB" -msgstr "%.1f GiB" +msgid "%.1f GiB" +msgstr "%.1f GiB" -#: glib/gutils.c:2255 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2359 #, c-format -msgid "%.1f TiB" -msgstr "%.1f TiB" +msgid "%.1f TiB" +msgstr "%.1f TiB" -#: glib/gutils.c:2256 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2361 #, c-format -msgid "%.1f PiB" -msgstr "%.1f PiB" +msgid "%.1f PiB" +msgstr "%.1f PiB" -#: glib/gutils.c:2257 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2363 #, c-format -msgid "%.1f EiB" -msgstr "%.1f EiB" +msgid "%.1f EiB" +msgstr "%.1f EiB" -#: glib/gutils.c:2260 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2367 #, c-format -msgid "%.1f kb" -msgstr "%.1f kb" +msgid "%.1f kb" +msgstr "%.1f kb" -#: glib/gutils.c:2261 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2369 #, c-format -msgid "%.1f Mb" -msgstr "%.1f Mb" +msgid "%.1f Mb" +msgstr "%.1f Mb" -#: glib/gutils.c:2262 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2371 #, c-format -msgid "%.1f Gb" -msgstr "%.1f Gb" +msgid "%.1f Gb" +msgstr "%.1f Gb" -#: glib/gutils.c:2263 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2373 #, c-format -msgid "%.1f Tb" +msgid "%.1f Tb" msgstr "%.1f Tb" -#: glib/gutils.c:2264 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2375 #, c-format -msgid "%.1f Pb" +msgid "%.1f Pb" msgstr "%.1f Pb" -#: glib/gutils.c:2265 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2377 #, c-format -msgid "%.1f Eb" +msgid "%.1f Eb" msgstr "%.1f Eb" -#: glib/gutils.c:2268 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2381 #, c-format -msgid "%.1f Kib" +msgid "%.1f Kib" msgstr "%.1f Kib" -#: glib/gutils.c:2269 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2383 #, c-format -msgid "%.1f Mib" +msgid "%.1f Mib" msgstr "%.1f Mib" -#: glib/gutils.c:2270 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2385 #, c-format -msgid "%.1f Gib" -msgstr "%.1f Gib" +msgid "%.1f Gib" +msgstr "%.1f Gib" -#: glib/gutils.c:2271 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2387 #, c-format -msgid "%.1f Tib" -msgstr "%.1f Tib" +msgid "%.1f Tib" +msgstr "%.1f Tib" -#: glib/gutils.c:2272 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2389 #, c-format -msgid "%.1f Pib" -msgstr "%.1f Pib" +msgid "%.1f Pib" +msgstr "%.1f Pib" -#: glib/gutils.c:2273 +#. Translators: Keep the no-break space between %.1f and the unit symbol +#: glib/gutils.c:2391 #, c-format -msgid "%.1f Eib" -msgstr "%.1f Eib" +msgid "%.1f Eib" +msgstr "%.1f Eib" -#: glib/gutils.c:2307 glib/gutils.c:2433 +#: glib/gutils.c:2425 glib/gutils.c:2551 #, c-format msgid "%u byte" msgid_plural "%u bytes" msgstr[0] "%u bayt" -#: glib/gutils.c:2311 +#: glib/gutils.c:2429 #, c-format msgid "%u bit" msgid_plural "%u bits" msgstr[0] "%u bit" #. Translators: the %s in "%s bytes" will always be replaced by a number. -#: glib/gutils.c:2378 +#: glib/gutils.c:2496 #, c-format msgid "%s byte" msgid_plural "%s bytes" msgstr[0] "%s bayt" #. Translators: the %s in "%s bits" will always be replaced by a number. -#: glib/gutils.c:2383 +#: glib/gutils.c:2501 #, c-format msgid "%s bit" msgid_plural "%s bits" @@ -5856,11 +5903,36 @@ #. * compatibility. Users will not see this string unless a program is using this deprecated function. #. * Please translate as literally as possible. #. -#: glib/gutils.c:2446 +#: glib/gutils.c:2564 #, c-format msgid "%.1f KB" msgstr "%.1f KB" +#: glib/gutils.c:2569 +#, c-format +msgid "%.1f MB" +msgstr "%.1f MB" + +#: glib/gutils.c:2574 +#, c-format +msgid "%.1f GB" +msgstr "%.1f GB" + +#: glib/gutils.c:2579 +#, c-format +msgid "%.1f TB" +msgstr "%.1f TB" + +#: glib/gutils.c:2584 +#, c-format +msgid "%.1f PB" +msgstr "%.1f PB" + +#: glib/gutils.c:2589 +#, c-format +msgid "%.1f EB" +msgstr "%.1f EB" + #~ msgid "No such interface '%s'" #~ msgstr "'%s' gibi bir arayüz yok" diff -Nru glib2.0-2.59.2/template-tap.test.in glib2.0-2.59.3/template-tap.test.in --- glib2.0-2.59.2/template-tap.test.in 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/template-tap.test.in 2019-03-04 09:01:42.000000000 +0000 @@ -1,4 +1,4 @@ [Test] Type=session -Exec=@installed_tests_dir@/@program@ --tap +Exec=@env@@installed_tests_dir@/@program@ --tap Output=TAP diff -Nru glib2.0-2.59.2/tests/.gitignore glib2.0-2.59.3/tests/.gitignore --- glib2.0-2.59.2/tests/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/tests/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -assert-msg-test -asyncqueue-test -atomic-test -base64-test -bit-test -bookmarkfile-test -child-test -closures -collate.out -completion-test -convert-test -cxx-test -datetime -deftype -dirname-test -env-test -file-test -file-test-get-contents -gio-test -iochannel-test -iochannel-test-outfile -list-test -mainloop-test -mapchild -mapping-test -maptest -markup-collect -markup-escape-test -markup-test -module-test -objects -objects2 -onceinit -patterntest -properties -properties2 -properties3 -properties4 -qsort-test -queue-test -regex-test -relation-test -scannerapi -sequence-test -shell-test -signal1 -signal2 -signal3 -signal4 -slice-color -slice-concurrent -slice-test -slice-threadinit -slist-test -sources -spawn-test -testgdate -testgdateparser -testglib -testgobject -testingbase64 -testmarshal.c -testmarshal.h -thread-test -threadpool-test -timeloop -timeloop-closure -tree-test -type-test -unicode-caseconv -unicode-collate -unicode-encoding -unicode-normalize -uri-test -utf8-pointer -utf8-validate diff -Nru glib2.0-2.59.2/tests/gobject/.gitignore glib2.0-2.59.3/tests/gobject/.gitignore --- glib2.0-2.59.2/tests/gobject/.gitignore 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/tests/gobject/.gitignore 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -accumulator -defaultiface -dynamictype -gvalue-test -ifacecheck -ifaceinherit -ifaceinit -ifaceproperties -override -paramspec-test -performance -performance-threaded -references -signals -singleton diff -Nru glib2.0-2.59.2/tests/gobject/meson.build glib2.0-2.59.3/tests/gobject/meson.build --- glib2.0-2.59.2/tests/gobject/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/tests/gobject/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -66,6 +66,7 @@ test_conf = configuration_data() test_conf.set('installed_tests_dir', installed_tests_execdir) test_conf.set('program', test_name) + test_conf.set('env', '') configure_file( input: template, output: test_name + '.test', diff -Nru glib2.0-2.59.2/tests/meson.build glib2.0-2.59.3/tests/meson.build --- glib2.0-2.59.2/tests/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/tests/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -109,6 +109,7 @@ test_conf = configuration_data() test_conf.set('installed_tests_dir', installed_tests_execdir) test_conf.set('program', test_name) + test_conf.set('env', '') configure_file( input: template, output: test_name + '.test', diff -Nru glib2.0-2.59.2/tests/refcount/closures.c glib2.0-2.59.3/tests/refcount/closures.c --- glib2.0-2.59.2/tests/refcount/closures.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/tests/refcount/closures.c 2019-03-04 09:01:42.000000000 +0000 @@ -237,6 +237,14 @@ GTest *object; guint i; +#if defined(__aarch64__) || defined(__arm__) + if (g_getenv ("DEB_ALLOW_FLAKY_TESTS") != NULL) + { + g_print ("SKIP: Test is known to be flaky on arm* (#880883, #917983)\n"); + return 0; + } +#endif + g_print ("START: %s\n", argv[0]); g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | g_log_set_always_fatal (G_LOG_FATAL_MASK)); diff -Nru glib2.0-2.59.2/tests/refcount/meson.build glib2.0-2.59.3/tests/refcount/meson.build --- glib2.0-2.59.2/tests/refcount/meson.build 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/tests/refcount/meson.build 2019-03-04 09:01:42.000000000 +0000 @@ -36,6 +36,7 @@ test_conf = configuration_data() test_conf.set('installed_tests_dir', installed_tests_execdir) test_conf.set('program', test_name) + test_conf.set('env', '') configure_file( input: installed_tests_template, output: test_name + '.test', diff -Nru glib2.0-2.59.2/tests/testgdate.c glib2.0-2.59.3/tests/testgdate.c --- glib2.0-2.59.2/tests/testgdate.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/tests/testgdate.c 2019-03-04 09:01:42.000000000 +0000 @@ -133,10 +133,13 @@ g_date_set_julian(d, 1); TEST("GDate's \"Julian\" epoch's first day is valid", g_date_valid(d)); +#ifndef G_OS_WIN32 g_date_strftime(buf,100,"Our \"Julian\" epoch begins on a %A, in the month of %B, %x\n", d); g_print("%s", buf); - +#else + g_print ("But Windows FILETIME does not support dates before Jan 1 1601, so we can't strftime() the beginning of the \"Julian\" epoch.\n"); +#endif g_date_set_dmy(d, 10, 1, 2000); g_date_strftime(buf,100,"%x", d); diff -Nru glib2.0-2.59.2/tests/testglib.c glib2.0-2.59.3/tests/testglib.c --- glib2.0-2.59.2/tests/testglib.c 2019-02-04 13:57:04.000000000 +0000 +++ glib2.0-2.59.3/tests/testglib.c 2019-03-04 09:01:42.000000000 +0000 @@ -843,6 +843,7 @@ gchar *relative_path; gchar *canonical_path; } canonicalize_filename_checks[] = { +#ifndef G_OS_WIN32 { "/etc", "../usr/share", "/usr/share" }, { "/", "/foo/bar", "/foo/bar" }, { "/usr/bin", "../../foo/bar", "/foo/bar" }, @@ -857,7 +858,22 @@ { "///triple/slash", ".", "/triple/slash" }, { "//double/slash", ".", "//double/slash" }, { "/cwd/../with/./complexities/", "./hello", "/with/complexities/hello" }, -#ifdef G_OS_WIN32 +#else + { "/etc", "../usr/share", "\\usr\\share" }, + { "/", "/foo/bar", "\\foo\\bar" }, + { "/usr/bin", "../../foo/bar", "\\foo\\bar" }, + { "/", "../../foo/bar", "\\foo\\bar" }, + { "/double//dash", "../../foo/bar", "\\foo\\bar" }, + { "/usr/share/foo", ".././././bar", "\\usr\\share\\bar" }, + { "/foo/bar", "../bar/./.././bar", "\\foo\\bar" }, + { "/test///dir", "../../././foo/bar", "\\foo\\bar" }, + { "/test///dir", "../../././/foo///bar", "\\foo\\bar" }, + { "/etc", "///triple/slash", "\\triple\\slash" }, + { "/etc", "//double/slash", "//double/slash" }, + { "///triple/slash", ".", "\\triple\\slash" }, + { "//double/slash", ".", "//double/slash\\" }, + { "/cwd/../with/./complexities/", "./hello", "\\with\\complexities\\hello" }, + { "\\etc", "..\\usr\\share", "\\usr\\share" }, { "\\", "\\foo\\bar", "\\foo\\bar" }, { "\\usr\\bin", "..\\..\\foo\\bar", "\\foo\\bar" }, @@ -870,8 +886,8 @@ { "\\etc", "\\\\\\triple\\slash", "\\triple\\slash" }, { "\\etc", "\\\\double\\slash", "\\\\double\\slash" }, { "\\\\\\triple\\slash", ".", "\\triple\\slash" }, - { "\\\\double\\slash", ".", "\\\\double\\slash" }, - { "\\cwd\\..\\with\\.\\complexities\\", ".\\hello", "\\cwd\\with\\complexities\\hello" }, + { "\\\\double\\slash", ".", "\\\\double\\slash\\" }, + { "\\cwd\\..\\with\\.\\complexities\\", ".\\hello", "\\with\\complexities\\hello" }, #endif }; const guint n_canonicalize_filename_checks = G_N_ELEMENTS (canonicalize_filename_checks);