2828
2929/* -- Methods -- */
3030
31+ static int configuration_path_from_library_path (dynlink_path library_relative_path , const char relative_path [], size_t relative_path_size )
32+ {
33+ static const char library_name [] = "metacall"
34+ #if (!defined(NDEBUG ) || defined(DEBUG ) || defined(_DEBUG ) || defined(__DEBUG ) || defined(__DEBUG__ ))
35+ "d"
36+ #endif
37+ ;
38+
39+ dynlink_path library_path , join_path ;
40+
41+ size_t size , length = 0 ;
42+
43+ if (dynlink_library_path (library_name , library_path , & length ) != 0 )
44+ {
45+ return 1 ;
46+ }
47+
48+ /* Get the current folder without the library */
49+ size = portability_path_get_directory_inplace (library_path , length + 1 );
50+
51+ /* Append the relative path */
52+ size = portability_path_join (library_path , size , relative_path , relative_path_size , join_path , PORTABILITY_PATH_SIZE );
53+
54+ /* Make it cannonical */
55+ size = portability_path_canonical (join_path , size , library_relative_path , PORTABILITY_PATH_SIZE );
56+
57+ return size == 0 ;
58+ }
59+
3160int configuration_initialize (const char * reader , const char * path , void * allocator )
3261{
3362 configuration global = NULL ;
@@ -39,12 +68,20 @@ int configuration_initialize(const char *reader, const char *path, void *allocat
3968 return 1 ;
4069 }
4170
71+ /* The order of precedence is:
72+ * 1) Environment variable
73+ * 2) Default relative path to metacall library
74+ * 3) Locate it relative to metacall library install path
75+ * 4) Default installation path (if any)
76+ */
4277 if (path == NULL )
4378 {
4479 static const char configuration_path [] = CONFIGURATION_PATH ;
4580
4681 const char * env_path = environment_variable_get (configuration_path , NULL );
4782
83+ dynlink_path library_relative_path ;
84+
4885 if (env_path != NULL )
4986 {
5087 global = configuration_object_initialize (CONFIGURATION_GLOBAL_SCOPE , env_path , NULL );
@@ -56,9 +93,24 @@ int configuration_initialize(const char *reader, const char *path, void *allocat
5693 {
5794 static const char configuration_default_path [] = CONFIGURATION_DEFAULT_PATH ;
5895
59- global = configuration_object_initialize (CONFIGURATION_GLOBAL_SCOPE , configuration_default_path , NULL );
96+ if (configuration_path_from_library_path (library_relative_path , configuration_default_path , sizeof (configuration_default_path )) == 0 )
97+ {
98+ global = configuration_object_initialize (CONFIGURATION_GLOBAL_SCOPE , library_relative_path , NULL );
99+
100+ path = library_relative_path ;
101+ }
102+ }
103+
104+ if (global == NULL )
105+ {
106+ static const char relative_path [] = ".." ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR "share" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR "metacall" ENVIRONMENT_VARIABLE_PATH_SEPARATOR_STR CONFIGURATION_DEFAULT_PATH ;
107+
108+ if (configuration_path_from_library_path (library_relative_path , relative_path , sizeof (relative_path )) == 0 )
109+ {
110+ global = configuration_object_initialize (CONFIGURATION_GLOBAL_SCOPE , library_relative_path , NULL );
60111
61- path = configuration_default_path ;
112+ path = library_relative_path ;
113+ }
62114 }
63115
64116#if defined(CONFIGURATION_INSTALL_PATH )
0 commit comments