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
9bfe6082cSmrg documentation, and that the name of Silicon Graphics not be
10bfe6082cSmrg used in advertising or publicity pertaining to distribution
11f46a6179Smrg of the software without specific prior written permission.
12bfe6082cSmrg 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.
15bfe6082cSmrg
16bfe6082cSmrg SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17bfe6082cSmrg SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18f46a6179Smrg AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19bfe6082cSmrg GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20bfe6082cSmrg DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21bfe6082cSmrg 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
396930ead5Smrg#ifdef DEBUG
4034345a63Smrgunsigned int scanDebug;
416930ead5Smrg#endif
42f46a6179Smrg
43c82dfdfbSmrgstatic FILE *yyin;
44f46a6179Smrg
4534345a63Smrgstatic char scanFileBuf[1024] = {0};
4634345a63Smrgchar *scanFile = scanFileBuf;
4734345a63Smrgint lineNum = 0;
48f46a6179Smrg
4934345a63Smrgint scanInt;
5034345a63Smrg
5183e5f723Smrgchar scanBuf[1024];
5234345a63Smrgstatic int scanStrLine = 0;
53f46a6179Smrg
5483e5f723Smrg#define	BUFSIZE	4096
5583e5f723Smrgstatic char readBuf[BUFSIZE];
5683e5f723Smrgstatic int readBufPos = 0;
5783e5f723Smrgstatic int readBufLen = 0;
58f46a6179Smrg
59f46a6179Smrg#ifdef DEBUG
6083e5f723Smrgextern int debugFlags;
6183e5f723Smrg
62f46a6179Smrgstatic char *
63f46a6179SmrgtokText(int tok)
64f46a6179Smrg{
6534345a63Smrg    static char buf[32];
6634345a63Smrg
6734345a63Smrg    switch (tok)
6834345a63Smrg    {
6934345a63Smrg    case END_OF_FILE:
7034345a63Smrg        snprintf(buf, sizeof(buf), "END_OF_FILE");
7134345a63Smrg        break;
7234345a63Smrg    case ERROR_TOK:
7334345a63Smrg        snprintf(buf, sizeof(buf), "ERROR");
7434345a63Smrg        break;
7534345a63Smrg
7634345a63Smrg    case XKB_KEYMAP:
7734345a63Smrg        snprintf(buf, sizeof(buf), "XKB_KEYMAP");
7834345a63Smrg        break;
7934345a63Smrg    case XKB_KEYCODES:
8034345a63Smrg        snprintf(buf, sizeof(buf), "XKB_KEYCODES");
8134345a63Smrg        break;
8234345a63Smrg    case XKB_TYPES:
8334345a63Smrg        snprintf(buf, sizeof(buf), "XKB_TYPES");
8434345a63Smrg        break;
8534345a63Smrg    case XKB_SYMBOLS:
8634345a63Smrg        snprintf(buf, sizeof(buf), "XKB_SYMBOLS");
8734345a63Smrg        break;
8834345a63Smrg    case XKB_COMPATMAP:
8934345a63Smrg        snprintf(buf, sizeof(buf), "XKB_COMPATMAP");
9034345a63Smrg        break;
9134345a63Smrg    case XKB_GEOMETRY:
9234345a63Smrg        snprintf(buf, sizeof(buf), "XKB_GEOMETRY");
9334345a63Smrg        break;
9434345a63Smrg    case XKB_SEMANTICS:
9534345a63Smrg        snprintf(buf, sizeof(buf), "XKB_SEMANTICS");
9634345a63Smrg        break;
9734345a63Smrg    case XKB_LAYOUT:
9834345a63Smrg        snprintf(buf, sizeof(buf), "XKB_LAYOUT");
9934345a63Smrg        break;
10034345a63Smrg
10134345a63Smrg    case INCLUDE:
10234345a63Smrg        snprintf(buf, sizeof(buf), "INCLUDE");
10334345a63Smrg        break;
10434345a63Smrg    case OVERRIDE:
10534345a63Smrg        snprintf(buf, sizeof(buf), "OVERRIDE");
10634345a63Smrg        break;
10734345a63Smrg    case AUGMENT:
10834345a63Smrg        snprintf(buf, sizeof(buf), "AUGMENT");
10934345a63Smrg        break;
11034345a63Smrg    case REPLACE:
11134345a63Smrg        snprintf(buf, sizeof(buf), "REPLACE");
11234345a63Smrg        break;
11334345a63Smrg    case ALTERNATE:
11434345a63Smrg        snprintf(buf, sizeof(buf), "ALTERNATE");
11534345a63Smrg        break;
11634345a63Smrg
11734345a63Smrg    case VIRTUAL_MODS:
11834345a63Smrg        snprintf(buf, sizeof(buf), "VIRTUAL_MODS");
11934345a63Smrg        break;
12034345a63Smrg    case TYPE:
12134345a63Smrg        snprintf(buf, sizeof(buf), "TYPE");
12234345a63Smrg        break;
12334345a63Smrg    case INTERPRET:
12434345a63Smrg        snprintf(buf, sizeof(buf), "INTERPRET");
12534345a63Smrg        break;
12634345a63Smrg    case ACTION_TOK:
12734345a63Smrg        snprintf(buf, sizeof(buf), "ACTION");
12834345a63Smrg        break;
12934345a63Smrg    case KEY:
13034345a63Smrg        snprintf(buf, sizeof(buf), "KEY");
13134345a63Smrg        break;
13234345a63Smrg    case ALIAS:
13334345a63Smrg        snprintf(buf, sizeof(buf), "ALIAS");
13434345a63Smrg        break;
13534345a63Smrg    case GROUP:
13634345a63Smrg        snprintf(buf, sizeof(buf), "GROUP");
13734345a63Smrg        break;
13834345a63Smrg    case MODIFIER_MAP:
13934345a63Smrg        snprintf(buf, sizeof(buf), "MODIFIER_MAP");
14034345a63Smrg        break;
14134345a63Smrg    case INDICATOR:
14234345a63Smrg        snprintf(buf, sizeof(buf), "INDICATOR");
14334345a63Smrg        break;
14434345a63Smrg    case SHAPE:
14534345a63Smrg        snprintf(buf, sizeof(buf), "SHAPE");
14634345a63Smrg        break;
14734345a63Smrg    case KEYS:
14834345a63Smrg        snprintf(buf, sizeof(buf), "KEYS");
14934345a63Smrg        break;
15034345a63Smrg    case ROW:
15134345a63Smrg        snprintf(buf, sizeof(buf), "ROW");
15234345a63Smrg        break;
15334345a63Smrg    case SECTION:
15434345a63Smrg        snprintf(buf, sizeof(buf), "SECTION");
15534345a63Smrg        break;
15634345a63Smrg    case OVERLAY:
15734345a63Smrg        snprintf(buf, sizeof(buf), "OVERLAY");
15834345a63Smrg        break;
15934345a63Smrg    case TEXT:
16034345a63Smrg        snprintf(buf, sizeof(buf), "TEXT");
16134345a63Smrg        break;
16234345a63Smrg    case OUTLINE:
16334345a63Smrg        snprintf(buf, sizeof(buf), "OUTLINE");
16434345a63Smrg        break;
16534345a63Smrg    case SOLID:
16634345a63Smrg        snprintf(buf, sizeof(buf), "SOLID");
16734345a63Smrg        break;
16834345a63Smrg    case LOGO:
16934345a63Smrg        snprintf(buf, sizeof(buf), "LOGO");
17034345a63Smrg        break;
17134345a63Smrg    case VIRTUAL:
17234345a63Smrg        snprintf(buf, sizeof(buf), "VIRTUAL");
17334345a63Smrg        break;
17434345a63Smrg
17534345a63Smrg    case EQUALS:
17634345a63Smrg        snprintf(buf, sizeof(buf), "EQUALS");
17734345a63Smrg        break;
17834345a63Smrg    case PLUS:
17934345a63Smrg        snprintf(buf, sizeof(buf), "PLUS");
18034345a63Smrg        break;
18134345a63Smrg    case MINUS:
18234345a63Smrg        snprintf(buf, sizeof(buf), "MINUS");
18334345a63Smrg        break;
18434345a63Smrg    case DIVIDE:
18534345a63Smrg        snprintf(buf, sizeof(buf), "DIVIDE");
18634345a63Smrg        break;
18734345a63Smrg    case TIMES:
18834345a63Smrg        snprintf(buf, sizeof(buf), "TIMES");
18934345a63Smrg        break;
19034345a63Smrg    case OBRACE:
19134345a63Smrg        snprintf(buf, sizeof(buf), "OBRACE");
19234345a63Smrg        break;
19334345a63Smrg    case CBRACE:
19434345a63Smrg        snprintf(buf, sizeof(buf), "CBRACE");
19534345a63Smrg        break;
19634345a63Smrg    case OPAREN:
19734345a63Smrg        snprintf(buf, sizeof(buf), "OPAREN");
19834345a63Smrg        break;
19934345a63Smrg    case CPAREN:
20034345a63Smrg        snprintf(buf, sizeof(buf), "CPAREN");
20134345a63Smrg        break;
20234345a63Smrg    case OBRACKET:
20334345a63Smrg        snprintf(buf, sizeof(buf), "OBRACKET");
20434345a63Smrg        break;
20534345a63Smrg    case CBRACKET:
20634345a63Smrg        snprintf(buf, sizeof(buf), "CBRACKET");
20734345a63Smrg        break;
20834345a63Smrg    case DOT:
20934345a63Smrg        snprintf(buf, sizeof(buf), "DOT");
21034345a63Smrg        break;
21134345a63Smrg    case COMMA:
21234345a63Smrg        snprintf(buf, sizeof(buf), "COMMA");
21334345a63Smrg        break;
21434345a63Smrg    case SEMI:
21534345a63Smrg        snprintf(buf, sizeof(buf), "SEMI");
21634345a63Smrg        break;
21734345a63Smrg    case EXCLAM:
21834345a63Smrg        snprintf(buf, sizeof(buf), "EXCLAM");
21934345a63Smrg        break;
22034345a63Smrg    case INVERT:
22134345a63Smrg        snprintf(buf, sizeof(buf), "INVERT");
22234345a63Smrg        break;
22334345a63Smrg
22434345a63Smrg    case STRING:
22583e5f723Smrg        snprintf(buf, sizeof(buf), "STRING (%s)", scanBuf);
22634345a63Smrg        break;
22734345a63Smrg    case INTEGER:
22834345a63Smrg        snprintf(buf, sizeof(buf), "INTEGER (0x%x)", scanInt);
22934345a63Smrg        break;
23034345a63Smrg    case FLOAT:
23134345a63Smrg        snprintf(buf, sizeof(buf), "FLOAT (%d.%d)",
23234345a63Smrg                scanInt / XkbGeomPtsPerMM, scanInt % XkbGeomPtsPerMM);
23334345a63Smrg        break;
23434345a63Smrg    case IDENT:
23583e5f723Smrg        snprintf(buf, sizeof(buf), "IDENT (%s)", scanBuf);
23634345a63Smrg        break;
23734345a63Smrg    case KEYNAME:
23883e5f723Smrg        snprintf(buf, sizeof(buf), "KEYNAME (%s)", scanBuf);
23934345a63Smrg        break;
24034345a63Smrg
24134345a63Smrg    case PARTIAL:
24234345a63Smrg        snprintf(buf, sizeof(buf), "PARTIAL");
24334345a63Smrg        break;
24434345a63Smrg    case DEFAULT:
24534345a63Smrg        snprintf(buf, sizeof(buf), "DEFAULT");
24634345a63Smrg        break;
24734345a63Smrg    case HIDDEN:
24834345a63Smrg        snprintf(buf, sizeof(buf), "HIDDEN");
24934345a63Smrg        break;
25034345a63Smrg
25134345a63Smrg    case ALPHANUMERIC_KEYS:
25234345a63Smrg        snprintf(buf, sizeof(buf), "ALPHANUMERIC_KEYS");
25334345a63Smrg        break;
25434345a63Smrg    case MODIFIER_KEYS:
25534345a63Smrg        snprintf(buf, sizeof(buf), "MODIFIER_KEYS");
25634345a63Smrg        break;
25734345a63Smrg    case KEYPAD_KEYS:
25834345a63Smrg        snprintf(buf, sizeof(buf), "KEYPAD_KEYS");
25934345a63Smrg        break;
26034345a63Smrg    case FUNCTION_KEYS:
26134345a63Smrg        snprintf(buf, sizeof(buf), "FUNCTION_KEYS");
26234345a63Smrg        break;
26334345a63Smrg    case ALTERNATE_GROUP:
26434345a63Smrg        snprintf(buf, sizeof(buf), "ALTERNATE_GROUP");
26534345a63Smrg        break;
26634345a63Smrg
26734345a63Smrg    default:
26834345a63Smrg        snprintf(buf, sizeof(buf), "UNKNOWN");
26934345a63Smrg        break;
270f46a6179Smrg    }
271f46a6179Smrg    return buf;
272f46a6179Smrg}
273f46a6179Smrg#endif
274f46a6179Smrg
275c82dfdfbSmrgvoid
276c82dfdfbSmrgscan_set_file(FILE *file)
277c82dfdfbSmrg{
278c82dfdfbSmrg    readBufLen = 0;
279c82dfdfbSmrg    readBufPos = 0;
280c82dfdfbSmrg    yyin = file;
281c82dfdfbSmrg}
282c82dfdfbSmrg
28383e5f723Smrgstatic int
28483e5f723Smrgscanchar(void)
28583e5f723Smrg{
28683e5f723Smrg    if (readBufPos >= readBufLen) {
28783e5f723Smrg        readBufLen = fread(readBuf, 1, BUFSIZE, yyin);
28883e5f723Smrg        readBufPos = 0;
28983e5f723Smrg        if (!readBufLen)
29083e5f723Smrg            return EOF;
29183e5f723Smrg        if (feof(yyin))
29283e5f723Smrg            readBuf[readBufLen] = EOF;
29383e5f723Smrg    }
29483e5f723Smrg
29583e5f723Smrg    return readBuf[readBufPos++];
29683e5f723Smrg}
29783e5f723Smrg
29883e5f723Smrgstatic void
29983e5f723Smrgunscanchar(int c)
30083e5f723Smrg{
30183e5f723Smrg    if (readBuf[--readBufPos] != c) {
30283e5f723Smrg        fprintf(stderr, "UNGETCHAR FAILED! Put back %c, was expecting %c at "
30383e5f723Smrg                        "position %d, buf is '%s'\n", c, readBuf[readBufPos],
30483e5f723Smrg                        readBufPos, readBuf);
30583e5f723Smrg        _exit(94);
30683e5f723Smrg    }
30783e5f723Smrg}
30883e5f723Smrg
309f46a6179Smrgint
31034345a63SmrgsetScanState(char *file, int line)
311f46a6179Smrg{
31234345a63Smrg    if (file != NULL)
31334345a63Smrg        strncpy(scanFile, file, 1024);
31434345a63Smrg    if (line >= 0)
31534345a63Smrg        lineNum = line;
316f46a6179Smrg    return 1;
317f46a6179Smrg}
318f46a6179Smrg
319f46a6179Smrgstatic int
320f46a6179SmrgyyGetString(void)
321f46a6179Smrg{
32283e5f723Smrg    int ch, i;
323f46a6179Smrg
32483e5f723Smrg    i = 0;
32583e5f723Smrg    while (((ch = scanchar()) != EOF) && (ch != '"'))
32634345a63Smrg    {
32734345a63Smrg        if (ch == '\\')
32834345a63Smrg        {
32983e5f723Smrg            if ((ch = scanchar()) != EOF)
33034345a63Smrg            {
33134345a63Smrg                if (ch == 'n')
33234345a63Smrg                    ch = '\n';
33334345a63Smrg                else if (ch == 't')
33434345a63Smrg                    ch = '\t';
33534345a63Smrg                else if (ch == 'v')
33634345a63Smrg                    ch = '\v';
33734345a63Smrg                else if (ch == 'b')
33834345a63Smrg                    ch = '\b';
33934345a63Smrg                else if (ch == 'r')
34034345a63Smrg                    ch = '\r';
34134345a63Smrg                else if (ch == 'f')
34234345a63Smrg                    ch = '\f';
34334345a63Smrg                else if (ch == 'e')
34434345a63Smrg                    ch = '\033';
34534345a63Smrg                else if (ch == '0')
34634345a63Smrg                {
34734345a63Smrg                    int tmp, stop;
34834345a63Smrg                    ch = stop = 0;
34983e5f723Smrg                    if (((tmp = scanchar()) != EOF) && (isdigit(tmp))
35034345a63Smrg                        && (tmp != '8') && (tmp != '9'))
35134345a63Smrg                    {
35234345a63Smrg                        ch = (ch * 8) + (tmp - '0');
35334345a63Smrg                    }
35434345a63Smrg                    else
35534345a63Smrg                    {
35634345a63Smrg                        stop = 1;
35783e5f723Smrg                        unscanchar(tmp);
35834345a63Smrg                    }
35934345a63Smrg                    if (!stop)
36034345a63Smrg                    {
36183e5f723Smrg                        if (((tmp = scanchar()) != EOF)
36234345a63Smrg                            && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
36334345a63Smrg                        {
36434345a63Smrg                            ch = (ch * 8) + (tmp - '0');
36534345a63Smrg                        }
36634345a63Smrg                        else
36734345a63Smrg                        {
36834345a63Smrg                            stop = 1;
36983e5f723Smrg                            unscanchar(tmp);
37034345a63Smrg                        }
37134345a63Smrg                    }
37234345a63Smrg                    if (!stop)
37334345a63Smrg                    {
37483e5f723Smrg                        if (((tmp = scanchar()) != EOF)
37534345a63Smrg                            && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
37634345a63Smrg                        {
37734345a63Smrg                            ch = (ch * 8) + (tmp - '0');
37834345a63Smrg                        }
37934345a63Smrg                        else
38034345a63Smrg                        {
38134345a63Smrg                            stop = 1;
38283e5f723Smrg                            unscanchar(tmp);
38334345a63Smrg                        }
38434345a63Smrg                    }
38534345a63Smrg                }
38634345a63Smrg            }
38734345a63Smrg            else
38834345a63Smrg                return ERROR_TOK;
38934345a63Smrg        }
39083e5f723Smrg        if (i < sizeof(scanBuf) - 1)
39183e5f723Smrg            scanBuf[i++] = ch;
392f46a6179Smrg    }
393c82dfdfbSmrg    scanBuf[i] = '\0';
39434345a63Smrg    if (ch == '"')
39534345a63Smrg    {
39634345a63Smrg        scanStrLine = lineNum;
39734345a63Smrg        return STRING;
398f46a6179Smrg    }
399f46a6179Smrg    return ERROR_TOK;
400f46a6179Smrg}
401f46a6179Smrg
402f46a6179Smrgstatic int
403f46a6179SmrgyyGetKeyName(void)
404f46a6179Smrg{
40583e5f723Smrg    int ch, i;
406f46a6179Smrg
40783e5f723Smrg    i = 0;
40883e5f723Smrg    while (((ch = scanchar()) != EOF) && (ch != '>'))
40934345a63Smrg    {
41034345a63Smrg        if (ch == '\\')
41134345a63Smrg        {
41283e5f723Smrg            if ((ch = scanchar()) != EOF)
41334345a63Smrg            {
41434345a63Smrg                if (ch == 'n')
41534345a63Smrg                    ch = '\n';
41634345a63Smrg                else if (ch == 't')
41734345a63Smrg                    ch = '\t';
41834345a63Smrg                else if (ch == 'v')
41934345a63Smrg                    ch = '\v';
42034345a63Smrg                else if (ch == 'b')
42134345a63Smrg                    ch = '\b';
42234345a63Smrg                else if (ch == 'r')
42334345a63Smrg                    ch = '\r';
42434345a63Smrg                else if (ch == 'f')
42534345a63Smrg                    ch = '\f';
42634345a63Smrg                else if (ch == 'e')
42734345a63Smrg                    ch = '\033';
42834345a63Smrg                else if (ch == '0')
42934345a63Smrg                {
43034345a63Smrg                    int tmp, stop;
43134345a63Smrg                    ch = stop = 0;
43283e5f723Smrg                    if (((tmp = scanchar()) != EOF) && (isdigit(tmp))
43334345a63Smrg                        && (tmp != '8') && (tmp != '9'))
43434345a63Smrg                    {
43534345a63Smrg                        ch = (ch * 8) + (tmp - '0');
43634345a63Smrg                    }
43734345a63Smrg                    else
43834345a63Smrg                    {
43934345a63Smrg                        stop = 1;
44083e5f723Smrg                        unscanchar(tmp);
44134345a63Smrg                    }
44283e5f723Smrg                    if ((!stop) && ((tmp = scanchar()) != EOF)
44334345a63Smrg                        && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
44434345a63Smrg                    {
44534345a63Smrg                        ch = (ch * 8) + (tmp - '0');
44634345a63Smrg                    }
44734345a63Smrg                    else
44834345a63Smrg                    {
44934345a63Smrg                        stop = 1;
45083e5f723Smrg                        unscanchar(tmp);
45134345a63Smrg                    }
45283e5f723Smrg                    if ((!stop) && ((tmp = scanchar()) != EOF)
45334345a63Smrg                        && (isdigit(tmp)) && (tmp != '8') && (tmp != '9'))
45434345a63Smrg                    {
45534345a63Smrg                        ch = (ch * 8) + (tmp - '0');
45634345a63Smrg                    }
45734345a63Smrg                    else
45834345a63Smrg                    {
45934345a63Smrg                        stop = 1;
46083e5f723Smrg                        unscanchar(tmp);
46134345a63Smrg                    }
46234345a63Smrg                }
46334345a63Smrg            }
46434345a63Smrg            else
46534345a63Smrg                return ERROR_TOK;
46634345a63Smrg        }
46783e5f723Smrg        if (i < sizeof(scanBuf) - 1)
46883e5f723Smrg            scanBuf[i++] = ch;
469f46a6179Smrg    }
470c82dfdfbSmrg    scanBuf[i] = '\0';
47183e5f723Smrg    if ((ch == '>') && (i < 5))
47234345a63Smrg    {
47334345a63Smrg        scanStrLine = lineNum;
47434345a63Smrg        return KEYNAME;
475f46a6179Smrg    }
476f46a6179Smrg    return ERROR_TOK;
477f46a6179Smrg}
478f46a6179Smrg
47934345a63Smrgstatic struct _Keyword
48034345a63Smrg{
48134345a63Smrg    const char *keyword;
48234345a63Smrg    int token;
48334345a63Smrg} keywords[] =
48434345a63Smrg{
48534345a63Smrg    {
48634345a63Smrg    "xkb_keymap", XKB_KEYMAP},
48734345a63Smrg    {
48834345a63Smrg    "xkb_keycodes", XKB_KEYCODES},
48934345a63Smrg    {
49034345a63Smrg    "xkb_types", XKB_TYPES},
49134345a63Smrg    {
49234345a63Smrg    "xkb_symbols", XKB_SYMBOLS},
49334345a63Smrg    {
49434345a63Smrg    "xkb_compat", XKB_COMPATMAP},
49534345a63Smrg    {
49634345a63Smrg    "xkb_compat_map", XKB_COMPATMAP},
49734345a63Smrg    {
49834345a63Smrg    "xkb_compatibility", XKB_COMPATMAP},
49934345a63Smrg    {
50034345a63Smrg    "xkb_compatibility_map", XKB_COMPATMAP},
50134345a63Smrg    {
50234345a63Smrg    "xkb_geometry", XKB_GEOMETRY},
50334345a63Smrg    {
50434345a63Smrg    "xkb_semantics", XKB_SEMANTICS},
50534345a63Smrg    {
50634345a63Smrg    "xkb_layout", XKB_LAYOUT},
50734345a63Smrg    {
50834345a63Smrg    "include", INCLUDE},
50934345a63Smrg    {
51034345a63Smrg    "override", OVERRIDE},
51134345a63Smrg    {
51234345a63Smrg    "augment", AUGMENT},
51334345a63Smrg    {
51434345a63Smrg    "replace", REPLACE},
51534345a63Smrg    {
51634345a63Smrg    "alternate", ALTERNATE},
51734345a63Smrg    {
51834345a63Smrg    "partial", PARTIAL},
51934345a63Smrg    {
52034345a63Smrg    "default", DEFAULT},
52134345a63Smrg    {
52234345a63Smrg    "hidden", HIDDEN},
52334345a63Smrg    {
52434345a63Smrg    "virtual_modifiers", VIRTUAL_MODS},
52534345a63Smrg    {
52634345a63Smrg    "type", TYPE},
52734345a63Smrg    {
52834345a63Smrg    "interpret", INTERPRET},
52934345a63Smrg    {
53034345a63Smrg    "action", ACTION_TOK},
53134345a63Smrg    {
53234345a63Smrg    "key", KEY},
53334345a63Smrg    {
53434345a63Smrg    "alias", ALIAS},
53534345a63Smrg    {
53634345a63Smrg    "group", GROUP},
53734345a63Smrg    {
53834345a63Smrg    "modmap", MODIFIER_MAP},
53934345a63Smrg    {
54034345a63Smrg    "mod_map", MODIFIER_MAP},
54134345a63Smrg    {
54234345a63Smrg    "modifier_map", MODIFIER_MAP},
54334345a63Smrg    {
54434345a63Smrg    "indicator", INDICATOR},
54534345a63Smrg    {
54634345a63Smrg    "shape", SHAPE},
54734345a63Smrg    {
54834345a63Smrg    "row", ROW},
54934345a63Smrg    {
55034345a63Smrg    "keys", KEYS},
55134345a63Smrg    {
55234345a63Smrg    "section", SECTION},
55334345a63Smrg    {
55434345a63Smrg    "overlay", OVERLAY},
55534345a63Smrg    {
55634345a63Smrg    "text", TEXT},
55734345a63Smrg    {
55834345a63Smrg    "outline", OUTLINE},
55934345a63Smrg    {
56034345a63Smrg    "solid", SOLID},
56134345a63Smrg    {
56234345a63Smrg    "logo", LOGO},
56334345a63Smrg    {
56434345a63Smrg    "virtual", VIRTUAL},
56534345a63Smrg    {
56634345a63Smrg    "alphanumeric_keys", ALPHANUMERIC_KEYS},
56734345a63Smrg    {
56834345a63Smrg    "modifier_keys", MODIFIER_KEYS},
56934345a63Smrg    {
57034345a63Smrg    "keypad_keys", KEYPAD_KEYS},
57134345a63Smrg    {
57234345a63Smrg    "function_keys", FUNCTION_KEYS},
57334345a63Smrg    {
57434345a63Smrg    "alternate_group", ALTERNATE_GROUP}
575f46a6179Smrg};
57634345a63Smrgstatic int numKeywords = sizeof(keywords) / sizeof(struct _Keyword);
577f46a6179Smrg
578f46a6179Smrgstatic int
579f46a6179SmrgyyGetIdent(int first)
580f46a6179Smrg{
5816930ead5Smrg    int ch, j, found;
58234345a63Smrg    int rtrn = IDENT;
58334345a63Smrg
58483e5f723Smrg    scanBuf[0] = first;
58583e5f723Smrg    j = 1;
58683e5f723Smrg    while (((ch = scanchar()) != EOF) && (isalnum(ch) || (ch == '_')))
58734345a63Smrg    {
58883e5f723Smrg        if (j < sizeof(scanBuf) - 1)
58983e5f723Smrg            scanBuf[j++] = ch;
590f46a6179Smrg    }
59183e5f723Smrg    scanBuf[j++] = '\0';
59234345a63Smrg    found = 0;
59334345a63Smrg
5946930ead5Smrg    for (int i = 0; (!found) && (i < numKeywords); i++)
59534345a63Smrg    {
59683e5f723Smrg        if (uStrCaseCmp(scanBuf, keywords[i].keyword) == 0)
59734345a63Smrg        {
59834345a63Smrg            rtrn = keywords[i].token;
59934345a63Smrg            found = 1;
60034345a63Smrg        }
601f46a6179Smrg    }
60234345a63Smrg    if (!found)
60334345a63Smrg    {
60434345a63Smrg        scanStrLine = lineNum;
60534345a63Smrg        rtrn = IDENT;
606f46a6179Smrg    }
607f46a6179Smrg
60834345a63Smrg    if ((ch != EOF) && (!isspace(ch)))
60983e5f723Smrg        unscanchar(ch);
61034345a63Smrg    else if (ch == '\n')
61134345a63Smrg        lineNum++;
612f46a6179Smrg
613f46a6179Smrg    return rtrn;
614f46a6179Smrg}
615f46a6179Smrg
616f46a6179Smrgstatic int
617f46a6179SmrgyyGetNumber(int ch)
618f46a6179Smrg{
619690143ccSmrg    const int nMaxBuffSize = 1024;
62034345a63Smrg    int isFloat = 0;
621690143ccSmrg    char buf[nMaxBuffSize];
62283e5f723Smrg    int nInBuf = 0;
62334345a63Smrg
62434345a63Smrg    buf[0] = ch;
62534345a63Smrg    nInBuf = 1;
62683e5f723Smrg    while (((ch = scanchar()) != EOF)
627690143ccSmrg           && (isxdigit(ch) || ((nInBuf == 1) && (ch == 'x')))
6281d8c7986Smrg           && nInBuf < (nMaxBuffSize - 1))
62934345a63Smrg    {
63034345a63Smrg        buf[nInBuf++] = ch;
631f46a6179Smrg    }
6321d8c7986Smrg    if ((ch == '.') && (nInBuf < (nMaxBuffSize - 1)))
63334345a63Smrg    {
63434345a63Smrg        isFloat = 1;
63534345a63Smrg        buf[nInBuf++] = ch;
636690143ccSmrg        while (((ch = scanchar()) != EOF) && (isxdigit(ch))
6371d8c7986Smrg               && nInBuf < (nMaxBuffSize - 1))
63834345a63Smrg        {
63934345a63Smrg            buf[nInBuf++] = ch;
64034345a63Smrg        }
641f46a6179Smrg    }
64234345a63Smrg    buf[nInBuf++] = '\0';
64334345a63Smrg    if ((ch != EOF) && (!isspace(ch)))
64483e5f723Smrg        unscanchar(ch);
64534345a63Smrg
64634345a63Smrg    if (isFloat)
64734345a63Smrg    {
64834345a63Smrg        float tmp;
64934345a63Smrg        if (sscanf(buf, "%g", &tmp) == 1)
65034345a63Smrg        {
65134345a63Smrg            scanInt = tmp * XkbGeomPtsPerMM;
65234345a63Smrg            return FLOAT;
65334345a63Smrg        }
654f46a6179Smrg    }
65534345a63Smrg    else if (sscanf(buf, "%i", &scanInt) == 1)
65634345a63Smrg        return INTEGER;
65734345a63Smrg    fprintf(stderr, "Malformed number %s\n", buf);
658f46a6179Smrg    return ERROR_TOK;
659f46a6179Smrg}
660f46a6179Smrg
661f46a6179Smrgint
662f46a6179Smrgyylex(void)
663f46a6179Smrg{
66434345a63Smrg    int ch;
66534345a63Smrg    int rtrn;
66634345a63Smrg
66734345a63Smrg    do
66834345a63Smrg    {
66983e5f723Smrg        ch = scanchar();
67034345a63Smrg        if (ch == '\n')
67134345a63Smrg        {
67234345a63Smrg            lineNum++;
67334345a63Smrg        }
67434345a63Smrg        else if (ch == '#')
67534345a63Smrg        {                       /* handle shell style '#' comments */
67634345a63Smrg            do
67734345a63Smrg            {
67883e5f723Smrg                ch = scanchar();
67934345a63Smrg            }
68034345a63Smrg            while ((ch != '\n') && (ch != EOF));
68134345a63Smrg            lineNum++;
68234345a63Smrg        }
68334345a63Smrg        else if (ch == '/')
68434345a63Smrg        {                       /* handle C++ style double-/ comments */
68583e5f723Smrg            int newch = scanchar();
68634345a63Smrg            if (newch == '/')
68734345a63Smrg            {
68834345a63Smrg                do
68934345a63Smrg                {
69083e5f723Smrg                    ch = scanchar();
69134345a63Smrg                }
69234345a63Smrg                while ((ch != '\n') && (ch != EOF));
69334345a63Smrg                lineNum++;
69434345a63Smrg            }
69534345a63Smrg            else if (newch != EOF)
69634345a63Smrg            {
69783e5f723Smrg                unscanchar(newch);
69834345a63Smrg            }
69934345a63Smrg        }
70034345a63Smrg    }
70134345a63Smrg    while ((ch != EOF) && (isspace(ch)));
70234345a63Smrg    if (ch == '=')
70334345a63Smrg        rtrn = EQUALS;
70434345a63Smrg    else if (ch == '+')
70534345a63Smrg        rtrn = PLUS;
70634345a63Smrg    else if (ch == '-')
70734345a63Smrg        rtrn = MINUS;
70834345a63Smrg    else if (ch == '/')
70934345a63Smrg        rtrn = DIVIDE;
71034345a63Smrg    else if (ch == '*')
71134345a63Smrg        rtrn = TIMES;
71234345a63Smrg    else if (ch == '{')
71334345a63Smrg        rtrn = OBRACE;
71434345a63Smrg    else if (ch == '}')
71534345a63Smrg        rtrn = CBRACE;
71634345a63Smrg    else if (ch == '(')
71734345a63Smrg        rtrn = OPAREN;
71834345a63Smrg    else if (ch == ')')
71934345a63Smrg        rtrn = CPAREN;
72034345a63Smrg    else if (ch == '[')
72134345a63Smrg        rtrn = OBRACKET;
72234345a63Smrg    else if (ch == ']')
72334345a63Smrg        rtrn = CBRACKET;
72434345a63Smrg    else if (ch == '.')
72534345a63Smrg        rtrn = DOT;
72634345a63Smrg    else if (ch == ',')
72734345a63Smrg        rtrn = COMMA;
72834345a63Smrg    else if (ch == ';')
72934345a63Smrg        rtrn = SEMI;
73034345a63Smrg    else if (ch == '!')
73134345a63Smrg        rtrn = EXCLAM;
73234345a63Smrg    else if (ch == '~')
73334345a63Smrg        rtrn = INVERT;
73434345a63Smrg    else if (ch == '"')
73534345a63Smrg        rtrn = yyGetString();
73634345a63Smrg    else if (ch == '<')
73734345a63Smrg        rtrn = yyGetKeyName();
73834345a63Smrg    else if (isalpha(ch) || (ch == '_'))
73934345a63Smrg        rtrn = yyGetIdent(ch);
74034345a63Smrg    else if (isdigit(ch))
74134345a63Smrg        rtrn = yyGetNumber(ch);
74234345a63Smrg    else if (ch == EOF)
74334345a63Smrg        rtrn = END_OF_FILE;
74434345a63Smrg    else
74534345a63Smrg    {
746f46a6179Smrg#ifdef DEBUG
74734345a63Smrg        if (debugFlags)
74834345a63Smrg            fprintf(stderr,
74934345a63Smrg                    "Unexpected character %c (%d) in input stream\n", ch, ch);
750f46a6179Smrg#endif
75134345a63Smrg        rtrn = ERROR_TOK;
752f46a6179Smrg    }
753f46a6179Smrg#ifdef DEBUG
75434345a63Smrg    if (debugFlags & 0x2)
75534345a63Smrg        fprintf(stderr, "scan: %s\n", tokText(rtrn));
756f46a6179Smrg#endif
757f46a6179Smrg    return rtrn;
758f46a6179Smrg}
759