test: drop some now-obsolete functions
[platform/upstream/libxkbcommon.git] / test / common.c
1 /*
2  * Copyright © 2009 Dan Nicholson <dbn.lists@gmail.com>
3  * Copyright © 2012 Intel Corporation
4  * Copyright © 2012 Ran Benita <ran234@gmail.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Except as contained in this notice, the names of the authors or their
24  * institutions shall not be used in advertising or otherwise to promote the
25  * sale, use or other dealings in this Software without prior written
26  * authorization from the authors.
27  *
28  * Author: Dan Nicholson <dbn.lists@gmail.com>
29  *         Daniel Stone <daniel@fooishbar.org>
30  *         Ran Benita <ran234@gmail.com>
31  */
32
33 #include "config.h"
34
35 #include <limits.h>
36 #include <fcntl.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #ifdef _MSC_VER
40 #include <io.h>
41 #include <windows.h>
42 #else
43 #include <unistd.h>
44 #include <termios.h>
45 #endif
46
47 #include "test.h"
48 #include "utils.h"
49
50 /*
51  * Test a sequence of keysyms, resulting from a sequence of key presses,
52  * against the keysyms they're supposed to generate.
53  *
54  * - Each test runs with a clean state.
55  * - Each line in the test is made up of:
56  *   + A keycode, given as a KEY_* from linux/input.h.
57  *   + A direction - DOWN for press, UP for release, BOTH for
58  *     immediate press + release, REPEAT to just get the syms.
59  *   + A sequence of keysyms that should result from this keypress.
60  *
61  * The vararg format is:
62  * <KEY_*>  <DOWN | UP | BOTH>  <XKB_KEY_* (zero or more)>  <NEXT | FINISH>
63  *
64  * See below for examples.
65  */
66 int
67 test_key_seq_va(struct xkb_keymap *keymap, va_list ap)
68 {
69     struct xkb_state *state;
70
71     xkb_keycode_t kc;
72     int op;
73     xkb_keysym_t keysym;
74
75     const xkb_keysym_t *syms;
76     xkb_keysym_t sym;
77     unsigned int nsyms, i;
78     char ksbuf[64];
79
80     fprintf(stderr, "----\n");
81
82     state = xkb_state_new(keymap);
83     assert(state);
84
85     for (;;) {
86         kc = va_arg(ap, int) + EVDEV_OFFSET;
87         op = va_arg(ap, int);
88
89         nsyms = xkb_state_key_get_syms(state, kc, &syms);
90         if (nsyms == 1) {
91             sym = xkb_state_key_get_one_sym(state, kc);
92             syms = &sym;
93         }
94
95         fprintf(stderr, "got %u syms for keycode %u: [", nsyms, kc);
96
97         if (op == DOWN || op == BOTH)
98             xkb_state_update_key(state, kc, XKB_KEY_DOWN);
99         if (op == UP || op == BOTH)
100             xkb_state_update_key(state, kc, XKB_KEY_UP);
101
102         for (i = 0; i < nsyms; i++) {
103             keysym = va_arg(ap, int);
104             xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
105             fprintf(stderr, "%s%s", (i != 0) ? ", " : "", ksbuf);
106
107             if (keysym == FINISH || keysym == NEXT) {
108                 xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
109                 fprintf(stderr, "Did not expect keysym: %s.\n", ksbuf);
110                 goto fail;
111             }
112
113             if (keysym != syms[i]) {
114                 xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf));
115                 fprintf(stderr, "Expected keysym: %s. ", ksbuf);;
116                 xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
117                 fprintf(stderr, "Got keysym: %s.\n", ksbuf);;
118                 goto fail;
119             }
120         }
121
122         if (nsyms == 0) {
123             keysym = va_arg(ap, int);
124             if (keysym != XKB_KEY_NoSymbol) {
125                 xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf));
126                 fprintf(stderr, "Expected %s, but got no keysyms.\n", ksbuf);
127                 goto fail;
128             }
129         }
130
131         fprintf(stderr, "]\n");
132
133         keysym = va_arg(ap, int);
134         if (keysym == NEXT)
135             continue;
136         if (keysym == FINISH)
137             break;
138
139         xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf));
140         fprintf(stderr, "Expected keysym: %s. Didn't get it.\n", ksbuf);
141         goto fail;
142     }
143
144     xkb_state_unref(state);
145     return 1;
146
147 fail:
148     xkb_state_unref(state);
149     return 0;
150 }
151
152 int
153 test_key_seq(struct xkb_keymap *keymap, ...)
154 {
155     va_list ap;
156     int ret;
157
158     va_start(ap, keymap);
159     ret = test_key_seq_va(keymap, ap);
160     va_end(ap);
161
162     return ret;
163 }
164
165 char *
166 test_get_path(const char *path_rel)
167 {
168     int ret;
169     char *path;
170     const char *srcdir;
171
172     srcdir = getenv("top_srcdir");
173     if (!srcdir)
174         srcdir = ".";
175
176     if (path_rel[0] == '/')
177         return strdup(path_rel);
178
179     ret = asprintf(&path, "%s/test/data%s%s", srcdir,
180                    path_rel[0] ? "/" : "", path_rel);
181     if (ret < 0) {
182         fprintf(stderr, "Failed to allocate path for %s\n", path_rel);
183         return NULL;
184     }
185     return path;
186 }
187
188 char *
189 test_read_file(const char *path_rel)
190 {
191     struct stat info;
192     char *ret, *tmp, *path;
193     int fd, count, remaining;
194
195     path = test_get_path(path_rel);
196     if (!path)
197         return NULL;
198
199     fd = open(path, O_RDONLY);
200     free(path);
201     if (fd < 0)
202         return NULL;
203
204     if (fstat(fd, &info) != 0) {
205         close(fd);
206         return NULL;
207     }
208
209     ret = malloc(info.st_size + 1);
210     if (!ret) {
211         close(fd);
212         return NULL;
213     }
214
215     remaining = info.st_size;
216     tmp = ret;
217     while ((count = read(fd, tmp, remaining))) {
218         remaining -= count;
219         tmp += count;
220     }
221     ret[info.st_size] = '\0';
222     close(fd);
223
224     if (remaining != 0) {
225         free(ret);
226         return NULL;
227     }
228
229     return ret;
230 }
231
232 struct xkb_context *
233 test_get_context(enum test_context_flags test_flags)
234 {
235     enum xkb_context_flags ctx_flags;
236     struct xkb_context *ctx;
237     char *path;
238
239     ctx_flags = XKB_CONTEXT_NO_DEFAULT_INCLUDES;
240     if (test_flags & CONTEXT_ALLOW_ENVIRONMENT_NAMES) {
241         unsetenv("XKB_DEFAULT_RULES");
242         unsetenv("XKB_DEFAULT_MODEL");
243         unsetenv("XKB_DEFAULT_LAYOUT");
244         unsetenv("XKB_DEFAULT_VARIANT");
245         unsetenv("XKB_DEFAULT_OPTIONS");
246     }
247     else {
248         ctx_flags |= XKB_CONTEXT_NO_ENVIRONMENT_NAMES;
249     }
250
251     ctx = xkb_context_new(ctx_flags);
252     if (!ctx)
253         return NULL;
254
255     path = test_get_path("");
256     if (!path) {
257         xkb_context_unref(ctx);
258         return NULL;
259     }
260
261     xkb_context_include_path_append(ctx, path);
262     free(path);
263
264     return ctx;
265 }
266
267 struct xkb_keymap *
268 test_compile_file(struct xkb_context *context, const char *path_rel)
269 {
270     struct xkb_keymap *keymap;
271     FILE *file;
272     char *path;
273
274     path = test_get_path(path_rel);
275     if (!path)
276         return NULL;
277
278     file = fopen(path, "rb");
279     if (!file) {
280         fprintf(stderr, "Failed to open path: %s\n", path);
281         free(path);
282         return NULL;
283     }
284     assert(file != NULL);
285
286     keymap = xkb_keymap_new_from_file(context, file,
287                                       XKB_KEYMAP_FORMAT_TEXT_V1, 0);
288     fclose(file);
289
290     if (!keymap) {
291         fprintf(stderr, "Failed to compile path: %s\n", path);
292         free(path);
293         return NULL;
294     }
295
296     fprintf(stderr, "Successfully compiled path: %s\n", path);
297     free(path);
298
299     return keymap;
300 }
301
302 struct xkb_keymap *
303 test_compile_string(struct xkb_context *context, const char *string)
304 {
305     struct xkb_keymap *keymap;
306
307     keymap = xkb_keymap_new_from_string(context, string,
308                                         XKB_KEYMAP_FORMAT_TEXT_V1, 0);
309     if (!keymap) {
310         fprintf(stderr, "Failed to compile string\n");
311         return NULL;
312     }
313
314     return keymap;
315 }
316
317 struct xkb_keymap *
318 test_compile_buffer(struct xkb_context *context, const char *buf, size_t len)
319 {
320     struct xkb_keymap *keymap;
321
322     keymap = xkb_keymap_new_from_buffer(context, buf, len,
323                                         XKB_KEYMAP_FORMAT_TEXT_V1, 0);
324     if (!keymap) {
325         fprintf(stderr, "Failed to compile keymap from memory buffer\n");
326         return NULL;
327     }
328
329     return keymap;
330 }
331
332 struct xkb_keymap *
333 test_compile_rules(struct xkb_context *context, const char *rules,
334                    const char *model, const char *layout,
335                    const char *variant, const char *options)
336 {
337     struct xkb_keymap *keymap;
338     struct xkb_rule_names rmlvo = {
339         .rules = isempty(rules) ? NULL : rules,
340         .model = isempty(model) ? NULL : model,
341         .layout = isempty(layout) ? NULL : layout,
342         .variant = isempty(variant) ? NULL : variant,
343         .options = isempty(options) ? NULL : options
344     };
345
346     if (!rules && !model && !layout && !variant && !options)
347         keymap = xkb_keymap_new_from_names(context, NULL, 0);
348     else
349         keymap = xkb_keymap_new_from_names(context, &rmlvo, 0);
350
351     if (!keymap) {
352         fprintf(stderr,
353                 "Failed to compile RMLVO: '%s', '%s', '%s', '%s', '%s'\n",
354                 rules, model, layout, variant, options);
355         return NULL;
356     }
357
358     return keymap;
359 }