modules: Enable setting multiple loader/filter paths

IMLIB2_LOADER_PATH and IMLIB2_FILTER_PATH may now contain multiple colon
separated paths.
This commit is contained in:
Kim Woelders 2022-05-13 21:33:58 +02:00
parent d0372038fd
commit c035f8d19a
2 changed files with 102 additions and 48 deletions

View File

@ -44,9 +44,9 @@ void __imlib_FileDel(const char *s);
char *__imlib_FileHomeDir(int uid); char *__imlib_FileHomeDir(int uid);
int __imlib_ItemInList(char **list, int size, char *item); int __imlib_ItemInList(char **list, int size, char *item);
const char *__imlib_PathToFilters(void); char **__imlib_PathToFilters(void);
const char *__imlib_PathToLoaders(void); char **__imlib_PathToLoaders(void);
char **__imlib_ModulesList(const char *path, int *num_ret); char **__imlib_ModulesList(char **path, int *num_ret);
char *__imlib_ModuleFind(const char *path, const char *name); char *__imlib_ModuleFind(char **path, const char *name);
#endif #endif

View File

@ -5,6 +5,7 @@
#include <string.h> #include <string.h>
#include "file.h" #include "file.h"
#include "strutils.h"
static const char * static const char *
__imlib_PathToModules(void) __imlib_PathToModules(void)
@ -23,42 +24,70 @@ __imlib_PathToModules(void)
return PACKAGE_LIB_DIR "/imlib2"; return PACKAGE_LIB_DIR "/imlib2";
} }
const char * static char **
__imlib_PathToFilters(void) _module_paths(const char *env, const char *mdir)
{ {
static char *path = NULL; char **ppaths, **pp;
const char *penv;
char buf[1024]; char buf[1024];
if (path) penv = getenv(env);
return path; if (penv)
{
path = getenv("IMLIB2_FILTER_PATH"); ppaths = __imlib_StrSplit(penv, ':');
if (path && __imlib_FileIsDir(path)) if (!ppaths)
return path; goto done;
for (pp = ppaths; *pp; pp++)
snprintf(buf, sizeof(buf), "%s/%s", __imlib_PathToModules(), "filters"); {
path = strdup(buf); if (strcmp(*pp, "*") == 0)
{
return path; /* Substitute default path */
free(*pp);
snprintf(buf, sizeof(buf), "%s/%s",
__imlib_PathToModules(), mdir);
*pp = strdup(buf);
}
}
}
else
{
/* Use default path */
ppaths = malloc(2 * sizeof(char *));
if (!ppaths)
goto done;
snprintf(buf, sizeof(buf), "%s/%s", __imlib_PathToModules(), mdir);
ppaths[0] = strdup(buf);
ppaths[1] = NULL;
} }
const char * done:
return ppaths;
}
char **
__imlib_PathToFilters(void)
{
static char **ppaths = NULL;
if (ppaths)
return ppaths;
ppaths = _module_paths("IMLIB2_FILTER_PATH", "filters");
return ppaths;
}
char **
__imlib_PathToLoaders(void) __imlib_PathToLoaders(void)
{ {
static char *path = NULL; static char **ppaths = NULL;
char buf[1024];
if (path) if (ppaths)
return path; return ppaths;
path = getenv("IMLIB2_LOADER_PATH"); ppaths = _module_paths("IMLIB2_LOADER_PATH", "loaders");
if (path && __imlib_FileIsDir(path))
return path;
snprintf(buf, sizeof(buf), "%s/%s", __imlib_PathToModules(), "loaders"); return ppaths;
path = strdup(buf);
return path;
} }
static bool static bool
@ -81,45 +110,70 @@ _file_is_module(const char *name)
} }
char ** char **
__imlib_ModulesList(const char *path, int *num_ret) __imlib_ModulesList(char **ppath, int *num_ret)
{ {
char **list = NULL, **l; char **pp, **list, **l;
char file[1024], *p; char file[1024], *p;
int num, i, ntot; int num, i, ntot;
*num_ret = 0; *num_ret = 0;
list = NULL;
if (!ppath)
goto done;
ntot = 0; ntot = 0;
l = __imlib_FileDir(path, &num); for (pp = ppath; *pp; pp++)
{
l = __imlib_FileDir(*pp, &num);
if (!l)
continue;
if (num <= 0) if (num <= 0)
return NULL; continue;
list = malloc(num * sizeof(char *)); list = realloc(list, (ntot + num) * sizeof(char *));
if (list) if (list)
{ {
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
{ {
if (!_file_is_module(l[i])) if (!_file_is_module(l[i]))
continue; continue;
snprintf(file, sizeof(file), "%s/%s", path, l[i]); snprintf(file, sizeof(file), "%s/%s", *pp, l[i]);
p = strdup(file); p = strdup(file);
if (p) if (p)
list[ntot++] = p; list[ntot++] = p;
} }
} }
__imlib_FileFreeDirList(l, num); __imlib_FileFreeDirList(l, num);
if (!list)
goto done;
}
*num_ret = ntot; *num_ret = ntot;
done:
return list; return list;
} }
char * char *
__imlib_ModuleFind(const char *path, const char *name) __imlib_ModuleFind(char **ppath, const char *name)
{ {
char **pp;
char nbuf[4096]; char nbuf[4096];
snprintf(nbuf, sizeof(nbuf), "%s/%s.so", path, name); if (!ppath)
return NULL;
for (pp = ppath; *pp; pp++)
{
snprintf(nbuf, sizeof(nbuf), "%s/%s.so", *pp, name);
if (!__imlib_FileIsFile(nbuf))
continue;
return strdup(nbuf); return strdup(nbuf);
} }
return NULL;
}