test: Add flags argument to test_get_context()
[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 <limits.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38
39 #include "test.h"
40
41 /*
42  * Test a sequence of keysyms, resulting from a sequence of key presses,
43  * against the keysyms they're supposed to generate.
44  *
45  * - Each test runs with a clean state.
46  * - Each line in the test is made up of:
47  *   + A keycode, given as a KEY_* from linux/input.h.
48  *   + A direction - DOWN for press, UP for release, BOTH for
49  *     immediate press + release, REPEAT to just get the syms.
50  *   + A sequence of keysyms that should result from this keypress.
51  *
52  * The vararg format is:
53  * <KEY_*>  <DOWN | UP | BOTH>  <XKB_KEY_* (zero or more)>  <NEXT | FINISH>
54  *
55  * See below for examples.
56  */
57 int
58 test_key_seq(struct xkb_keymap *keymap, ...)
59 {
60     struct xkb_state *state;
61
62     va_list ap;
63     xkb_keycode_t kc;
64     int op;
65     xkb_keysym_t keysym;
66
67     const xkb_keysym_t *syms;
68     unsigned int nsyms, i;
69     char ksbuf[64];
70
71     fprintf(stderr, "----\n");
72
73     state = xkb_state_new(keymap);
74     assert(state);
75
76     va_start(ap, keymap);
77
78     for (;;) {
79         kc = va_arg(ap, int) + EVDEV_OFFSET;
80         op = va_arg(ap, int);
81
82         nsyms = xkb_state_key_get_syms(state, kc, &syms);
83         fprintf(stderr, "got %d syms for key 0x%x: [", nsyms, kc);
84
85         if (op == DOWN || op == BOTH)
86             xkb_state_update_key(state, kc, XKB_KEY_DOWN);
87         if (op == UP || op == BOTH)
88             xkb_state_update_key(state, kc, XKB_KEY_UP);
89
90         for (i = 0; i < nsyms; i++) {
91             keysym = va_arg(ap, int);
92             xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
93             fprintf(stderr, "%s%s", (i != 0) ? ", " : "", ksbuf);
94
95             if (keysym == FINISH || keysym == NEXT) {
96                 xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
97                 fprintf(stderr, "Did not expect keysym: %s.\n", ksbuf);
98                 goto fail;
99             }
100
101             if (keysym != syms[i]) {
102                 xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf));
103                 fprintf(stderr, "Expected keysym: %s. ", ksbuf);;
104                 xkb_keysym_get_name(syms[i], ksbuf, sizeof(ksbuf));
105                 fprintf(stderr, "Got keysym: %s.\n", ksbuf);;
106                 goto fail;
107             }
108         }
109
110         fprintf(stderr, "]\n");
111
112         keysym = va_arg(ap, int);
113         if (keysym == NEXT)
114             continue;
115         if (keysym == FINISH)
116             break;
117
118         xkb_keysym_get_name(keysym, ksbuf, sizeof(ksbuf));
119         fprintf(stderr, "Expected keysym: %s. Didn't get it.\n", ksbuf);
120         goto fail;
121     }
122
123     va_end(ap);
124     xkb_state_unref(state);
125     return 1;
126
127 fail:
128     va_end(ap);
129     xkb_state_unref(state);
130     return 0;
131 }
132
133 const char *
134 test_get_path(const char *path_rel)
135 {
136     static char path[PATH_MAX];
137     const char *srcdir = getenv("srcdir");
138
139     snprintf(path, PATH_MAX - 1,
140              "%s/test/data/%s", srcdir ? srcdir : ".",
141              path_rel ? path_rel : "");
142
143     return path;
144 }
145
146 char *
147 test_read_file(const char *path_rel)
148 {
149     struct stat info;
150     char *ret, *tmp;
151     int fd, count, remaining;
152
153     fd = open(test_get_path(path_rel), O_RDONLY);
154     if (fd < 0)
155         return NULL;
156
157     if (fstat(fd, &info) != 0) {
158         close(fd);
159         return NULL;
160     }
161
162     ret = malloc(info.st_size + 1);
163     if (!ret) {
164         close(fd);
165         return NULL;
166     }
167
168     remaining = info.st_size;
169     tmp = ret;
170     while ((count = read(fd, tmp, remaining))) {
171         remaining -= count;
172         tmp += count;
173     }
174     ret[info.st_size] = '\0';
175     close(fd);
176
177     if (remaining != 0) {
178         free(ret);
179         return NULL;
180     }
181
182     return ret;
183 }
184
185 struct xkb_context *
186 test_get_context(enum test_context_flags test_flags)
187 {
188     struct xkb_context *ctx = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES);
189
190     if (!ctx)
191         return NULL;
192
193     xkb_context_include_path_append(ctx, test_get_path(""));
194
195     return ctx;
196 }
197
198 struct xkb_keymap *
199 test_compile_file(struct xkb_context *context, const char *path_rel)
200 {
201     struct xkb_keymap *keymap;
202     FILE *file;
203     const char *path = test_get_path(path_rel);
204
205     file = fopen(path, "r");
206     if (!file) {
207         fprintf(stderr, "Failed to open path: %s\n", path);
208         return NULL;
209     }
210     assert(file != NULL);
211
212     keymap = xkb_keymap_new_from_file(context, file,
213                                       XKB_KEYMAP_FORMAT_TEXT_V1, 0);
214     fclose(file);
215
216     if (!keymap) {
217         fprintf(stderr, "Failed to compile path: %s\n", path);
218         return NULL;
219     }
220
221     fprintf(stderr, "Successfully compiled path: %s\n", path);
222
223     return keymap;
224 }
225
226 struct xkb_keymap *
227 test_compile_string(struct xkb_context *context, const char *string)
228 {
229     struct xkb_keymap *keymap;
230
231     keymap = xkb_keymap_new_from_string(context, string,
232                                         XKB_KEYMAP_FORMAT_TEXT_V1, 0);
233     if (!keymap) {
234         fprintf(stderr, "Failed to compile string\n");
235         return NULL;
236     }
237
238     return keymap;
239 }
240
241 struct xkb_keymap *
242 test_compile_rules(struct xkb_context *context, const char *rules,
243                    const char *model, const char *layout,
244                    const char *variant, const char *options)
245 {
246     struct xkb_keymap *keymap;
247     struct xkb_rule_names rmlvo = {
248         .rules = rules,
249         .model = model,
250         .layout = layout,
251         .variant = variant,
252         .options = options
253     };
254
255     keymap = xkb_keymap_new_from_names(context, &rmlvo, 0);
256     if (!keymap) {
257         fprintf(stderr,
258                 "Failed to compile RMLVO: '%s', '%s', '%s', '%s', '%s'\n",
259                 rules, model, layout, variant, options);
260         return NULL;
261     }
262
263     return keymap;
264 }