Skip to content

Commit

Permalink
Generalize loader searching algorithm
Browse files Browse the repository at this point in the history
Allow loader to shorten the name word by word to the point where only single word is left.
  • Loading branch information
chfast committed Aug 30, 2018
1 parent e43026c commit cd3a8f2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 23 deletions.
15 changes: 8 additions & 7 deletions include/evmc/loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,16 @@ enum evmc_loader_error_code
* "libexample-interpreter.so",
* - the "lib" prefix and file extension are stripped from the name:
* "example-interpreter"
* - all "-" are replaced with "_" to construct _full name_:
* - all "-" are replaced with "_" to construct _base name_:
* "example_interpreter",
* - the _full name_ is split by "_" char and the last item is taken to form the _short name_:
* "interpreter",
* - the name "evmc_create_" + _full name_ is checked in the library:
* - the function name "evmc_create_" + _base name_ is searched in the library:
* "evmc_create_example_interpreter",
* - then, the name "evmc_create_" + _short name_ is checked in the library:
* "evmc_create_interpreter".
* - lastly, the name "evmc_create" is checked in the library
* - if function not found, the _base name_ is shorten by skipping the first word separated by "_":
* "interpreter",
* - then, the function of the shorter name "evmc_create_" + _base name_ is searched in the library:
* "evmc_create_interpreter",
* - the name shortening continues until a function is found or the name cannot be shorten more,
* - lastly, when no function found, the function name "evmc_create" is searched in the library.
*
* If the create function is found in the library, the pointer to the function is returned.
* Otherwise, the ::EVMC_LOADER_SYMBOL_NOT_FOUND error code is signaled and NULL is returned.
Expand Down
30 changes: 14 additions & 16 deletions lib/loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
// Create name buffer with the prefix.
const char prefix[] = "evmc_create_";
const size_t prefix_length = strlen(prefix);
char name[sizeof(prefix) + PATH_MAX_LENGTH];
strcpy_s(name, sizeof(name), prefix);
char prefixed_name[sizeof(prefix) + PATH_MAX_LENGTH];
strcpy_s(prefixed_name, sizeof(prefixed_name), prefix);

// Find filename in the path.
const char* sep_pos = strrchr(filename, '/');
Expand All @@ -87,30 +87,28 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
if (strncmp(name_pos, lib_prefix, lib_prefix_length) == 0)
name_pos += lib_prefix_length;

strcpy_s(name + prefix_length, PATH_MAX_LENGTH, name_pos);
char* base_name = prefixed_name + prefix_length;
strcpy_s(base_name, PATH_MAX_LENGTH, name_pos);

// Trim the file extension.
char* ext_pos = strrchr(name, '.');
char* ext_pos = strrchr(prefixed_name, '.');
if (ext_pos)
*ext_pos = 0;

// Replace all "-" with "_".
char* dash_pos = name;
char* dash_pos = base_name;
while ((dash_pos = strchr(dash_pos, '-')) != NULL)
*dash_pos++ = '_';

// Search for the "full name" based function name.
create_fn = DLL_GET_CREATE_FN(handle, name);
if (!create_fn)
// Search for the built function name.
while ((create_fn = DLL_GET_CREATE_FN(handle, prefixed_name)) == NULL)
{
// Try the "short name" based function name.
const char* short_name_pos = strrchr(name, '_');
if (short_name_pos)
{
short_name_pos += 1;
memmove(name + prefix_length, short_name_pos, strlen(short_name_pos) + 1);
create_fn = DLL_GET_CREATE_FN(handle, name);
}
// Shorten the base name by skipping the `word_` segment.
const char* shorter_name_pos = strchr(base_name, '_');
if (!shorter_name_pos)
break;

memmove(base_name, shorter_name_pos + 1, strlen(shorter_name_pos) + 1);
}

if (!create_fn)
Expand Down

0 comments on commit cd3a8f2

Please sign in to comment.