4 * Copyright (c) Tuomo Valkonen 1999-2005.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
16 #include <sys/types.h>
18 #include "readconfig.h"
33 static char *userdir
=NULL
;
34 static char *sessiondir
=NULL
;
35 static char *scriptpath
=NULL
;
38 bool extl_add_searchdir(const char *dir
)
41 scriptpath
=extl_scopy(dir
);
45 char *p
=extl_scat3(dir
, ":", scriptpath
);
56 bool extl_set_searchpath(const char *path
)
74 bool extl_set_userdirs(const char *appname
)
86 extl_warn(TR("$HOME not set"));
88 libtu_asprintf(&userdir
, "%s/.%s", home
, appname
);
90 fails
-=extl_add_searchdir(userdir
);
92 libtu_asprintf(&tmp
, "%s/.%s/lib", home
, appname
);
94 fails
-=extl_add_searchdir(tmp
);
103 bool extl_set_sessiondir(const char *session
)
108 if(strchr(session
, '/')!=NULL
){
109 tmp
=extl_scopy(session
);
110 }else if(userdir
!=NULL
){
111 libtu_asprintf(&tmp
, "%s/%s", userdir
, session
);
113 extl_warn(TR("User directory not set. "
114 "Unable to set session directory."));
130 const char *extl_userdir()
136 const char *extl_sessiondir()
142 const char *extl_searchpath()
151 /*{{{ try_etcpath, do_include, etc. */
154 static int do_try(const char *dir
, const char *file
, ExtlTryConfigFn
*tryfn
,
160 libtu_asprintf(&tmp
, "%s/%s", dir
, file
);
162 return EXTL_TRYCONFIG_MEMERROR
;
164 ret
=tryfn(tmp
, tryfnparam
);
170 static int try_dir(const char *const *files
, const char *cfdir
,
171 ExtlTryConfigFn
*tryfn
, void *tryfnparam
)
173 const char *const *file
;
174 int ret
, ret2
=EXTL_TRYCONFIG_NOTFOUND
;
176 for(file
=files
; *file
!=NULL
; file
++){
178 ret
=tryfn(*file
, tryfnparam
);
180 ret
=do_try(cfdir
, *file
, tryfn
, tryfnparam
);
183 if(ret2
==EXTL_TRYCONFIG_NOTFOUND
)
191 static int try_etcpath(const char *const *files
,
192 ExtlTryConfigFn
*tryfn
, void *tryfnparam
)
194 const char *const *file
=NULL
;
195 int i
, ret
, ret2
=EXTL_TRYCONFIG_NOTFOUND
;
196 char *path
, *colon
, *dir
;
198 if(sessiondir
!=NULL
){
199 for(file
=files
; *file
!=NULL
; file
++){
200 ret
=do_try(sessiondir
, *file
, tryfn
, tryfnparam
);
203 if(ret2
==EXTL_TRYCONFIG_NOTFOUND
)
210 colon
=strchr(path
, ':');
212 dir
=extl_scopyn(path
, colon
-path
);
215 dir
=extl_scopy(path
);
221 for(file
=files
; *file
!=NULL
; file
++){
222 ret
=do_try(dir
, *file
, tryfn
, tryfnparam
);
227 if(ret2
==EXTL_TRYCONFIG_NOTFOUND
)
239 static int try_lookup(const char *file
, char **ptr
)
241 if(access(file
, F_OK
)!=0)
242 return EXTL_TRYCONFIG_NOTFOUND
;
243 *ptr
=extl_scopy(file
);
248 static int try_load(const char *file
, TryCallParam
*param
)
250 if(access(file
, F_OK
)!=0)
251 return EXTL_TRYCONFIG_NOTFOUND
;
254 extl_warn(TR("Falling back to %s."), file
);
256 if(!extl_loadfile(file
, &(param
->fn
))){
258 return EXTL_TRYCONFIG_LOAD_FAILED
;
261 return EXTL_TRYCONFIG_OK
;
265 static int try_call(const char *file
, TryCallParam
*param
)
267 int ret
=try_load(file
, param
);
269 if(ret
!=EXTL_TRYCONFIG_OK
)
272 ret
=extl_call(param
->fn
, NULL
, NULL
);
274 extl_unref_fn(param
->fn
);
276 return (ret
? EXTL_TRYCONFIG_OK
: EXTL_TRYCONFIG_CALL_FAILED
);
280 static int try_read_savefile(const char *file
, TryCallParam
*param
)
282 int ret
=try_load(file
, param
);
284 if(ret
!=EXTL_TRYCONFIG_OK
)
287 ret
=extl_call(param
->fn
, NULL
, "t", &(param
->tab
));
289 extl_unref_fn(param
->fn
);
291 return (ret
? EXTL_TRYCONFIG_OK
: EXTL_TRYCONFIG_CALL_FAILED
);
295 int extl_try_config(const char *fname
, const char *cfdir
,
296 ExtlTryConfigFn
*tryfn
, void *tryfnparam
,
297 const char *ext1
, const char *ext2
)
299 char *files
[]={NULL
, NULL
, NULL
, NULL
};
300 int n
=0, ret
=EXTL_TRYCONFIG_NOTFOUND
, ret2
;
301 bool search
=FALSE
, has_ext
;
303 /* Search etcpath only if path is not absolute */
304 search
=(fname
[0]!='/');
306 /* Build list of files to look for */
307 has_ext
=strrchr(fname
, '.')>strrchr(fname
, '/');
311 files
[n
]=extl_scat3(fname
, ".", ext1
);
317 files
[n
]=extl_scat3(fname
, ".", ext2
);
323 if(has_ext
|| !search
){
324 files
[n
]=extl_scopy(fname
);
329 /* NOTE for future changes: cfdir must not be scanned first for
330 * user configuration files to take precedence.
333 /* Scan through all possible files */
335 ret2
=try_etcpath((const char**)&files
, tryfn
, tryfnparam
);
336 if(ret
==EXTL_TRYCONFIG_NOTFOUND
)
339 ret
=try_dir((const char**)&files
, cfdir
, tryfn
, tryfnparam
);
341 ret
=try_dir((const char**)&files
, NULL
, tryfn
, tryfnparam
);
352 * Lookup script \var{file}. If \var{try_in_dir} is set, it is tried
353 * before the standard search path.
356 char *extl_lookup_script(const char *file
, const char *sp
)
358 const char *files
[]={NULL
, NULL
};
365 try_dir(files
, sp
, (ExtlTryConfigFn
*)try_lookup
, &tmp
);
367 try_etcpath(files
, (ExtlTryConfigFn
*)try_lookup
, &tmp
);
373 static int warn_notfound(const char *file
, void *param
)
375 warn(TR("Tried: '%s'"), file
);
377 return EXTL_TRYCONFIG_NOTFOUND
;
380 bool extl_read_config(const char *file
, const char *sp
, bool warn_nx
)
390 retval
=extl_try_config(file
, sp
, (ExtlTryConfigFn
*)try_call
, ¶m
,
391 EXTL_COMPILED_EXTENSION
, EXTL_EXTENSION
);
393 if(retval
==EXTL_TRYCONFIG_NOTFOUND
&& warn_nx
){
394 extl_warn(TR("Unable to find '%s.%s' or '%s.%s' on search path..."),
395 file
, EXTL_COMPILED_EXTENSION
, file
, EXTL_EXTENSION
);
396 extl_try_config(file
, sp
, (ExtlTryConfigFn
*)warn_notfound
, NULL
,
397 EXTL_COMPILED_EXTENSION
, EXTL_EXTENSION
);
400 return (retval
==EXTL_TRYCONFIG_OK
);
404 bool extl_read_savefile(const char *basename
, ExtlTab
*tabret
)
410 param
.tab
=extl_table_none();
412 retval
=extl_try_config(basename
, NULL
, (ExtlTryConfigFn
*)try_read_savefile
,
413 ¶m
, EXTL_EXTENSION
, NULL
);
417 return (retval
==EXTL_TRYCONFIG_OK
);
424 EXTL_EXPORT_AS(extl
, read_savefile
)
425 ExtlTab
extl_extl_read_savefile(const char *basename
)
428 if(!extl_read_savefile(basename
, &tab
))
429 return extl_table_none();
437 /*{{{ extl_get_savefile */
440 static bool ensuredir(char *f
)
446 if(access(f
, F_OK
)==0)
449 if(mkdir(f
, 0700)==0)
454 extl_warn_err_obj(f
);
463 if(mkdir(f
, 0700)==0)
466 extl_warn_err_obj(f
);
472 * Get a file name to save (session) data in. The string \var{basename}
473 * should contain no path or extension components.
476 char *extl_get_savefile(const char *basename
)
483 if(!ensuredir(sessiondir
)){
484 extl_warn(TR("Unable to create session directory \"%s\"."),
489 libtu_asprintf(&res
, "%s/%s." EXTL_EXTENSION
, sessiondir
, basename
);
496 * Write \var{tab} in file with basename \var{basename} in the
500 bool extl_write_savefile(const char *basename
, ExtlTab tab
)
503 char *fname
=extl_get_savefile(basename
);
506 ret
=extl_serialise(fname
, tab
);