summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2015-03-09 10:56:53 +0000
committerRichard Hughes <richard@hughsie.com>2015-03-09 11:03:33 +0000
commit7dfe4bc3a7394cc5dc5831f2c36bc2818583cadc (patch)
tree274515f8d41989169b0fc4eed39bf5a91fb0b216
parent28b97cd484e8f99b509ab1c97050e31fc831d3dc (diff)
downloadappstream-glib-7dfe4bc3a7394cc5dc5831f2c36bc2818583cadc.tar.gz
Support parsing .inf files into an AsApp
-rw-r--r--data/tests/example.inf4
-rw-r--r--libappstream-builder/plugins/asb-plugin-firmware.c124
-rw-r--r--libappstream-glib/Makefile.am1
-rw-r--r--libappstream-glib/as-app-inf.c187
-rw-r--r--libappstream-glib/as-app-private.h4
-rw-r--r--libappstream-glib/as-app.c10
-rw-r--r--libappstream-glib/as-app.h2
-rw-r--r--libappstream-glib/as-self-test.c51
8 files changed, 270 insertions, 113 deletions
diff --git a/data/tests/example.inf b/data/tests/example.inf
index 62b1d21..c6e2a87 100644
--- a/data/tests/example.inf
+++ b/data/tests/example.inf
@@ -9,6 +9,10 @@ DriverVer=03/03/2015,2.0.2
PnpLockdown=1
CatalogFile=firmware.cat
+; nonstandard
+[Location]
+URLs = "http://www.hughski.com/foo.cab"
+
[Manufacturer]
%MfgName% = Hughski,NTamd64
diff --git a/libappstream-builder/plugins/asb-plugin-firmware.c b/libappstream-builder/plugins/asb-plugin-firmware.c
index 20916f8..b0ec5e4 100644
--- a/libappstream-builder/plugins/asb-plugin-firmware.c
+++ b/libappstream-builder/plugins/asb-plugin-firmware.c
@@ -64,24 +64,6 @@ asb_plugin_check_filename (AsbPlugin *plugin, const gchar *filename)
}
/**
- * asb_plugin_firmware_sanitize_guid:
- */
-static gchar *
-asb_plugin_firmware_sanitize_guid (const gchar *id)
-{
- GString *id_new;
- guint i;
-
- id_new = g_string_sized_new (strlen (id));
-
- for (i = 0; id[i] != '\0'; i++) {
- if (g_ascii_isalnum (id[i]) || id[i] == '-')
- g_string_append_c (id_new, id[i]);
- }
- return g_string_free (id_new, FALSE);
-}
-
-/**
* asb_plugin_firmware_get_source_package:
*/
static gchar *
@@ -124,107 +106,33 @@ asb_plugin_process_filename (AsbPlugin *plugin,
const gchar *tmpdir,
GError **error)
{
- guint64 timestamp;
- guint i;
+ AsRelease *release;
+ GError *error_local = NULL;
_cleanup_free_ gchar *checksum = NULL;
- _cleanup_free_ gchar *class = NULL;
- _cleanup_free_ gchar *comment = NULL;
_cleanup_free_ gchar *filename_full = NULL;
- _cleanup_free_ gchar *id_new = NULL;
- _cleanup_free_ gchar *id = NULL;
_cleanup_free_ gchar *location_checksum = NULL;
- _cleanup_free_ gchar *location_url = NULL;
- _cleanup_free_ gchar *name = NULL;
_cleanup_free_ gchar *srcpkg = NULL;
- _cleanup_free_ gchar *vendor = NULL;
- _cleanup_free_ gchar *version = NULL;
- _cleanup_keyfile_unref_ GKeyFile *kf = NULL;
_cleanup_object_unref_ AsbApp *app = NULL;
- _cleanup_object_unref_ AsIcon *icon = NULL;
- _cleanup_object_unref_ AsProvide *provide = NULL;
- _cleanup_object_unref_ AsRelease *release = NULL;
-
- /* fix up the inf file */
- filename_full = g_build_filename (tmpdir, filename, NULL);
- kf = g_key_file_new ();
- if (!as_inf_load_file (kf, filename_full, AS_INF_LOAD_FLAG_NONE, error))
- return FALSE;
/* parse */
- class = g_key_file_get_string (kf, "Version", "Class", NULL);
- if (class == NULL) {
- g_set_error_literal (error,
- ASB_PLUGIN_ERROR,
- ASB_PLUGIN_ERROR_NOT_SUPPORTED,
- "Driver class is missing");
- return FALSE;
- }
- if (g_strcmp0 (class, "Firmware") != 0) {
- g_set_error (error,
- ASB_PLUGIN_ERROR,
- ASB_PLUGIN_ERROR_NOT_SUPPORTED,
- "Driver class is '%s', not 'Firmware'", class);
- return FALSE;
- }
-
- /* get the GUID */
- id = g_key_file_get_string (kf, "Version", "ClassGuid", NULL);
- if (id == NULL) {
+ filename_full = g_build_filename (tmpdir, filename, NULL);
+ app = asb_app_new (pkg, NULL);
+ if (!as_app_parse_file (AS_APP (app), filename_full,
+ AS_APP_PARSE_FLAG_NONE, &error_local)) {
g_set_error_literal (error,
ASB_PLUGIN_ERROR,
ASB_PLUGIN_ERROR_NOT_SUPPORTED,
- "Driver ID is missing");
- return FALSE;
- }
-
- /* strip any curley brackets */
- id_new = asb_plugin_firmware_sanitize_guid (id);
- app = asb_app_new (pkg, id_new);
- as_app_set_id_kind (AS_APP (app), AS_ID_KIND_FIRMWARE);
-
- /* add localizable strings */
- vendor = g_key_file_get_string (kf, "Version", "Provider", NULL);
- if (vendor == NULL)
- vendor = g_key_file_get_string (kf, "Version", "MfgName", NULL);
- if (vendor == NULL)
- vendor = g_key_file_get_string (kf, "Strings", "Provider", NULL);
- if (vendor != NULL)
- as_app_set_developer_name (AS_APP (app), NULL, vendor, -1);
- name = g_key_file_get_string (kf, "Strings", "FirmwareDesc", NULL);
- if (name != NULL)
- as_app_set_name (AS_APP (app), NULL, name, -1);
- comment = g_key_file_get_string (kf, "SourceDisksNames", "1", NULL);
- if (comment == NULL)
- comment = g_key_file_get_string (kf, "Strings", "DiskName", NULL);
- if (comment != NULL)
- as_app_set_comment (AS_APP (app), NULL, comment, -1);
-
- /* parse the DriverVer */
- version = as_inf_get_driver_version (kf, &timestamp, error);
- if (version == NULL)
+ error_local->message);
return FALSE;
-
- /* add a release with no real description */
- release = as_release_new ();
- as_release_set_version (release, version, -1);
- as_release_set_timestamp (release, timestamp);
- as_app_add_release (AS_APP (app), release);
-
- /* this is a Linux extension */
- location_url = g_key_file_get_string (kf, "Location", "URLs", NULL);
- if (location_url != NULL) {
- _cleanup_strv_free_ gchar **location_urls = NULL;
- location_urls = g_strsplit (location_url, ",", -1);
- for (i = 0; location_urls[i] != NULL; i++)
- as_release_add_location (release, location_urls[i], -1);
}
- /* checksum the .cab file */
+ /* add the checksum for the .cab file */
checksum = asb_plugin_firmware_get_checksum (asb_package_get_filename (pkg),
G_CHECKSUM_SHA1,
error);
if (checksum == NULL)
return FALSE;
+ release = as_app_get_release_default (AS_APP (app));
as_release_set_checksum (release, G_CHECKSUM_SHA1, checksum, -1);
/* this is a hack */
@@ -232,15 +140,7 @@ asb_plugin_process_filename (AsbPlugin *plugin,
if (srcpkg != NULL)
asb_package_set_source_pkgname (pkg, srcpkg);
- /* add icon */
- icon = as_icon_new ();
- as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
- as_icon_set_name (icon, "application-x-executable", -1);
- as_app_add_icon (AS_APP (app), icon);
-
asb_plugin_add_app (apps, AS_APP (app));
-
- /* add provide */
return TRUE;
}
@@ -303,7 +203,9 @@ asb_plugin_merge (AsbPlugin *plugin, GList *list)
/* remove the source package name, which doesn't make sense */
for (l = list; l != NULL; l = l->next) {
app = AS_APP (l->data);
- if (as_app_get_id_kind (app) == AS_ID_KIND_FIRMWARE)
- as_app_set_source_pkgname (app, NULL, -1);
+ if (as_app_get_id_kind (app) != AS_ID_KIND_FIRMWARE)
+ continue;
+ as_app_set_source_pkgname (app, NULL, -1);
+ as_app_remove_metadata (app, "FirmwareBasename");
}
}
diff --git a/libappstream-glib/Makefile.am b/libappstream-glib/Makefile.am
index cfde3c6..9491b2b 100644
--- a/libappstream-glib/Makefile.am
+++ b/libappstream-glib/Makefile.am
@@ -86,6 +86,7 @@ libappstream_glib_include_HEADERS = \
libappstream_glib_la_SOURCES = \
as-app.c \
as-app-desktop.c \
+ as-app-inf.c \
as-app-private.h \
as-app-validate.c \
as-bundle.c \
diff --git a/libappstream-glib/as-app-inf.c b/libappstream-glib/as-app-inf.c
new file mode 100644
index 0000000..3bb8481
--- /dev/null
+++ b/libappstream-glib/as-app-inf.c
@@ -0,0 +1,187 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013-2015 Richard Hughes <richard@hughsie.com>
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <fnmatch.h>
+#include <string.h>
+
+#include "as-app-private.h"
+#include "as-cleanup.h"
+#include "as-inf.h"
+//#include "as-utils.h"
+
+/**
+ * as_app_parse_inf_sanitize_guid:
+ */
+static gchar *
+as_app_parse_inf_sanitize_guid (const gchar *guid)
+{
+ GString *id;
+ guint i;
+
+ id = g_string_sized_new (strlen (guid));
+
+ for (i = 0; guid[i] != '\0'; i++) {
+ if (g_ascii_isalnum (guid[i]) || guid[i] == '-')
+ g_string_append_c (id, guid[i]);
+ }
+ return g_string_free (id, FALSE);
+}
+
+/**
+ * as_app_parse_inf_file:
+ **/
+gboolean
+as_app_parse_inf_file (AsApp *app,
+ const gchar *filename,
+ AsAppParseFlags flags,
+ GError **error)
+{
+ guint64 timestamp;
+ guint i;
+ _cleanup_error_free_ GError *error_local = NULL;
+ _cleanup_free_ gchar *class = NULL;
+ _cleanup_free_ gchar *comment = NULL;
+ _cleanup_free_ gchar *filename_full = NULL;
+ _cleanup_free_ gchar *firmware_basename = NULL;
+ _cleanup_free_ gchar *guid = NULL;
+ _cleanup_free_ gchar *id = NULL;
+ _cleanup_free_ gchar *location_checksum = NULL;
+ _cleanup_free_ gchar *location_url = NULL;
+ _cleanup_free_ gchar *name = NULL;
+ _cleanup_free_ gchar *srcpkg = NULL;
+ _cleanup_free_ gchar *vendor = NULL;
+ _cleanup_free_ gchar *version = NULL;
+ _cleanup_keyfile_unref_ GKeyFile *kf = NULL;
+ _cleanup_object_unref_ AsIcon *icon = NULL;
+ _cleanup_object_unref_ AsProvide *provide = NULL;
+ _cleanup_object_unref_ AsRelease *release = NULL;
+ _cleanup_strv_free_ gchar **source_keys = NULL;
+
+ /* load file */
+ kf = g_key_file_new ();
+ if (!as_inf_load_file (kf, filename, AS_INF_LOAD_FLAG_NONE, &error_local)) {
+ g_set_error (error,
+ AS_APP_ERROR,
+ AS_APP_ERROR_INVALID_TYPE,
+ "Failed to parse %s: %s",
+ filename, error_local->message);
+ return FALSE;
+ }
+
+ /* get the type of .inf file */
+ class = g_key_file_get_string (kf, "Version", "Class", NULL);
+ if (class == NULL) {
+ g_set_error_literal (error,
+ AS_APP_ERROR,
+ AS_APP_ERROR_INVALID_TYPE,
+ "Driver class is missing");
+ return FALSE;
+ }
+ if (g_strcmp0 (class, "Firmware") != 0) {
+ g_set_error (error,
+ AS_APP_ERROR,
+ AS_APP_ERROR_INVALID_TYPE,
+ "Driver class is '%s', not 'Firmware'", class);
+ return FALSE;
+ }
+ as_app_set_id_kind (app, AS_ID_KIND_FIRMWARE);
+
+ /* get the GUID */
+ guid = g_key_file_get_string (kf, "Version", "ClassGuid", NULL);
+ if (guid == NULL) {
+ g_set_error_literal (error,
+ AS_APP_ERROR,
+ AS_APP_ERROR_INVALID_TYPE,
+ "Driver ID is missing");
+ return FALSE;
+ }
+
+ /* strip any curley brackets */
+ id = as_app_parse_inf_sanitize_guid (guid);
+ as_app_set_id (app, id, -1);
+
+ /* get vendor */
+ vendor = g_key_file_get_string (kf, "Version", "Provider", NULL);
+ if (vendor == NULL)
+ vendor = g_key_file_get_string (kf, "Version", "MfgName", NULL);
+ if (vendor == NULL) /* FIXME: is a hack */
+ vendor = g_key_file_get_string (kf, "Strings", "Provider", NULL);
+ if (vendor != NULL)
+ as_app_set_developer_name (app, NULL, vendor, -1);
+
+ /* get name */
+ name = g_key_file_get_string (kf, "Strings", "FirmwareDesc", NULL);
+ if (name != NULL)
+ as_app_set_name (app, NULL, name, -1);
+
+ /* get comment */
+ comment = g_key_file_get_string (kf, "SourceDisksNames", "1", NULL);
+ if (comment == NULL) /* FIXME: is a hack */
+ comment = g_key_file_get_string (kf, "Strings", "DiskName", NULL);
+ if (comment != NULL)
+ as_app_set_comment (app, NULL, comment, -1);
+
+ /* parse the DriverVer */
+ version = as_inf_get_driver_version (kf, &timestamp, error);
+ if (version == NULL)
+ return FALSE;
+
+ /* find the firmware file we're installing */
+ source_keys = g_key_file_get_keys (kf, "SourceDisksFiles", NULL, NULL);
+ if (source_keys != NULL && g_strv_length (source_keys) == 1) {
+ firmware_basename = g_strdup (source_keys[0]);
+ } else {
+ firmware_basename = g_key_file_get_string (kf,
+ "Firmware_CopyFiles",
+ "value000", NULL);
+ }
+ if (firmware_basename == NULL) {
+ g_set_error (error,
+ AS_APP_ERROR,
+ AS_APP_ERROR_INVALID_TYPE,
+ "no SourceDisksFiles or Firmware_CopyFiles");
+ return FALSE;
+ }
+ as_app_add_metadata (app, "FirmwareBasename", firmware_basename, -1);
+
+ /* add a release with no real description */
+ release = as_release_new ();
+ as_release_set_version (release, version, -1);
+ as_release_set_timestamp (release, timestamp);
+ as_app_add_release (app, release);
+
+ /* this is a Linux extension */
+ location_url = g_key_file_get_string (kf, "Location", "URLs", NULL);
+ if (location_url != NULL) {
+ _cleanup_strv_free_ gchar **location_urls = NULL;
+ location_urls = g_strsplit (location_url, ",", -1);
+ for (i = 0; location_urls[i] != NULL; i++)
+ as_release_add_location (release, location_urls[i], -1);
+ }
+
+ /* add icon */
+ icon = as_icon_new ();
+ as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
+ as_icon_set_name (icon, "application-x-executable", -1);
+ as_app_add_icon (app, icon);
+
+ return TRUE;
+}
diff --git a/libappstream-glib/as-app-private.h b/libappstream-glib/as-app-private.h
index 63d3530..d5e74d7 100644
--- a/libappstream-glib/as-app-private.h
+++ b/libappstream-glib/as-app-private.h
@@ -94,6 +94,10 @@ gboolean as_app_parse_desktop_file (AsApp *app,
const gchar *filename,
AsAppParseFlags flags,
GError **error);
+gboolean as_app_parse_inf_file (AsApp *app,
+ const gchar *filename,
+ AsAppParseFlags flags,
+ GError **error);
G_END_DECLS
diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c
index 6b5c53c..4fadc7f 100644
--- a/libappstream-glib/as-app.c
+++ b/libappstream-glib/as-app.c
@@ -143,6 +143,8 @@ as_app_source_kind_from_string (const gchar *source_kind)
return AS_APP_SOURCE_KIND_METAINFO;
if (g_strcmp0 (source_kind, "desktop") == 0)
return AS_APP_SOURCE_KIND_DESKTOP;
+ if (g_strcmp0 (source_kind, "inf") == 0)
+ return AS_APP_SOURCE_KIND_INF;
return AS_APP_SOURCE_KIND_UNKNOWN;
}
@@ -167,6 +169,8 @@ as_app_source_kind_to_string (AsAppSourceKind source_kind)
return "metainfo";
if (source_kind == AS_APP_SOURCE_KIND_DESKTOP)
return "desktop";
+ if (source_kind == AS_APP_SOURCE_KIND_INF)
+ return "inf";
return NULL;
}
@@ -237,6 +241,8 @@ as_app_guess_source_kind (const gchar *filename)
return AS_APP_SOURCE_KIND_METAINFO;
if (g_str_has_suffix (filename, ".xml"))
return AS_APP_SOURCE_KIND_APPSTREAM;
+ if (g_str_has_suffix (filename, ".inf"))
+ return AS_APP_SOURCE_KIND_INF;
return AS_APP_SOURCE_KIND_UNKNOWN;
}
@@ -4500,6 +4506,10 @@ as_app_parse_file (AsApp *app,
if (!as_app_parse_appdata_file (app, filename, flags, error))
return FALSE;
break;
+ case AS_APP_SOURCE_KIND_INF:
+ if (!as_app_parse_inf_file (app, filename, flags, error))
+ return FALSE;
+ break;
default:
g_set_error (error,
AS_APP_ERROR,
diff --git a/libappstream-glib/as-app.h b/libappstream-glib/as-app.h
index 59d104a..d3cd076 100644
--- a/libappstream-glib/as-app.h
+++ b/libappstream-glib/as-app.h
@@ -163,6 +163,7 @@ typedef enum {
* @AS_APP_SOURCE_KIND_DESKTOP: Sourced from a desktop file
* @AS_APP_SOURCE_KIND_APPDATA: Sourced from a AppData file
* @AS_APP_SOURCE_KIND_METAINFO: Sourced from a MetaInfo file
+ * @AS_APP_SOURCE_KIND_INF: Sourced from a inf file
*
* The source kind.
**/
@@ -172,6 +173,7 @@ typedef enum {
AS_APP_SOURCE_KIND_DESKTOP, /* Since: 0.1.4 */
AS_APP_SOURCE_KIND_APPDATA, /* Since: 0.1.4 */
AS_APP_SOURCE_KIND_METAINFO, /* Since: 0.1.7 */
+ AS_APP_SOURCE_KIND_INF, /* Since: 0.3.5 */
/*< private >*/
AS_APP_SOURCE_KIND_LAST
} AsAppSourceKind;
diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c
index 33f3b96..b81a84a 100644
--- a/libappstream-glib/as-self-test.c
+++ b/libappstream-glib/as-self-test.c
@@ -1458,7 +1458,7 @@ as_test_app_validate_style_func (void)
}
static void
-as_test_app_parse_file_func (void)
+as_test_app_parse_file_desktop_func (void)
{
AsIcon *ic;
GError *error = NULL;
@@ -1521,6 +1521,52 @@ as_test_app_parse_file_func (void)
}
static void
+as_test_app_parse_file_inf_func (void)
+{
+ AsIcon *ic;
+ AsRelease *rel;
+ GError *error = NULL;
+ GPtrArray *releases;
+ gboolean ret;
+ _cleanup_free_ gchar *filename = NULL;
+ _cleanup_object_unref_ AsApp *app = NULL;
+
+ /* create an AsApp from a desktop file */
+ app = as_app_new ();
+ filename = as_test_get_filename ("example.inf");
+ ret = as_app_parse_file (app,
+ filename,
+ AS_APP_PARSE_FLAG_NONE,
+ &error);
+ g_assert_no_error (error);
+ g_assert (ret);
+
+ /* test things we found */
+ g_assert_cmpstr (as_app_get_name (app, "C"), ==, "ColorHug Firmware");
+ g_assert_cmpstr (as_app_get_comment (app, "C"), ==,
+ "Firmware for the ColorHug Colorimeter");
+ g_assert_cmpstr (as_app_get_source_file (app), ==, filename);
+
+ /* check icon */
+ g_assert_cmpint (as_app_get_icons(app)->len, ==, 1);
+ ic = as_app_get_icon_default (app);
+ g_assert (ic != NULL);
+ g_assert_cmpstr (as_icon_get_name (ic), ==, "application-x-executable");
+ g_assert_cmpint (as_icon_get_kind (ic), ==, AS_ICON_KIND_STOCK);
+ g_assert_cmpint (as_icon_get_width (ic), ==, 0);
+ g_assert_cmpint (as_icon_get_height (ic), ==, 0);
+
+ /* check releases */
+ releases = as_app_get_releases (app);
+ g_assert_cmpint (releases->len, ==, 1);
+ rel = g_ptr_array_index (releases, 0);
+ g_assert_cmpstr (as_release_get_location_default (rel), ==, "http://www.hughski.com/foo.cab");
+ g_assert_cmpint (as_release_get_timestamp (rel), ==, 1425340800);
+ g_assert_cmpstr (as_release_get_version (rel), ==, "2.0.2");
+ //g_assert_cmpstr (as_release_get_description (rel), ==, "XXX");
+}
+
+static void
as_test_app_no_markup_func (void)
{
GError *error = NULL;
@@ -3708,7 +3754,8 @@ main (int argc, char **argv)
g_test_add_func ("/AppStream/app{validate-file-bad}", as_test_app_validate_file_bad_func);
g_test_add_func ("/AppStream/app{validate-meta-bad}", as_test_app_validate_meta_bad_func);
g_test_add_func ("/AppStream/app{validate-intltool}", as_test_app_validate_intltool_func);
- g_test_add_func ("/AppStream/app{parse-file}", as_test_app_parse_file_func);
+ g_test_add_func ("/AppStream/app{parse-file:desktop}", as_test_app_parse_file_desktop_func);
+ g_test_add_func ("/AppStream/app{parse-file:inf}", as_test_app_parse_file_inf_func);
g_test_add_func ("/AppStream/app{no-markup}", as_test_app_no_markup_func);
g_test_add_func ("/AppStream/app{subsume}", as_test_app_subsume_func);
g_test_add_func ("/AppStream/app{search}", as_test_app_search_func);