]> sigrok.org Git - libsigrok.git/commitdiff
Introduce sr_resourcepaths_get()
authorSoeren Apel <redacted>
Sat, 17 Mar 2018 20:21:32 +0000 (21:21 +0100)
committerUwe Hermann <redacted>
Sun, 18 Mar 2018 17:25:36 +0000 (18:25 +0100)
This provides an interface to fix #1128.

include/libsigrok/proto.h
src/resource.c

index 08e12496d1903e88a40f2aa51db6c55595be414d..350cffa35127a86d75a33623d82301114cba452e 100644 (file)
@@ -229,6 +229,8 @@ typedef int (*sr_resource_close_callback)(struct sr_resource *res,
 typedef gssize (*sr_resource_read_callback)(const struct sr_resource *res,
                void *buf, size_t count, void *cb_data);
 
+SR_API GSList *sr_resourcepaths_get(int res_type);
+
 SR_API int sr_resource_set_hooks(struct sr_context *ctx,
                sr_resource_open_callback open_cb,
                sr_resource_close_callback close_cb,
index ec32a4420f7755de5c5491047a756c59d56d3ba7..1e8d9458a0709a6d1bdc7199186c4d276d93cf17 100644 (file)
  * Access to resource files.
  */
 
-/** Retrieve the size of the open stream @a file.
+/**
+ * Get a list of paths where we look for resource (e.g. firmware) files.
+ *
+ * @param res_type The type of resource to get the search paths for.
+ *
+ * @return List of strings that must be freed after use, including the strings.
+ *
+ * @since 0.6.0
+ */
+SR_API GSList *sr_resourcepaths_get(int res_type)
+{
+       const char *subdir = NULL;
+       GSList *l = NULL;
+       const char *env;
+       const char *const *datadirs;
+
+       if (res_type == SR_RESOURCE_FIRMWARE) {
+               subdir = "sigrok-firmware";
+
+               env = g_getenv("SIGROK_FIRMWARE_DIR");
+               if (!env)
+                       sr_dbg("SIGROK_FIRMWARE_DIR environment variable not set, ignoring.");
+               else
+                       l = g_slist_append(l, g_strdup(env));
+       }
+
+       l = g_slist_append(l, g_build_filename(g_get_user_data_dir(), subdir, NULL));
+
+#ifdef FIRMWARE_DIR
+       if (res_type == SR_RESOURCE_FIRMWARE) {
+               /*
+                * Scan the hard-coded directory before the system directories to
+                * avoid picking up possibly outdated files from a system install.
+                */
+               l = g_slist_append(l, g_strdup(FIRMWARE_DIR));
+       }
+#endif
+
+       datadirs = g_get_system_data_dirs();
+       while (*datadirs)
+               l = g_slist_append(l, g_build_filename(*datadirs++, subdir, NULL));
+
+       return l;
+}
+
+/**
+ * Retrieve the size of the open stream @a file.
  *
  * This function only works on seekable streams. However, the set of seekable
  * streams is generally congruent with the set of streams that have a size.
@@ -98,50 +144,27 @@ static FILE *try_open_file(const char *datadir, const char *subdir,
 static int resource_open_default(struct sr_resource *res,
                const char *name, void *cb_data)
 {
+       GSList *paths, *p = NULL;
        int64_t filesize;
-#ifdef FIRMWARE_DIR
-       const char *builtindir;
-#endif
-       const char *subdir, *env;
-       const char *const *datadirs;
        FILE *file = NULL;
 
        (void)cb_data;
 
-       switch (res->type) {
-       case SR_RESOURCE_FIRMWARE:
-#ifdef FIRMWARE_DIR
-               builtindir = FIRMWARE_DIR;
-#endif
-               subdir = "sigrok-firmware";
-               break;
-       default:
+       paths = sr_resourcepaths_get(res->type);
+
+       /* Currently, the enum only defines SR_RESOURCE_FIRMWARE. */
+       if (res->type != SR_RESOURCE_FIRMWARE) {
                sr_err("%s: unknown type %d.", __func__, res->type);
                return SR_ERR_ARG;
        }
 
-       env = g_getenv("SIGROK_FIRMWARE_DIR");
-       if (!env)
-               sr_dbg("SIGROK_FIRMWARE_DIR environment variable not set, ignoring.");
-       else
-               file = try_open_file(env, "", name);
-
-       if (!file)
-               file = try_open_file(g_get_user_data_dir(), subdir, name);
-
-       /*
-        * Scan the hard-coded directory before the system directories to
-        * avoid picking up possibly outdated files from a system install.
-        */
-#ifdef FIRMWARE_DIR
-       if (!file)
-               file = try_open_file(builtindir, "", name);
-#endif
-       if (!file) {
-               datadirs = g_get_system_data_dirs();
-               while (*datadirs && !file)
-                       file = try_open_file(*datadirs++, subdir, name);
+       p = paths;
+       while (p && !file) {
+               file = try_open_file((const char *)(p->data), NULL, name);
+               p = p->next;
        }
+       g_slist_free_full(paths, g_free);
+
        if (!file) {
                sr_dbg("Failed to locate '%s'.", name);
                return SR_ERR;