xkbscan.c revision c82dfdfb
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
27c82dfdfbSmrg#include <stdlib.h>
28f46a6179Smrg#include <stdio.h>
29f46a6179Smrg#include <ctype.h>
30f46a6179Smrg#include <X11/Xos.h>
31f46a6179Smrg#include <X11/Xlib.h>
32f46a6179Smrg#include <X11/XKBlib.h>
33f46a6179Smrg
34f46a6179Smrg#include "tokens.h"
35f46a6179Smrg#define	DEBUG_VAR	scanDebug
36f46a6179Smrg#include "utils.h"
37f46a6179Smrg#include "parseutils.h"
38f46a6179Smrg
3934345a63Smrgunsigned int scanDebug;
40f46a6179Smrg
41c82dfdfbSmrgstatic FILE *yyin;
42f46a6179Smrg
4334345a63Smrgstatic char scanFileBuf[1024] = {0};
4434345a63Smrgchar *scanFile = scanFileBuf;
4534345a63Smrgint lineNum = 0;
46f46a6179Smrg
4734345a63Smrgint scanInt;
4834345a63Smrg
4983e5f723Smrgchar scanBuf[1024];
5034345a63Smrgstatic int scanStrLine = 0;
51f46a6179Smrg
5283e5f723Smrg#define	BUFSIZE	4096
5383e5f723Smrgstatic char readBuf[BUFSIZE];
5483e5f723Smrgstatic int readBufPos = 0;
5583e5f723Smrgstatic int readBufLen = 0;
56f46a6179Smrg
57f46a6179Smrg#ifdef DEBUG
5883e5f723Smrgextern int debugFlags;
5983e5f723Smrg
60f46a6179Smrgstatic char *
61f46a6179SmrgtokText(int tok)
62f46a6179Smrg{
6334345a63Smrg    static char buf[32];
6434345a63Smrg
6534345a63Smrg    switch (tok)
6634345a63Smrg    {
6734345a63Smrg    case END_OF_FILE:
6834345a63Smrg        snprintf(buf, sizeof(buf), "END_OF_FILE");
6934345a63Smrg        break;
7034345a63Smrg    case ERROR_TOK:
7134345a63Smrg        snprintf(buf, sizeof(buf), "ERROR");
7234345a63Smrg        break;
7334345a63Smrg
7434345a63Smrg    case XKB_KEYMAP:
7534345a63Smrg        snprintf(buf, sizeof(buf), "XKB_KEYMAP");
7634345a63Smrg        break;
7734345a63Smrg    case XKB_KEYCODES:
7834345a63Smrg        snprintf(buf, sizeof(buf), "XKB_KEYCODES");
7934345a63Smrg        break;
8034345a63Smrg    case XKB_TYPES:
8134345a63Smrg        snprintf(buf, sizeof(buf), "XKB_TYPES");
8234345a63Smrg        break;
8334345a63Smrg    case XKB_SYMBOLS:
8434345a63Smrg        snprintf(buf, sizeof(buf), "XKB_SYMBOLS");
8534345a63Smrg        break;
8634345a63Smrg    case XKB_COMPATMAP:
8734345a63Smrg        snprintf(buf, sizeof(buf), "XKB_COMPATMAP");
8834345a63Smrg        break;
8934345a63Smrg    case XKB_GEOMETRY:
9034345a63Smrg        snprintf(buf, sizeof(buf), "XKB_GEOMETRY");
9134345a63Smrg        break;
9234345a63Smrg    case XKB_SEMANTICS:
9334345a63Smrg        snprintf(buf, sizeof(buf), "XKB_SEMANTICS");
9434345a63Smrg        break;
9534345a63Smrg    case XKB_LAYOUT:
9634345a63Smrg        snprintf(buf, sizeof(buf), "XKB_LAYOUT");
9734345a63Smrg        break;
9834345a63Smrg
9934345a63Smrg    case INCLUDE:
10034345a63Smrg        snprintf(buf, sizeof(buf), "INCLUDE");
10134345a63Smrg        break;
10234345a63Smrg    case OVERRIDE:
10334345a63Smrg        snprintf(buf, sizeof(buf), "OVERRIDE");
10434345a63Smrg        break;
10534345a63Smrg    case AUGMENT:
10634345a63Smrg        snprintf(buf, sizeof(buf), "AUGMENT");
10734345a63Smrg        break;
10834345a63Smrg    case REPLACE:
10934345a63Smrg        snprintf(buf, sizeof(buf), "REPLACE");
11034345a63Smrg        break;
11134345a63Smrg    case ALTERNATE:
11234345a63Smrg        snprintf(buf, sizeof(buf), "ALTERNATE");
11334345a63Smrg        break;
11434345a63Smrg
11534345a63Smrg    case VIRTUAL_MODS:
11634345a63Smrg        snprintf(buf, sizeof(buf), "VIRTUAL_MODS");
11734345a63Smrg        break;
11834345a63Smrg    case TYPE:
11934345a63Smrg        snprintf(buf, sizeof(buf), "TYPE");
12034345a63Smrg        break;
12134345a63Smrg    case INTERPRET:
12234345a63Smrg        snprintf(buf, sizeof(buf), "INTERPRET");
12334345a63Smrg        break;
12434345a63Smrg    case ACTION_TOK:
12534345a63Smrg        snprintf(buf, sizeof(buf), "ACTION");
12634345a63Smrg        break;
12734345a63Smrg    case KEY:
12834345a63Smrg        snprintf(buf, sizeof(buf), "KEY");
12934345a63Smrg        break;
13034345a63Smrg    case ALIAS:
13134345a63Smrg        snprintf(buf, sizeof(buf), "ALIAS");
13234345a63Smrg        break;
13334345a63Smrg    case GROUP:
13434345a63Smrg        snprintf(buf, sizeof(buf), "GROUP");
13534345a63Smrg        break;
13634345a63Smrg    case MODIFIER_MAP:
13734345a63Smrg        snprintf(buf, sizeof(buf), "MODIFIER_MAP");
13834345a63Smrg        break;
13934345a63Smrg    case INDICATOR:
14034345a63Smrg        snprintf(buf, sizeof(buf), "INDICATOR");
14134345a63Smrg        break;
14234345a63Smrg    case SHAPE:
14334345a63Smrg        snprintf(buf, sizeof(buf), "SHAPE");
14434345a63Smrg        break;
14534345a63Smrg    case KEYS:
14634345a63Smrg        snprintf(buf, sizeof(buf), "KEYS");
14734345a63Smrg        break;
14834345a63Smrg    case ROW:
14934345a63Smrg        snprintf(buf, sizeof(buf), "ROW");
15034345a63Smrg        break;
15134345a63Smrg    case SECTION:
15234345a63Smrg        snprintf(buf, sizeof(buf), "SECTION");
15334345a63Smrg        break;
15434345a63Smrg    case OVERLAY:
15534345a63Smrg        snprintf(buf, sizeof(buf), "OVERLAY");
15634345a63Smrg        break;
15734345a63Smrg    case TEXT:
15834345a63Smrg        snprintf(buf, sizeof(buf), "TEXT");
15934345a63Smrg        break;
16034345a63Smrg    case OUTLINE:
16134345a63Smrg        snprintf(buf, sizeof(buf), "OUTLINE");
16234345a63Smrg        break;
16334345a63Smrg    case SOLID:
16434345a63Smrg        snprintf(buf, sizeof(buf), "SOLID");
16534345a63Smrg        break;
16634345a63Smrg    case LOGO:
16734345a63Smrg        snprintf(buf, sizeof(buf), "LOGO");
16834345a63Smrg        break;
16934345a63Smrg    case VIRTUAL:
17034345a63Smrg        snprintf(buf, sizeof(buf), "VIRTUAL");
17134345a63Smrg        break;
17234345a63Smrg
17334345a63Smrg    case EQUALS:
17434345a63Smrg        snprintf(buf, sizeof(buf), "EQUALS");
17534345a63Smrg        break;
17634345a63Smrg    case PLUS:
17734345a63Smrg        snprintf(buf, sizeof(buf), "PLUS");
17834345a63Smrg        break;
17934345a63Smrg    case MINUS:
18034345a63Smrg        snprintf(buf, sizeof(buf), "MINUS");
18134345a63Smrg        break;
18234345a63Smrg    case DIVIDE:
18334345a63Smrg        snprintf(buf, sizeof(buf), "DIVIDE");
18434345a63Smrg        break;
18534345a63Smrg    case TIMES:
18634345a63Smrg        snprintf(buf, sizeof(buf), "TIMES");
18734345a63Smrg        break;
18834345a63Smrg    case OBRACE:
18934345a63Smrg        snprintf(buf, sizeof(buf), "OBRACE");
19034345a63Smrg        break;
19134345a63Smrg    case CBRACE:
19234345a63Smrg        snprintf(buf, sizeof(buf), "CBRACE");
19334345a63Smrg        break;
19434345a63Smrg    case OPAREN:
19534345a63Smrg        snprintf(buf, sizeof(buf), "OPAREN");
19634345a63Smrg        break;
19734345a63Smrg    case CPAREN:
19834345a63Smrg        snprintf(buf, sizeof(buf), "CPAREN");
19934345a63Smrg        break;
20034345a63Smrg    case OBRACKET:
20134345a63Smrg        snprintf(buf, sizeof(buf), "OBRACKET");
20234345a63Smrg        break;
20334345a63Smrg    case CBRACKET:
20434345a63Smrg        snprintf(buf, sizeof(buf), "CBRACKET");
20534345a63Smrg        break;
20634345a63Smrg    case DOT:
20734345a63Smrg        snprintf(buf, sizeof(buf), "DOT");
20834345a63Smrg        break;
20934345a63Smrg    case COMMA:
21034345a63Smrg        snprintf(buf, sizeof(buf), "COMMA");
21134345a63Smrg        break;
21234345a63Smrg    case SEMI:
21334345a63Smrg        snprintf(buf, sizeof(buf), "SEMI");
21434345a63Smrg        break;
21534345a63Smrg    case EXCLAM:
21634345a63Smrg        snprintf(buf, sizeof(buf), "EXCLAM");
21734345a63Smrg        break;
21834345a63Smrg    case INVERT:
21934345a63Smrg        snprintf(buf, sizeof(buf), "INVERT");
22034345a63Smrg        break;
22134345a63Smrg
22234345a63Smrg    case STRING:
22383e5f723Smrg        snprintf(buf, sizeof(buf), "STRING (%s)", scanBuf);
22434345a63Smrg        break;
22534345a63Smrg    case INTEGER:
22634345a63Smrg        snprintf(buf, sizeof(buf), "INTEGER (0x%x)", scanInt);
22734345a63Smrg        break;
22834345a63Smrg    case FLOAT:
22934345a63Smrg        snprintf(buf, sizeof(buf), "FLOAT (%d.%d)",
23034345a63Smrg                scanInt / XkbGeomPtsPerMM, scanInt % XkbGeomPtsPerMM);
23134345a63Smrg        break;
23234345a63Smrg    case IDENT:
23383e5f723Smrg        snprintf(buf, sizeof(buf), "IDENT (%s)", scanBuf);
23434345a63Smrg        break;
23534345a63Smrg    case KEYNAME:
23683e5f723Smrg        snprintf(buf, sizeof(buf), "KEYNAME (%s)", scanBuf);
23734345a63Smrg        break;
23834345a63Smrg
23934345a63Smrg    case PARTIAL:
24034345a63Smrg        snprintf(buf, sizeof(buf), "PARTIAL");
24134345a63Smrg        break;
24234345a63Smrg    case DEFAULT:
24334345a63Smrg        snprintf(buf, sizeof(buf), "DEFAULT");
24434345a63Smrg        break;
24534345a63Smrg    case HIDDEN:
24634345a63Smrg        snprintf(buf, sizeof(buf), "HIDDEN");
24734345a63Smrg        break;
24834345a63Smrg
24934345a63Smrg    case ALPHANUMERIC_KEYS:
25034345a63Smrg        snprintf(buf, sizeof(buf), "ALPHANUMERIC_KEYS");
25134345a63Smrg        break;
25234345a63Smrg    case MODIFIER_KEYS:
25334345a63Smrg        snprintf(buf, sizeof(buf), "MODIFIER_KEYS");
25434345a63Smrg        break;
25534345a63Smrg    case KEYPAD_KEYS:
25634345a63Smrg        snprintf(buf, sizeof(buf), "KEYPAD_KEYS");
25734345a63Smrg        break;
25834345a63Smrg    case FUNCTION_KEYS:
25934345a63Smrg        snprintf(buf, sizeof(buf), "FUNCTION_KEYS");
26034345a63Smrg        break;
26134345a63Smrg    case ALTERNATE_GROUP:
26234345a63Smrg        snprintf(buf, sizeof(buf), "ALTERNATE_GROUP");
26334345a63Smrg        break;
26434345a63Smrg
26534345a63Smrg    default:
26634345a63Smrg        snprintf(buf, sizeof(buf), "UNKNOWN");
26734345a63Smrg        break;
268f46a6179Smrg    }
269f46a6179Smrg    return buf;
270f46a6179Smrg}
271f46a6179Smrg#endif
272f46a6179Smrg
273c82dfdfbSmrgvoid
274c82dfdfbSmrgscan_set_file(FILE *file)
275c82dfdfbSmrg{
276c82dfdfbSmrg    readBufLen = 0;
277c82dfdfbSmrg    readBufPos = 0;
278c82dfdfbSmrg    yyin = file;
279c82dfdfbSmrg}
280c82dfdfbSmrg
28183e5f723Smrgstatic int
28283e5f723Smrgscanchar(void)
28383e5f723Smrg{
28483e5f723Smrg    if (readBufPos >= readBufLen) {
28583e5f723Smrg        readBufLen = fread(readBuf, 1, BUFSIZE, yyin);
28683e5f723Smrg        readBufPos = 0;
28783e5f723Smrg        if (!readBufLen)
28883e5f723Smrg            return EOF;
28983e5f723Smrg        if (feof(yyin))
29083e5f723Smrg            readBuf[readBufLen] = EOF;
29183e5f723Smrg    }
29283e5f723Smrg
29383e5f723Smrg    return readBuf[readBufPos++];
29483e5f723Smrg}
29583e5f723Smrg
29683e5f723Smrgstatic void
29783e5f723Smrgunscanchar(int c)
29883e5f723Smrg{
29983e5f723Smrg    if (readBuf[--readBufPos] != c) {
30083e5f723Smrg        fprintf(stderr, "UNGETCHAR FAILED! Put back %c, was expecting %c at "
30183e5f723Smrg                        "position %d, buf is '%s'\n", c, readBuf[readBufPos],
30283e5f723Smrg                        readBufPos, readBuf);
30383e5f723Smrg        _exit(94);
30483e5f723Smrg    }
30583e5f723Smrg}
30683e5f723Smrg
307f46a6179Smrgint
30834345a63SmrgsetScanState(char *file, int line)
309f46a6179Smrg{
31034345a63Smrg    if (file != NULL)
31134345a63Smrg        strncpy(scanFile, file, 1024);
31234345a63Smrg    if (line >= 0)
31334345a63Smrg        lineNum = line;
314f46a6179Smrg    return 1;
315f46a6179Smrg}
316f46a6179Smrg
317f46a6179Smrgstatic int
318f46a6179SmrgyyGetString(void)
319f46a6179Smrg{
32083e5f723Smrg    int ch, i;
321f46a6179Smrg
32283e5f723Smrg    i = 0;
32383e5f723Smrg    while (((ch = scanchar()) != EOF) && (ch != '"'))
32434345a63Smrg    {
32534345a63Smrg        if (ch == '\\')
32634345a63Smrg        {
32783e5f723Smrg            if ((ch = scanchar()) != EOF)
32834345a63Smrg            {
32934345a63Smrg                if (ch == 'n')
33034345a63Smrg                    ch = '\n';
33134345a63Smrg                else if (ch == 't')
33234345a63Smrg                    ch = '\t';
33334345a63Smrg                else if (ch == 'v')
33434345a63Smrg                    ch = '\v';
33534345a63Smrg                else if (ch == 'b')
33634345a63Smrg                    ch = '\b';
33734345a63Smrg                else if (ch == 'r')
33834345a63Smrg                    ch = '\r';
33934345a63Smrg                else if (ch == 'f')
34034345a63Smrg                    ch = '\f';
34134345a63Smrg                else if (ch == 'e')
34234345a63Smrg                    ch = '\033';
34334345a63Smrg                else if (ch == '0')
34434345a63Smrg                {
34534345a63Smrg                    int tmp, stop;
34634345a63Smrg                    ch = stop = 0;
34783e5f723Smrg                    if (((tmp = scanchar()) != EOF) && (isdigit(tmp))
34834345a63Smrg                        && (tmp != '8') && (tmp != '9'))
34934345a63Smrg                    {
35034345a63Smrg                        ch = (ch * 8) + (tmp - '0');
35134345a63Smrg                    }
35234345a63Smrg                    else
35334345a63Smrg                    {
35434345a63Smrg                        stop = 1;
35583e5f723Smrg                        unscanchar(tmp);
35634345a63Smrg                    }
35734345a63Smrg                    if (!stop)
35834345a63Smrg                    {
35983e5f723Smrg                        if (((tmp = scanchar()) != EOF)
36034345a63Smrg                            && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
36134345a63Smrg                        {
36234345a63Smrg                            ch = (ch * 8) + (tmp - '0');
36334345a63Smrg                        }
36434345a63Smrg                        else
36534345a63Smrg                        {
36634345a63Smrg                            stop = 1;
36783e5f723Smrg                            unscanchar(tmp);
36834345a63Smrg                        }
36934345a63Smrg                    }
37034345a63Smrg                    if (!stop)
37134345a63Smrg                    {
37283e5f723Smrg                        if (((tmp = scanchar()) != EOF)
37334345a63Smrg                            && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
37434345a63Smrg                        {
37534345a63Smrg                            ch = (ch * 8) + (tmp - '0');
37634345a63Smrg                        }
37734345a63Smrg                        else
37834345a63Smrg                        {
37934345a63Smrg                            stop = 1;
38083e5f723Smrg                            unscanchar(tmp);
38134345a63Smrg                        }
38234345a63Smrg                    }
38334345a63Smrg                }
38434345a63Smrg            }
38534345a63Smrg            else
38634345a63Smrg                return ERROR_TOK;
38734345a63Smrg        }
38883e5f723Smrg        if (i < sizeof(scanBuf) - 1)
38983e5f723Smrg            scanBuf[i++] = ch;
390f46a6179Smrg    }
391c82dfdfbSmrg    scanBuf[i] = '\0';
39234345a63Smrg    if (ch == '"')
39334345a63Smrg    {
39434345a63Smrg        scanStrLine = lineNum;
39534345a63Smrg        return STRING;
396f46a6179Smrg    }
397f46a6179Smrg    return ERROR_TOK;
398f46a6179Smrg}
399f46a6179Smrg
400f46a6179Smrgstatic int
401f46a6179SmrgyyGetKeyName(void)
402f46a6179Smrg{
40383e5f723Smrg    int ch, i;
404f46a6179Smrg
40583e5f723Smrg    i = 0;
40683e5f723Smrg    while (((ch = scanchar()) != EOF) && (ch != '>'))
40734345a63Smrg    {
40834345a63Smrg        if (ch == '\\')
40934345a63Smrg        {
41083e5f723Smrg            if ((ch = scanchar()) != EOF)
41134345a63Smrg            {
41234345a63Smrg                if (ch == 'n')
41334345a63Smrg                    ch = '\n';
41434345a63Smrg                else if (ch == 't')
41534345a63Smrg                    ch = '\t';
41634345a63Smrg                else if (ch == 'v')
41734345a63Smrg                    ch = '\v';
41834345a63Smrg                else if (ch == 'b')
41934345a63Smrg                    ch = '\b';
42034345a63Smrg                else if (ch == 'r')
42134345a63Smrg                    ch = '\r';
42234345a63Smrg                else if (ch == 'f')
42334345a63Smrg                    ch = '\f';
42434345a63Smrg                else if (ch == 'e')
42534345a63Smrg                    ch = '\033';
42634345a63Smrg                else if (ch == '0')
42734345a63Smrg                {
42834345a63Smrg                    int tmp, stop;
42934345a63Smrg                    ch = stop = 0;
43083e5f723Smrg                    if (((tmp = scanchar()) != EOF) && (isdigit(tmp))
43134345a63Smrg                        && (tmp != '8') && (tmp != '9'))
43234345a63Smrg                    {
43334345a63Smrg                        ch = (ch * 8) + (tmp - '0');
43434345a63Smrg                    }
43534345a63Smrg                    else
43634345a63Smrg                    {
43734345a63Smrg                        stop = 1;
43883e5f723Smrg                        unscanchar(tmp);
43934345a63Smrg                    }
44083e5f723Smrg                    if ((!stop) && ((tmp = scanchar()) != EOF)
44134345a63Smrg                        && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
44234345a63Smrg                    {
44334345a63Smrg                        ch = (ch * 8) + (tmp - '0');
44434345a63Smrg                    }
44534345a63Smrg                    else
44634345a63Smrg                    {
44734345a63Smrg                        stop = 1;
44883e5f723Smrg                        unscanchar(tmp);
44934345a63Smrg                    }
45083e5f723Smrg                    if ((!stop) && ((tmp = scanchar()) != EOF)
45134345a63Smrg                        && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
45234345a63Smrg                    {
45334345a63Smrg                        ch = (ch * 8) + (tmp - '0');
45434345a63Smrg                    }
45534345a63Smrg                    else
45634345a63Smrg                    {
45734345a63Smrg                        stop = 1;
45883e5f723Smrg                        unscanchar(tmp);
45934345a63Smrg                    }
46034345a63Smrg                }
46134345a63Smrg            }
46234345a63Smrg            else
46334345a63Smrg                return ERROR_TOK;
46434345a63Smrg        }
46583e5f723Smrg        if (i < sizeof(scanBuf) - 1)
46683e5f723Smrg            scanBuf[i++] = ch;
467f46a6179Smrg    }
468c82dfdfbSmrg    scanBuf[i] = '\0';
46983e5f723Smrg    if ((ch == '>') && (i < 5))
47034345a63Smrg    {
47134345a63Smrg        scanStrLine = lineNum;
47234345a63Smrg        return KEYNAME;
473f46a6179Smrg    }
474f46a6179Smrg    return ERROR_TOK;
475f46a6179Smrg}
476f46a6179Smrg
47734345a63Smrgstatic struct _Keyword
47834345a63Smrg{
47934345a63Smrg    const char *keyword;
48034345a63Smrg    int token;
48134345a63Smrg} keywords[] =
48234345a63Smrg{
48334345a63Smrg    {
48434345a63Smrg    "xkb_keymap", XKB_KEYMAP},
48534345a63Smrg    {
48634345a63Smrg    "xkb_keycodes", XKB_KEYCODES},
48734345a63Smrg    {
48834345a63Smrg    "xkb_types", XKB_TYPES},
48934345a63Smrg    {
49034345a63Smrg    "xkb_symbols", XKB_SYMBOLS},
49134345a63Smrg    {
49234345a63Smrg    "xkb_compat", XKB_COMPATMAP},
49334345a63Smrg    {
49434345a63Smrg    "xkb_compat_map", XKB_COMPATMAP},
49534345a63Smrg    {
49634345a63Smrg    "xkb_compatibility", XKB_COMPATMAP},
49734345a63Smrg    {
49834345a63Smrg    "xkb_compatibility_map", XKB_COMPATMAP},
49934345a63Smrg    {
50034345a63Smrg    "xkb_geometry", XKB_GEOMETRY},
50134345a63Smrg    {
50234345a63Smrg    "xkb_semantics", XKB_SEMANTICS},
50334345a63Smrg    {
50434345a63Smrg    "xkb_layout", XKB_LAYOUT},
50534345a63Smrg    {
50634345a63Smrg    "include", INCLUDE},
50734345a63Smrg    {
50834345a63Smrg    "override", OVERRIDE},
50934345a63Smrg    {
51034345a63Smrg    "augment", AUGMENT},
51134345a63Smrg    {
51234345a63Smrg    "replace", REPLACE},
51334345a63Smrg    {
51434345a63Smrg    "alternate", ALTERNATE},
51534345a63Smrg    {
51634345a63Smrg    "partial", PARTIAL},
51734345a63Smrg    {
51834345a63Smrg    "default", DEFAULT},
51934345a63Smrg    {
52034345a63Smrg    "hidden", HIDDEN},
52134345a63Smrg    {
52234345a63Smrg    "virtual_modifiers", VIRTUAL_MODS},
52334345a63Smrg    {
52434345a63Smrg    "type", TYPE},
52534345a63Smrg    {
52634345a63Smrg    "interpret", INTERPRET},
52734345a63Smrg    {
52834345a63Smrg    "action", ACTION_TOK},
52934345a63Smrg    {
53034345a63Smrg    "key", KEY},
53134345a63Smrg    {
53234345a63Smrg    "alias", ALIAS},
53334345a63Smrg    {
53434345a63Smrg    "group", GROUP},
53534345a63Smrg    {
53634345a63Smrg    "modmap", MODIFIER_MAP},
53734345a63Smrg    {
53834345a63Smrg    "mod_map", MODIFIER_MAP},
53934345a63Smrg    {
54034345a63Smrg    "modifier_map", MODIFIER_MAP},
54134345a63Smrg    {
54234345a63Smrg    "indicator", INDICATOR},
54334345a63Smrg    {
54434345a63Smrg    "shape", SHAPE},
54534345a63Smrg    {
54634345a63Smrg    "row", ROW},
54734345a63Smrg    {
54834345a63Smrg    "keys", KEYS},
54934345a63Smrg    {
55034345a63Smrg    "section", SECTION},
55134345a63Smrg    {
55234345a63Smrg    "overlay", OVERLAY},
55334345a63Smrg    {
55434345a63Smrg    "text", TEXT},
55534345a63Smrg    {
55634345a63Smrg    "outline", OUTLINE},
55734345a63Smrg    {
55834345a63Smrg    "solid", SOLID},
55934345a63Smrg    {
56034345a63Smrg    "logo", LOGO},
56134345a63Smrg    {
56234345a63Smrg    "virtual", VIRTUAL},
56334345a63Smrg    {
56434345a63Smrg    "alphanumeric_keys", ALPHANUMERIC_KEYS},
56534345a63Smrg    {
56634345a63Smrg    "modifier_keys", MODIFIER_KEYS},
56734345a63Smrg    {
56834345a63Smrg    "keypad_keys", KEYPAD_KEYS},
56934345a63Smrg    {
57034345a63Smrg    "function_keys", FUNCTION_KEYS},
57134345a63Smrg    {
57234345a63Smrg    "alternate_group", ALTERNATE_GROUP}
573f46a6179Smrg};
57434345a63Smrgstatic int numKeywords = sizeof(keywords) / sizeof(struct _Keyword);
575f46a6179Smrg
576f46a6179Smrgstatic int
577f46a6179SmrgyyGetIdent(int first)
578f46a6179Smrg{
57983e5f723Smrg    int ch, i, j, found;
58034345a63Smrg    int rtrn = IDENT;
58134345a63Smrg
58283e5f723Smrg    scanBuf[0] = first;
58383e5f723Smrg    j = 1;
58483e5f723Smrg    while (((ch = scanchar()) != EOF) && (isalnum(ch) || (ch == '_')))
58534345a63Smrg    {
58683e5f723Smrg        if (j < sizeof(scanBuf) - 1)
58783e5f723Smrg            scanBuf[j++] = ch;
588f46a6179Smrg    }
58983e5f723Smrg    scanBuf[j++] = '\0';
59034345a63Smrg    found = 0;
59134345a63Smrg
59234345a63Smrg    for (i = 0; (!found) && (i < numKeywords); i++)
59334345a63Smrg    {
59483e5f723Smrg        if (uStrCaseCmp(scanBuf, keywords[i].keyword) == 0)
59534345a63Smrg        {
59634345a63Smrg            rtrn = keywords[i].token;
59734345a63Smrg            found = 1;
59834345a63Smrg        }
599f46a6179Smrg    }
60034345a63Smrg    if (!found)
60134345a63Smrg    {
60234345a63Smrg        scanStrLine = lineNum;
60334345a63Smrg        rtrn = IDENT;
604f46a6179Smrg    }
605f46a6179Smrg
60634345a63Smrg    if ((ch != EOF) && (!isspace(ch)))
60783e5f723Smrg        unscanchar(ch);
60834345a63Smrg    else if (ch == '\n')
60934345a63Smrg        lineNum++;
610f46a6179Smrg
611f46a6179Smrg    return rtrn;
612f46a6179Smrg}
613f46a6179Smrg
614f46a6179Smrgstatic int
615f46a6179SmrgyyGetNumber(int ch)
616f46a6179Smrg{
617690143ccSmrg    const int nMaxBuffSize = 1024;
61834345a63Smrg    int isFloat = 0;
619690143ccSmrg    char buf[nMaxBuffSize];
62083e5f723Smrg    int nInBuf = 0;
62134345a63Smrg
62234345a63Smrg    buf[0] = ch;
62334345a63Smrg    nInBuf = 1;
62483e5f723Smrg    while (((ch = scanchar()) != EOF)
625690143ccSmrg           && (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x')))
6261d8c7986Smrg           && nInBuf < (nMaxBuffSize - 1))
62734345a63Smrg    {
62834345a63Smrg        buf[nInBuf++] = ch;
629f46a6179Smrg    }
6301d8c7986Smrg    if ((ch == '.') && (nInBuf < (nMaxBuffSize - 1)))
63134345a63Smrg    {
63234345a63Smrg        isFloat = 1;
63334345a63Smrg        buf[nInBuf++] = ch;
634690143ccSmrg        while (((ch = scanchar()) != EOF) && (isxdigit(ch))
6351d8c7986Smrg               && nInBuf < (nMaxBuffSize - 1))
63634345a63Smrg        {
63734345a63Smrg            buf[nInBuf++] = ch;
63834345a63Smrg        }
639f46a6179Smrg    }
64034345a63Smrg    buf[nInBuf++] = '\0';
64134345a63Smrg    if ((ch != EOF) && (!isspace(ch)))
64283e5f723Smrg        unscanchar(ch);
64334345a63Smrg
64434345a63Smrg    if (isFloat)
64534345a63Smrg    {
64634345a63Smrg        float tmp;
64734345a63Smrg        if (sscanf(buf, "%g", &tmp) == 1)
64834345a63Smrg        {
64934345a63Smrg            scanInt = tmp * XkbGeomPtsPerMM;
65034345a63Smrg            return FLOAT;
65134345a63Smrg        }
652f46a6179Smrg    }
65334345a63Smrg    else if (sscanf(buf, "%i", &scanInt) == 1)
65434345a63Smrg        return INTEGER;
65534345a63Smrg    fprintf(stderr, "Malformed number %s\n", buf);
656f46a6179Smrg    return ERROR_TOK;
657f46a6179Smrg}
658f46a6179Smrg
659f46a6179Smrgint
660f46a6179Smrgyylex(void)
661f46a6179Smrg{
66234345a63Smrg    int ch;
66334345a63Smrg    int rtrn;
66434345a63Smrg
66534345a63Smrg    do
66634345a63Smrg    {
66783e5f723Smrg        ch = scanchar();
66834345a63Smrg        if (ch == '\n')
66934345a63Smrg        {
67034345a63Smrg            lineNum++;
67134345a63Smrg        }
67234345a63Smrg        else if (ch == '#')
67334345a63Smrg        {                       /* handle shell style '#' comments */
67434345a63Smrg            do
67534345a63Smrg            {
67683e5f723Smrg                ch = scanchar();
67734345a63Smrg            }
67834345a63Smrg            while ((ch != '\n') && (ch != EOF));
67934345a63Smrg            lineNum++;
68034345a63Smrg        }
68134345a63Smrg        else if (ch == '/')
68234345a63Smrg        {                       /* handle C++ style double-/ comments */
68383e5f723Smrg            int newch = scanchar();
68434345a63Smrg            if (newch == '/')
68534345a63Smrg            {
68634345a63Smrg                do
68734345a63Smrg                {
68883e5f723Smrg                    ch = scanchar();
68934345a63Smrg                }
69034345a63Smrg                while ((ch != '\n') && (ch != EOF));
69134345a63Smrg                lineNum++;
69234345a63Smrg            }
69334345a63Smrg            else if (newch != EOF)
69434345a63Smrg            {
69583e5f723Smrg                unscanchar(newch);
69634345a63Smrg            }
69734345a63Smrg        }
69834345a63Smrg    }
69934345a63Smrg    while ((ch != EOF) && (isspace(ch)));
70034345a63Smrg    if (ch == '=')
70134345a63Smrg        rtrn = EQUALS;
70234345a63Smrg    else if (ch == '+')
70334345a63Smrg        rtrn = PLUS;
70434345a63Smrg    else if (ch == '-')
70534345a63Smrg        rtrn = MINUS;
70634345a63Smrg    else if (ch == '/')
70734345a63Smrg        rtrn = DIVIDE;
70834345a63Smrg    else if (ch == '*')
70934345a63Smrg        rtrn = TIMES;
71034345a63Smrg    else if (ch == '{')
71134345a63Smrg        rtrn = OBRACE;
71234345a63Smrg    else if (ch == '}')
71334345a63Smrg        rtrn = CBRACE;
71434345a63Smrg    else if (ch == '(')
71534345a63Smrg        rtrn = OPAREN;
71634345a63Smrg    else if (ch == ')')
71734345a63Smrg        rtrn = CPAREN;
71834345a63Smrg    else if (ch == '[')
71934345a63Smrg        rtrn = OBRACKET;
72034345a63Smrg    else if (ch == ']')
72134345a63Smrg        rtrn = CBRACKET;
72234345a63Smrg    else if (ch == '.')
72334345a63Smrg        rtrn = DOT;
72434345a63Smrg    else if (ch == ',')
72534345a63Smrg        rtrn = COMMA;
72634345a63Smrg    else if (ch == ';')
72734345a63Smrg        rtrn = SEMI;
72834345a63Smrg    else if (ch == '!')
72934345a63Smrg        rtrn = EXCLAM;
73034345a63Smrg    else if (ch == '~')
73134345a63Smrg        rtrn = INVERT;
73234345a63Smrg    else if (ch == '"')
73334345a63Smrg        rtrn = yyGetString();
73434345a63Smrg    else if (ch == '<')
73534345a63Smrg        rtrn = yyGetKeyName();
73634345a63Smrg    else if (isalpha(ch) || (ch == '_'))
73734345a63Smrg        rtrn = yyGetIdent(ch);
73834345a63Smrg    else if (isdigit(ch))
73934345a63Smrg        rtrn = yyGetNumber(ch);
74034345a63Smrg    else if (ch == EOF)
74134345a63Smrg        rtrn = END_OF_FILE;
74234345a63Smrg    else
74334345a63Smrg    {
744f46a6179Smrg#ifdef DEBUG
74534345a63Smrg        if (debugFlags)
74634345a63Smrg            fprintf(stderr,
74734345a63Smrg                    "Unexpected character %c (%d) in input stream\n", ch, ch);
748f46a6179Smrg#endif
74934345a63Smrg        rtrn = ERROR_TOK;
750f46a6179Smrg    }
751f46a6179Smrg#ifdef DEBUG
75234345a63Smrg    if (debugFlags & 0x2)
75334345a63Smrg        fprintf(stderr, "scan: %s\n", tokText(rtrn));
754f46a6179Smrg#endif
755f46a6179Smrg    return rtrn;
756f46a6179Smrg}
757