[glib: 1/2] gutils: Add g_get_os_info()



commit 349318e8db35bd63508270ca44a7e894e411ab32
Author: Robert Ancell <robert ancell canonical com>
Date:   Tue Aug 27 10:50:35 2019 +0300

    gutils: Add g_get_os_info()
    
    Add a new function that gets OS information for /etc/os-release.

 docs/reference/glib/glib-sections.txt |  14 ++++
 glib/gutils.c                         |  88 ++++++++++++++++++++++++
 glib/gutils.h                         | 123 ++++++++++++++++++++++++++++++++++
 glib/tests/utils.c                    |  15 +++++
 4 files changed, 240 insertions(+)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index c67af683d..8c7923bfd 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2086,6 +2086,20 @@ g_get_user_special_dir
 g_get_system_data_dirs
 g_get_system_config_dirs
 g_reload_user_special_dirs_cache
+g_get_os_info
+
+<SUBSECTION>
+G_OS_INFO_KEY_NAME
+G_OS_INFO_KEY_PRETTY_NAME
+G_OS_INFO_KEY_VERSION
+G_OS_INFO_KEY_VERSION_CODENAME
+G_OS_INFO_KEY_VERSION_ID
+G_OS_INFO_KEY_ID
+G_OS_INFO_KEY_HOME_URL
+G_OS_INFO_KEY_DOCUMENTATION_URL
+G_OS_INFO_KEY_SUPPORT_URL
+G_OS_INFO_KEY_BUG_REPORT_URL
+G_OS_INFO_KEY_PRIVACY_POLICY_URL
 
 <SUBSECTION>
 g_get_host_name
diff --git a/glib/gutils.c b/glib/gutils.c
index e2476a963..79ee24fff 100644
--- a/glib/gutils.c
+++ b/glib/gutils.c
@@ -1154,6 +1154,94 @@ g_set_application_name (const gchar *application_name)
     g_warning ("g_set_application_name() called multiple times");
 }
 
