int idx;
const char *prefix;
const char *suffix;
+ gboolean first_call;
int prlen;
+ int suffixlen;
char *res;
+
if (!iter)
return NULL;
+
+ /*
+ The first time we are called, idx = 0 (as *iter is initialized to NULL). This is our
+ "bootstrap" phase in which we check the passed name verbatim and only if we fail to find
+ the dll thus named, we start appending suffixes, each time increasing idx twice (since now
+ the 0 value became special and we need to offset idx to a 0-based array index). This is
+ done to handle situations when mapped dll name is specified as libsomething.so.1 or
+ libsomething.so.1.1 or libsomething.so - testing it algorithmically would be an overkill
+ here.
+ */
idx = GPOINTER_TO_UINT (*iter);
- if (idx >= G_N_ELEMENTS (suffixes))
- return NULL;
+ if (idx == 0) {
+ first_call = TRUE;
+ suffix = "";
+ suffixlen = 0;
+ } else {
+ idx--;
+ if (idx >= G_N_ELEMENTS (suffixes))
+ return NULL;
+ first_call = FALSE;
+ suffix = suffixes [idx];
+ suffixlen = strlen (suffix);
+ }
prlen = strlen (SOPREFIX);
if (prlen && strncmp (name, SOPREFIX, prlen) != 0)
prefix = SOPREFIX;
else
prefix = "";
- /* if the platform prefix is already provided, we suppose the caller knows the full name already */
- if (prlen && strncmp (name, SOPREFIX, prlen) == 0)
+
+ if (first_call || (suffixlen && strstr (name, suffix) == (name + strlen (name) - suffixlen)))
suffix = "";
- else
- suffix = suffixes [idx];
+
if (directory && *directory)
- res = g_strconcat (directory, G_DIR_SEPARATOR_S, prefix, name, suffixes [idx], NULL);
+ res = g_strconcat (directory, G_DIR_SEPARATOR_S, prefix, name, suffix, NULL);
else
- res = g_strconcat (prefix, name, suffixes [idx], NULL);
+ res = g_strconcat (prefix, name, suffix, NULL);
++idx;
+ if (!first_call)
+ idx++;
*iter = GUINT_TO_POINTER (idx);
return res;
}