summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2015-03-03 19:12:16 +0000
committerRichard Hughes <richard@hughsie.com>2015-03-03 19:12:16 +0000
commita90d5e18dbd061b4dc01c41f8fac4762e401655b (patch)
treeb3294c7d832d40d025286f22d72ded61d9c06ffd
parentc90e4f94e136ec0ff2cbfe31f93f42c629d8ec5b (diff)
downloadappstream-glib-a90d5e18dbd061b4dc01c41f8fac4762e401655b.tar.gz
Add as_utils_load_inf_file()
This is for future use when loading firmware files.
-rw-r--r--data/tests/Makefile.am1
-rw-r--r--data/tests/example.inf50
-rw-r--r--libappstream-glib/as-self-test.c33
-rw-r--r--libappstream-glib/as-utils.c106
-rw-r--r--libappstream-glib/as-utils.h2
5 files changed, 192 insertions, 0 deletions
diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
index 375178e..dd7033c 100644
--- a/data/tests/Makefile.am
+++ b/data/tests/Makefile.am
@@ -14,6 +14,7 @@ test_files = \
composite-1-1.fc21.x86_64.rpm \
example.appdata.xml \
example.desktop \
+ example.inf \
example.metainfo.xml \
example-v04.xml.gz \
example-v06.yml.gz \
diff --git a/data/tests/example.inf b/data/tests/example.inf
new file mode 100644
index 0000000..62b1d21
--- /dev/null
+++ b/data/tests/example.inf
@@ -0,0 +1,50 @@
+; Copyright (C) 2015 Hughski Limited
+
+[Version]
+Signature="$WINDOWS NT$"
+Class=Firmware
+ClassGuid={84f40464-9272-4ef7-9399-cd95f12da696}
+Provider=%Provider%
+DriverVer=03/03/2015,2.0.2
+PnpLockdown=1
+CatalogFile=firmware.cat
+
+[Manufacturer]
+%MfgName% = Hughski,NTamd64
+
+[Hughski.NTamd64]
+%FirmwareDesc% = Firmware_Install,firmware\RES_{84f40464-9272-4ef7-9399-cd95f12da695}
+
+[Firmware_Install.NT]
+CopyFiles = Firmware_CopyFiles
+
+[Firmware_CopyFiles]
+firmware.bin
+
+[Firmware_Install.NT.Hw]
+AddReg = Firmware_AddReg
+
+[Firmware_AddReg]
+HKR,,FirmwareId,,{84f40464-9272-4ef7-9399-cd95f12da695}
+HKR,,FirmwareVersion,%REG_DWORD%,0x0000000
+HKR,,FirmwareFilename,,firmware.bin
+
+[SourceDisksNames]
+1 = %DiskName%
+
+[SourceDisksFiles]
+firmware.bin = 1
+
+[DestinationDirs]
+DefaultDestDir = %DIRID_WINDOWS%,Firmware ; %SystemRoot%\Firmware
+
+[Strings]
+; localizable
+Provider = "Hughski"
+MfgName = "Hughski Limited"
+FirmwareDesc = "ColorHug Firmware"
+DiskName = "Firmware for the ColorHug Colorimeter"
+
+; non-localizable
+DIRID_WINDOWS = 10
+REG_DWORD = 0x00010001
diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c
index 69eb0be..5baea2a 100644
--- a/libappstream-glib/as-self-test.c
+++ b/libappstream-glib/as-self-test.c
@@ -3288,6 +3288,38 @@ as_test_store_speed_yaml_func (void)
}
static void
+as_test_utils_inf_func (void)
+{
+ GError *error = NULL;
+ _cleanup_free_ gchar *filename = NULL;
+ _cleanup_free_ gchar *test1 = NULL;
+ _cleanup_free_ gchar *test2 = NULL;
+ _cleanup_free_ gchar *test3 = NULL;
+ _cleanup_keyfile_unref_ GKeyFile *kf= NULL;
+
+ /* load example */
+ filename = as_test_get_filename ("example.inf");
+ kf = as_utils_load_inf_file (filename, &error);
+ g_assert_no_error (error);
+ g_assert (kf != NULL);
+
+ /* simple */
+ test1 = g_key_file_get_string (kf, "Version", "Class", &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (test1, ==, "Firmware");
+
+ /* key replacement */
+ test2 = g_key_file_get_string (kf, "Firmware_CopyFiles", "Value000", &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (test2, ==, "firmware.bin");
+
+ /* double quotes swallowing */
+ test3 = g_key_file_get_string (kf, "Strings", "FirmwareDesc", &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (test3, ==, "ColorHug Firmware");
+}
+
+static void
as_test_utils_install_filename_func (void)
{
gboolean ret;
@@ -3396,6 +3428,7 @@ main (int argc, char **argv)
g_test_add_func ("/AppStream/utils{icons}", as_test_utils_icons_func);
g_test_add_func ("/AppStream/utils{spdx-token}", as_test_utils_spdx_token_func);
g_test_add_func ("/AppStream/utils{install-filename}", as_test_utils_install_filename_func);
+ g_test_add_func ("/AppStream/utils{inf}", as_test_utils_inf_func);
g_test_add_func ("/AppStream/yaml", as_test_yaml_func);
g_test_add_func ("/AppStream/store", as_test_store_func);
g_test_add_func ("/AppStream/store{demote}", as_test_store_demote_func);
diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c
index c2eeb9d..82c4067 100644
--- a/libappstream-glib/as-utils.c
+++ b/libappstream-glib/as-utils.c
@@ -1523,3 +1523,109 @@ as_utils_search_tokenize (const gchar *search)
}
return values;
}
+
+/**
+ * as_utils_line_is_blank:
+ */
+static gboolean
+as_utils_line_is_blank (const gchar *str)
+{
+ guint i;
+ for (i = 0; str[i] != '\0'; i++) {
+ if (!g_ascii_isspace (str[i]))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * as_utils_remove_quotes:
+ */
+static gchar *
+as_utils_remove_quotes (const gchar *txt)
+{
+ GString *str;
+ guint i;
+
+ /* remove double quotes */
+ str = g_string_sized_new (strlen (txt));
+ for (i = 0; txt[i] != '\0'; i++) {
+ if (txt[i] == '"')
+ continue;
+ g_string_append_c (str, txt[i]);
+ }
+ return g_string_free (str, FALSE);
+}
+
+/**
+ * as_utils_load_inf_file:
+ * @filename: the .inf file to open
+ * @error: A #GError or %NULL
+ *
+ * Repairs an .inf file and opens it as a keyfile.
+ *
+ * Returns: (transfer full): a #GKeyFile, or %NULL for error
+ *
+ * Since: 0.3.5
+ */
+GKeyFile *
+as_utils_load_inf_file (const gchar *filename, GError **error)
+{
+ guint i;
+ guint idx = 0;
+ guint nokey_idx = 0;
+ _cleanup_free_ gchar *data_fixed = NULL;
+ _cleanup_free_ gchar *data = NULL;
+ _cleanup_keyfile_unref_ GKeyFile *kf = NULL;
+ _cleanup_strv_free_ gchar **lines_fixed = NULL;
+ _cleanup_strv_free_ gchar **lines = NULL;
+
+ /* load lines of keyfile */
+ if (!g_file_get_contents (filename, &data, NULL, error))
+ return NULL;
+ lines = g_strsplit (data, "\n", -1);
+ lines_fixed = g_new0 (gchar *, g_strv_length (lines));
+
+ /* verify each line, and make sane */
+ for (i = 0; lines[i] != NULL; i++) {
+
+ /* is just whitespace */
+ if (as_utils_line_is_blank (lines[i])) {
+ lines[i][0] = '\0';
+ continue;
+ }
+
+ /* convert comments */
+ if (lines[i][0] == ';') {
+ lines_fixed[idx++] = g_strdup_printf ("#%s", lines[i] + 1);
+ continue;
+ }
+
+ /* is valid section header */
+ if (g_strstr_len (lines[i], -1, "[") != NULL &&
+ g_strstr_len (lines[i], -1, "]") != NULL) {
+ lines_fixed[idx++] = g_strdup (lines[i]);
+ nokey_idx = 0;
+ continue;
+ }
+
+ /* value, possibly with quotes */
+ if (g_strstr_len (lines[i], -1, "=") != NULL) {
+ lines_fixed[idx++] = as_utils_remove_quotes (lines[i]);
+ } else {
+ /* value with no key */
+ lines_fixed[idx++] = g_strdup_printf ("Value%03i=%s",
+ nokey_idx++,
+ lines[i]);
+ continue;
+ }
+ }
+
+ /* load file */
+ kf = g_key_file_new ();
+ data_fixed = g_strjoinv ("\n", lines_fixed);
+ if (!g_key_file_load_from_data (kf, data_fixed, -1,
+ G_KEY_FILE_NONE, error))
+ return NULL;
+ return g_key_file_ref (kf);
+}
diff --git a/libappstream-glib/as-utils.h b/libappstream-glib/as-utils.h
index dd67eed..b187e5f 100644
--- a/libappstream-glib/as-utils.h
+++ b/libappstream-glib/as-utils.h
@@ -128,6 +128,8 @@ gboolean as_utils_install_filename (AsUtilsLocation location,
GError **error);
gboolean as_utils_search_token_valid (const gchar *token);
gchar **as_utils_search_tokenize (const gchar *search);
+GKeyFile *as_utils_load_inf_file (const gchar *filename,
+ GError **error);
G_END_DECLS