Introduce sr_resourcepaths_get()
This provides an interface to fix #1128.
This commit is contained in:
parent
e843992dda
commit
addb7340dd
|
@ -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,
|
typedef gssize (*sr_resource_read_callback)(const struct sr_resource *res,
|
||||||
void *buf, size_t count, void *cb_data);
|
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_API int sr_resource_set_hooks(struct sr_context *ctx,
|
||||||
sr_resource_open_callback open_cb,
|
sr_resource_open_callback open_cb,
|
||||||
sr_resource_close_callback close_cb,
|
sr_resource_close_callback close_cb,
|
||||||
|
|
|
@ -35,7 +35,53 @@
|
||||||
* Access to resource files.
|
* 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
|
* 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.
|
* 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,
|
static int resource_open_default(struct sr_resource *res,
|
||||||
const char *name, void *cb_data)
|
const char *name, void *cb_data)
|
||||||
{
|
{
|
||||||
|
GSList *paths, *p = NULL;
|
||||||
int64_t filesize;
|
int64_t filesize;
|
||||||
#ifdef FIRMWARE_DIR
|
|
||||||
const char *builtindir;
|
|
||||||
#endif
|
|
||||||
const char *subdir, *env;
|
|
||||||
const char *const *datadirs;
|
|
||||||
FILE *file = NULL;
|
FILE *file = NULL;
|
||||||
|
|
||||||
(void)cb_data;
|
(void)cb_data;
|
||||||
|
|
||||||
switch (res->type) {
|
paths = sr_resourcepaths_get(res->type);
|
||||||
case SR_RESOURCE_FIRMWARE:
|
|
||||||
#ifdef FIRMWARE_DIR
|
/* Currently, the enum only defines SR_RESOURCE_FIRMWARE. */
|
||||||
builtindir = FIRMWARE_DIR;
|
if (res->type != SR_RESOURCE_FIRMWARE) {
|
||||||
#endif
|
|
||||||
subdir = "sigrok-firmware";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sr_err("%s: unknown type %d.", __func__, res->type);
|
sr_err("%s: unknown type %d.", __func__, res->type);
|
||||||
return SR_ERR_ARG;
|
return SR_ERR_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
env = g_getenv("SIGROK_FIRMWARE_DIR");
|
p = paths;
|
||||||
if (!env)
|
while (p && !file) {
|
||||||
sr_dbg("SIGROK_FIRMWARE_DIR environment variable not set, ignoring.");
|
file = try_open_file((const char *)(p->data), NULL, name);
|
||||||
else
|
p = p->next;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
g_slist_free_full(paths, g_free);
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
sr_dbg("Failed to locate '%s'.", name);
|
sr_dbg("Failed to locate '%s'.", name);
|
||||||
return SR_ERR;
|
return SR_ERR;
|
||||||
|
|
Loading…
Reference in New Issue