Convert CompileKeymap to early-return style
[platform/upstream/libxkbcommon.git] / src / xkbcomp / keymap.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 "xkbmisc.h"
29 #include "expr.h"
30 #include "vmod.h"
31 #include "action.h"
32 #include "misc.h"
33 #include "indicators.h"
34
35 /**
36  * Compile the given file and store the output in xkb.
37  * @param file A list of XkbFiles, each denoting one type (e.g.
38  * XkmKeyNamesIdx, etc.)
39  */
40 Bool
41 CompileKeymap(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
42 {
43     unsigned have;
44     Bool ok;
45     unsigned required, legal;
46     unsigned mainType;
47     char *mainName;
48     LEDInfo *unbound = NULL;
49     struct {
50         XkbFile *keycodes;
51         XkbFile *types;
52         XkbFile *compat;
53         XkbFile *symbols;
54     } sections;
55
56     memset(&sections, 0, sizeof(sections));
57     mainType = file->type;
58     mainName = file->name;
59     switch (mainType)
60     {
61     case XkmSemanticsFile:
62         required = XkmSemanticsRequired;
63         legal = XkmSemanticsLegal;
64         break;
65     case XkmLayoutFile:        /* standard type  if setxkbmap -print */
66         required = XkmLayoutRequired;
67         legal = XkmKeymapLegal;
68         break;
69     case XkmKeymapFile:
70         required = XkmKeymapRequired;
71         legal = XkmKeymapLegal;
72         break;
73     default:
74         ERROR("Cannot compile %s alone into an XKM file\n",
75                XkbcConfigText(mainType));
76         return False;
77     }
78     have = 0;
79     ok = 1;
80     /* Check for duplicate entries in the input file */
81     for (file = (XkbFile *) file->defs; file; file = (XkbFile *) file->common.next)
82     {
83         if (file->topName != mainName) {
84             free(file->topName);
85             file->topName = strdup(mainName);
86         }
87
88         if ((have & (1 << file->type)) != 0)
89         {
90             ERROR("More than one %s section in a %s file\n",
91                    XkbcConfigText(file->type), XkbcConfigText(mainType));
92             ACTION("All sections after the first ignored\n");
93             return False;
94         }
95         else if ((1 << file->type) & (~legal))
96         {
97             ERROR("Cannot define %s in a %s file\n",
98                    XkbcConfigText(file->type), XkbcConfigText(mainType));
99             return False;
100         }
101
102         switch (file->type)
103         {
104         case XkmKeyNamesIndex:
105             sections.keycodes = file;
106             break;
107         case XkmTypesIndex:
108             sections.types = file;
109             break;
110         case XkmSymbolsIndex:
111             sections.symbols = file;
112             break;
113         case XkmCompatMapIndex:
114             sections.compat = file;
115             break;
116         case XkmGeometryIndex:
117             continue;
118         case XkmVirtualModsIndex:
119         case XkmIndicatorsIndex:
120             WSGO("Found an isolated %s section\n", XkbcConfigText(file->type));
121             ACTION("Ignored\n");
122             continue;
123         default:
124             WSGO("Unknown file type %d\n", file->type);
125             ACTION("Ignored\n");
126             continue;
127         case XkmSemanticsFile:
128         case XkmLayoutFile:
129         case XkmKeymapFile:
130             WSGO("Illegal %s configuration in a %s file\n",
131                   XkbcConfigText(file->type), XkbcConfigText(mainType));
132             ACTION("Ignored\n");
133             continue;
134         }
135
136         have |= (1 << file->type);
137     }
138
139     /* compile the sections we have in the file one-by-one, or fail. */
140     if (sections.keycodes != NULL &&
141         !CompileKeycodes(sections.keycodes, xkb, MergeOverride))
142         return False;
143     if (sections.types != NULL &&
144         !CompileKeyTypes(sections.types, xkb, MergeOverride))
145         return False;
146     if (sections.compat != NULL &&
147         !CompileCompatMap(sections.compat, xkb, MergeOverride, &unbound))
148         return False;
149     if (sections.symbols != NULL &&
150         !CompileSymbols(sections.symbols, xkb, MergeOverride))
151         return False;
152
153     xkb->defined = have;
154     if (required & (~have))
155     {
156         int i, bit;
157         unsigned missing;
158         missing = required & (~have);
159         for (i = 0, bit = 1; missing != 0; i++, bit <<= 1)
160         {
161             if (missing & bit)
162             {
163                 ERROR("Missing %s section in a %s file\n",
164                        XkbcConfigText(i), XkbcConfigText(mainType));
165                 missing &= ~bit;
166             }
167         }
168         ACTION("Description of %s not compiled\n",
169                 XkbcConfigText(mainType));
170         return False;
171     }
172
173     ok = BindIndicators(xkb, True, unbound, NULL);
174     return ok;
175 }