+/**
+ * g_get_os_info:
+ * @key_name: a key for the OS info being requested, for example %G_OS_INFO_KEY_NAME.
+ *
+ * Get information about the operating system.
+ *
+ * On Linux this comes from the /etc/os-release file. On other systems, it may
+ * come from a variety of sources. You can either use the standard key names
+ * like %G_OS_INFO_KEY_NAME or pass any UTF-8 string key name. For example,
+ * /etc/os-release provides a number of other less commonly used values that may
+ * be useful. No key is guaranteed to be provided, so the caller should always
+ * check if the result is %NULL.
+ *
+ * Returns: (nullable): The associated value for the requested key or %NULL if
+ *   this information is not provided.
+ *
+ * Since: 2.64
+ **/
+gchar *
+g_get_os_info (const gchar *key_name)
+{
+#if defined (__APPLE__)
+  if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
+    return g_strdup (_("macOS"));
+  else
+    return NULL;
+#elif defined (G_OS_UNIX)
+  gchar *buffer;
+  gchar *prefix;
+  GStrv lines;
+  int i;
+  gchar *result = NULL;
+  GError *error = NULL;
+
+  g_return_val_if_fail (key_name != NULL, NULL);
+
+  if (!g_file_get_contents ("/etc/os-release", &buffer, NULL, &error))
+    {
+      gboolean file_missing;
+
+      file_missing = g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
+      g_clear_error (&error);
+
+      if (!file_missing ||
+          !g_file_get_contents ("/usr/lib/os-release", &buffer, NULL, NULL))
+        return NULL;
+    }
+
+  lines = g_strsplit (buffer, "\n", -1);
+  g_free (buffer);
+  prefix = g_strdup_printf ("%s=", key_name);
+  for (i = 0; lines[i] != NULL; i++)
+    {
+      const gchar *line = lines[i];
+      const gchar *value;
+
+      if (g_str_has_prefix (line, prefix))
+        {
+          value = line + strlen (prefix);
+          result = g_shell_unquote (value, NULL);
+          if (result == NULL)
+            result = g_strdup (value);
+          break;
+        }
+    }
+  g_strfreev (lines);
+  g_free (prefix);
+
+  /* Default values in spec */
+  if (result == NULL)
+    {
+      if (g_str_equal (key_name, G_OS_INFO_KEY_NAME))
+        return g_strdup ("Linux");
+      if (g_str_equal (key_name, G_OS_INFO_KEY_ID))
+        return g_strdup ("linux");
+      if (g_str_equal (key_name, G_OS_INFO_KEY_PRETTY_NAME))
+        return g_strdup ("Linux");
+    }
+
+  return g_steal_pointer (&result);
+#elif defined (G_OS_WIN32)
+  if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
+    return g_strdup (_("Windows"));
+  else
+    return NULL;
+#endif
+}
+
 /* 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
diff --git a/glib/gutils.h b/glib/gutils.h
index 560a84e3a..8a927d0b3 100644
--- a/glib/gutils.h
+++ b/glib/gutils.h
@@ -65,6 +65,129 @@ GLIB_AVAILABLE_IN_ALL
 const gchar *         g_get_application_name (void);
 GLIB_AVAILABLE_IN_ALL
 void                  g_set_application_name (const gchar *application_name);
+GLIB_AVAILABLE_IN_2_64
+gchar *               g_get_os_info          (const gchar *key_name);
+
+/**
+ * G_OS_INFO_KEY_NAME:
+ *
+ * A key to get the name of the operating system excluding version information suitable for presentation to 
the user, e.g. "YoYoOS"
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_NAME \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "NAME"
+
+/**
+ * G_OS_INFO_KEY_PRETTY_NAME:
+ *
+ * A key to get the name of the operating system in a format suitable for presentation to the user, e.g. 
"YoYoOS Foo"
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_PRETTY_NAME \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "PRETTY_NAME"
+
+/**
+ * G_OS_INFO_KEY_VERSION:
+ *
+ * A key to get the operating system version suitable for presentation to the user, e.g. "42 (Foo)"
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_VERSION \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "VERSION"
+
+/**
+ * G_OS_INFO_KEY_VERSION_CODENAME:
+ *
+ * A key to get a codename identifying the operating system release suitable for processing by scripts or 
usage in generated filenames, e.g. "foo"
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_VERSION_CODENAME \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "VERSION_CODENAME"
+
+/**
+ * G_OS_INFO_KEY_VERSION_ID:
+ *
+ * A key to get the version of the operating system suitable for processing by scripts or usage in generated 
filenames, e.g. "42"
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_VERSION_ID \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "VERSION_ID"
+
+/**
+ * G_OS_INFO_KEY_ID:
+ *
+ * A key to get an ID identifying the operating system suitable for processing by scripts or usage in 
generated filenames, e.g. "yoyoos"
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_ID \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "ID"
+
+/**
+ * G_OS_INFO_KEY_HOME_URL:
+ *
+ * A key to get the homepage for the operating system, e.g. "https://www.yoyo-os.com/";
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_HOME_URL \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "HOME_URL"
+
+/**
+ * G_OS_INFO_KEY_DOCUMENTATION_URL:
+ *
+ * A key to get the documentation page for the operating system, e.g. "https://docs.yoyo-os.com/";
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_DOCUMENTATION_URL \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "DOCUMENTATION_URL"
+
+/**
+ * G_OS_INFO_KEY_SUPPORT_URL:
+ *
+ * A key to get the support page for the operating system, e.g. "https://support.yoyo-os.com/";
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_SUPPORT_URL \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "SUPPORT_URL"
+
+/**
+ * G_OS_INFO_KEY_BUG_REPORT_URL:
+ *
+ * A key to get the bug reporting page for the operating system, e.g. "https://bugs.yoyo-os.com/";
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_BUG_REPORT_URL \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "BUG_REPORT_URL"
+
+/**
+ * G_OS_INFO_KEY_PRIVACY_POLICY_URL:
+ *
+ * A key to get the privacy policy for the operating system, e.g. "https://privacy.yoyo-os.com/";
+ *
+ * Since: 2.64
+ */
+#define G_OS_INFO_KEY_PRIVACY_POLICY_URL \
+    GLIB_AVAILABLE_MACRO_IN_2_64 \
+    "PRIVACY_POLICY_URL"
 
 GLIB_AVAILABLE_IN_ALL
 void      g_reload_user_special_dirs_cache     (void);
diff --git a/glib/tests/utils.c b/glib/tests/utils.c
index d1ca0b633..7dbfb1e47 100644
--- a/glib/tests/utils.c
+++ b/glib/tests/utils.c
@@ -517,6 +517,20 @@ test_desktop_special_dir (void)
   g_assert (dir2 != NULL);
 }
 
+static void
+test_os_info (void)
+{
+#if defined (G_OS_UNIX) || defined (G_OS_WIN32)
+  gchar *name;
+
+  name = g_get_os_info (G_OS_INFO_KEY_NAME);
+  g_assert (name != NULL);
+  g_free (name);
+#else
+  g_test_skip ("g_get_os_info() not supported on this platform");
+#endif
+}
+
 static gboolean
 source_test (gpointer data)
 {
@@ -767,6 +781,7 @@ main (int   argc,
 #endif
   g_test_add_func ("/utils/specialdir", test_special_dir);
   g_test_add_func ("/utils/specialdir/desktop", test_desktop_special_dir);
+  g_test_add_func ("/utils/os-info", test_os_info);
   g_test_add_func ("/utils/clear-pointer", test_clear_pointer);
   g_test_add_func ("/utils/clear-pointer-cast", test_clear_pointer_cast);
   g_test_add_func ("/utils/clear-pointer/side-effects", test_clear_pointer_side_effects);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]