2 This is a small cross-platform resource file locator library.
3 Author: John Tsiombikas <nuclear@siggraph.org> 2004
5 This library is public domain, you are free to do whatever you like with it,
6 NO WARANTY whatsoever is provided with this library, use it at your own risk.
16 #endif /* HAVE_CONFIG */
19 #define __USE_BSD /* to include readlink() prototype */
23 #define HOME_ENV "HOME"
25 #else /* assume WIN32 */
29 #define HOME_ENV "USERPROFILE"
39 #define CONF_ENV "NLOC_CONFIG_PATH"
40 #define DATA_ENV "NLOC_DATA_PATH"
41 #define LOC_FUNC_COUNT 2
43 typedef const char *(*loc_func_type)(const char*);
45 static const char *locate_config(const char *file);
46 static const char *locate_data(const char *file);
47 static const char *exec_path(void);
49 static char path[MAX_PATH];
50 static loc_func_type loc_func[LOC_FUNC_COUNT] = {locate_config, locate_data};
52 const char *loc_get_path(const char *file, enum loc_file_type file_type) {
53 if(file_type >= LOC_FUNC_COUNT) return 0;
54 return loc_func[file_type](file);
57 static const char *locate_config(const char *file) {
59 char *env, *pptr = path;
60 const char *ex_path, *fptr = file;
62 /* first try $NLOC_CONFIG_PATH/file */
63 env = getenv(CONF_ENV);
65 while(*env) *pptr++ = *env++;
66 if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP;
67 while(*fptr) *pptr++ = *fptr++;
70 fprintf(stderr, "trying: %s\n", path);
71 if((fp = fopen(path, "r"))) {
77 /* then try $HOME/.file */
80 env = getenv(HOME_ENV);
82 while(*env) *pptr++ = *env++;
83 if(*(env - 1) != DIR_SEP) *pptr++ = DIR_SEP;
87 while(*fptr) *pptr++ = *fptr++;
90 fprintf(stderr, "trying: %s\n", path);
91 if((fp = fopen(path, "r"))) {
98 /* then PREFIX/etc/file */
100 strcat(path, "/etc/");
103 fprintf(stderr, "trying: %s\n", path);
104 if((fp = fopen(path, "r"))) {
109 /* or something similar on win32 */
110 env = getenv("ALLUSERSPROFILE");
116 fprintf(stderr, "trying: %s\n", path);
117 if((fp = fopen(path, "r"))) {
122 #endif /* __unix__ */
125 /* finally as a last resort try the executable directory, this may not work */
126 if((ex_path = exec_path())) {
127 strcpy(path, ex_path);
130 fprintf(stderr, "trying: %s\n", path);
131 if((fp = fopen(path, "r"))) {
140 /* TODO: not implemented yet */
141 static const char *locate_data(const char *file) {
145 static const char *exec_path(void) {
146 static char path[MAX_PATH];
151 ccount = readlink("/proc/self/exe", path, MAX_PATH - 1);
152 #endif /* __linux__ */
155 ccount = readlink("/proc/curproc/file", path, MAX_PATH - 1);
156 #endif /* __FreeBSD__ */
159 ccount = GetModuleFileName(0, path, MAX_PATH - 1);
162 if(!ccount) return 0;
166 ptr = strrchr(path, DIR_SEP);