diff options
author | Richard Hughes <richard@hughsie.com> | 2015-03-03 19:12:16 +0000 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2015-03-03 19:12:16 +0000 |
commit | a90d5e18dbd061b4dc01c41f8fac4762e401655b (patch) | |
tree | b3294c7d832d40d025286f22d72ded61d9c06ffd | |
parent | c90e4f94e136ec0ff2cbfe31f93f42c629d8ec5b (diff) | |
download | appstream-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.am | 1 | ||||
-rw-r--r-- | data/tests/example.inf | 50 | ||||
-rw-r--r-- | libappstream-glib/as-self-test.c | 33 | ||||
-rw-r--r-- | libappstream-glib/as-utils.c | 106 | ||||
-rw-r--r-- | libappstream-glib/as-utils.h | 2 |
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 |