Remove all uses of the register keyword
[profile/ivi/libxkbcommon.git] / src / xkbcomp / misc.c
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 #include "xkbcomp.h"
28 #include "xkballoc.h"
29 #include "xkbmisc.h"
30 #include "xkbpath.h"
31 #include "keycodes.h"
32 #include "misc.h"
33 #include <X11/keysym.h>
34 #include "parseutils.h"
35
36 /***====================================================================***/
37
38 /**
39  * Open the file given in the include statement and parse it's content.
40  * If the statement defines a specific map to use, this map is returned in
41  * file_rtrn. Otherwise, the default map is returned.
42  *
43  * @param stmt The include statement, specifying the file name to look for.
44  * @param file_type Type of file (XkmKeyNamesIdx, etc.)
45  * @param file_rtrn Returns the key map to be used.
46  * @param merge_rtrn Always returns stmt->merge.
47  *
48  * @return True on success or False otherwise.
49  */
50 Bool
51 ProcessIncludeFile(IncludeStmt * stmt,
52                    unsigned file_type,
53                    XkbFile ** file_rtrn, unsigned *merge_rtrn)
54 {
55     FILE *file;
56     XkbFile *rtrn, *mapToUse;
57     char oldFile[1024] = {0};
58     int oldLine = lineNum;
59
60     rtrn = XkbFindFileInCache(stmt->file, file_type, &stmt->path);
61     if (rtrn == NULL)
62     {
63         /* file not in cache, open it, parse it and store it in cache for next
64            time. */
65         file = XkbFindFileInPath(stmt->file, file_type, &stmt->path);
66         if (file == NULL)
67         {
68             ERROR("Can't find file \"%s\" for %s include\n", stmt->file,
69                    XkbDirectoryForInclude(file_type));
70             return False;
71         }
72         if (scanFile)
73             strcpy(oldFile, scanFile);
74         else
75             memset(oldFile, 0, sizeof(oldFile));
76         oldLine = lineNum;
77         setScanState(stmt->file, 1);
78         if (debugFlags & 2)
79             INFO("About to parse include file %s\n", stmt->file);
80         /* parse the file */
81         if ((XKBParseFile(file, &rtrn) == 0) || (rtrn == NULL))
82         {
83             setScanState(oldFile, oldLine);
84             ERROR("Error interpreting include file \"%s\"\n", stmt->file);
85             fclose(file);
86             return False;
87         }
88         fclose(file);
89         XkbAddFileToCache(stmt->file, file_type, stmt->path, rtrn);
90     }
91     mapToUse = rtrn;
92     if (stmt->map != NULL)
93     {
94         while ((mapToUse) && ((!uStringEqual(mapToUse->name, stmt->map)) ||
95                               (mapToUse->type != file_type)))
96         {
97             mapToUse = (XkbFile *) mapToUse->common.next;
98         }
99         if (!mapToUse)
100         {
101             ERROR("No %s named \"%s\" in the include file \"%s\"\n",
102                    XkbcConfigText(file_type), stmt->map, stmt->file);
103             return False;
104         }
105     }
106     else if ((rtrn->common.next != NULL) && (warningLevel > 5))
107     {
108         WARN("No map in include statement, but \"%s\" contains several\n",
109               stmt->file);
110         ACTION("Using first defined map, \"%s\"\n", rtrn->name);
111     }
112     setScanState(oldFile, oldLine);
113     if (mapToUse->type != file_type)
114     {
115         ERROR("Include file wrong type (expected %s, got %s)\n",
116                XkbcConfigText(file_type), XkbcConfigText(mapToUse->type));
117         ACTION("Include file \"%s\" ignored\n", stmt->file);
118         return False;
119     }
120     /* FIXME: we have to check recursive includes here (or somewhere) */
121
122     mapToUse->compiled = True;
123     *file_rtrn = mapToUse;
124     *merge_rtrn = stmt->merge;
125     return True;
126 }
127
128 /***====================================================================***/
129
130 int
131 ReportNotArray(const char *type, const char *field, const char *name)
132 {
133     ERROR("The %s %s field is not an array\n", type, field);
134     ACTION("Ignoring illegal assignment in %s\n", name);
135     return False;
136 }
137
138 int
139 ReportShouldBeArray(const char *type, const char *field, const char *name)
140 {
141     ERROR("Missing subscript for %s %s\n", type, field);
142     ACTION("Ignoring illegal assignment in %s\n", name);
143     return False;
144 }
145
146 int
147 ReportBadType(const char *type, const char *field,
148               const char *name, const char *wanted)
149 {
150     ERROR("The %s %s field must be a %s\n", type, field, wanted);
151     ACTION("Ignoring illegal assignment in %s\n", name);
152     return False;
153 }
154
155 int
156 ReportBadField(const char *type, const char *field, const char *name)
157 {
158     ERROR("Unknown %s field %s in %s\n", type, field, name);
159     ACTION("Ignoring assignment to unknown field in %s\n", name);
160     return False;
161 }
162
163 /***====================================================================***/
164
165 Bool
166 UseNewField(unsigned field,
167             CommonInfo * oldDefs, CommonInfo * newDefs, unsigned *pCollide)
168 {
169     Bool useNew;
170
171     useNew = False;
172     if (oldDefs->defined & field)
173     {
174         if (newDefs->defined & field)
175         {
176             if (((oldDefs->fileID == newDefs->fileID)
177                  && (warningLevel > 0)) || (warningLevel > 9))
178             {
179                 *pCollide |= field;
180             }
181             if (newDefs->merge != MergeAugment)
182                 useNew = True;
183         }
184     }
185     else if (newDefs->defined & field)
186         useNew = True;
187     return useNew;
188 }
189
190 char *
191 ClearCommonInfo(CommonInfo * cmn)
192 {
193     if (cmn != NULL)
194     {
195         CommonInfo *this, *next;
196         for (this = cmn; this != NULL; this = next)
197         {
198             next = this->next;
199             free(this);
200         }
201     }
202     return NULL;
203 }
204
205 char *
206 AddCommonInfo(CommonInfo * old, CommonInfo * new)
207 {
208     CommonInfo *first;
209
210     first = old;
211     while (old && old->next)
212     {
213         old = old->next;
214     }
215     new->next = NULL;
216     if (old)
217     {
218         old->next = new;
219         return (char *) first;
220     }
221     return (char *) new;
222 }
223
224 /***====================================================================***/
225
226 typedef struct _KeyNameDesc
227 {
228     uint32_t level1;
229     uint32_t level2;
230     char name[5];
231     Bool used;
232 } KeyNameDesc;
233
234 /**
235  * Find the key with the given name and return its keycode in kc_rtrn.
236  *
237  * @param name The 4-letter name of the key as a long.
238  * @param kc_rtrn Set to the keycode if the key was found, otherwise 0.
239  * @param use_aliases True if the key aliases should be searched too.
240  * @param create If True and the key is not found, it is added to the
241  *        xkb->names at the first free keycode.
242  * @param start_from Keycode to start searching from.
243  *
244  * @return True if found, False otherwise.
245  */
246 Bool
247 FindNamedKey(struct xkb_desc * xkb,
248              unsigned long name,
249              xkb_keycode_t *kc_rtrn,
250              Bool use_aliases, Bool create, int start_from)
251 {
252     unsigned n;
253
254     if (start_from < xkb->min_key_code)
255     {
256         start_from = xkb->min_key_code;
257     }
258     else if (start_from > xkb->max_key_code)
259     {
260         return False;
261     }
262
263     *kc_rtrn = 0;               /* some callers rely on this */
264     if (xkb && xkb->names && xkb->names->keys)
265     {
266         for (n = start_from; n <= xkb->max_key_code; n++)
267         {
268             unsigned long tmp;
269             tmp = KeyNameToLong(xkb->names->keys[n].name);
270             if (tmp == name)
271             {
272                 *kc_rtrn = n;
273                 return True;
274             }
275         }
276         if (use_aliases)
277         {
278             unsigned long new_name;
279             if (FindKeyNameForAlias(xkb, name, &new_name))
280                 return FindNamedKey(xkb, new_name, kc_rtrn, False, create, 0);
281         }
282     }
283     if (create)
284     {
285         if ((!xkb->names) || (!xkb->names->keys))
286         {
287             if (XkbcAllocNames(xkb, XkbKeyNamesMask, 0, 0) != Success)
288             {
289                 if (warningLevel > 0)
290                 {
291                     WARN("Couldn't allocate key names in FindNamedKey\n");
292                     ACTION("Key \"%s\" not automatically created\n",
293                             longText(name));
294                 }
295                 return False;
296             }
297         }
298         /* Find first unused keycode and store our key here */
299         for (n = xkb->min_key_code; n <= xkb->max_key_code; n++)
300         {
301             if (xkb->names->keys[n].name[0] == '\0')
302             {
303                 char buf[XkbKeyNameLength + 1];
304                 LongToKeyName(name, buf);
305                 memcpy(xkb->names->keys[n].name, buf, XkbKeyNameLength);
306                 *kc_rtrn = n;
307                 return True;
308             }
309         }
310     }
311     return False;
312 }
313
314 Bool
315 FindKeyNameForAlias(struct xkb_desc * xkb, unsigned long lname,
316                     unsigned long *real_name)
317 {
318     int i;
319     char name[XkbKeyNameLength + 1];
320
321     if (xkb && xkb->geom && xkb->geom->key_aliases)
322     {
323         struct xkb_key_alias * a;
324         a = xkb->geom->key_aliases;
325         LongToKeyName(lname, name);
326         name[XkbKeyNameLength] = '\0';
327         for (i = 0; i < xkb->geom->num_key_aliases; i++, a++)
328         {
329             if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
330             {
331                 *real_name = KeyNameToLong(a->real);
332                 return True;
333             }
334         }
335     }
336     if (xkb && xkb->names && xkb->names->key_aliases)
337     {
338         struct xkb_key_alias * a;
339         a = xkb->names->key_aliases;
340         LongToKeyName(lname, name);
341         name[XkbKeyNameLength] = '\0';
342         for (i = 0; i < xkb->names->num_key_aliases; i++, a++)
343         {
344             if (strncmp(name, a->alias, XkbKeyNameLength) == 0)
345             {
346                 *real_name = KeyNameToLong(a->real);
347                 return True;
348             }
349         }
350     }
351     return False;
352 }