xkbscan.c revision 1d8c7986
1f46a6179Smrg/************************************************************
2f46a6179Smrg Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3f46a6179Smrg
4f46a6179Smrg Permission to use, copy, modify, and distribute this
5f46a6179Smrg software and its documentation for any purpose and without
6f46a6179Smrg fee is hereby granted, provided that the above copyright
7f46a6179Smrg notice appear in all copies and that both that copyright
8f46a6179Smrg notice and this permission notice appear in supporting
9f46a6179Smrg documentation, and that the name of Silicon Graphics not be
10f46a6179Smrg used in advertising or publicity pertaining to distribution
11f46a6179Smrg of the software without specific prior written permission.
12f46a6179Smrg Silicon Graphics makes no representation about the suitability
13f46a6179Smrg of this software for any purpose. It is provided "as is"
14f46a6179Smrg without any express or implied warranty.
15f46a6179Smrg
16f46a6179Smrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17f46a6179Smrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19f46a6179Smrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20f46a6179Smrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21f46a6179Smrg DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22f46a6179Smrg OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23f46a6179Smrg THE USE OR PERFORMANCE OF THIS SOFTWARE.
24f46a6179Smrg
25f46a6179Smrg ********************************************************/
26f46a6179Smrg
27f46a6179Smrg#include <stdio.h>
28f46a6179Smrg#include <ctype.h>
29f46a6179Smrg#include <X11/Xos.h>
30f46a6179Smrg#include <X11/Xlib.h>
31f46a6179Smrg#include <X11/XKBlib.h>
32f46a6179Smrg
33f46a6179Smrg#include "tokens.h"
34f46a6179Smrg#define	DEBUG_VAR	scanDebug
35f46a6179Smrg#include "utils.h"
36f46a6179Smrg#include "parseutils.h"
37f46a6179Smrg
3834345a63Smrgunsigned int scanDebug;
39f46a6179Smrg
4034345a63SmrgFILE *yyin = NULL;
41f46a6179Smrg
4234345a63Smrgstatic char scanFileBuf[1024] = {0};
4334345a63Smrgchar *scanFile = scanFileBuf;
4434345a63Smrgint lineNum = 0;
45f46a6179Smrg
4634345a63Smrgint scanInt;
4734345a63Smrg
4883e5f723Smrgchar scanBuf[1024];
4934345a63Smrgstatic int scanStrLine = 0;
50f46a6179Smrg
5183e5f723Smrg#define	BUFSIZE	4096
5283e5f723Smrgstatic char readBuf[BUFSIZE];
5383e5f723Smrgstatic int readBufPos = 0;
5483e5f723Smrgstatic int readBufLen = 0;
55f46a6179Smrg
56f46a6179Smrg#ifdef DEBUG
5783e5f723Smrgextern int debugFlags;
5883e5f723Smrg
59f46a6179Smrgstatic char *
60f46a6179SmrgtokText(int tok)
61f46a6179Smrg{
6234345a63Smrg    static char buf[32];
6334345a63Smrg
6434345a63Smrg    switch (tok)
6534345a63Smrg    {
6634345a63Smrg    case END_OF_FILE:
6734345a63Smrg        snprintf(buf, sizeof(buf), "END_OF_FILE");
6834345a63Smrg        break;
6934345a63Smrg    case ERROR_TOK:
7034345a63Smrg        snprintf(buf, sizeof(buf), "ERROR");
7134345a63Smrg        break;
7234345a63Smrg
7334345a63Smrg    case XKB_KEYMAP:
7434345a63Smrg        snprintf(buf, sizeof(buf), "XKB_KEYMAP");
7534345a63Smrg        break;
7634345a63Smrg    case XKB_KEYCODES:
7734345a63Smrg        snprintf(buf, sizeof(buf), "XKB_KEYCODES");
7834345a63Smrg        break;
7934345a63Smrg    case XKB_TYPES:
8034345a63Smrg        snprintf(buf, sizeof(buf), "XKB_TYPES");
8134345a63Smrg        break;
8234345a63Smrg    case XKB_SYMBOLS:
8334345a63Smrg        snprintf(buf, sizeof(buf), "XKB_SYMBOLS");
8434345a63Smrg        break;
8534345a63Smrg    case XKB_COMPATMAP:
8634345a63Smrg        snprintf(buf, sizeof(buf), "XKB_COMPATMAP");
8734345a63Smrg        break;
8834345a63Smrg    case XKB_GEOMETRY:
8934345a63Smrg        snprintf(buf, sizeof(buf), "XKB_GEOMETRY");
9034345a63Smrg        break;
9134345a63Smrg    case XKB_SEMANTICS:
9234345a63Smrg        snprintf(buf, sizeof(buf), "XKB_SEMANTICS");
9334345a63Smrg        break;
9434345a63Smrg    case XKB_LAYOUT:
9534345a63Smrg        snprintf(buf, sizeof(buf), "XKB_LAYOUT");
9634345a63Smrg        break;
9734345a63Smrg
9834345a63Smrg    case INCLUDE:
9934345a63Smrg        snprintf(buf, sizeof(buf), "INCLUDE");
10034345a63Smrg        break;
10134345a63Smrg    case OVERRIDE:
10234345a63Smrg        snprintf(buf, sizeof(buf), "OVERRIDE");
10334345a63Smrg        break;
10434345a63Smrg    case AUGMENT:
10534345a63Smrg        snprintf(buf, sizeof(buf), "AUGMENT");
10634345a63Smrg        break;
10734345a63Smrg    case REPLACE:
10834345a63Smrg        snprintf(buf, sizeof(buf), "REPLACE");
10934345a63Smrg        break;
11034345a63Smrg    case ALTERNATE:
11134345a63Smrg        snprintf(buf, sizeof(buf), "ALTERNATE");
11234345a63Smrg        break;
11334345a63Smrg
11434345a63Smrg    case VIRTUAL_MODS:
11534345a63Smrg        snprintf(buf, sizeof(buf), "VIRTUAL_MODS");
11634345a63Smrg        break;
11734345a63Smrg    case TYPE:
11834345a63Smrg        snprintf(buf, sizeof(buf), "TYPE");
11934345a63Smrg        break;
12034345a63Smrg    case INTERPRET:
12134345a63Smrg        snprintf(buf, sizeof(buf), "INTERPRET");
12234345a63Smrg        break;
12334345a63Smrg    case ACTION_TOK:
12434345a63Smrg        snprintf(buf, sizeof(buf), "ACTION");
12534345a63Smrg        break;
12634345a63Smrg    case KEY:
12734345a63Smrg        snprintf(buf, sizeof(buf), "KEY");
12834345a63Smrg        break;
12934345a63Smrg    case ALIAS:
13034345a63Smrg        snprintf(buf, sizeof(buf), "ALIAS");
13134345a63Smrg        break;
13234345a63Smrg    case GROUP:
13334345a63Smrg        snprintf(buf, sizeof(buf), "GROUP");
13434345a63Smrg        break;
13534345a63Smrg    case MODIFIER_MAP:
13634345a63Smrg        snprintf(buf, sizeof(buf), "MODIFIER_MAP");
13734345a63Smrg        break;
13834345a63Smrg    case INDICATOR:
13934345a63Smrg        snprintf(buf, sizeof(buf), "INDICATOR");
14034345a63Smrg        break;
14134345a63Smrg    case SHAPE:
14234345a63Smrg        snprintf(buf, sizeof(buf), "SHAPE");
14334345a63Smrg        break;
14434345a63Smrg    case KEYS:
14534345a63Smrg        snprintf(buf, sizeof(buf), "KEYS");
14634345a63Smrg        break;
14734345a63Smrg    case ROW:
14834345a63Smrg        snprintf(buf, sizeof(buf), "ROW");
14934345a63Smrg        break;
15034345a63Smrg    case SECTION:
15134345a63Smrg        snprintf(buf, sizeof(buf), "SECTION");
15234345a63Smrg        break;
15334345a63Smrg    case OVERLAY:
15434345a63Smrg        snprintf(buf, sizeof(buf), "OVERLAY");
15534345a63Smrg        break;
15634345a63Smrg    case TEXT:
15734345a63Smrg        snprintf(buf, sizeof(buf), "TEXT");
15834345a63Smrg        break;
15934345a63Smrg    case OUTLINE:
16034345a63Smrg        snprintf(buf, sizeof(buf), "OUTLINE");
16134345a63Smrg        break;
16234345a63Smrg    case SOLID:
16334345a63Smrg        snprintf(buf, sizeof(buf), "SOLID");
16434345a63Smrg        break;
16534345a63Smrg    case LOGO:
16634345a63Smrg        snprintf(buf, sizeof(buf), "LOGO");
16734345a63Smrg        break;
16834345a63Smrg    case VIRTUAL:
16934345a63Smrg        snprintf(buf, sizeof(buf), "VIRTUAL");
17034345a63Smrg        break;
17134345a63Smrg
17234345a63Smrg    case EQUALS:
17334345a63Smrg        snprintf(buf, sizeof(buf), "EQUALS");
17434345a63Smrg        break;
17534345a63Smrg    case PLUS:
17634345a63Smrg        snprintf(buf, sizeof(buf), "PLUS");
17734345a63Smrg        break;
17834345a63Smrg    case MINUS:
17934345a63Smrg        snprintf(buf, sizeof(buf), "MINUS");
18034345a63Smrg        break;
18134345a63Smrg    case DIVIDE:
18234345a63Smrg        snprintf(buf, sizeof(buf), "DIVIDE");
18334345a63Smrg        break;
18434345a63Smrg    case TIMES:
18534345a63Smrg        snprintf(buf, sizeof(buf), "TIMES");
18634345a63Smrg        break;
18734345a63Smrg    case OBRACE:
18834345a63Smrg        snprintf(buf, sizeof(buf), "OBRACE");
18934345a63Smrg        break;
19034345a63Smrg    case CBRACE:
19134345a63Smrg        snprintf(buf, sizeof(buf), "CBRACE");
19234345a63Smrg        break;
19334345a63Smrg    case OPAREN:
19434345a63Smrg        snprintf(buf, sizeof(buf), "OPAREN");
19534345a63Smrg        break;
19634345a63Smrg    case CPAREN:
19734345a63Smrg        snprintf(buf, sizeof(buf), "CPAREN");
19834345a63Smrg        break;
19934345a63Smrg    case OBRACKET:
20034345a63Smrg        snprintf(buf, sizeof(buf), "OBRACKET");
20134345a63Smrg        break;
20234345a63Smrg    case CBRACKET:
20334345a63Smrg        snprintf(buf, sizeof(buf), "CBRACKET");
20434345a63Smrg        break;
20534345a63Smrg    case DOT:
20634345a63Smrg        snprintf(buf, sizeof(buf), "DOT");
20734345a63Smrg        break;
20834345a63Smrg    case COMMA:
20934345a63Smrg        snprintf(buf, sizeof(buf), "COMMA");
21034345a63Smrg        break;
21134345a63Smrg    case SEMI:
21234345a63Smrg        snprintf(buf, sizeof(buf), "SEMI");
21334345a63Smrg        break;
21434345a63Smrg    case EXCLAM:
21534345a63Smrg        snprintf(buf, sizeof(buf), "EXCLAM");
21634345a63Smrg        break;
21734345a63Smrg    case INVERT:
21834345a63Smrg        snprintf(buf, sizeof(buf), "INVERT");
21934345a63Smrg        break;
22034345a63Smrg
22134345a63Smrg    case STRING:
22283e5f723Smrg        snprintf(buf, sizeof(buf), "STRING (%s)", scanBuf);
22334345a63Smrg        break;
22434345a63Smrg    case INTEGER:
22534345a63Smrg        snprintf(buf, sizeof(buf), "INTEGER (0x%x)", scanInt);
22634345a63Smrg        break;
22734345a63Smrg    case FLOAT:
22834345a63Smrg        snprintf(buf, sizeof(buf), "FLOAT (%d.%d)",
22934345a63Smrg                scanInt / XkbGeomPtsPerMM, scanInt % XkbGeomPtsPerMM);
23034345a63Smrg        break;
23134345a63Smrg    case IDENT:
23283e5f723Smrg        snprintf(buf, sizeof(buf), "IDENT (%s)", scanBuf);
23334345a63Smrg        break;
23434345a63Smrg    case KEYNAME:
23583e5f723Smrg        snprintf(buf, sizeof(buf), "KEYNAME (%s)", scanBuf);
23634345a63Smrg        break;
23734345a63Smrg
23834345a63Smrg    case PARTIAL:
23934345a63Smrg        snprintf(buf, sizeof(buf), "PARTIAL");
24034345a63Smrg        break;
24134345a63Smrg    case DEFAULT:
24234345a63Smrg        snprintf(buf, sizeof(buf), "DEFAULT");
24334345a63Smrg        break;
24434345a63Smrg    case HIDDEN:
24534345a63Smrg        snprintf(buf, sizeof(buf), "HIDDEN");
24634345a63Smrg        break;
24734345a63Smrg
24834345a63Smrg    case ALPHANUMERIC_KEYS:
24934345a63Smrg        snprintf(buf, sizeof(buf), "ALPHANUMERIC_KEYS");
25034345a63Smrg        break;
25134345a63Smrg    case MODIFIER_KEYS:
25234345a63Smrg        snprintf(buf, sizeof(buf), "MODIFIER_KEYS");
25334345a63Smrg        break;
25434345a63Smrg    case KEYPAD_KEYS:
25534345a63Smrg        snprintf(buf, sizeof(buf), "KEYPAD_KEYS");
25634345a63Smrg        break;
25734345a63Smrg    case FUNCTION_KEYS:
25834345a63Smrg        snprintf(buf, sizeof(buf), "FUNCTION_KEYS");
25934345a63Smrg        break;
26034345a63Smrg    case ALTERNATE_GROUP:
26134345a63Smrg        snprintf(buf, sizeof(buf), "ALTERNATE_GROUP");
26234345a63Smrg        break;
26334345a63Smrg
26434345a63Smrg    default:
26534345a63Smrg        snprintf(buf, sizeof(buf), "UNKNOWN");
26634345a63Smrg        break;
267f46a6179Smrg    }
268f46a6179Smrg    return buf;
269f46a6179Smrg}
270f46a6179Smrg#endif
271f46a6179Smrg
27283e5f723Smrgstatic int
27383e5f723Smrgscanchar(void)
27483e5f723Smrg{
27583e5f723Smrg    if (readBufPos >= readBufLen) {
27683e5f723Smrg        readBufLen = fread(readBuf, 1, BUFSIZE, yyin);
27783e5f723Smrg        readBufPos = 0;
27883e5f723Smrg        if (!readBufLen)
27983e5f723Smrg            return EOF;
28083e5f723Smrg        if (feof(yyin))
28183e5f723Smrg            readBuf[readBufLen] = EOF;
28283e5f723Smrg    }
28383e5f723Smrg
28483e5f723Smrg    return readBuf[readBufPos++];
28583e5f723Smrg}
28683e5f723Smrg
28783e5f723Smrgstatic void
28883e5f723Smrgunscanchar(int c)
28983e5f723Smrg{
29083e5f723Smrg    if (readBuf[--readBufPos] != c) {
29183e5f723Smrg        fprintf(stderr, "UNGETCHAR FAILED! Put back %c, was expecting %c at "
29283e5f723Smrg                        "position %d, buf is '%s'\n", c, readBuf[readBufPos],
29383e5f723Smrg                        readBufPos, readBuf);
29483e5f723Smrg        _exit(94);
29583e5f723Smrg    }
29683e5f723Smrg}
29783e5f723Smrg
298f46a6179Smrgint
29934345a63SmrgsetScanState(char *file, int line)
300f46a6179Smrg{
30134345a63Smrg    if (file != NULL)
30234345a63Smrg        strncpy(scanFile, file, 1024);
30334345a63Smrg    if (line >= 0)
30434345a63Smrg        lineNum = line;
305f46a6179Smrg    return 1;
306f46a6179Smrg}
307f46a6179Smrg
308f46a6179Smrgstatic int
309f46a6179SmrgyyGetString(void)
310f46a6179Smrg{
31183e5f723Smrg    int ch, i;
312f46a6179Smrg
31383e5f723Smrg    i = 0;
31483e5f723Smrg    while (((ch = scanchar()) != EOF) && (ch != '"'))
31534345a63Smrg    {
31634345a63Smrg        if (ch == '\\')
31734345a63Smrg        {
31883e5f723Smrg            if ((ch = scanchar()) != EOF)
31934345a63Smrg            {
32034345a63Smrg                if (ch == 'n')
32134345a63Smrg                    ch = '\n';
32234345a63Smrg                else if (ch == 't')
32334345a63Smrg                    ch = '\t';
32434345a63Smrg                else if (ch == 'v')
32534345a63Smrg                    ch = '\v';
32634345a63Smrg                else if (ch == 'b')
32734345a63Smrg                    ch = '\b';
32834345a63Smrg                else if (ch == 'r')
32934345a63Smrg                    ch = '\r';
33034345a63Smrg                else if (ch == 'f')
33134345a63Smrg                    ch = '\f';
33234345a63Smrg                else if (ch == 'e')
33334345a63Smrg                    ch = '\033';
33434345a63Smrg                else if (ch == '0')
33534345a63Smrg                {
33634345a63Smrg                    int tmp, stop;
33734345a63Smrg                    ch = stop = 0;
33883e5f723Smrg                    if (((tmp = scanchar()) != EOF) && (isdigit(tmp))
33934345a63Smrg                        && (tmp != '8') && (tmp != '9'))
34034345a63Smrg                    {
34134345a63Smrg                        ch = (ch * 8) + (tmp - '0');
34234345a63Smrg                    }
34334345a63Smrg                    else
34434345a63Smrg                    {
34534345a63Smrg                        stop = 1;
34683e5f723Smrg                        unscanchar(tmp);
34734345a63Smrg                    }
34834345a63Smrg                    if (!stop)
34934345a63Smrg                    {
35083e5f723Smrg                        if (((tmp = scanchar()) != EOF)
35134345a63Smrg                            && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
35234345a63Smrg                        {
35334345a63Smrg                            ch = (ch * 8) + (tmp - '0');
35434345a63Smrg                        }
35534345a63Smrg                        else
35634345a63Smrg                        {
35734345a63Smrg                            stop = 1;
35883e5f723Smrg                            unscanchar(tmp);
35934345a63Smrg                        }
36034345a63Smrg                    }
36134345a63Smrg                    if (!stop)
36234345a63Smrg                    {
36383e5f723Smrg                        if (((tmp = scanchar()) != EOF)
36434345a63Smrg                            && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
36534345a63Smrg                        {
36634345a63Smrg                            ch = (ch * 8) + (tmp - '0');
36734345a63Smrg                        }
36834345a63Smrg                        else
36934345a63Smrg                        {
37034345a63Smrg                            stop = 1;
37183e5f723Smrg                            unscanchar(tmp);
37234345a63Smrg                        }
37334345a63Smrg                    }
37434345a63Smrg                }
37534345a63Smrg            }
37634345a63Smrg            else
37734345a63Smrg                return ERROR_TOK;
37834345a63Smrg        }
37983e5f723Smrg        if (i < sizeof(scanBuf) - 1)
38083e5f723Smrg            scanBuf[i++] = ch;
381f46a6179Smrg    }
38234345a63Smrg    if (ch == '"')
38334345a63Smrg    {
38483e5f723Smrg        scanBuf[i++] = '\0';
38534345a63Smrg        scanStrLine = lineNum;
38634345a63Smrg        return STRING;
387f46a6179Smrg    }
388f46a6179Smrg    return ERROR_TOK;
389f46a6179Smrg}
390f46a6179Smrg
391f46a6179Smrgstatic int
392f46a6179SmrgyyGetKeyName(void)
393f46a6179Smrg{
39483e5f723Smrg    int ch, i;
395f46a6179Smrg
39683e5f723Smrg    i = 0;
39783e5f723Smrg    while (((ch = scanchar()) != EOF) && (ch != '>'))
39834345a63Smrg    {
39934345a63Smrg        if (ch == '\\')
40034345a63Smrg        {
40183e5f723Smrg            if ((ch = scanchar()) != EOF)
40234345a63Smrg            {
40334345a63Smrg                if (ch == 'n')
40434345a63Smrg                    ch = '\n';
40534345a63Smrg                else if (ch == 't')
40634345a63Smrg                    ch = '\t';
40734345a63Smrg                else if (ch == 'v')
40834345a63Smrg                    ch = '\v';
40934345a63Smrg                else if (ch == 'b')
41034345a63Smrg                    ch = '\b';
41134345a63Smrg                else if (ch == 'r')
41234345a63Smrg                    ch = '\r';
41334345a63Smrg                else if (ch == 'f')
41434345a63Smrg                    ch = '\f';
41534345a63Smrg                else if (ch == 'e')
41634345a63Smrg                    ch = '\033';
41734345a63Smrg                else if (ch == '0')
41834345a63Smrg                {
41934345a63Smrg                    int tmp, stop;
42034345a63Smrg                    ch = stop = 0;
42183e5f723Smrg                    if (((tmp = scanchar()) != EOF) && (isdigit(tmp))
42234345a63Smrg                        && (tmp != '8') && (tmp != '9'))
42334345a63Smrg                    {
42434345a63Smrg                        ch = (ch * 8) + (tmp - '0');
42534345a63Smrg                    }
42634345a63Smrg                    else
42734345a63Smrg                    {
42834345a63Smrg                        stop = 1;
42983e5f723Smrg                        unscanchar(tmp);
43034345a63Smrg                    }
43183e5f723Smrg                    if ((!stop) && ((tmp = scanchar()) != EOF)
43234345a63Smrg                        && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
43334345a63Smrg                    {
43434345a63Smrg                        ch = (ch * 8) + (tmp - '0');
43534345a63Smrg                    }
43634345a63Smrg                    else
43734345a63Smrg                    {
43834345a63Smrg                        stop = 1;
43983e5f723Smrg                        unscanchar(tmp);
44034345a63Smrg                    }
44183e5f723Smrg                    if ((!stop) && ((tmp = scanchar()) != EOF)
44234345a63Smrg                        && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
44334345a63Smrg                    {
44434345a63Smrg                        ch = (ch * 8) + (tmp - '0');
44534345a63Smrg                    }
44634345a63Smrg                    else
44734345a63Smrg                    {
44834345a63Smrg                        stop = 1;
44983e5f723Smrg                        unscanchar(tmp);
45034345a63Smrg                    }
45134345a63Smrg                }
45234345a63Smrg            }
45334345a63Smrg            else
45434345a63Smrg                return ERROR_TOK;
45534345a63Smrg        }
45634345a63Smrg
45783e5f723Smrg        if (i < sizeof(scanBuf) - 1)
45883e5f723Smrg            scanBuf[i++] = ch;
459f46a6179Smrg    }
46083e5f723Smrg    if ((ch == '>') && (i < 5))
46134345a63Smrg    {
46283e5f723Smrg        scanBuf[i++] = '\0';
46334345a63Smrg        scanStrLine = lineNum;
46434345a63Smrg        return KEYNAME;
465f46a6179Smrg    }
466f46a6179Smrg    return ERROR_TOK;
467f46a6179Smrg}
468f46a6179Smrg
46934345a63Smrgstatic struct _Keyword
47034345a63Smrg{
47134345a63Smrg    const char *keyword;
47234345a63Smrg    int token;
47334345a63Smrg} keywords[] =
47434345a63Smrg{
47534345a63Smrg    {
47634345a63Smrg    "xkb_keymap", XKB_KEYMAP},
47734345a63Smrg    {
47834345a63Smrg    "xkb_keycodes", XKB_KEYCODES},
47934345a63Smrg    {
48034345a63Smrg    "xkb_types", XKB_TYPES},
48134345a63Smrg    {
48234345a63Smrg    "xkb_symbols", XKB_SYMBOLS},
48334345a63Smrg    {
48434345a63Smrg    "xkb_compat", XKB_COMPATMAP},
48534345a63Smrg    {
48634345a63Smrg    "xkb_compat_map", XKB_COMPATMAP},
48734345a63Smrg    {
48834345a63Smrg    "xkb_compatibility", XKB_COMPATMAP},
48934345a63Smrg    {
49034345a63Smrg    "xkb_compatibility_map", XKB_COMPATMAP},
49134345a63Smrg    {
49234345a63Smrg    "xkb_geometry", XKB_GEOMETRY},
49334345a63Smrg    {
49434345a63Smrg    "xkb_semantics", XKB_SEMANTICS},
49534345a63Smrg    {
49634345a63Smrg    "xkb_layout", XKB_LAYOUT},
49734345a63Smrg    {
49834345a63Smrg    "include", INCLUDE},
49934345a63Smrg    {
50034345a63Smrg    "override", OVERRIDE},
50134345a63Smrg    {
50234345a63Smrg    "augment", AUGMENT},
50334345a63Smrg    {
50434345a63Smrg    "replace", REPLACE},
50534345a63Smrg    {
50634345a63Smrg    "alternate", ALTERNATE},
50734345a63Smrg    {
50834345a63Smrg    "partial", PARTIAL},
50934345a63Smrg    {
51034345a63Smrg    "default", DEFAULT},
51134345a63Smrg    {
51234345a63Smrg    "hidden", HIDDEN},
51334345a63Smrg    {
51434345a63Smrg    "virtual_modifiers", VIRTUAL_MODS},
51534345a63Smrg    {
51634345a63Smrg    "type", TYPE},
51734345a63Smrg    {
51834345a63Smrg    "interpret", INTERPRET},
51934345a63Smrg    {
52034345a63Smrg    "action", ACTION_TOK},
52134345a63Smrg    {
52234345a63Smrg    "key", KEY},
52334345a63Smrg    {
52434345a63Smrg    "alias", ALIAS},
52534345a63Smrg    {
52634345a63Smrg    "group", GROUP},
52734345a63Smrg    {
52834345a63Smrg    "modmap", MODIFIER_MAP},
52934345a63Smrg    {
53034345a63Smrg    "mod_map", MODIFIER_MAP},
53134345a63Smrg    {
53234345a63Smrg    "modifier_map", MODIFIER_MAP},
53334345a63Smrg    {
53434345a63Smrg    "indicator", INDICATOR},
53534345a63Smrg    {
53634345a63Smrg    "shape", SHAPE},
53734345a63Smrg    {
53834345a63Smrg    "row", ROW},
53934345a63Smrg    {
54034345a63Smrg    "keys", KEYS},
54134345a63Smrg    {
54234345a63Smrg    "section", SECTION},
54334345a63Smrg    {
54434345a63Smrg    "overlay", OVERLAY},
54534345a63Smrg    {
54634345a63Smrg    "text", TEXT},
54734345a63Smrg    {
54834345a63Smrg    "outline", OUTLINE},
54934345a63Smrg    {
55034345a63Smrg    "solid", SOLID},
55134345a63Smrg    {
55234345a63Smrg    "logo", LOGO},
55334345a63Smrg    {
55434345a63Smrg    "virtual", VIRTUAL},
55534345a63Smrg    {
55634345a63Smrg    "alphanumeric_keys", ALPHANUMERIC_KEYS},
55734345a63Smrg    {
55834345a63Smrg    "modifier_keys", MODIFIER_KEYS},
55934345a63Smrg    {
56034345a63Smrg    "keypad_keys", KEYPAD_KEYS},
56134345a63Smrg    {
56234345a63Smrg    "function_keys", FUNCTION_KEYS},
56334345a63Smrg    {
56434345a63Smrg    "alternate_group", ALTERNATE_GROUP}
565f46a6179Smrg};
56634345a63Smrgstatic int numKeywords = sizeof(keywords) / sizeof(struct _Keyword);
567f46a6179Smrg
568f46a6179Smrgstatic int
569f46a6179SmrgyyGetIdent(int first)
570f46a6179Smrg{
57183e5f723Smrg    int ch, i, j, found;
57234345a63Smrg    int rtrn = IDENT;
57334345a63Smrg
57483e5f723Smrg    scanBuf[0] = first;
57583e5f723Smrg    j = 1;
57683e5f723Smrg    while (((ch = scanchar()) != EOF) && (isalnum(ch) || (ch == '_')))
57734345a63Smrg    {
57883e5f723Smrg        if (j < sizeof(scanBuf) - 1)
57983e5f723Smrg            scanBuf[j++] = ch;
580f46a6179Smrg    }
58183e5f723Smrg    scanBuf[j++] = '\0';
58234345a63Smrg    found = 0;
58334345a63Smrg
58434345a63Smrg    for (i = 0; (!found) && (i < numKeywords); i++)
58534345a63Smrg    {
58683e5f723Smrg        if (uStrCaseCmp(scanBuf, keywords[i].keyword) == 0)
58734345a63Smrg        {
58834345a63Smrg            rtrn = keywords[i].token;
58934345a63Smrg            found = 1;
59034345a63Smrg        }
591f46a6179Smrg    }
59234345a63Smrg    if (!found)
59334345a63Smrg    {
59434345a63Smrg        scanStrLine = lineNum;
59534345a63Smrg        rtrn = IDENT;
596f46a6179Smrg    }
597f46a6179Smrg
59834345a63Smrg    if ((ch != EOF) && (!isspace(ch)))
59983e5f723Smrg        unscanchar(ch);
60034345a63Smrg    else if (ch == '\n')
60134345a63Smrg        lineNum++;
602f46a6179Smrg
603f46a6179Smrg    return rtrn;
604f46a6179Smrg}
605f46a6179Smrg
606f46a6179Smrgstatic int
607f46a6179SmrgyyGetNumber(int ch)
608f46a6179Smrg{
609690143ccSmrg    const int nMaxBuffSize = 1024;
61034345a63Smrg    int isFloat = 0;
611690143ccSmrg    char buf[nMaxBuffSize];
61283e5f723Smrg    int nInBuf = 0;
61334345a63Smrg
61434345a63Smrg    buf[0] = ch;
61534345a63Smrg    nInBuf = 1;
61683e5f723Smrg    while (((ch = scanchar()) != EOF)
617690143ccSmrg           && (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x')))
6181d8c7986Smrg           && nInBuf < (nMaxBuffSize - 1))
61934345a63Smrg    {
62034345a63Smrg        buf[nInBuf++] = ch;
621f46a6179Smrg    }
6221d8c7986Smrg    if ((ch == '.') && (nInBuf < (nMaxBuffSize - 1)))
62334345a63Smrg    {
62434345a63Smrg        isFloat = 1;
62534345a63Smrg        buf[nInBuf++] = ch;
626690143ccSmrg        while (((ch = scanchar()) != EOF) && (isxdigit(ch))
6271d8c7986Smrg               && nInBuf < (nMaxBuffSize - 1))
62834345a63Smrg        {
62934345a63Smrg            buf[nInBuf++] = ch;
63034345a63Smrg        }
631f46a6179Smrg    }
63234345a63Smrg    buf[nInBuf++] = '\0';
63334345a63Smrg    if ((ch != EOF) && (!isspace(ch)))
63483e5f723Smrg        unscanchar(ch);
63534345a63Smrg
63634345a63Smrg    if (isFloat)
63734345a63Smrg    {
63834345a63Smrg        float tmp;
63934345a63Smrg        if (sscanf(buf, "%g", &tmp) == 1)
64034345a63Smrg        {
64134345a63Smrg            scanInt = tmp * XkbGeomPtsPerMM;
64234345a63Smrg            return FLOAT;
64334345a63Smrg        }
644f46a6179Smrg    }
64534345a63Smrg    else if (sscanf(buf, "%i", &scanInt) == 1)
64634345a63Smrg        return INTEGER;
64734345a63Smrg    fprintf(stderr, "Malformed number %s\n", buf);
648f46a6179Smrg    return ERROR_TOK;
649f46a6179Smrg}
650f46a6179Smrg
651f46a6179Smrgint
652f46a6179Smrgyylex(void)
653f46a6179Smrg{
65434345a63Smrg    int ch;
65534345a63Smrg    int rtrn;
65634345a63Smrg
65734345a63Smrg    do
65834345a63Smrg    {
65983e5f723Smrg        ch = scanchar();
66034345a63Smrg        if (ch == '\n')
66134345a63Smrg        {
66234345a63Smrg            lineNum++;
66334345a63Smrg        }
66434345a63Smrg        else if (ch == '#')
66534345a63Smrg        {                       /* handle shell style '#' comments */
66634345a63Smrg            do
66734345a63Smrg            {
66883e5f723Smrg                ch = scanchar();
66934345a63Smrg            }
67034345a63Smrg            while ((ch != '\n') && (ch != EOF));
67134345a63Smrg            lineNum++;
67234345a63Smrg        }
67334345a63Smrg        else if (ch == '/')
67434345a63Smrg        {                       /* handle C++ style double-/ comments */
67583e5f723Smrg            int newch = scanchar();
67634345a63Smrg            if (newch == '/')
67734345a63Smrg            {
67834345a63Smrg                do
67934345a63Smrg                {
68083e5f723Smrg                    ch = scanchar();
68134345a63Smrg                }
68234345a63Smrg                while ((ch != '\n') && (ch != EOF));
68334345a63Smrg                lineNum++;
68434345a63Smrg            }
68534345a63Smrg            else if (newch != EOF)
68634345a63Smrg            {
68783e5f723Smrg                unscanchar(newch);
68834345a63Smrg            }
68934345a63Smrg        }
69034345a63Smrg    }
69134345a63Smrg    while ((ch != EOF) && (isspace(ch)));
69234345a63Smrg    if (ch == '=')
69334345a63Smrg        rtrn = EQUALS;
69434345a63Smrg    else if (ch == '+')
69534345a63Smrg        rtrn = PLUS;
69634345a63Smrg    else if (ch == '-')
69734345a63Smrg        rtrn = MINUS;
69834345a63Smrg    else if (ch == '/')
69934345a63Smrg        rtrn = DIVIDE;
70034345a63Smrg    else if (ch == '*')
70134345a63Smrg        rtrn = TIMES;
70234345a63Smrg    else if (ch == '{')
70334345a63Smrg        rtrn = OBRACE;
70434345a63Smrg    else if (ch == '}')
70534345a63Smrg        rtrn = CBRACE;
70634345a63Smrg    else if (ch == '(')
70734345a63Smrg        rtrn = OPAREN;
70834345a63Smrg    else if (ch == ')')
70934345a63Smrg        rtrn = CPAREN;
71034345a63Smrg    else if (ch == '[')
71134345a63Smrg        rtrn = OBRACKET;
71234345a63Smrg    else if (ch == ']')
71334345a63Smrg        rtrn = CBRACKET;
71434345a63Smrg    else if (ch == '.')
71534345a63Smrg        rtrn = DOT;
71634345a63Smrg    else if (ch == ',')
71734345a63Smrg        rtrn = COMMA;
71834345a63Smrg    else if (ch == ';')
71934345a63Smrg        rtrn = SEMI;
72034345a63Smrg    else if (ch == '!')
72134345a63Smrg        rtrn = EXCLAM;
72234345a63Smrg    else if (ch == '~')
72334345a63Smrg        rtrn = INVERT;
72434345a63Smrg    else if (ch == '"')
72534345a63Smrg        rtrn = yyGetString();
72634345a63Smrg    else if (ch == '<')
72734345a63Smrg        rtrn = yyGetKeyName();
72834345a63Smrg    else if (isalpha(ch) || (ch == '_'))
72934345a63Smrg        rtrn = yyGetIdent(ch);
73034345a63Smrg    else if (isdigit(ch))
73134345a63Smrg        rtrn = yyGetNumber(ch);
73234345a63Smrg    else if (ch == EOF)
73334345a63Smrg        rtrn = END_OF_FILE;
73434345a63Smrg    else
73534345a63Smrg    {
736f46a6179Smrg#ifdef DEBUG
73734345a63Smrg        if (debugFlags)
73834345a63Smrg            fprintf(stderr,
73934345a63Smrg                    "Unexpected character %c (%d) in input stream\n", ch, ch);
740f46a6179Smrg#endif
74134345a63Smrg        rtrn = ERROR_TOK;
742f46a6179Smrg    }
743f46a6179Smrg#ifdef DEBUG
74434345a63Smrg    if (debugFlags & 0x2)
74534345a63Smrg        fprintf(stderr, "scan: %s\n", tokText(rtrn));
746f46a6179Smrg#endif
747f46a6179Smrg    return rtrn;
748f46a6179Smrg}
749