@@ -48,7 +48,7 @@ static int path_is_relative(jv p) {
4848// in the following order:
4949// 1. lib_path
5050// 2. -L paths passed in on the command line (from jq_state*) or builtin list
51- static jv build_lib_search_chain (jq_state * jq , jv search_path , jv jq_origin , jv lib_origin ) {
51+ static jv build_lib_search_chain (jq_state * jq , jv search_path , jv xdg_config_home , jv jq_origin , jv lib_origin ) {
5252 assert (jv_get_kind (search_path ) == JV_KIND_ARRAY );
5353 jv expanded = jv_array ();
5454 jv expanded_elt ;
@@ -66,6 +66,15 @@ static jv build_lib_search_chain(jq_state *jq, jv search_path, jv jq_origin, jv
6666 }
6767 if (strcmp ("." ,jv_string_value (path )) == 0 ) {
6868 expanded_elt = jv_copy (path );
69+ } else if (strncmp ("$XDG_CONFIG_HOME/" ,jv_string_value (path ),sizeof ("$XDG_CONFIG_HOME/" ) - 1 ) == 0 ) {
70+ if (jv_is_valid (xdg_config_home )) {
71+ expanded_elt = jv_string_fmt ("%s/%s" ,
72+ jv_string_value (xdg_config_home ),
73+ jv_string_value (path ) + sizeof ("$XDG_CONFIG_HOME/" ) - 1 );
74+ } else {
75+ // Remove $XDG_CONFIG_HOME/* from the search path if $XDG_CONFIG_HOME is not defined.
76+ expanded_elt = jv_null ();
77+ }
6978 } else if (strncmp ("$ORIGIN/" ,jv_string_value (path ),sizeof ("$ORIGIN/" ) - 1 ) == 0 ) {
7079 expanded_elt = jv_string_fmt ("%s/%s" ,
7180 jv_string_value (jq_origin ),
@@ -82,6 +91,7 @@ static jv build_lib_search_chain(jq_state *jq, jv search_path, jv jq_origin, jv
8291 expanded = jv_array_append (expanded , expanded_elt );
8392 jv_free (path );
8493 }
94+ jv_free (xdg_config_home );
8595 jv_free (jq_origin );
8696 jv_free (lib_origin );
8797 jv_free (search_path );
@@ -133,23 +143,26 @@ static jv jv_basename(jv name) {
133143}
134144
135145// Asummes validated relative path to module
136- static jv find_lib (jq_state * jq , jv rel_path , jv search , const char * suffix , jv jq_origin , jv lib_origin ) {
146+ static jv find_lib (jq_state * jq , jv rel_path , jv search , const char * suffix , jv xdg_config_home , jv jq_origin , jv lib_origin ) {
137147 if (!jv_is_valid (rel_path )) {
138148 jv_free (search );
149+ jv_free (xdg_config_home );
139150 jv_free (jq_origin );
140151 jv_free (lib_origin );
141152 return rel_path ;
142153 }
143154 if (jv_get_kind (rel_path ) != JV_KIND_STRING ) {
144155 jv_free (rel_path );
145156 jv_free (search );
157+ jv_free (xdg_config_home );
146158 jv_free (jq_origin );
147159 jv_free (lib_origin );
148160 return jv_invalid_with_msg (jv_string_fmt ("Module path must be a string" ));
149161 }
150162 if (jv_get_kind (search ) != JV_KIND_ARRAY ) {
151163 jv_free (rel_path );
152164 jv_free (search );
165+ jv_free (xdg_config_home );
153166 jv_free (jq_origin );
154167 jv_free (lib_origin );
155168 return jv_invalid_with_msg (jv_string_fmt ("Module search path must be an array" ));
@@ -159,7 +172,7 @@ static jv find_lib(jq_state *jq, jv rel_path, jv search, const char *suffix, jv
159172 int ret ;
160173
161174 // Ideally we should cache this somewhere
162- search = build_lib_search_chain (jq , search , jq_origin , lib_origin );
175+ search = build_lib_search_chain (jq , search , xdg_config_home , jq_origin , lib_origin );
163176 jv err = jv_array_get (jv_copy (search ), 1 );
164177 search = jv_array_get (search , 0 );
165178
@@ -241,7 +254,7 @@ static jv default_search(jq_state *jq, jv value) {
241254}
242255
243256// XXX Split this into a util that takes a callback, and then...
244- static int process_dependencies (jq_state * jq , jv jq_origin , jv lib_origin , block * src_block , struct lib_loading_state * lib_state ) {
257+ static int process_dependencies (jq_state * jq , jv xdg_config_home , jv jq_origin , jv lib_origin , block * src_block , struct lib_loading_state * lib_state ) {
245258 jv deps = block_take_imports (src_block );
246259 block bk = * src_block ;
247260 int nerrors = 0 ;
@@ -270,7 +283,7 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block
270283 // dep is now freed; do not reuse
271284
272285 // find_lib does a lot of work that could be cached...
273- jv resolved = find_lib (jq , relpath , search , is_data ? ".json" : ".jq" , jv_copy (jq_origin ), jv_copy (lib_origin ));
286+ jv resolved = find_lib (jq , relpath , search , is_data ? ".json" : ".jq" , jv_copy (xdg_config_home ), jv_copy ( jq_origin ), jv_copy (lib_origin ));
274287 // XXX ...move the rest of this into a callback.
275288 if (!jv_is_valid (resolved )) {
276289 jv_free (as );
@@ -282,6 +295,7 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block
282295 jq_report_error (jq , jv_string_fmt ("jq: error: %s\n" ,jv_string_value (emsg )));
283296 jv_free (emsg );
284297 jv_free (deps );
298+ jv_free (xdg_config_home );
285299 jv_free (jq_origin );
286300 jv_free (lib_origin );
287301 return 1 ;
@@ -321,6 +335,7 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block
321335 jv_free (as );
322336 }
323337 jv_free (lib_origin );
338+ jv_free (xdg_config_home );
324339 jv_free (jq_origin );
325340 jv_free (deps );
326341 return nerrors ;
@@ -359,7 +374,8 @@ static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, int opt
359374 locfile_free (src );
360375 if (nerrors == 0 ) {
361376 char * lib_origin = strdup (jv_string_value (lib_path ));
362- nerrors += process_dependencies (jq , jq_get_jq_origin (jq ),
377+ nerrors += process_dependencies (jq , get_xdg_config_home (),
378+ jq_get_jq_origin (jq ),
363379 jv_string (dirname (lib_origin )),
364380 & program , lib_state );
365381 free (lib_origin );
@@ -382,7 +398,7 @@ static int load_library(jq_state *jq, jv lib_path, int is_data, int raw, int opt
382398// as we do in process_dependencies.
383399jv load_module_meta (jq_state * jq , jv mod_relpath ) {
384400 // We can't know the caller's origin; we could though, if it was passed in
385- jv lib_path = find_lib (jq , validate_relpath (mod_relpath ), jq_get_lib_dirs (jq ), ".jq" , jq_get_jq_origin (jq ), jv_null ());
401+ jv lib_path = find_lib (jq , validate_relpath (mod_relpath ), jq_get_lib_dirs (jq ), ".jq" , get_xdg_config_home (), jq_get_jq_origin (jq ), jv_null ());
386402 if (!jv_is_valid (lib_path ))
387403 return lib_path ;
388404 jv meta = jv_null ();
@@ -432,7 +448,7 @@ int load_program(jq_state *jq, struct locfile* src, block *out_block) {
432448 jv_free (home );
433449 }
434450
435- nerrors = process_dependencies (jq , jq_get_jq_origin (jq ), jq_get_prog_origin (jq ), & program , & lib_state );
451+ nerrors = process_dependencies (jq , get_xdg_config_home (), jq_get_jq_origin (jq ), jq_get_prog_origin (jq ), & program , & lib_state );
436452 block libs = gen_noop ();
437453 for (uint64_t i = 0 ; i < lib_state .ct ; ++ i ) {
438454 free (lib_state .names [i ]);
0 commit comments