2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 * Author: Daniel Stone <daniel@fooishbar.org>
33 /* keeps a cache of all makedir/maketmpdir directories so we can free and
34 * rmdir them in one go, see unmakedirs() */
38 /* keeps a cache of all buffered env vars so we can restore
39 * them in one go, see restore_env() */
46 static void buffer_env(const char *key)
48 char *v = getenv(key);
50 environment[nenviron].key = strdup(key);
51 environment[nenviron].value = v ? strdup(v) : NULL;
55 static void restore_env(void)
57 for (int i = 0; i < nenviron; i++) {
58 char *key = environment[i].key,
59 *value = environment[i].value;
62 setenv(key, value, 1);
70 memset(environment, 0, sizeof(environment));
73 static const char *makedir(const char *parent, const char *path)
78 err = asprintf(&dirname, "%s/%s", parent, path);
80 err = mkdir(dirname, 0777);
83 dirnames[ndirs++] = dirname;
88 static const char *maketmpdir(void)
90 const char *template = "/tmp/xkbcommon-test.XXXXXX";
91 char *tmpdir = strdup(template);
93 tmpdir = mkdtemp(tmpdir);
94 assert(tmpdir != NULL);
96 dirnames[ndirs++] = tmpdir;
101 static void unmakedirs(void)
103 /* backwards order for rmdir to work */
104 for (int i = ndirs - 1; i >= 0; i--) {
105 char *dir = dirnames[i];
112 memset(dirnames, 0, sizeof(dirnames));
116 test_config_root_include_path(void)
118 struct xkb_context *ctx;
120 const char *context_path;
123 buffer_env("XKB_CONFIG_ROOT");
125 buffer_env("XDG_CONFIG_HOME");
127 tmpdir = maketmpdir();
128 setenv("XKB_CONFIG_ROOT", tmpdir, 1);
130 unsetenv("XDG_CONFIG_HOME");
132 /* built-in path is last */
133 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
134 nincludes = xkb_context_num_include_paths(ctx);
135 assert(nincludes >= 1);
136 context_path = xkb_context_include_path_get(ctx, nincludes - 1);
137 assert(strcmp(context_path, tmpdir) == 0);
138 xkb_context_unref(ctx);
145 test_config_root_include_path_fallback(void)
147 struct xkb_context *ctx;
148 const char *xkbdir = DFLT_XKB_CONFIG_ROOT;
149 const char *context_path;
153 /* quick and dirty check that the default directory exists.
154 * It may not on a vanilla test box if we just run the test
155 * suite, so where it's not there just skip this test. */
156 dir = opendir(xkbdir);
161 buffer_env("XKB_CONFIG_ROOT");
163 buffer_env("XDG_CONFIG_HOME");
165 unsetenv("XKB_CONFIG_ROOT");
167 unsetenv("XDG_CONFIG_HOME");
169 /* built-in path is last */
170 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
171 nincludes = xkb_context_num_include_paths(ctx);
172 assert(nincludes >= 1);
173 context_path = xkb_context_include_path_get(ctx, nincludes - 1);
174 assert(strcmp(context_path, xkbdir) == 0);
175 xkb_context_unref(ctx);
182 test_xkbdir_include_path(void)
184 struct xkb_context *ctx;
186 const char *xkb_path;
187 const char *context_path;
190 buffer_env("XDG_CONFIG_HOME");
192 tmpdir = maketmpdir();
193 xkb_path = makedir(tmpdir, ".xkb");
194 setenv("HOME", tmpdir, 1);
195 setenv("XDG_CONFIG_HOME", tmpdir, 1);
197 /* No XDG directory in our tmpdir, so we expect
198 * the $HOME/.xkb to be the first include path */
199 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
200 assert(xkb_context_num_include_paths(ctx) >= 1);
201 context_path = xkb_context_include_path_get(ctx, 0);
202 assert(strcmp(context_path, xkb_path) == 0);
203 xkb_context_unref(ctx);
210 test_xdg_include_path(void)
212 struct xkb_context *ctx;
214 const char *xdg_path;
215 const char *context_path;
217 buffer_env("XDG_CONFIG_HOME");
219 tmpdir = maketmpdir();
220 xdg_path = makedir(tmpdir, "xkb");
221 setenv("XDG_CONFIG_HOME", tmpdir, 1);
223 /* XDG path is always first */
224 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
225 assert(xkb_context_num_include_paths(ctx) >= 1);
226 context_path = xkb_context_include_path_get(ctx, 0);
227 assert(strcmp(context_path, xdg_path) == 0);
228 xkb_context_unref(ctx);
235 test_xdg_include_path_fallback(void)
237 struct xkb_context *ctx;
239 const char *xdg_root, *xdg_path;
240 const char *context_path;
242 buffer_env("XDG_CONFIG_HOME");
245 tmpdir = maketmpdir();
246 xdg_root = makedir(tmpdir, ".config");
247 xdg_path = makedir(xdg_root, "xkb");
248 setenv("HOME", tmpdir, 1);
249 unsetenv("XDG_CONFIG_HOME");
251 /* XDG path is always first, even if fallback */
252 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
253 assert(xkb_context_num_include_paths(ctx) >= 1);
254 context_path = xkb_context_include_path_get(ctx, 0);
255 assert(strcmp(context_path, xdg_path) == 0);
256 xkb_context_unref(ctx);
263 test_include_order(void)
265 struct xkb_context *ctx;
267 const char *xdg_path;
268 const char *xkb_home_path;
269 const char *xkb_root_path;
270 const char *context_path;
272 buffer_env("XKB_CONFIG_ROOT");
273 buffer_env("XDG_CONFIG_HOME");
276 tmpdir = maketmpdir();
277 xdg_path = makedir(tmpdir, "xkb");
278 xkb_home_path = makedir(tmpdir, ".xkb");
279 xkb_root_path = makedir(tmpdir, "xkbroot");
280 setenv("HOME", tmpdir, 1);
281 setenv("XDG_CONFIG_HOME", tmpdir, 1);
282 setenv("XKB_CONFIG_ROOT", xkb_root_path, 1);
284 ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
285 assert(xkb_context_num_include_paths(ctx) >= 3);
287 context_path = xkb_context_include_path_get(ctx, 0);
288 assert(strcmp(context_path, xdg_path) == 0);
289 /* $HOME/.xkb is second */
290 context_path = xkb_context_include_path_get(ctx, 1);
291 assert(strcmp(context_path, xkb_home_path) == 0);
292 /* CONFIG_ROOT is last */
293 context_path = xkb_context_include_path_get(ctx, 2);
294 assert(strcmp(context_path, xkb_root_path) == 0);
296 xkb_context_unref(ctx);
305 struct xkb_context *context = test_get_context(0);
310 assert(xkb_context_num_include_paths(context) == 1);
311 assert(!xkb_context_include_path_append(context, "¡NONSENSE!"));
312 assert(xkb_context_num_include_paths(context) == 1);
314 atom = xkb_atom_intern(context, "HELLOjunkjunkjunk", 5);
315 assert(atom != XKB_ATOM_NONE);
316 assert(streq(xkb_atom_text(context, atom), "HELLO"));
318 atom = xkb_atom_intern_literal(context, "HELLOjunkjunkjunk");
319 assert(atom != XKB_ATOM_NONE);
320 assert(streq(xkb_atom_text(context, atom), "HELLOjunkjunkjunk"));
322 xkb_context_unref(context);
324 test_config_root_include_path();
325 test_config_root_include_path_fallback();
326 test_xkbdir_include_path();
327 test_xdg_include_path();
328 test_xdg_include_path_fallback();
329 test_include_order();