* Allow some tests to pass on Windows. Just for the fun
[framework/uifw/efreet.git] / src / lib / efreet_base.c
1 /* vim: set sw=4 ts=4 sts=4 et: */
2
3 #ifdef HAVE_CONFIG_H
4 # include <config.h>
5 #endif
6
7 #include <stdio.h>
8 #include <string.h>
9
10 #include "Efreet.h"
11 #include "efreet_private.h"
12
13 #ifdef _WIN32
14 # define EFREET_PATH_SEP ';'
15 #else
16 # define EFREET_PATH_SEP ':'
17 #endif
18
19 static const char *efreet_home_dir = NULL;
20 static const char *xdg_data_home = NULL;
21 static const char *xdg_config_home = NULL;
22 static const char *xdg_cache_home = NULL;
23 static Eina_List  *xdg_data_dirs = NULL;
24 static Eina_List  *xdg_config_dirs = NULL;
25
26 static const char *efreet_dir_get(const char *key, const char *fallback);
27 static Eina_List  *efreet_dirs_get(const char *key,
28                                         const char *fallback);
29
30 /**
31  * @internal
32  * @return Returns 1 on success or 0 on failure
33  * @brief Initializes the efreet base settings
34  */
35 int
36 efreet_base_init(void)
37 {
38     if (!eina_stringshare_init()) return 0;
39     if (!eina_list_init())
40     {
41         eina_stringshare_shutdown();
42         return 0;
43     }
44
45     return 1;
46 }
47
48 /**
49  * @internal
50  * @return Returns no value
51  * @brief Cleans up the efreet base settings system
52  */
53 void
54 efreet_base_shutdown(void)
55 {
56     IF_RELEASE(efreet_home_dir);
57     IF_RELEASE(xdg_data_home);
58     IF_RELEASE(xdg_config_home);
59     IF_RELEASE(xdg_cache_home);
60
61     IF_FREE_LIST(xdg_data_dirs, eina_stringshare_del);
62     IF_FREE_LIST(xdg_config_dirs, eina_stringshare_del);
63
64     eina_list_shutdown();
65     eina_stringshare_shutdown();
66 }
67
68 /**
69  * @internal
70  * @return Returns the users home directory
71  * @brief Gets the users home directory and returns it.
72  */
73 const char *
74 efreet_home_dir_get(void)
75 {
76     if (efreet_home_dir) return efreet_home_dir;
77
78     efreet_home_dir = getenv("HOME");
79 #ifdef _WIN32
80     if (!efreet_home_dir || efreet_home_dir[0] == '\0')
81         efreet_home_dir = getenv("USERPROFILE");
82 #endif
83     if (!efreet_home_dir || efreet_home_dir[0] == '\0')
84         efreet_home_dir = "/tmp";
85
86     efreet_home_dir = eina_stringshare_add(efreet_home_dir);
87
88     return efreet_home_dir;
89 }
90
91 /**
92  * @return Returns the XDG Data Home directory
93  * @brief Retrieves the XDG Data Home directory
94  */
95 EAPI const char *
96 efreet_data_home_get(void)
97 {
98     if (xdg_data_home) return xdg_data_home;
99     xdg_data_home = efreet_dir_get("XDG_DATA_HOME", "/.local/share");
100     return xdg_data_home;
101 }
102
103 /**
104  * @return Returns the Eina_List of preference ordered extra data directories
105  * @brief Returns the Eina_List of prefernece oredred extra data
106  * directories
107  *
108  * @note The returned list is static inside Efreet. If you add/remove from the
109  * list then the next call to efreet_data_dirs_get() will return your
110  * modified values. DO NOT free this list.
111  */
112 EAPI Eina_List *
113 efreet_data_dirs_get(void)
114 {
115 #ifdef _WIN32
116     char buf[4096];
117 #endif
118
119     if (xdg_data_dirs) return xdg_data_dirs;
120
121 #ifdef _WIN32
122     snprintf(buf, 4096, "%s\\Efl;" PACKAGE_DATA_DIR ";/usr/share", getenv("APPDATA"));
123     xdg_data_dirs = efreet_dirs_get("XDG_DATA_DIRS", buf);
124 #else
125     xdg_data_dirs = efreet_dirs_get("XDG_DATA_DIRS",
126                             PACKAGE_DATA_DIR ":/usr/share");
127 #endif
128     return xdg_data_dirs;
129 }
130
131 /**
132  * @return Returns the XDG Config Home directory
133  * @brief Retrieves the XDG Config Home directory
134  */
135 EAPI const char *
136 efreet_config_home_get(void)
137 {
138     if (xdg_config_home) return xdg_config_home;
139     xdg_config_home = efreet_dir_get("XDG_CONFIG_HOME", "/.config");
140     return xdg_config_home;
141 }
142
143 /**
144  * @return Returns the Eina_List of preference ordered extra config directories
145  * @brief Returns the Eina_List of prefernece ordered extra config
146  * directories
147  *
148  * @note The returned list is static inside Efreet. If you add/remove from the
149  * list then the next call to efreet_config_dirs_get() will return your
150  * modified values. DO NOT free this list.
151  */
152 EAPI Eina_List *
153 efreet_config_dirs_get(void)
154 {
155     if (xdg_config_dirs) return xdg_config_dirs;
156     xdg_config_dirs = efreet_dirs_get("XDG_CONFIG_DIRS", "/etc/xdg");
157     return xdg_config_dirs;
158 }
159
160 /**
161  * @return Returns the XDG Cache Home directory
162  * @brief Retrieves the XDG Cache Home directory
163  */
164 EAPI const char *
165 efreet_cache_home_get(void)
166 {
167     if (xdg_cache_home) return xdg_cache_home;
168     xdg_cache_home = efreet_dir_get("XDG_CACHE_HOME", "/.cache");
169     return xdg_cache_home;
170 }
171
172 /**
173  * @internal
174  * @param key: The environemnt key to lookup
175  * @param fallback: The fallback value to use
176  * @return Returns the directory related to the given key or the fallback
177  * @brief This trys to determine the correct directory name given the
178  * environment key @a key and fallbacks @a fallback.
179  */
180 static const char *
181 efreet_dir_get(const char *key, const char *fallback)
182 {
183     char *dir;
184     const char *t;
185
186     dir = getenv(key);
187     if (!dir || dir[0] == '\0')
188     {
189         int len;
190         const char *user;
191
192         user = efreet_home_dir_get();
193         len = strlen(user) + strlen(fallback) + 1;
194         dir = malloc(sizeof(char) * len);
195         snprintf(dir, len, "%s%s", user, fallback);
196
197         t = eina_stringshare_add(dir);
198         FREE(dir);
199     }
200     else t = eina_stringshare_add(dir);
201
202     return t;
203 }
204
205 /**
206  * @internal
207  * @param key: The environment key to lookup
208  * @param fallback: The fallback value to use
209  * @return Returns a list of directories specified by the given key @a key
210  * or from the list of fallbacks in @a fallback.
211  * @brief Creates a list of directories as given in the environment key @a
212  * key or from the fallbacks in @a fallback
213  */
214 static Eina_List *
215 efreet_dirs_get(const char *key, const char *fallback)
216 {
217     Eina_List *dirs = NULL;
218     const char *path;
219     char *tmp, *s, *p;
220
221     path = getenv(key);
222     if (!path || (path[0] == '\0')) path = fallback;
223
224     if (!path) return dirs;
225
226     tmp = strdup(path);
227     s = tmp;
228     p = strchr(s, EFREET_PATH_SEP);
229     while (p)
230     {
231         *p = '\0';
232         if (!eina_list_search_unsorted(dirs, EINA_COMPARE_CB(strcmp), s))
233             dirs = eina_list_append(dirs, (void *)eina_stringshare_add(s));
234
235         s = ++p;
236         p = strchr(s, EFREET_PATH_SEP);
237     }
238     if (!eina_list_search_unsorted(dirs, EINA_COMPARE_CB(strcmp), s))
239       dirs = eina_list_append(dirs, (void *)eina_stringshare_add(s));
240     FREE(tmp);
241
242     return dirs;
243 }